quore/Documentación de la API

Flujo de emisión

De la cotización a la póliza emitida: cotizar, emitir, resolver condiciones y obtener los documentos.

Paso a paso

  1. Cotizar con POST /api/quotes: devuelve el quoteId y las coberturas con su prima y su premio.
  2. Si la cotización quedó pending_approval, espera la aprobación de la aseguradora (webhook quote.approved).
  3. Emitir con POST /api/policies indicando quoteId, la coverageId elegida y los datos de emisión.
  4. Si el producto tiene emisión condicional, la póliza queda pending hasta resolver sus condiciones con POST /api/policies/{id}/conditions/resolve; recién entonces se habilita el pago (payment_url).
  5. Obtener los documentos: el certificado se genera solo; también puedes renderizar o regenerar PDFs.

1. Cotizar

POST/api/quotes
  • Requiere una clave con scope quote. Body: productId y variables (las variables del producto que afectan el precio). La referencia de cada producto lista sus variables, tipos, rangos y opciones.
  • Responde 200 con la cotización calculada.
  • La cotización vence según el producto (quoteTtlHours, 48 horas por defecto): ver expiresAt.
  • status: priced, o pending_approval si alguna cobertura requiere aprobación.
  • Los montos: netPremium es la prima (precio técnico neto, sin impuestos) y totalPremium es el premio (total a pagar).

Pedido

curl -X POST https://api.quore.app/api/quotes \
  -H "x-api-key: sk_test_…" \
  -H "Content-Type: application/json" \
  -d '{
    "productId": "PRODUCT_ID",
    "variables": { "edad": 35, "plan": "full" }
  }'

Respuesta (resumida)

{
  "quoteId": "3f1c2a9e-5b7d-4c1e-9a1f-2d6b8e0c4a11",
  "status": "priced",
  "expiresAt": "2026-10-28T14:00:00.000Z",
  "term_type": "annual_installments",
  "coverages": [
    {
      "key": "basica",
      "name": "Cobertura Básica",
      "currency": "ARS",
      "netPremium": 42000,
      "taxes": 8820,
      "totalPremium": 50820,
      "installments": 12,
      "installment": 4235
    }
  ]
}

2. Emitir

POST/api/policies
  • Requiere una clave con scope emit. Body: quoteId, coverageId (la key de una cobertura de la cotización) y data.
  • data lleva las variables de los pasos de emisión y el medio de pago. Los valores cotizados se toman de la cotización.
  • Responde 201 con la póliza. Reintentar con la misma cotización y la misma cobertura devuelve la misma póliza; con otra cobertura, 409.
  • Con un proveedor de pago online la respuesta incluye payment para completar el cobro (ver Cobros).
  • Medio de pago manual: nunca envíes el número completo de tarjeta ni el CVV; solo card_last4, card_brand y card_holder.

Pedido

curl -X POST https://api.quore.app/api/policies \
  -H "x-api-key: sk_test_…" \
  -H "Content-Type: application/json" \
  -d '{
    "quoteId": "QUOTE_ID",
    "coverageId": "basica",
    "data": {
      "nombre": "Ana Pérez",
      "payment": { "method": "credit_card", "card_last4": "4242", "card_brand": "visa", "card_holder": "Ana Pérez" }
    }
  }'

3. Condiciones de emisión

POST/api/policies/{id}/conditions/resolve
  • En productos con emisión condicional la póliza nace pending, con la lista conditions (por ejemplo, una inspección).
  • Resuelve cada condición con status approved o failed (y failureReason). La aseguradora también puede resolverlas desde su panel.
  • Con todas aprobadas (o una, si la lógica es OR) la póliza pasa a active; una condición fallida con comportamiento reject la pasa a rejected.
  • Las condiciones se resuelven ANTES del pago: mientras están pendientes no se inicia ningún cobro (payment_after_conditions: true en la emisión). Con todas aprobadas, si el producto cobra en línea (Stripe, Mercado Pago o Rebill), la póliza pasa a pending_payment, el webhook policy.status_changed y la respuesta de la resolución traen payment_url (la página pública de pago) y se le envía al asegurado y al intermediario el link para pagar. Al confirmarse el pago la póliza pasa a active en ese momento. Sin cobro en línea pasa directo a active. Una condición de tipo pago con cobro en línea no se agrega: el pago es el último paso.
  • Un pago rechazado deja la póliza payment_failed («Pago rechazado», con payment_status: failed) y dispara payment.failed. Se avisa al intermediario (o a los administradores si no hay) y al asegurado, con el motivo y el mismo link de pago para reintentar; un reintento aprobado la activa.
  • Una condición rechazada (o vencida) termina el flujo sin cobro: la póliza pasa a rejected y nunca se habilita el pago. Las pólizas antiguas que se pagaron antes de resolver sus condiciones y luego se rechazaron siguen marcadas con refund_status: pending (payment.refund_required) y se marcan como reembolsadas en Aprobaciones o en el detalle de la póliza (payment.refunded).
  • Vencimiento opcional: con issuance.expires_after_hours (o expires_after_hours en una condición), una póliza con condiciones aún pendientes al vencer se rechaza con el motivo «Vencida». Sin configurarlo, no vence.
  • Las resoluciones simultáneas de una misma póliza se aplican de a una, sin perder ninguna.
  • Cada cambio de estado dispara el webhook policy.status_changed.

