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 | |
|---|---|---|---|
after | Date | 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 |
page | number | Obrigatório | Número da página, inteiro a partir de 1. Página além da última responde 200 com data vazio |
pageSize | number | Obrigatório | Itens por página, inteiro de 1 a 50 |
updatedAt | Date | 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/:phone | 422 | Customer not found |
| PUT /customers/:id, DELETE /customers/:id | 404 | Customer not found |
| /products/:id, /products/external/:externalId, /products/name/:name | 404 | Product not found |
| GET /orders/:id, DELETE /orders/:id, GET /orders/external/:externalId | 404 | Order not found |
| PUT /orders/:id | 404 | Pedido não encontrado |
| /abandoned-carts/:id, /abandoned-carts/external/:externalId | 404 | Abandoned Cart not found |
| /stores/:id, /stores/external/:externalId | 404 | Store not found |
| GET /users/:id | 404 | Usuário não encontrado |
| GET /users/email/:email | 422 | Usuário não encontrado |
| DELETE /users/:id | 400 | Usuário não encontrado |
| GET /coupons/:id, /coupons/code/:code, /coupons/external/:externalId | 404 | Coupon not found |
| PUT /coupons/:id | 422 | Coupon not found |
| PUT /webhooks/:id, DELETE /webhooks/:id | 404 | Configuração de webhook não encontrada |
Quer testar os recursos sem montar as requests manualmente? Acesse nosso Swagger diretamente.
Swagger UI →