Skip to main content

Transaction Timeline

The API maintains a public timeline of relevant lifecycle events for every transaction. The CorpX dashboard consumes this timeline to render the step-by-step view of a transaction; you can consume the same API to power your own dashboards or accelerate end-customer support.

Endpoint

GET /v1/transactions/{transactionId}/timeline
Authorization: Bearer <jwt>

Response:

{
"transactionId": "pay_01HMABCD...",
"level": "public",
"events": [
{
"eventId": "8a2c...",
"transactionId": "pay_01HMABCD...",
"workflowId": "pixout-acc_X-key_Y",
"type": "pix_out.requested",
"source": "workflow",
"audience": "public",
"severity": "info",
"occurredAt": "2026-05-05T22:14:01.045Z",
"recordedAt": "2026-05-05T22:14:01.231Z",
"message": "PIX out requested",
"payload": {
"paymentId": "pay_01HMABCD...",
"accountId": "acc_X",
"amount": "100.00",
"mode": "KEY"
}
},
{
"type": "pix_out.confirmed",
"occurredAt": "2026-05-05T22:14:03.612Z",
"severity": "info",
"payload": {
"status": "COMPLETED",
"endToEndId": "E18236120202605051914aBcDeF"
}
}
]
}

Filters (query params)

  • eventType — filter by exact type (e.g. pix_out.confirmed).
  • source — filter by origin (workflow, partner_webhook, client_webhook, backoffice, system, partner_poll, api).
  • since — ISO 8601 (e.g. 2026-05-05T00:00:00Z); only events with occurredAt >= since.
  • limit — maximum 1000 (default 500).

Ordering

Events are returned in ascending chronological order by occurredAt, tie-broken by recordedAt (insertion time). Use the last event's occurredAt from the response as a cursor for simple pagination via since.

Contract guarantees

The event types listed below are part of the public contract and follow append-only evolution rules:

  • Additions are minor SemVer and don't require any change on your side — new event_type values simply start appearing.
  • Renames or removals are major (breaking) and go through a formal deprecation period announced in the changelog.
  • Payload fields may gain new optional fields without notice; existing fields are never removed without a major version.

In short: treat any unknown event_type as informational and ignore gracefully — future versions may add types without breaking your client.

Public event catalog

Each event is identified by a dot-separated string (<domain>.<verb>). The severity, source and payload fields help you render and filter in your UI.

Verb conventions (mnemonic):

  • received — arrived at you without prior action (e.g. pix_in.received, refund.received).
  • requested — you requested it via API (e.g. pix_out.requested, boleto_pay.requested).
  • created — you created a resource (e.g. qrcode.created).
  • confirmed, failed, timeout, refunded — outcomes.

PIX out (pix_out.*)

pix_out.requested

