Esdeveniments
Objectes event de només lectura amb un id opac. Consulta històrica via l'API i entrega per webhook.
Cada esdeveniment publicat a Factuarea es persisteix com un objecte
event de només lectura amb un id opac (un UUID v7, p. ex.
01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a0d), coherent amb l'id de
qualsevol altre recurs v1. Això et permet:
- Consultar-lo via API:
GET /v1/events/{id}iGET /v1/events?type=invoice.paid. - Entregar-lo als webhook endpoints subscrits (el mateix objecte s'envia al body de l'entrega — vegeu Webhooks).
- Reenviar una entrega des del dashboard
(
Developers > Webhooks > Deliveries).
Forma del payload
Cada esdeveniment comparteix aquesta estructura:
{
"id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a0d",
"object": "event",
"type": "invoice.paid",
"aggregate_id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a03",
"api_version": "2026-05-22",
"livemode": true,
"data": {
"invoice": { "id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a03" }
},
"created": "2026-05-15T10:23:18Z"
}Camps:
id— identificador opac de l'esdeveniment (UUID v7). Fes-lo servir com a idempotency key al teu costat.object— sempreevent.type— nom de l'esdeveniment com a<category>.<action>(p. ex.invoice.paid,quote.approved).aggregate_id— UUID v7 del recurs que va produir l'esdeveniment (p. ex. la factura per ainvoice.paid).nullper a esdeveniments sense agregat reomplert. Diferent d'id, que identifica el propi esdeveniment.api_version— versió per data sota la qual es va serialitzar el payload, segellada en l'emissió. Sempre present en els esdeveniments emesos avui;nullnomés per a esdeveniments antics emesos abans de segellar les versions.livemode—trueper a esdeveniments generats en producció (clau live,fact_live_);falseper a esdeveniments generats en mode de prova (empresa sandbox, claufact_test_). Els esdeveniments de mode de prova es registren i es poden consultar viaGET /v1/events, però no s'entreguen als webhook endpoints (vegeu Mode de prova i sandbox), de manera que qualsevol esdeveniment que el teu endpoint rebi realment és semprelivemode: true.data— una referència lleugera al recurs afectat, indexada pel seu tipus — p. ex.{ "invoice": { "id": "..." } }. Obtén el recurs des del seu propi endpoint per aconseguir la representació completa i actual.created— timestamp ISO 8601 UTC de quan es va crear l'esdeveniment.
Idempotència
Cada esdeveniment té un id únic. Els webhooks reentreguen el mateix id al
mateix endpoint a cada reintent. Al teu handler:
event_id = event['id']
if seen_in_db(event_id):
return '', 200
process(event)
mark_seen_in_db(event_id)Catàleg d'esdeveniments
El catàleg complet i autoritatiu de tipus d'esdeveniment subscribibles el retorna
GET /v1/event-catalog. Cada entrada porta un name, una category, una
description llegible i un status (available o
coming_soon):
curl https://api.factuarea.com/v1/event-catalog \
-H "Authorization: Bearer $FACTUAREA_API_KEY"{
"data": [
{
"name": "invoice.paid",
"category": "invoice",
"description": "Factura pagada",
"status": "available"
}
],
"has_more": false,
"next_cursor": null
}Tipus d'esdeveniment representatius per categoria (consulta el catàleg per a la llista completa i actualitzada):
Factures
invoice.created, invoice.auto_created,
invoice.corrective_auto_created, invoice.subscription_auto_created,
invoice.updated, invoice.sent, invoice.paid,
invoice.cancelled, invoice.annulled, invoice.overdue,
invoice.deleted, invoice.number_assigned, invoice.rectified,
invoice.email_sent, invoice.email_failed,
invoice.payment_reminder_sent, invoice.simplified_created,
invoice.simplified_substituted, invoice.substituted_by_complete,
invoice.verifactu_submitted, invoice.verifactu_failed,
invoice.metadata_changed.
invoice.auto_created / invoice.corrective_auto_created /
invoice.subscription_auto_created els emeten els fluxos d'
auto-facturació de passarel·les de pagament quan
un cobrament, una devolució o un cicle de subscripció generen una factura de
manera automàtica.
Pressupostos
quote.created, quote.updated, quote.deleted, quote.approved,
quote.rejected, quote.converted, quote.expired,
quote.marked_as_pending, quote.cancelled, quote.number_assigned,
quote.metadata_changed, quote.email_sent, quote.email_failed.
Factures proforma
proforma.created, proforma.updated, proforma.deleted,
proforma.accepted, proforma.rejected, proforma.cancelled,
proforma.expired, proforma.converted_to_invoice,
proforma.number_assigned, proforma.metadata_changed,
proforma.email_sent, proforma.email_failed.
Albarans
delivery_note.created, delivery_note.updated,
delivery_note.status_changed, delivery_note.signed,
delivery_note.converted, delivery_note.email_sent,
delivery_note.email_failed.
Factures de compra
purchase_invoice.created, purchase_invoice.updated,
purchase_invoice.paid, purchase_invoice.payment_registered,
purchase_invoice.cancelled, purchase_invoice.metadata_changed.
Factures recurrents
recurring_invoice.created, recurring_invoice.activated,
recurring_invoice.paused, recurring_invoice.updated,
recurring_invoice.deleted, recurring_invoice.completed,
recurring_invoice.executed, recurring_invoice.failed,
recurring_invoice.cancelled, recurring_invoice.metadata_changed.
Clients i productes
client.created, client.updated, client.deleted,
client.metadata_changed, product.created, product.updated.
Sèries i impostos
series.created, series.updated, series.deleted,
series.archived, series.unarchived, series.marked_as_default,
series.demoted_from_default, series.number_consumed,
series.year_reset, series.month_reset, tax.metadata_changed,
tax.validity_changed, tax.external_reference_changed.
FacturaE (FACe)
facturae.face_submitted, facturae.face_status_changed,
facturae.face_cancellation_requested.
Pagaments i passarel·les
payment.received, payment.reversed, payout.reconciled.
payment.received i payment.reversed són les dues meitats d'un mateix
cicle: el primer es dispara quan es registra un pagament contra una
factura, i el segon quan aquest pagament s'anul·la i la factura torna al
circuit de cobrament. Subscriu-te als dos — una factura que vas donar per
cobrada pot deixar d'estar-ho, i reaccionar només a la primera meitat és
confiar en una xifra que ha caducat. Consulta
payment.reversed més avall.
payout.reconciled es dispara quan un payout de Stripe es concilia amb el teu
extracte bancari (consulta Payouts i conciliació).
Automatitzacions
automation_rule.activated, automation_rule.paused,
automation_rule.auto_paused, automation_run.started,
automation_run.completed, automation_run.failed,
automation_run.step_dead_lettered.
El motor informa del seu propi cicle de vida. Els tres esdeveniments
automation_rule.* porten la regla al cos d'entrega, sota data.object:
activated quan una regla entra en servei i comença a escoltar el seu activador,
paused quan l'atura una persona i auto_paused quan l'atura la plataforma
després d'una ratxa d'execucions fallides.
Els quatre esdeveniments automation_run.* porten l'execució al cos d'entrega,
sota data.object: started quan un activador que ha coincidit supera els
límits del motor i
l'execució s'admet, completed quan tots els passos van aplicar el seu efecte,
failed quan l'execució va acabar sense produir el seu efecte i no es pot
reprocessar, i step_dead_lettered quan un pas concret queda aparcat a
l'espera d'un rellançament manual. Com a la resta d'esdeveniments, data.object
és el snapshot pres en emetre'l, no l'estat actual del recurs. Consulta la
referència de l'execució.
Dos d'ells porten claus extra al costat del snapshot.
automation_rule.auto_paused afegeix consecutive_failures, el nombre
d'execucions fallides consecutives que van provocar la pausa automàtica — la
regla la va pausar la plataforma, i automation_rule.paused és el seu
equivalent humà. automation_run.step_dead_lettered afegeix step_index i
discard_reason: step_index és la posició del pas aparcat començant per zero,
i es resol contra el mateix snapshot (l'element de data.object.steps el
step_index del qual coincideix, perquè un pas no és un recurs públic per si
mateix), i discard_reason és un valor tipat d'un catàleg tancat, mai text
lliure. A la pràctica sempre és un motiu de descart rellançable: un resultat que
no admet reprocés tanca l'execució com a failed en comptes d'aparcar el pas.
Aquests set noms són al mateix catàleg tancat que la resta d'esdeveniments, així
que també són activadors vàlids de regles: una automatització pot reaccionar
a automation_run.failed igual que reacciona a invoice.paid, i cap llista
d'exclusió no els amaga del catàleg d'activadors. Com la resta del motor,
requereixen el mòdul automations.
Encadenar-los està acotat, no prohibit. Cada salt «acció → esdeveniment → regla»
consumeix el límit de profunditat d'encadenament del motor —tres salts per
defecte—, així que una regla que reacciona a automation_run.failed i torna a
fallar no pot repetir-se sense fi: exhaurit el límit, l'execució no arriba a
executar-se i queda registrada com a blocked. Un esdeveniment que produeix una
persona o una integració entra amb profunditat zero, així que només consumeix
aquest pressupost allò que va provocar una automatització.
Exemples de payload
invoice.paid
{
"id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a0d",
"object": "event",
"type": "invoice.paid",
"aggregate_id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a03",
"api_version": "2026-05-22",
"livemode": true,
"data": {
"invoice": { "id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a03" }
},
"created": "2026-05-15T11:42:08Z"
}client.updated
{
"id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a1a",
"object": "event",
"type": "client.updated",
"aggregate_id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a2b",
"api_version": "2026-05-22",
"livemode": true,
"data": {
"client": { "id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a2b" }
},
"created": "2026-05-15T11:50:12Z"
}quote.converted
{
"id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a3c",
"object": "event",
"type": "quote.converted",
"aggregate_id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a4d",
"api_version": "2026-05-22",
"livemode": true,
"data": {
"quote": { "id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a4d" }
},
"created": "2026-05-15T12:01:55Z"
}L'esdeveniment només porta una referència lleugera al recurs afectat. Obtén
el recurs des del seu propi endpoint (p. ex. GET /v1/quotes/{id}) per llegir
la factura convertida a la qual enllaça.
payment.reversed
S'emet quan s'anul·la un pagament registrat contra una factura. Fins que
va existir, una integració que havia sentit payment.received no tenia
manera d'assabentar-se que aquell mateix pagament s'havia desfet.
El cos d'entrega d'aquest esdeveniment porta el recurs afectat complet
sota data.object — el pagament tal com el serialitza l'API v1, ja marcat
com a anul·lat — més un bloc data.reversal que descriu l'operació
mateixa:
{
"id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a5e",
"type": "payment.reversed",
"api_version": "2026-05-22",
"created": 1780646100,
"livemode": true,
"test": false,
"correlation_id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a6f",
"data": {
"type": "payment.reversed",
"object": {
"id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a0b",
"object": "payment",
"invoice_id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a01",
"amount": 500.00,
"payment_date": "2026-05-20",
"payment_method": "direct_debit",
"payment_method_text": "Domiciliación bancaria",
"reference": "TRF-2026-0042",
"notes": null,
"is_reversed": true,
"reversed_at": "2026-06-02T08:15:00Z",
"reversal_reason": "direct_debit_return",
"reversal_reason_text": "Devolución de adeudo SEPA",
"reversal_note": "Devuelto por el banco con motivo MD01.",
"created_at": "2026-05-20T10:30:00Z",
"updated_at": "2026-06-02T08:15:00Z"
},
"reversal": {
"reason": "direct_debit_return",
"origin": "gateway"
}
}
}data.reversal.reason— un dels cinc valors del catàleg tancat:direct_debit_return,card_dispute,misapplied_payment,bounced_effect,recording_error. Ramifica segons aquest camp, mai segonsreversal_reason_text, que és una etiqueta en castellà per a persones.data.reversal.origin—gatewayquan va ser la passarel·la de pagament la que va informar de la devolució, disputa o retrocessió (ja hi va haver moviment al banc);manualquan ho va registrar una persona. Útil per decidir si reclamar al client o esperar el fitxer bancari.
Què fer quan arriba: la factura ha tornat al circuit de cobrament
(sent, o overdue si el seu venciment ja ha passat) i el seu
paid_amount ja no inclou aquella entrada, així que refresca el que
tinguessis desat a la memòria cau sobre aquella factura. No emetis una
factura rectificativa com a reacció — una anul·lació no és una minoració
d'ingressos. Consulta
Anul·lació o rectificativa?.
Subscriure's a esdeveniments
Via API:
curl -X POST https://api.factuarea.com/v1/webhook_endpoints \
-H "Authorization: Bearer $FACTUAREA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://app.mycompany.com/factuarea/webhook",
"enabled_events": ["invoice.paid", "quote.approved"]
}'Per subscriure't a tots els esdeveniments (no recomanat en producció excepte per a dashboards interns):
{ "enabled_events": ["*"] }Per subscriure't a famílies senceres (tots els invoice.*):
{ "enabled_events": ["invoice.*", "quote.*"] }Llistar esdeveniments via API
GET /v1/events?type=invoice.paid&limit=50Filtres disponibles: type, type[in], created[gte], created[lte],
created[gt], created[lt]. Paginació per cursor estàndard
(limit, starting_after, ending_before) — vegeu
Paginació.
Esdeveniments de comandes
Subscriu-te a order.invoiced i order.refunded per rebre snapshots complets de la factura o rectificativa a data.object. Tots dos inclouen data.store.uuid, data.store.provider i data.order.external_id; les devolucions afegeixen data.refund.scope i data.refund.reason_code. Fes servir l’id de l’esdeveniment per deduplicar lliuraments i correlation_id per relacionar operacions. Consulta el processament de botigues i el trigger de n8n.
if (event.type === "order.invoiced" || event.type === "order.refunded") {
const invoice = event.data.object;
const storeId = event.data.store.uuid;
const orderId = event.data.order.external_id;
await saveOrderDocument({ eventId: event.id, storeId, orderId, invoice });
}