Aller au contenu

Événements

Ce qui s’est passé dans votre entreprise, avec le même catalogue que celui des webhooks et un historique pour rapprocher ce que votre serveur n’a pas reçu.

Chaque changement important dans Cord produit un événement : un enregistrement avec un type, un objet, des données et son auteur. Ces mêmes événements sont envoyés à vos webhooks, déclenchent Cord Workflows et restent dans un historique que vous consultez avec GET /api/v1/events, qu’un endpoint y soit abonné ou non.

Catalogue des événements

Il existe 41 types. La colonne Objet correspond à la valeur de object dans l’historique et détermine la forme de data (voir la section suivante).

Événement Objet Émis lorsque…
quote.created quote Un devis est créé depuis l’application, l’API, MCP ou Cord Elements.
quote.sent quote Le devis est envoyé au client.
quote.viewed quote Le client ouvre le lien public pour la première fois. Les consultations du commercial lui-même ne comptent pas.
quote.updated quote Le commercial le modifie et le renvoie.
quote.approved quote Le client l’approuve (totalement ou partiellement), ou il est marqué comme approuvé via l’API.
quote.rejected quote Le client le refuse, ou il est marqué comme refusé via l’API.
quote.expired quote Sa date de validité passe sans décision (il était envoyé ou consulté).
quote.deleted quote Un brouillon qui n’a jamais été envoyé est supprimé.
quote.paid quote Le paiement total est reçu, ou le dernier encaissement en attente d’un plan d’acompte ou d’échéances.
quote.approval_requested quote Un devis est mis en attente de validation interne en raison de la remise, du montant ou de la marge.
quote.approval_decided quote La direction approuve ou refuse cette demande.
quote.comment_added quote Le client ou le commercial écrit dans la conversation du devis.
payment.partial quote Un paiement partiel (acompte, solde ou échéance) est reçu sans compléter le total.
payment.failed quote Un prélèvement récurrent d’un forfait mensuel échoue.
invoice.stamped quote Le CFDI d’un devis est timbré (Mexique).
invoice.issued quote La facture commerciale d’un devis est émise hors du Mexique.
invoice.finalized invoice Une facture de Cord Invoicing est émise.
invoice.sent invoice Cette facture est envoyée au client.
invoice.paid invoice La facture est entièrement payée.
invoice.payment_failed invoice Un paiement sur la facture échoue.
invoice.voided invoice La facture est annulée.
invoice.marked_uncollectible invoice La facture est marquée comme irrécouvrable.
invoice.overdue invoice Sa date d’échéance passe sans qu’elle soit réglée.
client.created client Un client est créé.
client.updated client Les données d’un client sont modifiées.
client.deleted client Un client est supprimé.
product.created product Un produit est créé.
product.updated product Un produit est modifié.
product.deleted product Un produit est supprimé.
task.created task Une tâche est créée depuis l’application, l’API, MCP ou un workflow, ou par Cord lui-même (rétrofacturation, remboursement SPEI). Contient cotizacion_id et factura_id (ou null).
task.completed task Une tâche est marquée comme terminée.
promise.created promise Une promesse de paiement est enregistrée.
promise.kept promise La promesse est tenue.
promise.broken promise La promesse n’est pas tenue.
dispute.created dispute Un client ouvre une rétrofacturation sur un paiement Cord Payments.
dispute.closed dispute La rétrofacturation est clôturée avec son résultat.
refund.succeeded refund Un remboursement aboutit.
refund.failed refund Un remboursement échoue.
payout.paid payout Un versement arrive sur votre compte bancaire.
payout.failed payout Un versement échoue.
account.updated account Ce que votre compte d’encaissement peut faire change. N’est émis que lorsqu’un champ change.

ping n’est pas un événement du catalogue : c’est l’envoi de test du bouton Tester du Workbench et il n’apparaît jamais dans l’historique.

Types internes dans l’historique

