Get the invoice activity timeline
const url = 'http://localhost:8080/v1/invoices/example/payment-timeline';const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url http://localhost:8080/v1/invoices/example/payment-timeline \ --header 'Authorization: Bearer <token>'Returns everything that happened to an invoice, oldest first:
lifecycle steps (created, finalized, paid, voided, marked
uncollectible), charge attempts (source payment, event_type
charge_attempt.succeeded|failed|unknown|below_minimum), dunning retries, credit
notes, customer emails, and card disputes (source dispute, a
payment.dispute_opened row and, once Stripe closes the dispute, a
payment.dispute_closed row; both at Stripe’s own time).
A draft invoice returns an empty list.
Each row carries line, the row in the activity line standard’s
words (ADR-128). description, detail, error, status and
amount_cents repeat it for clients that read the older fields.
If one source cannot be read, the rest is still returned and the
source is named in degraded.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Responses
Section titled “Responses”Timeline events.
object
object
Stable key for the row.
The line’s tone in older words, read by the dashboard’s dot.
The line’s title.
The line’s meta line as text, its actor last, for example “Visa •••• 4242 · After 2 retries”.
The line’s problem.
True when timestamp is test-clock time.
Real-world time of a row whose timestamp is test-clock time.
One activity row in the words of the activity line standard
(ADR-128): a title with no values, the amount when the event moves
money, asks for it or cancels money owed, a problem line on failure
and warning rows, the meta line’s parts and the actor, a tone, and
the event’s time on the entity’s calendar. recorded_at is the
real-world time, set only for an entity on a test clock.
object
The row’s stable key: the event’s id on an invoice timeline
row, the audit entry’s id on a subscription timeline row,
dunning: and the event’s id on a dunning run event (the same
key the invoice timeline gives that event), and email: and
the email’s id on a sent email (likewise).
Machine name of the event.
object
The meta line before the actor. Each item is one segment, shown joined by “ · “; a segment’s parts read as one phrase, for example a money part followed by the text “ refunded to card”.
Who did it. person and api_key carry the name (a person’s email
when they have no name), customer says where through via, and
automatic is anything Hardcount did on its own. Absent when no fact
written with the row names one.
object
Neutral: something happened. success: money arrived, or was returned as intended. warning: needs a look, or money will not be collected. failure: an attempt failed.
Sources that could not be read, so their rows are missing.
True when the credit-note source hit its limit of 100 rows.
Example
{ "events": [ { "source": "lifecycle", "event_type": "invoice.finalized", "status": "neutral", "line": { "kind": "invoice.voided", "title": "Payment failed", "amount": { "currency": "USD" }, "problem": "Card declined: insufficient funds", "detail": [ [ { "money": { "currency": "USD" }, "link": { "kind": "invoice" } } ] ], "actor": { "kind": "person", "via": "payment_page" }, "tone": "neutral" } } ], "degraded": [ "audit" ]}Invoice not found.
object
object
One of invalid_request_error, authentication_error,
rate_limit_error or api_error. Every error the API
answers has this shape, including an unknown path (404,
code route_not_found) and a method the path does not take
(405, code method_not_allowed, with an Allow header).
The few exceptions are listed in docs/api-surface.md.
The request field the error is about. Sent only when the error
names one. A request body may hold only the fields its
operation lists, spelled and cased as listed: any other
field, or one the server sets (such as id), is refused
with 422 and param naming it. An operation with no request body lists no fields: send
no body, {} or null. The Stripe and Postmark webhooks and
the LiteLLM callback take their sender’s body as it comes.
Example
{ "error": { "type": "invalid_request_error" }}