Resolver una condición

curl -X POST https://api.quore.app/api/policies/POLICY_ID/conditions/resolve \
  -H "x-api-key: sk_test_…" \
  -H "Content-Type: application/json" \
  -d '{ "conditionId": "inspection", "status": "approved" }'

4. Documentos

  • El certificado se genera automáticamente cuando la póliza queda active (al emitir, o al activarse una póliza condicional) y se envía al asegurado. Una póliza pendiente o rechazada no tiene certificado (409 al pedirlo).
  • La póliza en PDF está disponible si el producto tiene su plantilla y tu plan incluye ese documento.
  • Los documentos de un registro de sandbox solo se leen con una clave de sandbox.
EndpointQué hace
GET/api/policies/{id}/documentsLista los documentos generados de la póliza (id, docType, generatedAt).
GET/api/documents/{id}/downloadDescarga un documento: devuelve una URL temporal o el PDF.
GET/api/documents/renderGenera al momento el PDF de una póliza o cotización (docType + policyId o quoteId), sin guardarlo.
POST/api/policies/{id}/documents/certificate/regenerateVuelve a generar el certificado (responde 202 con un jobId).

Documentos

curl https://api.quore.app/api/policies/POLICY_ID/documents -H "x-api-key: sk_test_…"
curl https://api.quore.app/api/documents/DOCUMENT_ID/download -H "x-api-key: sk_test_…"
curl "https://api.quore.app/api/documents/render?docType=certificate&policyId=POLICY_ID" -H "x-api-key: sk_test_…" -o certificado.pdf

5. Consultar y actualizar pólizas

Para reconciliar tu sistema con Quore: listar y consultar pólizas, registrar el número que asigna la aseguradora y obtener los documentos de una cotización. admin incluye todos los scopes.

EndpointScopePedidoRespuestaCódigos
GET/api/policiesread · emitQuery opcional: productId, status, environment, limit (50 por defecto, máximo 200), offset.200 con { data, total, limit, offset }, más recientes primero. Cada ítem trae la póliza con sus campos en camelCase (policyNumberInternal, netPremium, createdAt…).400 environment de otro entorno · 401 · 403 sin scope
GET/api/policies/{id}read · emitPath: id de la póliza.200 con la póliza (mismo formato que policy.created, con montos numéricos) y documents: id, doc_type, generated_at, download_path.401 · 403 sin scope · 404 no existe o es de otro entorno
POST/api/policies/{id}/insurer-numberemitBody: { "policyNumberInsurer": "AP-2026-000123" } (texto no vacío). Reemplaza el valor anterior.200 con la póliza actualizada (campos en camelCase, como en el listado).400 falta o está vacío · 401 · 403 sin scope · 404 no existe o es de otro entorno
GET/api/quotes/{id}/documentsread · quote · emitPath: id de la cotización.200 con la lista de documentos de la cotización: id, docType, policyId, quoteId, templateId, generatedAt, createdAt.401 · 403 clave pública o sin scope · 404 no existe o es de otro entorno

Pedidos

curl "https://api.quore.app/api/policies?status=active&limit=50&offset=0" -H "x-api-key: sk_test_…"
curl https://api.quore.app/api/policies/POLICY_ID -H "x-api-key: sk_test_…"
curl https://api.quore.app/api/quotes/QUOTE_ID/documents -H "x-api-key: sk_test_…"

curl -X POST https://api.quore.app/api/policies/POLICY_ID/insurer-number \
  -H "x-api-key: sk_test_…" \
  -H "Content-Type: application/json" \
  -d '{ "policyNumberInsurer": "AP-2026-000123" }'

GET /api/policies (resumida)

