É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_..."import { Cord } from '@flouviahq/node';
const cord = new Cord(process.env.CORD_API_KEY);
const page = await cord.events.list({ object_id: '8b0c6f0e-2d55-4c1e-9a43-6a2f1c7d9e10', limit: 10 });
for (const event of page.data) console.log(event.created_at, event.type, event.actor);{
"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’
idde 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, utilisezobject_id,typeetcreated_at. object_idvautnullpour les événements sans objet doté d’un UUID, commeaccount.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_idqui n’est pas un UUID ou uncursornon valide répondent400aveccode: "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_..."import { Cord } from '@flouviahq/node';
const cord = new Cord(process.env.CORD_API_KEY);
const me = await cord.me();
console.log(me.org.nombre, me.scope, me.mode);{
"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.