Orçamentos
O coração transacional do Cord. Crie propostas, obtenha os links públicos delas e administre-as.
Visão geral
O objeto Cotizacion (quote) representa uma proposta comercial para um cliente. Usando a API do Cord, você pode inserir orçamentos diretamente a partir de um ERP ou CRM, ou gerar fluxos automatizados de carrinho de compras.
Todos os orçamentos gerados pela API ficam registrados no log de auditoria (audit_log), marcados automaticamente como originados da sua chave de API.
Criar um orçamento
Para criar um rascunho de orçamento, faça um POST /api/v1/cotizaciones enviando os detalhes comerciais.
Requisição:
curl -X POST "https://cordhq.app/api/v1/cotizaciones" \
-H "Authorization: Bearer sk_live_tU..." \
-H "Content-Type: application/json" \
-d '{
"cliente_id": "8f7b2c1e-4d3a-4b9f-a6e2-1c5d7e9f0a3b",
"terminos": "net30",
"vigencia_dias": 15,
"notas": "Annual project",
"base_currency": "EUR",
"items": [
{
"descripcion": "Annual license — Pro plan",
"cantidad": 12,
"precio_unitario": 500
}
]
}'
Cada item de items exige descripcion, cantidad e precio_unitario — os nomes dos campos ficam em espanhol independentemente do idioma da requisição, porque são o esquema canônico da API. producto_id é opcional (referencia um produto do seu catálogo para herdar o nome e o preço de tabela dele) e precio_negociado permite informar um preço com desconto diferente do de tabela. Não existe um campo sku: se você quiser vincular o item a um produto, use o producto_id dele.
Campos do orçamento
| Campo | Detalhe |
|---|---|
items |
Obrigatório. Os itens (veja a tabela seguinte). |
cliente_id ou cliente |
Um cliente do seu cadastro, ou os dados para cadastrá-lo (empresa e, opcionalmente, email, contacto, telefono, rfc e fiscal). |
terminos |
contado, net7, net15, net30, net45, net60 ou net90 (N dias corridos). Sem ele, valem as condições do cliente ou as da sua conta. |
vigencia_dias |
Dias em que o orçamento é válido a partir do envio. |
notas |
Observações para o cliente. |
base_currency |
Moeda de venda (ISO 4217). |
fiscal_currency |
Moeda contábil; se for diferente da de venda, a fatura declara a taxa de câmbio. |
iva_incluido |
true se os preços já incluem o imposto. |
descuento |
Desconto do documento antes de impostos: { "tipo": "porcentaje", "valor": 10 } ou { "tipo": "monto", "valor": 2500 }. O Cord calcula o valor e o distribui entre os itens; um valor fixo é limitado ao subtotal. null o remove. Veja Descontos e cupons. |
cupon |
O código de um cupom da sua conta (por exemplo, "WELCOME10"). O Cord valida a validade, a moeda e os usos; se vier, prevalece sobre descuento. |
send |
true para enviá-lo ao criá-lo. Somente com chave secreta. |
| Campo do item | Detalhe |
|---|---|
descripcion, cantidad, precio_unitario |
Obrigatórios. |
producto_id |
Produto do catálogo. |
precio_negociado |
Preço final do item, se for diferente do de tabela. |
costo_unitario |
Custo interno para calcular a margem. O cliente nunca o vê. |
tax_rate |
Fração de 0 a 1 (0.16, não 16), validada com o seu catálogo de impostos. 0 significa isento de propósito. |
exemption_reason |
Somente com tax_rate 0. Espanha: a causa de isenção ou de não sujeição do Verifactu (E1–E6, N1, N2, S2). Resto da UE: o código VATEX da fatura eletrônica. |
clave_sat, clave_unidad_sat |
Somente México: o código SAT de produto ou serviço (8 dígitos) e o código SAT de unidade desse item. Prevalecem sobre os do produto; um código com formato inválido responde 400. Fora do México, são ignorados. |
curl -X POST "https://cordhq.app/api/v1/cotizaciones" \
-H "Authorization: Bearer sk_live_tU..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: quote-order-4471" \
-d '{
"cliente_id": "8f7b2c1e-4d3a-4b9f-a6e2-1c5d7e9f0a3b",
"terminos": "net45",
"base_currency": "MXN",
"cupon": "WELCOME10",
"items": [
{ "descripcion": "Gray cement CPC 30R", "cantidad": 400, "precio_unitario": 245,
"tax_rate": 0.16, "clave_sat": "30111601", "clave_unidad_sat": "H87" }
]
}'
Com uma chave publicável (a do seu site), o Cord ignora descuento, precio_negociado e costo_unitario: o único desconto que ele aceita é um cupon. Um cupom que não existe responde 404 com code: "coupon_no_existe"; um inativo, expirado, esgotado, de outra moeda ou limitado por cliente sem cliente responde 409 com coupon_inactivo, coupon_vencido, coupon_aun_no_vigente, coupon_agotado, coupon_agotado_cliente, coupon_moneda ou coupon_requiere_cliente.
base_currency é a moeda em que o cliente vê e paga o orçamento (ISO 4217, por exemplo, MXN, USD, EUR, GBP). É opcional — se você a omitir, o Cord usa a moeda contábil da sua organização —, mas a API não depende de país: uma conta em Madri, Austin ou Bogotá cria orçamentos na própria moeda sem nenhum parâmetro adicional.
Resposta bem-sucedida:
O Cord devolve o id (UUID) do orçamento, o token público dele e o link público (link_publico) já montado como URL absoluta, para que você o envie ao seu cliente imediatamente por WhatsApp, SMS ou um serviço de e-mail externo. Se a sua organização tiver um domínio próprio ativo, o link usa esse domínio em vez de cordhq.app.
{
"data": {
"id": "2a9d8e4f-6b1c-4d7a-9e3f-5c8b1a2d4e6f",
"folio": "COT-00104",
"token": "9f3b6c2a7e1d4f8b0a5c3e7d1b9f2a46",
"link_publico": "https://cordhq.app/q/9f3b6c2a7e1d4f8b0a5c3e7d1b9f2a46",
"needs_approval": false
}
}
Se o orçamento exigir aprovação interna antes de ser enviado (por exemplo, um desconto fora do limite), needs_approval vem como true e motivo descreve o motivo.
Listar orçamentos
Você pode recuperar o seu histórico paginado de orçamentos ou filtrar por status (por exemplo, buscar todos os orçamentos enviados ou pagos).
Requisição:
curl -X GET "https://cordhq.app/api/v1/cotizaciones?status=paid&limit=10" \
-H "Authorization: Bearer sk_live_tU..."
O valor de status é o status interno como está (em inglês, sem tradução): draft, sent, viewed, approved, rejected, expired, paid ou invoiced. Para buscar um orçamento pelo número, use folio=COT-00104: compara o número completo sem diferenciar maiúsculas e minúsculas. Para ver só os de um cliente, use cliente_id=<uuid>.
{
"data": [
{
"id": "2a9d8e4f-6b1c-4d7a-9e3f-5c8b1a2d4e6f",
"folio": "COT-00104",
"cliente": "Stark Industries",
"status": "paid",
"total": 6000,
"moneda": "MXN",
"terminos": "Net 30",
"terminos_codigo": "net30",
"vigencia": "10 sep 2026",
"creada": "20 ago 2026",
"link_publico": "https://cordhq.app/q/9f3b6c2a7e1d4f8b0a5c3e7d1b9f2a46",
"language": "es"
}
],
"meta": { "limit": 10, "offset": 0, "total": 1, "next_cursor": null }
}
Datas e condições em formato de exibição
Na lista e no detalhe, terminos chega como rótulo no idioma da sua conta (Contado ou Due on receipt, Net 45) e vigencia e creada como datas de exibição (10 sep 2026), não como datas ISO. Não faça o parse delas: para comparar o prazo, use terminos_codigo (contado, net7, net15, net30, net45, net60 ou net90), que não muda com o idioma; para a data exata de cada alteração, use o created_at do histórico de eventos com object_id.
Na listagem, link_publico também é uma URL absoluta, assim como na resposta de criação. Para o detalhe de um único orçamento (itens, eventos, aprovação), use GET /api/v1/cotizaciones/{id}.
language é o idioma em que o cliente recebe o orçamento: es, en, pt, fr ou de. É somente leitura: o orçamento o recebe ao ser enviado, do cliente ou, se ele não tiver, da sua organização, e uma nova versão o mantém. Vale null enquanto é rascunho. Para enviá-lo em outro idioma, altere o language do cliente antes de enviar.
O detalhe traz também descuento: null se não houver, ou o desconto do documento com a sua definição, o cupom de onde ele saiu e o valor calculado antes de impostos:
"descuento": { "tipo": "porcentaje", "valor": 10, "cupon": "WELCOME10", "monto": 9800, "moneda": "MXN" }
total já inclui o desconto.
Propor itens com IA
POST /api/v1/cotizaciones/ia recebe { "texto": "..." } (o pedido do cliente, até 6000 caracteres) e devolve os itens correspondentes ao seu catálogo, sem criar nada:
{ "data": { "moneda": "MXN", "items": [{ "id": "7e3c9a1f-2b4d-4c6e-8f0a-b1d3e5f7a9c2", "nombre": "Gray Cement 50kg", "unidad": "sack", "lista": 185, "negociado": null, "cantidad": 5 }] } }
id é null quando o item não está no seu catálogo. Os preços vêm em moneda. Para criar o orçamento, envie esses itens para POST /api/v1/cotizaciones. Exige uma chave com escrita e consome uma unidade de IA do seu plano: se não restar nenhuma, você recebe 429 com code: "ai_quota_exceeded"; se o texto não trouxer produtos, 422 com code: "no_items".
Alterar o status de um orçamento
Com uma chave de escrita (write), você pode mover o orçamento pelo ciclo de vida dele com POST /api/v1/cotizaciones/{id}:
curl -X POST "https://cordhq.app/api/v1/cotizaciones/2a9d8e4f-6b1c-4d7a-9e3f-5c8b1a2d4e6f" \
-H "Authorization: Bearer sk_live_tU..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: approve-COT-00104" \
-d '{ "action": "approve" }'
action |
A partir do status | Resultado |
|---|---|---|
send |
draft |
Envia o orçamento ao cliente (e-mail e link) no idioma dos documentos dele, que o orçamento guarda em language. No plano Grátis, consome um dos envios do mês. |
resend |
sent, viewed, expired |
Reenvia o orçamento ao cliente. |
approve |
sent, viewed |
Marca-o como aprovado. |
reject |
sent, viewed |
Marca-o como recusado. |
mark_paid |
approved, invoiced |
Registra o pagamento. Aceita payment_method opcional (por padrão, transferencia). Os pagamentos online pendentes desse orçamento são cancelados. |
A resposta é { "data": { "ok": true, "status": "approved" } }. Se o orçamento não estiver em um status a partir do qual a ação possa ser aplicada, ou se outra requisição o alterou ao mesmo tempo, você recebe 409 com code: "invalid_state" e nada é aplicado. Cada alteração fica no log de auditoria com a sua chave como autora e dispara o seu evento de webhook.
Emitir a fatura não está disponível por esta rota: as faturas são criadas e emitidas com POST /api/v1/facturas e POST /api/v1/facturas/{id}.
Excluir um rascunho
DELETE /api/v1/cotizaciones/{id} exclui um orçamento que nunca foi enviado (draft). Qualquer outro status responde 409.