Cotiza, factura y cobra desde tu propio código.

La API REST de Cord crea y consulta cotizaciones, clientes, productos y facturas con una llave Bearer, y ejecuta las mismas acciones que la app: enviar, aprobar, emitir o registrar un pago. Respuestas JSON predecibles, especificación OpenAPI y llaves de prueba que trabajan en un entorno aislado de tus datos reales.

En todos los planes. Gratis incluye 2 llaves y 100 llamadas al mes; las llaves de prueba no consumen tu cuota.

POST /api/v1/cotizaciones200 OK
$ curl https://cordhq.app/api/v1/cotizaciones \
  -H "Authorization: Bearer sk_live_8f2a…" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: pedido-7781" \
  -d '{"cliente_id": "9b41c2e0-3d7a-4f12-8c55-6e0b1a2d4f90", "vigencia_dias": 15,
       "items": [{"descripcion": "Cemento Portland 94 lb",
                  "cantidad": 240, "precio_unitario": 16.4}]}'
{
  "data": {
    "id": "c2f9a1d4-7b3e-4c1a-9e55-01a6c3d8f2b7",
    "token": "q8Fz2LkP",
    "folio": "COT-0149",
    "link_publico": "https://cordhq.app/q/q8Fz2LkP",
    "needs_approval": false,
    "motivo": null
  }
}
97 ms · v1600 peticiones/min por llave secreta

IDEMPOTENCIA

Reintenta sin miedo a duplicar.

Una red inestable no debería crear dos cotizaciones. Manda una Idempotency-Key en cualquier POST, PATCH o DELETE: si la petición se repite con la misma llave y el mismo cuerpo, Cord devuelve la respuesta original, marcada con Idempotent-Replayed, en vez de ejecutar dos veces. Si el cuerpo cambió, responde con un error explícito.

  • Funciona en todas las mutaciones de /api/v1
  • La respuesta repetida es idéntica, byte por byte
  • Misma llave con otro cuerpo: error, nunca un duplicado silencioso
Reintento con la misma Idempotency-Key/api/v1
# 1er intento: se crea la cotización
POST /api/v1/cotizaciones
Idempotency-Key: pedido-7781
← 200  { "data": { "folio": "COT-0150", … } }

# 2º intento (se cortó la red): misma llave, mismo cuerpo
POST /api/v1/cotizaciones
Idempotency-Key: pedido-7781
← 200  Idempotent-Replayed: true
      { "data": { "folio": "COT-0150", … } }
      # la misma respuesta, byte por byte

# misma llave, otro cuerpo
← 422  { "error": "Esta clave de idempotencia ya se usó con otra petición.",
        "code": "idempotency_key_reused" }

# la primera petición sigue en proceso
← 409  { "code": "idempotency_in_progress" }

RECURSOS

Lo que ves en la app, también por API.

No es una API de solo lectura. Crea una cotización y envíala, apruébala o regístrala como pagada. Crea una factura como borrador y emítela, mándala, anótale un pago o una nota de crédito. Todo con los mismos permisos, validaciones y totales que usa la app.

  • Cotizaciones, facturas, clientes, productos, tareas y cobranza
  • Acciones con POST { "action": "send" | "approve" | "finalize" | … }
  • Paginación con limit y offset, o con cursor en eventos y facturas
ResumenRegistrosErroresEventosWebhooksShellLlavesSalud

Referencia de la API

34 operaciones. Base https://cordhq.app/api/v1 con Authorization: Bearer y tu llave.

Spec OpenAPI ↗llms.txt (IA Docs) ↗
Ejemplo
curl https://cordhq.app/api/v1/me \
  -H "Authorization: Bearer $CORD_SECRET_KEY"
