Vendas (sales)
O recurso sales expõe as vendas e os pedidos da sua conta, isto é, as
transações com transaction_type igual a sale ou order. É um recurso de
leitura e escrita: você lista, busca por id, cria com itens, atualiza e
cancela vendas pela API.
| Módulo | vendas — precisa estar habilitado no contrato |
| Escopos | sales:read para ler; sales:write para criar, atualizar e cancelar |
| Operações | leitura e escrita |
Endpoints
Seção intitulada “Endpoints”| Método | Endpoint | Escopo | Descrição |
|---|---|---|---|
GET | /v1/sales | sales:read | Lista vendas e pedidos com paginação por cursor |
GET | /v1/sales/{id} | sales:read | Busca uma venda pelo id, com ?include=items,status_history |
POST | /v1/sales | sales:write | Cria uma venda com itens e responde 201 |
PATCH | /v1/sales/{id} | sales:write | Atualiza status, pagamento, entrega e observações |
DELETE | /v1/sales/{id} | sales:write | Cancela a venda (status="cancelled") e responde 204 |
| Campo | Tipo | Descrição |
|---|---|---|
id | uuid | Identificador da venda |
customer_id | uuid | null | Cliente associado à venda |
transaction_type | string | Tipo da transação: sale para venda ou order para pedido |
transaction_number | string | null | Número sequencial da transação |
status | string | null | Situação da venda, por exemplo pending, completed ou cancelled |
sale_date | string (ISO 8601) | null | Data da venda |
delivery_date | string (YYYY-MM-DD) | null | Data de entrega |
subtotal | number | null | Soma dos subtotais dos itens, antes dos descontos |
discount_amount | number | null | Desconto em valor absoluto |
discount_percentage | number | null | Desconto percentual |
tax_amount | number | null | Impostos |
total_amount | number | null | Valor total: itens com descontos mais delivery_fee |
notes | string | null | Observações |
payment_method | string | null | Forma de pagamento, por exemplo pix, credit_card ou cash |
payment_status | string | null | Situação do pagamento, por exemplo pending ou paid |
delivery_fee | number | null | Taxa de entrega |
order_code | string | null | Código do pedido, de uso livre na integração |
is_active | boolean | null | Se o registro está ativo |
created_at | string (ISO 8601) | Data de criação |
updated_at | string (ISO 8601) | null | Data da última atualização |
items | TransactionItem[] | Itens da venda, presentes apenas com ?include=items |
status_history | TransactionStatusHistory[] | Histórico de status, presente apenas com ?include=status_history |
Campos internos como team_id, contract_id, created_by e internal_notes
nunca aparecem nas respostas.
Itens (TransactionItem)
Seção intitulada “Itens (TransactionItem)”| Campo | Tipo | Descrição |
|---|---|---|
id | uuid | Identificador do item |
catalog_type | string | Tipo do item do catálogo: product, service ou package |
catalog_item_id | uuid | Item do catálogo, veja Produtos (products) |
quantity | number | Quantidade |
unit_price | number | Preço unitário |
discount_amount | number | null | Desconto em valor no item |
discount_percentage | number | null | Desconto percentual no item |
subtotal | number | quantity × unit_price, antes dos descontos |
total_amount | number | Total do item depois dos descontos |
notes | string | null | Observações do item |
created_at | string (ISO 8601) | Data de criação |
Histórico de status (TransactionStatusHistory)
Seção intitulada “Histórico de status (TransactionStatusHistory)”| Campo | Tipo | Descrição |
|---|---|---|
id | uuid | Identificador da entrada |
old_status | string | null | Status anterior, null na criação |
new_status | string | Novo status |
change_reason | string | null | Motivo da mudança |
created_at | string (ISO 8601) | Quando a mudança ocorreu |
Corpo da criação (POST /v1/sales)
Seção intitulada “Corpo da criação (POST /v1/sales)”| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
items | array (1–200) | sim | Itens da venda, descritos abaixo |
customer_id | uuid | null | não | Cliente da venda |
transaction_type | 'sale' | 'order' | não, padrão sale | Venda ou pedido |
sale_date | string (ISO 8601) | não, padrão agora | Data da venda |
delivery_date | string (YYYY-MM-DD) | null | não | Data de entrega |
status | string | não, padrão pending | Status inicial |
payment_method | string | null | não | Forma de pagamento |
payment_status | string | null | não | Situação do pagamento |
delivery_fee | number ≥ 0 | null | não | Taxa de entrega |
order_code | string | null | não | Código do pedido |
notes | string | null | não | Observações |
Cada entrada de items:
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
catalog_type | 'product' | 'service' | 'package' | sim | Tipo do item do catálogo |
catalog_item_id | uuid | sim | Identificador do item do catálogo |
quantity | number > 0 | sim | Quantidade |
unit_price | number ≥ 0 | sim | Preço unitário |
discount_amount | number ≥ 0 | não | Desconto em valor |
discount_percentage | number 0–100 | não | Desconto percentual |
notes | string | null | não | Observações do item |
Corpo da atualização (PATCH /v1/sales/{id})
Seção intitulada “Corpo da atualização (PATCH /v1/sales/{id})”Só estes campos podem ser alterados: status, payment_status,
payment_method, notes, delivery_date e delivery_fee. Quando status
muda, uma entrada é acrescentada automaticamente ao status_history.
Itens e valores não são editáveis por PATCH. Para corrigir itens, cancele a
venda e crie outra.
Filtros e ordenação
Seção intitulada “Filtros e ordenação”O formato do filtro é ?filter[<campo>][<operador>]=<valor>. Os operadores
disponíveis são eq, neq, gt, gte, lt, lte, in, nin, ilike e
is_null.
| Campo | Uso típico | Exemplo |
|---|---|---|
customer_id | vendas de um cliente | filter[customer_id][eq]=9c8d7e6f-1a2b-4c3d-8e9f-0a1b2c3d4e5f |
status | por situação | filter[status][in]=pending,completed |
transaction_type | só vendas ou só pedidos | filter[transaction_type][eq]=order |
transaction_number | busca pelo número | filter[transaction_number][eq]=000123 |
payment_status | pagamentos pendentes | filter[payment_status][eq]=pending |
payment_method | por forma de pagamento | filter[payment_method][eq]=pix |
sale_date | por período | filter[sale_date][gte]=2026-07-01 |
total_amount | por faixa de valor | filter[total_amount][gte]=100 |
is_active | apenas ativos | filter[is_active][eq]=true |
created_at | por data de criação | filter[created_at][gte]=2026-07-01T00:00:00Z |
updated_at | sincronização incremental | filter[updated_at][gt]=2026-07-09T12:00:00Z |
- Ordenação:
sort=created_at,sort=sale_dateousort=total_amount. O padrão é-created_at, das mais recentes para as mais antigas. - Paginação por cursor:
?limit=50&cursor=<next_cursor>. Olimitvai de 1 a 100 e o padrão é 20. - Campos parciais:
?fields=id,transaction_number,status,total_amount.
Filtros combinados:
GET /v1/sales?filter[status][neq]=cancelled&sort=-sale_dateGET /v1/sales?filter[customer_id][eq]=9c8d7e6f-1a2b-4c3d-8e9f-0a1b2c3d4e5f&filter[payment_status][eq]=pendingGET /v1/sales?filter[sale_date][gte]=2026-07-01&filter[sale_date][lt]=2026-08-01&limit=50Os detalhes de cada parâmetro estão em Paginação, filtros e ordenação.
Relações incluídas
Seção intitulada “Relações incluídas”GET /v1/sales/{id} aceita o parâmetro include, com valores separados por
vírgula:
items— itens da venda, ordenados porcreated_atcrescente;status_history— mudanças de status, em ordem cronológica.
GET /v1/sales/3f9a1b7e-2c4d-4e8f-b6a1-5d0c9e8f7a2b?include=items,status_historyValores desconhecidos em include são ignorados. A listagem GET /v1/sales
não aceita include, e a resposta do POST já vem com items.
Exemplos
Seção intitulada “Exemplos”curl "$LIGGA_BASE/v1/sales?filter[status][eq]=pending&limit=2&sort=-sale_date" \ -H "Authorization: Bearer $LIGGA_API_KEY"{ "data": [ { "id": "3f9a1b7e-2c4d-4e8f-b6a1-5d0c9e8f7a2b", "customer_id": "9c8d7e6f-1a2b-4c3d-8e9f-0a1b2c3d4e5f", "transaction_type": "sale", "transaction_number": "000231", "status": "pending", "sale_date": "2026-07-09T18:40:00.000Z", "delivery_date": null, "subtotal": 189.8, "discount_amount": null, "discount_percentage": null, "tax_amount": null, "total_amount": 179.8, "notes": null, "payment_method": "pix", "payment_status": "pending", "delivery_fee": null, "order_code": null, "is_active": true, "created_at": "2026-07-09T18:40:02.000Z", "updated_at": null }, { "id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d", "customer_id": null, "transaction_type": "order", "transaction_number": "000230", "status": "pending", "sale_date": "2026-07-08T10:12:00.000Z", "delivery_date": "2026-07-15", "subtotal": 250, "discount_amount": null, "discount_percentage": null, "tax_amount": null, "total_amount": 265, "notes": "Entregar no período da manhã", "payment_method": null, "payment_status": null, "delivery_fee": 15, "order_code": "PED-2026-0230", "is_active": true, "created_at": "2026-07-08T10:12:05.000Z", "updated_at": "2026-07-08T10:20:44.000Z" } ], "pagination": { "next_cursor": "eyJpZCI6ImExYjJjM2Q0LWU1ZjYtNGE3Yi04YzlkLTBlMWYyYTNiNGM1ZCIsInYiOiIyMDI2LTA3LTA4VDEwOjEyOjAwLjAwMFoifQ", "has_more": true, "limit": 2 }, "meta": { "request_id": "req_01J9ZXAMPLE" }}O cursor da próxima página está em pagination.next_cursor. Enquanto
pagination.has_more for true, repita a chamada com cursor igual a esse
valor.
Buscar por id
Seção intitulada “Buscar por id”curl "$LIGGA_BASE/v1/sales/3f9a1b7e-2c4d-4e8f-b6a1-5d0c9e8f7a2b?include=items,status_history" \ -H "Authorization: Bearer $LIGGA_API_KEY"{ "data": { "id": "3f9a1b7e-2c4d-4e8f-b6a1-5d0c9e8f7a2b", "customer_id": "9c8d7e6f-1a2b-4c3d-8e9f-0a1b2c3d4e5f", "transaction_type": "sale", "transaction_number": "000231", "status": "pending", "sale_date": "2026-07-09T18:40:00.000Z", "delivery_date": null, "subtotal": 189.8, "discount_amount": null, "discount_percentage": null, "tax_amount": null, "total_amount": 179.8, "notes": null, "payment_method": "pix", "payment_status": "pending", "delivery_fee": null, "order_code": null, "is_active": true, "created_at": "2026-07-09T18:40:02.000Z", "updated_at": null, "items": [ { "id": "6c7d8e9f-0a1b-4c2d-8e3f-4a5b6c7d8e9f", "catalog_type": "product", "catalog_item_id": "b7e1f3a2-8c4d-4e5f-9a6b-1c2d3e4f5a6b", "quantity": 2, "unit_price": 49.9, "discount_amount": null, "discount_percentage": null, "subtotal": 99.8, "total_amount": 99.8, "notes": null, "created_at": "2026-07-09T18:40:02.000Z" }, { "id": "7d8e9f0a-1b2c-4d3e-8f4a-5b6c7d8e9f0a", "catalog_type": "service", "catalog_item_id": "0d9e8f7a-6b5c-4d3e-2f1a-9b8c7d6e5f4a", "quantity": 1, "unit_price": 90, "discount_amount": 10, "discount_percentage": null, "subtotal": 90, "total_amount": 80, "notes": null, "created_at": "2026-07-09T18:40:02.000Z" } ], "status_history": [ { "id": "8e9f0a1b-2c3d-4e4f-8a5b-6c7d8e9f0a1b", "old_status": null, "new_status": "pending", "change_reason": null, "created_at": "2026-07-09T18:40:02.000Z" } ] }, "meta": { "request_id": "req_01J9ZXAMPLE" }}Um id que não existe, que pertence a outra conta ou que não é sale nem
order responde 404 not_found.
curl -X POST "$LIGGA_BASE/v1/sales" \ -H "Authorization: Bearer $LIGGA_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: pedido-loja-8842" \ -d '{ "customer_id": "9c8d7e6f-1a2b-4c3d-8e9f-0a1b2c3d4e5f", "transaction_type": "sale", "payment_method": "pix", "payment_status": "pending", "items": [ { "catalog_type": "product", "catalog_item_id": "b7e1f3a2-8c4d-4e5f-9a6b-1c2d3e4f5a6b", "quantity": 2, "unit_price": 49.9 }, { "catalog_type": "service", "catalog_item_id": "0d9e8f7a-6b5c-4d3e-2f1a-9b8c7d6e5f4a", "quantity": 1, "unit_price": 90, "discount_amount": 10 } ] }'Resposta 201 Created, já com items:
{ "data": { "id": "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e", "customer_id": "9c8d7e6f-1a2b-4c3d-8e9f-0a1b2c3d4e5f", "transaction_type": "sale", "transaction_number": "000232", "status": "pending", "sale_date": "2026-07-10T14:05:00.000Z", "delivery_date": null, "subtotal": 189.8, "discount_amount": null, "discount_percentage": null, "tax_amount": null, "total_amount": 179.8, "notes": null, "payment_method": "pix", "payment_status": "pending", "delivery_fee": null, "order_code": null, "is_active": true, "created_at": "2026-07-10T14:05:01.000Z", "updated_at": null, "items": [ { "id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d", "catalog_type": "product", "catalog_item_id": "b7e1f3a2-8c4d-4e5f-9a6b-1c2d3e4f5a6b", "quantity": 2, "unit_price": 49.9, "discount_amount": null, "discount_percentage": null, "subtotal": 99.8, "total_amount": 99.8, "notes": null, "created_at": "2026-07-10T14:05:01.000Z" }, { "id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e", "catalog_type": "service", "catalog_item_id": "0d9e8f7a-6b5c-4d3e-2f1a-9b8c7d6e5f4a", "quantity": 1, "unit_price": 90, "discount_amount": 10, "discount_percentage": null, "subtotal": 90, "total_amount": 80, "notes": null, "created_at": "2026-07-10T14:05:01.000Z" } ] }, "meta": { "request_id": "req_01J9ZXAMPLE" }}Atualizar
Seção intitulada “Atualizar”curl -X PATCH "$LIGGA_BASE/v1/sales/5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e" \ -H "Authorization: Bearer $LIGGA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "status": "completed", "payment_status": "paid" }'A mudança de status acrescenta uma entrada ao status_history, visível em
GET /v1/sales/{id}?include=status_history.
Cancelar
Seção intitulada “Cancelar”curl -X DELETE "$LIGGA_BASE/v1/sales/5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e" \ -H "Authorization: Bearer $LIGGA_API_KEY"A resposta é 204 No Content, sem corpo.
Erros comuns
Seção intitulada “Erros comuns”As respostas de erro usam application/problem+json, com type, title,
status e request_id. Os detalhes estão em Erros.
| HTTP | type | Quando acontece |
|---|---|---|
| 401 | invalid_token | Cabeçalho Authorization ausente ou chave inexistente |
| 401 | token_revoked | A chave foi revogada |
| 401 | token_expired | A chave passou da data de expiração |
| 403 | insufficient_scope | A chave não tem sales:read ou sales:write |
| 403 | module_not_enabled | Módulo vendas não habilitado no contrato |
| 404 | not_found | id inexistente, de outra conta, ou que não é sale nem order |
| 409 | idempotency_conflict | Mesma Idempotency-Key reenviada com outro corpo da requisição |
| 422 | validation | Corpo ou filtro inválido, por exemplo items vazio, quantity menor ou igual a zero, ou operador não permitido |
| 429 | rate-limit-exceeded | Limite de requisições do plano excedido |
Veja também
Seção intitulada “Veja também”- Clientes (customers) — o cliente indicado em
customer_id - Idempotência — como repetir um
POSTcom segurança - Paginação, filtros e ordenação —
cursor,filter,sortefields - Criar uma venda com itens — a receita completa