Desenvolvedores2026-11Prévia

API da NinjaBuy Business

Importe produtos da Taobao, Weidian e 1688, mantenha preço e estoque sincronizados, e acompanhe cada pedido do vendedor na China, passando pela verificação no nosso armazém, até a porta do seu cliente. JSON via HTTPS, uma conta, um saldo.

URL base

Todas as rotas deste site ficam sob uma URL base. O app da Shopify e tudo o que você desenvolve chamam as mesmas rotas, então o que o app faz, o seu código também pode fazer.

https://www.ninjabuy.com/api/v1

Prefere perguntar a um assistente de IA? A mesma conta funciona via MCP em https://www.ninjabuy.com/mcp: Assistentes de IA (MCP).

Catálogo
Pedidos
Conta
A sua primeira chamada
curl "https://www.ninjabuy.com/api/v1/balance" \
  -H "Authorization: Bearer $NINJABUY_API_KEY" \
  -H "NinjaBuy-Version: 2026-11"

Autenticação

Envie uma chave de API como bearer token em toda requisição. As chaves começam com nb_. Durante a prévia, a nossa equipe as emite: depois que a sua conta Business é configurada, enviamos cada chave uma única vez, pelo canal que você escolher, com os escopos que você pediu. Peça para revogarmos uma e ela para de funcionar na próxima requisição.

Guarde as chaves no seu servidor. Uma chave em um navegador, um app ou um repositório público pode ser lida por qualquer pessoa, e pode gastar o seu saldo.

Um app que age em nome de outros vendedores da NinjaBuy usa OAuth 2.1: registro dinâmico de clientes, o fluxo de código de autorização com PKCE (S256) e a própria tela de aprovação do vendedor. O token de acesso vai no mesmo cabeçalho e funciona nas mesmas rotas. Tokens de acesso duram uma hora; tokens de atualização os renovam por sete dias. Assistentes de IA se conectam do mesmo jeito (MCP).

products:readescopo
Ler importações, produtos, variantes e regras de sincronização.
products:writeescopo
Importe, edite, envie e exclua produtos; altere regras de sincronização.
inventory:readescopo
Ler níveis de estoque.
orders:readescopo
Ler pedidos, ordens de processamento e envios.
orders:writeescopo
Crie, retenha, libere e cancele pedidos. Usa o seu saldo.
balance:readescopo
Ler o saldo e as transações.
webhooks:writeescopo
Gerencie endpoints de webhook.

Uma chamada fora dos escopos de uma chave responde 403 insufficient-scope e informa o escopo necessário.

Cabeçalho
Authorization: Bearer nb_7Qk2...vX9e
Response 401
HTTP/2 401

{
  "type": "https://www.ninjabuy.com/api/v1/problems/unauthorized",
  "title": "Unauthorized",
  "status": 401,
  "detail": "The API key is missing, wrong, expired or revoked.",
  "request_id": "req_7Hq2Lw9c"
}

Versionamento

O caminho traz a versão principal, /v1. Dentro dela, versões com data mudam campos e comportamento. Fixe aquela com que você desenvolveu usando o cabeçalho NinjaBuy-Version; toda resposta informa no mesmo cabeçalho a versão usada.

2026-11 é a versão atual e está em prévia: nomes e campos ainda podem mudar antes de ela ser marcada como estável. Toda mudança está no changelog, e avisamos por e-mail cada titular de chave antes de uma mudança que possa quebrar a integração.

Dentro de uma versão, só adicionamos: novas rotas, novos parâmetros opcionais, novos campos nas respostas e novos tipos de evento. Construa o seu cliente para ignorar campos que ele não conhece.

Fixar uma versão
GET /api/v1/orders
NinjaBuy-Version: 2026-11

HTTP/2 200
NinjaBuy-Version: 2026-11

Requisições e respostas

  • Envie JSON com Content-Type: application/json; as respostas são JSON em UTF-8. Os erros são application/problem+json.
  • Dinheiro é um objeto com uma string decimal e uma moeda: { "amount": "264.20", "currency": "CNY" }. O que a NinjaBuy cobra está em CN¥; os seus preços de venda estão na moeda da sua loja.
  • Os ids são strings com um prefixo que indica o tipo (prd_, ord_, shp_). Trate-os como opacos.
  • Os horários são ISO 8601 em UTC. Os países são códigos ISO de duas letras.
  • Toda resposta traz um cabeçalho X-Request-Id, e todo erro traz o mesmo id como request_id. Informe-o quando nos escrever.
Dinheiro, ids e datas
{
  "id": "ord_3n7q",
  "created_at": "2026-11-01T09:14:02Z",
  "total": { "amount": "264.20", "currency": "CNY" },
  "suggested_price": { "amount": "49.99", "currency": "USD" }
}

Paginação

As listas respondem da mais recente para a mais antiga, como data, has_more e cursor. Envie esse cursor de volta para a próxima página enquanto has_more for true. Um cursor só funciona com os filtros de onde veio.