Cuenta
GET/meOrganización y alcance de la llaveProbar
Cotizaciones
GET/cotizacionesListar cotizacionesProbar
POST/cotizacionesCrear cotizaciónProbar
GET/cotizaciones/{id}Detalle de cotizaciónProbar
POST/cotizaciones/{id}Enviar, reenviar, aprobar, rechazar o marcar pagadaProbar
DELETE/cotizaciones/{id}Borrar un borradorProbar
POST/cotizaciones/iaProponer líneas a partir del texto de un pedidoProbar
Clientes
GET/clientesListar clientesProbar
POST/clientesCrear clienteProbar
GET/clientes/{id}Detalle de clienteProbar
PATCH/clientes/{id}Actualizar datos de contactoProbar
Productos
GET/productosListar productosProbar
POST/productosCrear productoProbar
Facturas
GET/facturasListar facturasProbar
POST/facturasCrear factura en borradorProbar
GET/facturas/{id}Detalle de facturaProbar
POST/facturas/{id}Emitir, enviar, anular, registrar pago o nota de créditoProbar
Cobranza
GET/cobranzaCartera por cobrarProbar
Eventos
GET/eventsHistorial de eventosProbar
Tareas
POST/tareasCrear tareaProbar
Workflows
POST/workflows/{id}/invokeCorrer un workflow "Lo corres tú" sobre cotizaciones o facturasProbar
Webhooks
GET/webhooksEndpoints creados por esta llave
POST/webhooksCrear endpoint (el secreto se devuelve una vez)
DELETE/webhooks/{id}Borrar endpoint
Elements
GET/elements/configConfiguración que dibuja Cord ElementsProbar
POST/elements/ai-draftLíneas con IA en streaming (text/event-stream)
Modo prueba
POST/test_helpers/fiscalForzar el resultado de la próxima emisiónProbar
POST/test_helpers/cotizaciones/{id}Simular apertura o vencimientoProbar
POST/test_helpers/webhooksDisparar un webhookProbar
POST/test_helpers/listenAbrir sesión de cord listen
GET/test_helpers/listen/{id}Recoger eventos de la sesión
DELETE/test_helpers/listen/{id}Cerrar sesión de cord listen
Configuración
POST/setup/plansProponer una configuración de la cuenta (una persona la aprueba en review_url)Probar
GET/setup/plans/{id}Estado de una propuesta de configuraciónProbar

EVENTOS

Sincroniza sin perderte nada.

GET /api/v1/events devuelve el historial de tu negocio, del más reciente al más antiguo: cotizaciones enviadas, vistas, aprobadas o pagadas, facturas emitidas, clientes nuevos. Filtra por tipo o por objeto y avanza con next_cursor. Es el complemento de los webhooks para reconstruir cualquier estado.

  • Filtros ?type=quote.approved y ?object_id=
  • Hasta 200 eventos por página con cursor estable
  • Los mismos tipos que reciben tus webhooks
GET /api/v1/events?type=quote.approved&limit=1200 OK
{
  "data": [
    {
      "id": "5e0b9d42-6a1f-4c87-b3e2-9d4f1a7c0e65",
      "type": "quote.approved",
      "object": "quote",
      "object_id": "c2f9a1d4-7b3e-4c1a-9e55-01a6c3d8f2b7",
      "data": { "id": "c2f9a1d4-7b3e-4c1a-9e55-01a6c3d8f2b7", "folio": "COT-0149",
                "status": "approved", "moneda": "USD", "total": 4123.4,
                "cliente": "Ridgeline Builders LLC", "cliente_id": "9b41c2e0-3d7a-4f12-8c55-6e0b1a2d4f90",
                "link_publico": "https://cordhq.app/q/q8Fz2LkP" },
      "actor": "client",
      "created_at": "2026-09-30T22:31:08.000Z"
    }
  ],
  "meta": {
    "next_cursor": "MjAyNi0wOS0zMFQyMjozMTowOC4wMDAwMDBafDVlMGI5ZDQyLTZhMWYtNGM4Ny1iM2UyLTlkNGYxYTdjMGU2NQ"
  }
}

HERRAMIENTAS

Tu backend y tu terminal, listos para Cord.

Dos paquetes oficiales en npm para que integrar no sea escribir peticiones a mano: un SDK tipado para tu servidor y un CLI para probar webhooks en tu máquina antes de desplegar.

SDK DE SERVIDOR

La API, ya tipada para tu backend.

@flouviahq/node envuelve toda la API: crea cotizaciones y facturas, recorre listas completas y verifica webhooks con su firma y su antigüedad. Manda la misma Idempotency-Key en cada reintento y fija la versión de la API, así una actualización de Cord nunca cambia lo que lees.

  • npm install @flouviahq/node, sin dependencias
  • Corre en Node, Bun, Deno, Cloudflare Workers y Vercel
  • Errores con code, request_id y la liga a su explicación
src / server.ts@flouviahq/node
  1. import { Cord, constructEvent } from '@flouviahq/node';
  2. const cord = new Cord(process.env.CORD_SECRET_KEY!, { apiVersion: '2026-10-01' });
  3. // Si la red falla, el reintento reusa la misma Idempotency-Key
  4. const quote = await cord.quotes.create({
  5. cliente: { empresa: 'Ridgeline Builders LLC' },
  6. items: [{ descripcion: 'Cemento Portland 94 lb', cantidad: 240, precio_unitario: 16.4 }],
  7. });
  8. // Recorre todas las páginas; el SDK lleva el cursor
  9. for await (const factura of cord.invoices.listAll({ estado: 'open' })) {
  10. await erp.actualizarSaldo(factura.numero, factura.saldo);
  11. }
  12. // Verifica X-Cord-Signature-V1 y rechaza firmas de más de 5 minutos
  13. export async function POST(req: Request) {
  14. const event = await constructEvent(await req.text(), req.headers,
  15. process.env.CORD_WEBHOOK_SECRET!);
  16. if (event.event === 'invoice.paid') {
  17. await erp.conciliar(event.data.numero, event.data.saldo);
  18. }
  19. return new Response(null, { status: 200 });
  20. }

