vamobotDocs

Pedidos

Registre pedidos que baixam o estoque na hora, liste e consulte pedidos e mova cada um pelas etapas até a entrega.

Um pedido criado pela API entra no Vamo como uma venda confirmada: o estoque dos produtos do catálogo baixa no mesmo instante, o pedido aparece nos pedidos do contato no Vamo e conta no total gasto dele.

Dinheiro em centavos

Todos os valores são inteiros em centavos (×100). R$ 4.599,00 vai como 459900; Gs. 150.000 vai como 15000000.

POST /orders

Cria um pedido para um contato. Acesso: chave secreta com Leitura e escrita.

Cabeçalho opcional: Idempotency-Key, até 200 caracteres (veja Repetir com segurança).

CampoTipoObrigatórioDescrição
storeIdstring (UUID)SimA sua loja
contactIdstring (UUID)SimQuem comprou
conversationIdstring (UUID)NãoA conversa de onde veio a venda
currencystringNãoBRL, PYG ou USD. Padrão: a moeda dos produtos do catálogo; sem produtos do catálogo, a moeda principal da organização
notesstringNãoObservações (endereço, horário de entrega…)
itemsarraySimPelo menos um item

Cada item:

CampoTipoObrigatórioDescrição
productNamestringSimNome do item. Num item do catálogo, o pedido grava o nome do catálogo no lugar
quantityinteiroSim1 ou mais
unitPriceinteiroSimPreço unitário em centavos. Num item do catálogo, substitui o preço do catálogo
productIdstring (UUID)NãoUm produto da loja. Com ele, o item baixa estoque
variantIdstring (UUID)NãoUma variação desse productId. Obrigatório quando o produto tem variações

Um item sem productId é avulso (frete, instalação, embalagem para presente): entra no total e não mexe no estoque.

curl -X POST https://vamo.ai/api/v1/orders \
  -H "Authorization: Bearer sk_live_SUA_CHAVE" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: site-pedido-1042" \
  -d '{
    "storeId": "7b1e2c3d-4a5f-4b6c-8d7e-9f0a1b2c3d4e",
    "contactId": "2c9d8e7f-6a5b-4c3d-9e2f-1a0b9c8d7e6f",
    "notes": "Entregar depois das 18h",
    "items": [
      {
        "productId": "4d5e6f70-8192-4a3b-9c4d-5e6f708192a3",
        "variantId": "6f708192-a3b4-4c5d-8e6f-708192a3b4c5",
        "productName": "iPhone 15",
        "quantity": 1,
        "unitPrice": 459900
      },
      { "productName": "Frete", "quantity": 1, "unitPrice": 2500 }
    ]
  }'

Resposta 201

{
  "data": {
    "id": "8192a3b4-c5d6-4e7f-9a8b-92a3b4c5d6e7",
    "storeId": "7b1e2c3d-4a5f-4b6c-8d7e-9f0a1b2c3d4e",
    "contactId": "2c9d8e7f-6a5b-4c3d-9e2f-1a0b9c8d7e6f",
    "conversationId": null,
    "total": 462400,
    "currency": "BRL",
    "status": "confirmed",
    "source": "api",
    "notes": "Entregar depois das 18h",
    "needsReview": false,
    "externalOrderId": null,
    "reservationExpiresAt": null,
    "createdAt": "2026-10-31T14:10:00.000Z",
    "updatedAt": "2026-10-31T14:10:00.000Z",
    "items": [
      {
        "id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
        "productId": "4d5e6f70-8192-4a3b-9c4d-5e6f708192a3",
        "productName": "iPhone 15",
        "variantId": "6f708192-a3b4-4c5d-8e6f-708192a3b4c5",
        "variantName": "128 GB Azul",
        "quantity": 1,
        "unitPrice": 459900,
        "total": 459900
      },
      {
        "id": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
        "productId": null,
        "productName": "Frete",
        "variantId": null,
        "variantName": null,
        "quantity": 1,
        "unitPrice": 2500,
        "total": 2500
      }
    ]
  }
}

Dispara o webhook order.created, com o pedido e os itens.

Estoque

  • Tudo ou nada. Cada produto do catálogo precisa ser da loja, estar ativo e ter estoque para a quantidade pedida (somando itens repetidos). Se um item falhar, nenhum pedido é criado e nenhum estoque muda.
  • Na hora e sem vender duas vezes. O estoque baixa junto com a criação do pedido. Se outra venda levou a última unidade um instante antes, o seu pedido responde 409 out_of_stock.
  • Variações. Num produto com variações (cor, memória, tamanho), cada item indica a variação em variantId, e é o estoque dela que baixa. Sem variantId: 400 variant_required.
  • Estoque que a loja não conta. Um produto marcado só como "em estoque" ou "sem estoque" (sem quantidade) vende qualquer quantidade enquanto estiver em estoque, e nada é baixado.
  • Catálogo do WhatsApp. Quando o estoque muda, o catálogo do WhatsApp da loja é atualizado em seguida.

Diferenças para os pedidos da IA