En plus des 41 types, l’historique peut afficher quote.expiring, invoice.due_soon, invoice.past_due et schedule.tick. Ce sont des signaux internes qu’utilise Cord Workflows pour agir avant une échéance ; ils ne sont pas envoyés par webhook et ne font pas partie du catalogue. Si vous parcourez l’historique complet, ignorez les types que vous ne connaissez pas.

Forme de data par objet

Tout montant voyage avec sa devise dans moneda. Les noms des champs sont ceux du serveur, en espagnol.

Objet Champs de data
quote id, folio, status, moneda, total, cliente, cliente_id, link_publico
invoice id, object, numero, folio_fiscal, estado, estado_fiscal, pais, tipo, moneda, total, pagado, saldo, vence, cliente, cotizacion_id, link_publico
client id, object, empresa, contacto, email, telefono, rfc, terminos, country_code
product id, object, sku, nombre, unidad, precio_lista, activo (jamais le coût ni la marge)
task id, object, titulo, due_date, done, cotizacion_id (ni responsable, ni priorité, ni notes)
promise id, object, cotizacion_id, fecha_promesa, monto, moneda, estado
dispute id, object, monto, moneda, motivo, estado, fecha_limite, referencia, cotizacion_id, folio, cliente
refund object, monto, moneda, motivo, motivo_falla, referencia, cotizacion_id, folio, cliente
payout id, object, monto, moneda, llegada, metodo, motivo_falla, referencia
account object, puede_cobrar, puede_depositar, motivo_bloqueo, pendientes

Champs supplémentaires par événement :

Événement Ajoute
payment.partial tipo (anticipo, saldo ou cuota), monto (de ce paiement), numero_cuota, saldo_pendiente, payment_method
quote.approval_requested motivo
quote.approval_decided decision (approved ou rejected)
quote.comment_added autor (cliente ou vendedor), mensaje, item_id s’il porte sur une ligne ; une contre-proposition du client contient tipo: "contraoferta" et propuesta
client.updated empresa_anterior, email_anterior, terminos_anterior lorsqu’ils ont changé
product.updated precio_lista_anterior, activo_anterior lorsqu’ils ont changé
client.deleted Uniquement id, object et empresa
product.deleted Uniquement id, object et nombre

Sur une facture, estado correspond à son cycle de vie (draft, open, paid, void ou uncollectible) et estado_fiscal à son enregistrement auprès du fournisseur fiscal (pending, issued, cancelled ou error). Sur un devis, status vaut draft, sent, viewed, approved, rejected, expired, invoiced ou paid.

Le data conservé dans l’historique est celui du webhook sans link_publico : le lien est un identifiant du client et n’est pas conservé.

Qui a provoqué l’événement : actor

Valeur Signification
user:<uuid> Une personne de votre équipe, connectée à l’application.
api:<id de clé> Une requête à l’API avec cette clé (ou une connexion OAuth).
mcp:<id de clé> Un outil du serveur MCP.
client Votre client, depuis le lien public du devis ou de la facture.
workflow:<uuid> Une action de Cord Workflows.
integration:<fournisseur>:<id> Une intégration qui synchronise vers Cord, par exemple HubSpot.
slack, slack:<e-mail>, shopify Une action depuis ces intégrations.
system, system:cron Cord lui-même : une expiration, un paiement du prestataire de paiement ou une tâche planifiée.

Traitez actor comme un texte avec un préfixe : décidez en fonction de ce qui précède les deux-points et ne supposez pas que la liste n’évoluera pas.

Historique : GET /api/v1/events

Renvoie les événements de votre organisation, du plus récent au plus ancien. Si votre serveur est resté indisponible plus longtemps que ce que couvrent les nouvelles tentatives, c’est ici que vous récupérez ce que vous avez manqué.