CLI

Prueba tus webhooks sin desplegar.

cord listen manda a tu máquina los webhooks de tu entorno de prueba, firmados igual que en producción. cord trigger dispara cualquier evento y cord simulate provoca lo que en producción hace un tercero, como un servicio de emisión fiscal que no responde o una cotización que vence.

  • npx @flouviahq/cli abre el asistente: entras desde el navegador, sin copiar llaves, y deja tu proyecto integrado
  • Solo acepta llaves de prueba: nada toca tus datos reales
  • cord events tail muestra los eventos conforme ocurren
erp-materiales— zshsk_test_…9c2a

$ cord listen --forward-to http://localhost:3000/api/webhooks/cord

Escuchando webhooks de prueba (todos los eventos) → http://localhost:3000/api/webhooks/cord

Secreto de esta sesión: whsec_5c2e8f0a9d41b7c3e6f2a8d0b4c19e7f3a5d2b8c6e0f4a17

Ponlo en CORD_WEBHOOK_SECRET de tu servidor local. Vence en 24 h. Ctrl+C para salir.

16:41:52quote.viewedevt_2a91f0c7d34b4e8fa15c6b0d9e7f3a21→ 200 38 ms

16:42:07quote.approvedevt_8d4c2b1e07a94f63b5e1c9a0f2d7b4e8→ 200 41 ms

16:42:58payment.partialevt_c35e9a7104bd4c2e8f6a1b0d3e9c5f72→ 200 52 ms

16:43:21invoice.finalizedevt_4be07a2d4e61b3f8a05c7d92e1aa9c1f→ 500 17 ms

16:44:05quote.expiredevt_f0a6d3b9c18e4a57b2d40e6c9a1f8b35→ 200 33 ms

16:44:12invoice.paidevt_9c1f4be07a2d4e61b3f8a05c7d92e1aa→ 200 36 ms

$ cord trigger quote.approved

Disparado quote.approved (datos ejemplo)

$ cord simulate fiscal pac_caido

La próxima emisión fiscal de prueba resultará en pac_caido

$ cord simulate quote 7e3b0c91-4d2a-4f6e-b8a5-2c9d1f0e6a47 vencer

Cotización 7e3b0c91-4d2a-4f6e-b8a5-2c9d1f0e6a47: vencida.

$ cord events tail --type invoice.paid

Mostrando eventos nuevos. Ctrl+C para salir.

16:44:12invoice.paidf3a8d1c4-2b6e-4d90-a1c7-5e8f0b3d2a61

PREGUNTAS FRECUENTES

Lo que preguntan los developers sobre API REST.

Es una API REST bajo https://cordhq.app/api/v1 que da acceso programático a cotizaciones, facturas, clientes, productos, tareas, cobranza y eventos de tu negocio. Se autentica con una llave Bearer y responde en JSON con la forma { data, meta } o { error, code }.

No. La API está en todos los planes, incluido Gratis, con 2 llaves y 100 llamadas al mes. Starter incluye 1,000 llamadas, Profesional 5,000, Scale 10,000 y Developer 50,000. Las llaves de prueba no consumen cuota.

Con una llave sk_test_. Opera sobre un entorno de prueba separado de tu cuenta, así que puedes crear y borrar cotizaciones sin afectar a tus clientes ni a tus reportes.

Manda el header Idempotency-Key en la petición. Si la repites con la misma llave y el mismo cuerpo, Cord devuelve la respuesta original sin ejecutarla otra vez.

Sí: @flouviahq/node para Node, Bun, Deno, Cloudflare Workers y Vercel, y @flouviahq/cli para probar webhooks en tu máquina. Los dos están en npm.

No. Cada llave y cada webhook guardan la versión de la API con la que se crearon, y puedes fijar otra por petición con el header Cord-Version. Cord adapta la respuesta a esa versión.

Sí. Una llave restringida (rk_) tiene permiso de lectura o escritura por recurso, y cualquier llave secreta puede limitarse a ciertas IPs, vencer y rotarse con un periodo de gracia.

Sí, en https://cordhq.app/openapi.yaml, y un resumen para asistentes de IA en https://cordhq.app/llms.txt. Los dos se enlazan desde el Workbench.

Explora el resto de la plataforma para desarrolladores.

Haz tu primera llamada hoy.

Crea tu cuenta, genera una llave de prueba y llama a /api/v1/me.

Ve lo que pagarás

Precios publicados, con la tarifa de cada cobro a la vista.

Información sobre precios →

Empieza a construir

Empieza a operar y a enviar cotizaciones desde el plan Gratis.

Opciones de integración →