Pedido da APIPedido da IA
Status inicialconfirmedconfirmed, ou pending quando precisa de aprovação
Prazo de reservaNão tem: o pedido não expiraExpira se não for pago no prazo (veja Pedidos e reservas)
PreçoO unitPrice que você enviarO do catálogo, com o desconto combinado dentro do limite
Vai para a loja conectada (Shopify, WooCommerce)NãoSim, quando a integração está configurada para enviar pedidos

Repetir com segurança

Uma falha de rede no meio do caminho deixa a dúvida: o pedido foi criado? Envie sempre o cabeçalho Idempotency-Key com um valor único por venda (o número do pedido no seu sistema, por exemplo). Repetindo a requisição com a mesma chave, o Vamo não cria outro pedido nem baixa o estoque de novo: responde 200 com o pedido que já existe, sem disparar outro webhook. Isso vale mesmo que o corpo seja diferente.

A chave vale só dentro da sua organização. Mais de 200 caracteres: 400 invalid_idempotency_key.

GET /orders

Lista os pedidos, do mais novo para o mais antigo, sem os itens. Acesso: chave secreta (leitura).

ParâmetroDescrição
statuspending, confirmed, shipped, delivered ou cancelled
contactIdSó os pedidos desse contato
page, pageSizePadrão 50, máximo 100
curl "https://vamo.ai/api/v1/orders?status=confirmed&contactId=2c9d8e7f-6a5b-4c3d-9e2f-1a0b9c8d7e6f" \
  -H "Authorization: Bearer sk_live_SUA_CHAVE"

Responde { "data": [ … ], "pagination": { … } }.

GET /orders/:id

Um pedido com os itens, no mesmo formato da criação. Acesso: chave secreta (leitura). 404 (Order not found) se não existir na sua organização.

curl https://vamo.ai/api/v1/orders/8192a3b4-c5d6-4e7f-9a8b-92a3b4c5d6e7 \
  -H "Authorization: Bearer sk_live_SUA_CHAVE"

source diz quem criou: ai (o agente de IA), human (a equipe no painel), api, ou null em pedidos antigos.

PATCH /orders/:id

Muda o status ou as observações. Acesso: chave secreta com Leitura e escrita.

CampoDescrição
statuspending, confirmed, shipped, delivered ou cancelled
notesObservações (até 2.000 caracteres)

Pelo menos um dos dois.

curl -X PATCH https://vamo.ai/api/v1/orders/8192a3b4-c5d6-4e7f-9a8b-92a3b4c5d6e7 \
  -H "Authorization: Bearer sk_live_SUA_CHAVE" \
  -H "Content-Type: application/json" \
  -d '{ "status": "shipped" }'

Responde 200 com o pedido (sem os itens) e dispara order.updated.

As etapas

Um pedido anda uma etapa por vez e pode ser cancelado até ser entregue:

DePode ir para
pendingconfirmed, cancelled
confirmedshipped, cancelled
shippeddelivered, cancelled
deliverednada (final)
cancellednada (final)

Pular uma etapa (confirmed → delivered) responde 409 invalid_transition, com from e to no corpo. Enviar o status que o pedido já tem não muda nada.

  • Cancelar devolve o estoque de um pedido pending ou confirmed, na hora (o da variação, quando o item tem uma). Um pedido shipped cancelado não devolve: as unidades já saíram da loja.
  • Pedido da loja conectada. Um pedido que está na sua Shopify ou WooCommerce muda de status lá, não no Vamo: 409 order_managed_by_store (o corpo traz platform). As observações continuam editáveis.
  • Pedido esperando aprovação. Um pedido da IA marcado para revisão só muda de status depois que a equipe aprova ou recusa: 409 order_in_review.

Erros

Os erros vêm no formato de sempre: { "error": { "code": "…", "message": "…" } }, com os detalhes ao lado.

StatuscodeQuando
400validation_errorFalta storeId, contactId ou items; item sem productName, quantity ou unitPrice; quantidade ou preço que não é inteiro; ID que não é UUID; variantId sem productId; mais de 200 itens; status fora da lista ou PATCH sem nenhum campo
400invalid_idempotency_keyIdempotency-Key com mais de 200 caracteres
400product_not_foundO productId não é um produto dessa loja
400inactive_productO produto não está ativo
400variant_requiredO produto tem variações e o item não diz qual
400variant_not_foundO variantId não é variação desse produto
400mixed_currencyProdutos de moedas diferentes, ou currency diferente da dos produtos
400total_too_largeO total passa do valor máximo
404not_foundContato, loja, conversa ou pedido não encontrado na sua organização
409out_of_stockFalta estoque. O corpo traz productName e, quando o Vamo sabe, available
409invalid_transitionO novo status pula uma etapa ou sai de um status final
409order_managed_by_storeO pedido é da loja conectada
409order_in_reviewO pedido espera a aprovação da equipe
{
  "error": {
    "code": "out_of_stock",
    "message": "Not enough stock for \"iPhone 15 (128 GB Azul)\"",
    "productName": "iPhone 15 (128 GB Azul)",
    "available": 0
  }
}

Nesta página