Paramètre Effet
type Un type d’événement, par exemple quote.approved. Un type inconnu répond 400.
object_id L’UUID de l’objet : l’historique complet d’un devis, d’une facture ou d’un client.
limit De 1 à 200 ; 50 par défaut.
cursor Le next_cursor de la page précédente.
curl "https://cordhq.app/api/v1/events?object_id=8b0c6f0e-2d55-4c1e-9a43-6a2f1c7d9e10&limit=10" \
  -H "Authorization: Bearer sk_test_..."
{
  "data": [
    {
      "id": "e81c5a3f-7d2b-4e9a-b6c1-0f4d8a2e5c71",
      "type": "quote.approved",
      "object": "quote",
      "object_id": "8b0c6f0e-2d55-4c1e-9a43-6a2f1c7d9e10",
      "data": {
        "id": "8b0c6f0e-2d55-4c1e-9a43-6a2f1c7d9e10",
        "folio": "COT-0001",
        "status": "approved",
        "moneda": "MXN",
        "total": 13920,
        "cliente": "Ferretería La Prueba",
        "cliente_id": "0e6f2b8a-91c4-4d7e-b3a5-6c2d8f1e4a90"
      },
      "actor": "client",
      "created_at": "2026-10-07T17:31:44.208Z"
    },
    {
      "id": "3a7f1c9e-2b4d-4a6e-8c0f-5d9b3e7a1c24",
      "type": "quote.sent",
      "object": "quote",
      "object_id": "8b0c6f0e-2d55-4c1e-9a43-6a2f1c7d9e10",
      "data": {
        "id": "8b0c6f0e-2d55-4c1e-9a43-6a2f1c7d9e10",
        "folio": "COT-0001",
        "status": "sent",
        "moneda": "MXN",
        "total": 13920,
        "cliente": "Ferretería La Prueba",
        "cliente_id": "0e6f2b8a-91c4-4d7e-b3a5-6c2d8f1e4a90"
      },
      "actor": "api:2c6e0a9d-4f1b-4c3e-8a7d-9b5f1e3c7a20",
      "created_at": "2026-10-07T17:04:12.318Z"
    }
  ],
  "meta": { "next_cursor": null }
}
  • L’id de l’historique est un UUID propre à l’enregistrement. Ce n’est pas l’evt_… de l’envoi du webhook : pour dédupliquer entre les deux, utilisez object_id, type et created_at.
  • object_id vaut null pour les événements sans objet doté d’un UUID, comme account.updated.
  • La pagination se fait par curseur et elle est stable : un nouvel événement ne décale pas la page que vous lisez. Voir Pagination.
  • Un object_id qui n’est pas un UUID ou un cursor non valide répondent 400 avec code: "invalid_request".

Conservation

L’historique fonctionne en ajout seul : un événement n’est pas modifié après son écriture. Il est conservé 90 jours, puis un traitement quotidien le supprime ; celui qui a lancé une exécution d’un workflow est conservé tant que cette exécution existe, et une exécution est supprimée un an après sa fin. Le journal des envois de webhooks a sa propre durée (30 jours ; 90 pour les envois échoués). Tout est supprimé avec l’organisation.

Vérifier une clé : GET /api/v1/me

C’est l’appel le plus simple de l’API : il confirme que la clé est valide et indique à quelle organisation elle appartient, son droit et son mode. Il répond à toute clé secrète, clé restreinte ou connexion OAuth, quels que soient ses droits par ressource.

curl https://cordhq.app/api/v1/me \
  -H "Authorization: Bearer sk_test_..."
{
  "data": {
    "org": { "id": "5b1f7d9e-3c2a-4e8b-9f61-0a7c4d2e8b13", "nombre": "Aceros del Norte", "plan": "pro" },
    "scope": "write",
    "mode": "test"
  }
}
Champ Contenu
org.id L’id de l’organisation sur laquelle opère la clé. Avec une clé de test, c’est celui de votre environnement de test, différent de celui du compte réel.
org.nombre Le nom de l’organisation.
org.plan L’offre en cours : free, starter, pro, scale ou developer.
scope read ou write. Sur une clé restreinte, les droits par ressource l’emportent sur cette valeur.
mode test ou live.

Utilisez-le pour tester un identifiant avant de l’enregistrer dans votre intégration.