Z
Zoppy Partners API

Autenticação

Nossa autenticação é do tipo Authorization: Bearer Token, acompanhada do header zoppy-access.

Cadastro de Parceiros

Para iniciar uma nova integração, entre em contato com o time da Zoppy para prosseguir com o cadastro de parceiros integradores: contato@zoppy.com.br

Base URL

Nossa URL base de acesso é https://api-partners.zoppy.com.br , usada diretamente em todas as chamadas.

GET https://api-partners.zoppy.com.br/products

Para testes, use o ambiente de homologação https://api-partners-staging.zoppy.com.br , com as mesmas rotas. O token e a chave zoppy-access de homologação são diferentes dos de produção: peça os dois ao time da Zoppy.

Configuração

Para obter o seu token, basta ir na plataforma da Zoppy, menu principal superior a direita → Chave de API, e copiar o token.

Authorization: Bearer seu_token_aqui

Header de acesso (zoppy-access)

Além do token de autenticação, toda requisição deve incluir o header zoppy-access. Solicite o valor desse header ao time de tecnologia da Zoppy. Ele é validado na nossa camada de borda e, sem ele ou com valor errado, a requisição é recusada com 403 em HTML (página "Just a moment...") antes de chegar à API.

zoppy-access: chave_fornecida_pela_zoppy

Requests

Toda requisição leva os dois headers: Authorization: Bearer {seu_token} e zoppy-access: {sua_chave}. Só o Authorization não basta: sem o zoppy-access, a requisição é recusada com 403 em HTML. Em POST e PUT, envie também Content-Type: application/json.

{
  "headers": {
    "Authorization": "Bearer seu_token_aqui",
    "zoppy-access": "chave_fornecida_pela_zoppy",
    "Content-Type": "application/json"
  }
}

Listas Paginadas

Todo método que retorna uma lista, retorna uma lista paginada. O request obrigatoriamente deverá possuir os campos after, page e pageSize:

Propriedade Tipo Descrição
afterDate Obrigatório Retorna os registros criados a partir desta data (createdAt maior ou igual). Envie data e hora com fuso; sem fuso, ou só a data, vale o horário de Brasília. Ausente ou inválida responde 422 Invalid after date
pagenumber Obrigatório Número da página, inteiro a partir de 1. Página além da última responde 200 com data vazio
pageSizenumber Obrigatório Itens por página, inteiro de 1 a 50
updatedAtDate Opcional Retorna só os registros com updatedAt maior ou igual ao valor. Combinado com after, valem os dois filtros. Envie com fuso: só a data é lida como 00:00 UTC
{
  "after": "2024-01-01T00:00:00-03:00",
  "page": 1,
  "pageSize": 20
}

A resposta traz os registros da página em data e os totais em pagination:

{
  "pagination": {
    "page": 1,
    "pageSize": 20,
    "totalRecords": 1,
    "totalPages": 1
  },
  "data": [
    {
      "id": "6f47b921-2e14-4515-bc6d-a11c42b33dad"
    }
  ]
}

Regras gerais

  • Toda chamada precisa de dois headers: Authorization: Bearer {token} e zoppy-access: {chave}. Sem o zoppy-access, a borda responde 403 em HTML antes de chegar à API.
  • O token identifica a empresa: não existe parâmetro de empresa nas chamadas. Não há renovação automática do token; se ele vazar, peça a revogação ao time da Zoppy. Envie o prefixo Bearer com B maiúsculo.
  • Envie Content-Type: application/json, os nomes exatos dos campos e números como número (não como texto). Sem esse header o corpo é ignorado e o 400 lista os campos como ausentes. Campos desconhecidos são ignorados sem aviso. JSON malformado responde 400.
  • Criações e atualizações respondem 200, nunca 201. DELETE responde {"result": true}, exceto DELETE /users/:id, que responde 200 sem corpo.
  • Validação de campo responde 400 com message em lista. Regra de negócio responde 422 com message em texto, com várias regras juntas separadas por vírgula. O 400 vem antes do 422. Erro interno responde 500 {"statusCode": 500, "message": "Internal server error"}.
  • Envie sempre data e hora com fuso, ex. 2026-09-05T10:26:00-03:00. Sem fuso, a Zoppy lê o horário de Brasília. Só a data no corpo (2026-09-05) vira 00:00 UTC. O formato 05/09/2026 é lido como mês/dia (9 de maio). As datas voltam em UTC, com Z.
  • Mande sempre externalId em loja, pedido e carrinho: sem ele, cada POST cria um registro novo. Cliente é identificado pelo telefone e produto pelo nome (mais provider, quando enviado): reenviar devolve o cadastro existente sem alterá-lo.
  • Toda listagem responde { "pagination": { "page", "pageSize", "totalRecords", "totalPages" }, "data": [...] }. Página além da última responde 200 com data vazio. A API não garante ordenação.
  • A resposta de POST e PUT pode repetir o corpo enviado em vez do valor gravado. Para conferir o que foi gravado, releia com GET.

Registro não encontrado

O status de registro inexistente muda conforme o recurso e o verbo:

Rota Status Mensagem
GET /customers/:id, /customers/external/:externalId, /customers/phone/:phone422Customer not found
PUT /customers/:id, DELETE /customers/:id404Customer not found
/products/:id, /products/external/:externalId, /products/name/:name404Product not found
GET /orders/:id, DELETE /orders/:id, GET /orders/external/:externalId404Order not found
PUT /orders/:id404Pedido não encontrado
/abandoned-carts/:id, /abandoned-carts/external/:externalId404Abandoned Cart not found
/stores/:id, /stores/external/:externalId404Store not found
GET /users/:id404Usuário não encontrado
GET /users/email/:email422Usuário não encontrado
DELETE /users/:id400Usuário não encontrado
GET /coupons/:id, /coupons/code/:code, /coupons/external/:externalId404Coupon not found
PUT /coupons/:id422Coupon not found
PUT /webhooks/:id, DELETE /webhooks/:id404Configuração de webhook não encontrada

Quer testar os recursos sem montar as requests manualmente? Acesse nosso Swagger diretamente.

Swagger UI →