Convenções da API
O endereço base, o cabeçalho de versão, o formato de requisição e resposta, como dinheiro, datas e IDs são representados, a tabela de erros, idempotência, paginação, limites de requisições, o cabeçalho Request-Id e o que muda em relação à Stripe.
A API do Vipter segue as convenções da API da Stripe sempre que existe um equivalente: nomes de campos, formato de erro, paginação por cursor, idempotência e versão por data. Quem já integrou a Stripe reconhece tudo. Esta página reúne o que vale para todos os endpoints; cada endpoint está na referência.
Endereço base
https://api.vipter.com/v1O mesmo serviço responde em https://app.vipter.com/api/v1, com os mesmos caminhos. Use api.vipter.com nas integrações novas; o outro endereço existe para ambientes onde só o domínio do painel está liberado na rede.
Toda chamada é HTTPS. Uma URL fora de /v1 ou um caminho que não existe recebe 404 resource_missing, no mesmo formato dos outros erros.
Versão
A API tem versões por data. A versão atual é 2026-11-01, a única que existe hoje.
Cada chave de API nasce presa à versão atual do dia em que foi criada, e as requisições com ela usam essa versão sem precisar dizer nada. Para pedir outra versão numa chamada, envie o cabeçalho:
Vipter-Version: 2026-11-01Uma versão desconhecida recebe 400 invalid_api_version, com a lista das versões aceitas na mensagem. Toda resposta autenticada traz o cabeçalho Vipter-Version com a versão usada.
Dentro de uma versão, a API só muda de forma compatível: campos novos podem aparecer em qualquer objeto a qualquer momento, e valores novos podem aparecer em campos de texto como status e payment_method. Escreva o seu código para ignorar campos que não conhece. Uma mudança incompatível, como renomear ou remover um campo, vira uma versão nova, e as chaves existentes continuam na versão antiga.
Formato da requisição
Parâmetros de consulta vão na query string. Corpos de requisição, nos endpoints que aceitam corpo, podem ir em JSON ou em formulário:
Content-Type | Exemplo |
|---|---|
application/json | {"metadata": {"plan": "pro"}, "tags": ["a", "b"]} |
application/x-www-form-urlencoded | metadata[plan]=pro&tags[]=a&tags[]=b |
O formato de formulário usa a notação de colchetes da Stripe: a[b]=1 vira um objeto, a[0]=x&a[1]=y ou a[]=x&a[]=y viram uma lista. Um curl copiado da documentação da Stripe funciona como está. Em formulário todo valor chega como texto; a API converte números e booleanos onde os espera.
A query string aceita a mesma notação de colchetes. Um corpo com outro Content-Type, ou um JSON que não é um objeto, recebe 400 parameter_invalid.
Formato da resposta
Toda resposta é JSON em UTF-8, com Cache-Control: no-store. Uma consulta de um objeto devolve o objeto; uma listagem devolve um objeto list (veja Paginação); um erro devolve um objeto error (veja Erros).
Cabeçalhos presentes em toda resposta:
| Cabeçalho | Conteúdo |
|---|---|
Request-Id | Identificador único da requisição, req_ seguido de 20 caracteres hexadecimais. Veja Request-Id. |
Vipter-Version | A versão da API usada. Só em respostas autenticadas. |
X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset | O estado do seu limite de requisições. |
Retry-After | Só em 429: segundos até poder tentar de novo. |
Idempotent-Replayed | Só quando a resposta é a repetição de uma requisição anterior com a mesma Idempotency-Key. Veja Idempotência. |
Tipos de dado
| O quê | Como vem | Exemplo |
|---|---|---|
| Dinheiro | Inteiro na menor unidade da moeda. Nunca decimal. | 9900 é R$ 99,00; 1250 é US$ 12,50. |
| Moeda | Código ISO 4217 em minúsculas. | "brl", "usd" |
| Data e hora | Inteiro em segundos Unix, em UTC. null quando não se aplica. | 1790790000 |
| IDs | Texto com prefixo por tipo de objeto. Trate como opaco: não dependa do tamanho nem do formato. | cust_…, sub_…, ord_…, ofr_…, prd_…, cs_…, bps_…, ak_…, req_… |
object | Em todo objeto: o nome do tipo. | "customer", "subscription", "order", "offer", "product", "checkout.session", "billing_portal.session", "account", "list" |
livemode | Em todo objeto. Nos pedidos, false quando o pagamento passou por uma conexão de teste do provedor. Nos demais objetos, true em produção. | true |
created | Em todo objeto: quando ele foi criado, em segundos Unix. | 1790790000 |
| Ausência | Campo presente com null, e não campo omitido. Listas vazias vêm como [], mapas vazios como {}. | "phone": null |
| País | Código ISO 3166-1 alfa-2 em maiúsculas. | "BR" |
| Documentos | Só o tipo e os últimos quatro dígitos. A API nunca devolve um CPF ou CNPJ inteiro. | {"type": "cpf", "number_masked": "*******1234"} |
Os campos metadata, client_reference_id e checkout_session dos pedidos e das assinaturas vêm preenchidos quando a venda nasceu de uma sessão de checkout criada pela API; nas outras vendas, vêm {} ou null.
Erros
Um erro é uma resposta com código HTTP 4xx ou 5xx e este corpo:
{
"error": {
"type": "invalid_request_error",
"code": "parameter_invalid",
"message": "Invalid query parameter 'limit': Number must be less than or equal to 100",
"param": "limit",
"doc_url": "https://docs.vipter.com/pt-br/developers/api-conventions#erros"
}
}| Campo | Conteúdo |
|---|---|
type | A família do erro. Decide como o seu código deve reagir. |
code | O motivo exato, estável entre versões. Use para tratar casos específicos. |
message | Texto em inglês para quem está depurando. Pode mudar; não compare com ele. |
param | O parâmetro ou cabeçalho que causou o erro, quando há um. Em corpos aninhados, usa pontos e colchetes: lines[0].amount. |
doc_url | Esta seção. |
Tipos de erro
| HTTP | type | Quando |
|---|---|---|
| 400 | invalid_request_error | Parâmetro faltando ou inválido, corpo malformado, versão desconhecida. |
| 401 | authentication_error | Chave ausente, inválida, revogada ou expirada. |
| 403 | permission_error | Chave sem o escopo necessário, API desativada para a loja, loja inativa. |
| 404 | invalid_request_error | O objeto ou o caminho não existe. code é resource_missing. |
| 400 ou 409 | idempotency_error | Problema com a Idempotency-Key. |
| 429 | rate_limit_error | Limite de requisições atingido. |
| 402 | card_error | Reservado para recusas de cobrança nos endpoints de pagamento, em breve. |
| 500 | api_error | Falha do lado do Vipter. Guarde o Request-Id e tente de novo. |
Códigos
code | HTTP | Significado |
|---|---|---|
parameter_missing | 400 | Um parâmetro obrigatório não veio. param diz qual. |
parameter_invalid | 400 | Um parâmetro veio com valor, tipo ou formato errado. param diz qual. |
invalid_api_version | 400 | O cabeçalho Vipter-Version tem uma versão desconhecida. |
api_key_missing, invalid_api_key, api_key_revoked, api_key_expired | 401 | Veja Erros de autenticação. |
api_not_enabled, project_inactive, insufficient_scope | 403 | Veja Erros de autenticação. |
resource_missing | 404 | Não há objeto com esse ID na loja, ou o caminho não existe. param é id, ou starting_after/ending_before quando o cursor não existe. |
idempotency_key_too_long | 400 | A Idempotency-Key tem mais de 255 caracteres. |
idempotency_key_reused | 400 | A mesma Idempotency-Key foi usada com outro método, caminho ou corpo. |
idempotency_key_in_use | 409 | A primeira requisição com essa Idempotency-Key ainda está sendo processada. |
rate_limit | 429 | Veja Limites de requisições. |
internal_error | 500 | Falha do lado do Vipter. |
Um objeto que existe mas pertence a outra loja é um 404, igual a um ID inexistente. Os códigos próprios de um endpoint, como offer_unavailable ou portal_disabled, estão na referência, junto do endpoint.
Idempotência
Repetir uma requisição por causa de um timeout de rede não pode cobrar duas vezes. Para isso, todo POST e DELETE aceita o cabeçalho Idempotency-Key, com um valor único que você gera, como um UUID v4:
curl -X POST https://api.vipter.com/v1/… \
-H "Authorization: Bearer vk_live_…" \
-H "Idempotency-Key: 5f0b2c8e-3a1d-4e7f-9b6c-2d4a8e1f0c3b" \
…Regras, as mesmas da Stripe:
- A chave vale por 24 horas dentro da loja. Até 255 caracteres.
- A mesma chave com o mesmo método, caminho e corpo devolve a resposta guardada da primeira vez, com o mesmo código HTTP, sem executar nada de novo. A resposta repetida traz
Idempotent-Replayed: trueeOriginal-Request-Idcom oRequest-Idda primeira. - A mesma chave com um corpo diferente recebe
400 idempotency_key_reused. - Enquanto a primeira requisição ainda está rodando, uma segunda com a mesma chave recebe
409 idempotency_key_in_use. Espere um instante e repita com a mesma chave. - Respostas
4xxtambém são guardadas e repetidas. Respostas5xxnão: você pode repetir com a mesma chave.
Os endpoints GET são idempotentes por natureza e ignoram o cabeçalho. Nos POST de hoje (sessões de checkout, clientes, sessões do portal) a chave é opcional e recomendada; nos endpoints de cobrança que vêm em seguida, ela será obrigatória.
Paginação
Toda listagem devolve um objeto list:
{
"object": "list",
"url": "https://api.vipter.com/v1/orders",
"has_more": true,
"data": [
{ "id": "ord_7b3e9f1c2a8d4e6f", "object": "order", "created": 1790790412 },
{ "id": "ord_5c1e8a2b9d4f4e7a", "object": "order", "created": 1790704011 }
]
}Os itens vêm do mais novo para o mais antigo. Parâmetros, os mesmos da Stripe:
| Parâmetro | Conteúdo |
|---|---|
limit | Quantos itens por página, de 1 a 100. Padrão 10. |
starting_after | O id do último item da página atual. Devolve os itens mais antigos que ele: a próxima página. |
ending_before | O id do primeiro item da página atual. Devolve os itens mais novos que ele: a página anterior. |
Não envie os dois cursores na mesma chamada (400 parameter_invalid). Um cursor que não existe na loja recebe 404 resource_missing, com param dizendo qual. Os filtros do endpoint, como customer ou status, continuam valendo com o cursor.
Para percorrer tudo, repita enquanto has_more for true, passando o id do último item em starting_after:
curl "https://api.vipter.com/v1/orders?limit=100" \
-H "Authorization: Bearer vk_live_…"
# has_more: true, último id: ord_5c1e8a2b9d4f4e7a
curl "https://api.vipter.com/v1/orders?limit=100&starting_after=ord_5c1e8a2b9d4f4e7a" \
-H "Authorization: Bearer vk_live_…"Ofertas vêm em ordem alfabética de nome, e não por data, porque são um catálogo pequeno. Os cursores funcionam do mesmo jeito.
Limites de requisições
Cada chave de API pode fazer 100 requisições a cada 2 segundos, o que dá 50 por segundo com espaço para rajadas. Toda resposta diz onde você está:
| Cabeçalho | Conteúdo |
|---|---|
X-RateLimit-Limit | O tamanho da janela: 100. |
X-RateLimit-Remaining | Quantas requisições ainda cabem na janela atual. |
X-RateLimit-Reset | Quando a janela reabre, em segundos Unix. |
Passou do limite, a resposta é 429 rate_limit com Retry-After em segundos. Espere esse tempo e repita. Numa integração que varre muitos dados, use limit=100 e um pequeno intervalo entre páginas em vez de paralelizar chamadas.
Requisições sem chave válida têm um limite separado, por endereço IP: 10 por minuto.
Request-Id
Toda resposta, inclusive erros e 429, traz um Request-Id único:
Request-Id: req_8c2f4e6a1b3d5f7e9a0cRegistre esse valor nos seus logs junto com a chamada. Ao falar com o suporte do Vipter sobre uma requisição, informe o Request-Id: com ele o suporte localiza a chamada exata, com o status, a duração e o erro. O mesmo valor aparece nos logs de requisições do painel, que ficam guardados por 30 dias.
Diferenças em relação à Stripe
A API não é um clone: o objetivo é que uma integração com a Stripe seja adaptada por mapeamento, não que o SDK da Stripe funcione apontando para o Vipter. O que muda:
| Tema | Stripe | Vipter |
|---|---|---|
| Chave | sk_live_… e sk_test_… | Só vk_live_…. Não há modo de teste; teste com uma conexão de teste e use livemode por objeto. |
| Versão | Stripe-Version | Vipter-Version, no mesmo formato de data. |
| Corpo da requisição | Só formulário | Formulário ou JSON. |
| Fatura | invoice | order, com billing_reason para dizer se é compra avulsa, primeira cobrança, renovação, cobrança manual ou uso. |
| Preço | price, um por produto e moeda | offer, com uma lista prices[], uma por moeda, e um checkout_url pronto. |
| Assinatura | items[] com vários preços | Uma oferta por assinatura: offer e product são um objeto cada. |
| Sessão de checkout | line_items[] com vários preços | Uma oferta por sessão: offer (ou line_items[0][price]), com pack para a quantidade. Os cupons vão em discounts[0][coupon], como na Stripe. |
| Status de assinatura | incomplete, unpaid | Não existem. past_due é a assinatura em recuperação de pagamento; os detalhes vêm em past_due_details. |
| Pedido com status manual | Não existe | status_source diz se o status veio do provedor ou foi definido no painel. |
expand[] | Expande objetos relacionados | Não existe. Os objetos relacionados vêm como id, ou como {id, name} quando o nome ajuda. |
| Webhooks | Stripe-Signature | Vipter-Signature, com o mesmo algoritmo. Veja Verificar a assinatura. |
O que fazer a seguir
- Veja cada endpoint e cada objeto na referência da API.
- Crie e proteja as chaves em Autenticação e chaves de API.
Autenticação e chaves de API
Como criar uma chave de API no painel, o formato vk_live_…, os escopos de leitura e escrita, como enviar a chave em cada requisição, como revogar, como testar sem modo de teste e o que cada erro 401 e 403 significa.
Referência da API (v1)
Cada endpoint da API do Vipter com os parâmetros, um exemplo de chamada e de resposta, e a tabela de campos de cada objeto: conta, cliente, assinatura e suas ações, cobrança na assinatura, uso medido (medidores, eventos de uso, itens e períodos), pedido, oferta, produto, sessão de checkout, sessão do portal do cliente, eventos e endpoints de webhook.