Pular para o conteúdo

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.