{
  "data": [
    {
      "id": "b2a7…",
      "policyNumberInternal": "POL-0042",
      "policyNumberInsurer": null,
      "status": "active",
      "productId": "PRODUCT_ID",
      "coverageId": "basica",
      "quoteId": "QUOTE_ID",
      "netPremium": 42000,
      "totalPremium": 50820,
      "currency": "ARS",
      "environment": "live",
      "createdAt": "2026-10-26T14:03:11.402Z"
    }
  ],
  "total": 1,
  "limit": 50,
  "offset": 0
}

GET /api/policies/{id} (resumida)

{
  "id": "b2a7…",
  "policy_number_internal": "POL-0042",
  "policy_number_insurer": "AP-2026-000123",
  "status": "active",
  "product_id": "PRODUCT_ID",
  "coverage_id": "basica",
  "quote_id": "QUOTE_ID",
  "net_premium": 42000,
  "total_premium": 50820,
  "currency": "ARS",
  "installments": 12,
  "installment_amount": 4235,
  "environment": "live",
  "payment_method_status": null,
  "start_date": "2026-10-26T00:00:00.000Z",
  "end_date": "2027-10-26T00:00:00.000Z",
  "documents": [
    {
      "id": "DOCUMENT_ID",
      "doc_type": "certificate",
      "generated_at": "2026-10-26T14:03:15.020Z",
      "download_path": "/api/documents/DOCUMENT_ID/download"
    }
  ]
}
  • Una clave solo ve registros de su entorno: una clave de test no encuentra pólizas live (404).
  • Las claves públicas (widget) no pueden usar ninguno de estos endpoints (403).

Aprobaciones

  • Cotización: una cobertura con aprobación requerida (siempre o según una condición) deja la cotización pending_approval. La aseguradora la aprueba o rechaza desde su panel; dispara quote.approved o quote.rejected.
  • Intermediarios: si el producto no permite que emitan directo, la cotización de un intermediario queda pending_approval hasta que la aseguradora la apruebe; aprobada, se emite y la póliza queda emitida al confirmarse el pago.
  • Una cotización pending_approval, vencida o rechazada no se puede emitir (400).

Estados

Cotización

EstadoSignificado
draftBorrador, todavía sin precio.
pricedCotizada: lista para emitir hasta expiresAt.
pending_approvalRequiere aprobación de la aseguradora antes de emitir y cobrar (una regla de cobertura o una cotización de intermediario sin emisión directa). El motivo está en result.approval_reasons.
approvedAprobada: se puede emitir.
rejectedRechazada: no se puede emitir.
acceptedAceptada por el cliente.
expiredVencida: hay que volver a cotizar.
issuedEmitida: ya tiene su póliza.

Póliza

EstadoSignificado
pendingPendiente de condiciones de emisión (por ejemplo, una inspección).
pending_paymentEmitida, esperando que se complete el pago online (en productos condicionales, una vez aprobadas sus condiciones).
activeActiva. Según sus fechas se muestra como Contratada (empieza más adelante), Vigente o Vencida.
rejectedRechazada (condición fallida o vencida).
cancelledCancelada.
expiredVencida.

Las pólizas con cobro recurrente o por uso informan además payment_method_status: pending hasta que el asegurado registra su medio de pago, luego active. La póliza recién pasa a active con el primer cobro confirmado (recurrente) o la tarjeta validada (por uso).

Errores

Todos los errores responden JSON con error (mensaje legible en español). Los errores de validación por campo (422) agregan fields: clave de variable → mensaje.

CódigoCuándo
400Datos faltantes o inválidos: sin productId/variables, producto inactivo o canal deshabilitado, cotización vencida, rechazada o pendiente de aprobación, adjunto requerido ausente, listado de otro entorno.
401Clave ausente, inválida o revocada; token de emisión ausente o vencido (widget).
403Scope insuficiente, clave pública en un recurso de lectura, intermediario inactivo, intermediario sin nivel de comisión para el producto, o función no incluida en tu plan.
404No existe, es de otra cuenta o de otro entorno (una clave de test solo ve datos de test).
409Conflicto: la cotización ya se emitió con otra cobertura, o un dato único ya existe (por ejemplo, externalRef).
422Validación por campo (fields), medio de pago no habilitado para el producto, o consumo no facturable para la póliza.
429Límite de pedidos alcanzado: espera los segundos de Retry-After.

422: validación por campo

{
  "error": "Edad: el valor mínimo es 18",
  "fields": {
    "edad": "Edad: el valor mínimo es 18",
    "plan": "Plan: este dato es obligatorio"
  }
}

Error

{
  "error": "Cotización no encontrada"
}