limitinteger
De 1 a 100. 25 se omitido.
cursorstring
O cursor da página anterior. Omita na primeira página.
curl "https://www.ninjabuy.com/api/v1/orders?limit=25&cursor=c_2v9kq" \
  -H "Authorization: Bearer $NINJABUY_API_KEY" \
  -H "NinjaBuy-Version: 2026-11"
Response 200
HTTP/2 200 OK

{
  "data": [
    { "id": "ord_3n7q", "status": "checked" },
    { "id": "ord_3n6z", "status": "shipped" }
  ],
  "has_more": true,
  "cursor": "c_1q4ea"
}

Limites de requisições

Os limites são por conta, compartilhados por todas as chaves, tokens OAuth e a conexão MCP. Toda resposta diz onde você está pelos cabeçalhos IETF RateLimit-Policy e RateLimit; uma recusa é 429 rate-limited com Retry-After em segundos.

JanelaO que conta
"create-links";q=30;w=60Chamadas que leem um anúncio do marketplace: criar ou atualizar uma importação, enviar um produto. 30 por minuto, compartilhadas com a API de links e o MCP.
"default";q=120;w=60Todas as outras chamadas. 120 por minuto.
Resposta 429
HTTP/2 429
Content-Type: application/problem+json
Retry-After: 12
RateLimit-Policy: "create-links";q=30;w=60
RateLimit: "create-links";r=0;t=12

{
  "type": "https://www.ninjabuy.com/api/v1/problems/rate-limited",
  "title": "Too many requests",
  "status": 429,
  "detail": "Try again in 12 seconds.",
  "request_id": "req_7Hq2Lw9c"
}

Idempotência

Envie uma Idempotency-Key (de 1 a 255 caracteres ASCII imprimíveis; um UUID é o ideal) em qualquer POST, e uma nova tentativa depois de um timeout não consegue criar um segundo pedido. Por 24 horas, a mesma chave, na mesma rota e com o mesmo corpo, devolve a primeira resposta de novo byte a byte, com Idempotent-Replayed: true, sem executar de novo nem contar para um limite.

  • A mesma chave com outro corpo ou outra rota: 422 idempotency-key-reused.
  • A primeira requisição ainda em execução: 409 idempotency-key-in-progress, com Retry-After.
  • Uma recusa por limite de requisições não é uma resposta: a chave continua livre, então tentar de novo após Retry-After executa a requisição.

Os pedidos também levam o seu próprio external_id: um segundo pedido com o mesmo é recusado com 409 duplicate-order, seja qual for a chave usada.

Uma requisição repetida
POST /api/v1/orders
Idempotency-Key: 4f0c2b4e-9d1a-4e0f-b0a8-5d1d3c7e2f61

HTTP/2 201
Idempotent-Replayed: true
X-Request-Id: req_7Hq2Lw9c

Erros

Os erros são problem JSON (RFC 9457): type é uma URL estável para usar em condicionais, title o nomeia, detail explica este caso com palavras que você pode mostrar, e request_id o encontra nos nossos logs. Um corpo que falha na validação adiciona errors, cada um com um pointer JSON para o campo.

StatusTipoQuando
400bad-jsonO corpo não é JSON.
400bad-bodyUm campo está faltando ou errado; errors[] aponta para ele.
400bad-idempotency-keyA Idempotency-Key está vazia, é longa demais ou não é ASCII imprimível.
401unauthorizedA chave ou o token está faltando, errado, expirado ou revogado.
403insufficient-scopeFalta à chave o escopo que a rota exige.
404not-foundEsse objeto não existe nesta conta. Ids de outra conta respondem igual.
405method-not-allowedA rota existe, mas não com este método; Allow lista os que ela aceita.
409duplicate-orderJá existe um pedido com este external_id; order o identifica.
409idempotency-key-in-progressA primeira requisição com esta chave ainda está em execução.
409invalid-stateO objeto não pode fazer isso agora, por exemplo cancelar um pedido enviado.
415unsupported-media-typeO corpo não é application/json.
422idempotency-key-reusedA chave foi usada para uma requisição diferente.
422unprocessableJSON válido sobre o qual não conseguimos agir: um link não lido, uma variante esgotada. detail diz qual.
429rate-limitedChamadas demais na janela. Espere Retry-After segundos.
500internal-errorErro nosso. Tente de novo com a mesma Idempotency-Key.
503service-unavailableNão conseguimos verificar a chave ou alcançar uma loja agora. Tente de novo após Retry-After.
Response 400
HTTP/2 400

{
  "type": "https://www.ninjabuy.com/api/v1/problems/bad-body",
  "title": "Invalid request body",
  "status": 400,
  "detail": "1 field is invalid.",
  "request_id": "req_7Hq2Lw9c",
  "errors": [
    {
      "pointer": "/ship_to/country",
      "detail": "Must be a two-letter country code."
    }
  ]
}