CorpX accepted the PIX out request initiated via POST /v1/payments/*. There is no BACEN confirmation yet.

  • severity: info
  • source: workflow
  • payload:
    {
    "paymentId": "pay_...",
    "accountId": "acc_...",
    "amount": "100.00",
    "mode": "KEY",
    "keyType": "EVP",
    "identifier": "client-ref-123",
    "idempotencyKey": "..."
    }

pix_out.confirmed

BACEN confirmed the transfer. Equivalent to the outbound webhook pix.out.completed.

  • severity: info
  • source: workflow
  • payload: {paymentId, accountId, status, transactionId, endToEndId, amount}

pix_out.failed

The transfer failed (insufficient balance, invalid key, BACEN refusal). The money did not leave the account.

  • severity: error
  • source: workflow
  • payload: {paymentId, status: "FAILED" | "REJECTED", errorCode, errorReason, ...}

pix_out.timeout

The partner accepted the call but the final status was not confirmed within 5 minutes. Do not retry with a new Idempotency-Key without first checking the account statement — the money may have left.

  • severity: warn
  • source: workflow
  • payload: {paymentId, errorCode: "confirmation_timeout", errorReason: "..."}

pix_out.refunded

A PIX out you sent was returned by the recipient (refund). The payload carries the linkage to the refund.

  • severity: info
  • source: workflow
  • payload:
    {
    "originalTransactionId": "pay_...",
    "refundTransactionId": "pay_...",
    "amount": "100.00"
    }

pix_out.client_webhook_sent

Confirms that the outbound webhook (pix.out.* or pix.refund.*) was successfully delivered to your configured endpoint. Useful for auditing — equivalent to delivered_at in the delivery log.

  • severity: info
  • source: client_webhook
  • payload: {eventId, eventType, subscriptionId, statusCode}

PIX in (pix_in.*)

pix_in.received

A PIX was credited to one of your accounts — CorpX persisted the credit on the statement. Typical uses: notify the integrator's internal system to reconcile against an order; trigger post-payment workflows.

  • severity: info
  • source: workflow
  • payload: {transactionId, endToEndId, accountId, amount, description, identifier, method, payerName, payerDocument}

pix_in.client_webhook_sent

Confirms delivery of the outbound webhook pix.in.completed to your endpoint.

  • severity: info
  • source: client_webhook

QR Code (qrcode.*)

qrcode.created

A dynamic or static QR code was created via POST /v1/accounts/{id}/pix/qr-code/*.

  • severity: info
  • source: workflow
  • payload: {txid, accountId, amount, qrType, identifier, expiresAt}

qrcode.paid

The QR code was paid by the end customer (signal received from BACEN or detected via proactive polling).

  • severity: info
  • source: workflow
  • payload: {txid, accountId, paidAmount, transactionId, endToEndId, payerDocument, payerName}

qrcode.client_webhook_sent

Confirms delivery of the outbound webhook qrcode.paid.

Boleto (boleto_pay.*)

boleto_pay.requested

Boleto payment requested via POST /v1/accounts/{id}/boleto/pay. Partner confirmation has not arrived yet.

  • severity: info
  • source: workflow
  • payload: {boletoId, accountId, line, amount, taxId, scheduled}

boleto_pay.confirmed

Stark/partner confirmed the boleto payment.

  • severity: info
  • source: workflow
  • payload: {boletoId, starkId, accountId, amount, line}

boleto_pay.failed

Boleto payment failed.

  • severity: error
  • source: workflow
  • payload: {boletoId, errorReason}

boleto_pay.client_webhook_sent

Confirms delivery of the outbound webhook boleto.paid or boleto.failed.

Inbound refund (refund.*)

These events appear on the timeline of the refund transaction that arrived. The original transaction that was refunded gets a pix_out.refunded event on its own timeline, linking the refund.

refund.received

A refund arrived for one of your accounts — someone returned a PIX you had sent.

  • severity: info
  • source: workflow
  • payload: {transactionId, refundEndToEndId, originalEndToEndId, accountId, amount}

refund.confirmed

The refund was marked as successfully completed (record persisted, balance credited back to the account).

  • severity: info
  • source: workflow

refund.failed

Attempt to process the refund failed (rare — usually part of an operational incident).

  • severity: error
  • source: workflow

Backoffice actions (backoffice.user_action)

CorpX operators occasionally act manually on a transaction (approval, adjustment, policy override). When that happens, the action is recorded on the timeline. These events always carry an actor (the operator's e-mail) and payload.action (a semantic string describing what was done).

  • severity: info or warn (depending on the action)
  • source: backoffice

Advanced mode (backoffice)

The CorpX dashboard internally exposes a ?level=full mode that returns, on top of the public events, the workflow's full Temporal History (internal decisions, activity retries, signals, timers). This mode is restricted to operators with the appropriate role and is not part of the public contract — do not program your client to depend on it.

If you need an additional level of transparency (e.g. SLA reporting, integration debugging), open a ticket — we can evaluate moving a relevant internal event into the public taxonomy.