List
List invoices for the authenticated merchant.
Returns a paginated list of invoices scoped to the API key's environment. Supports exact-match filters for status, currency, static_address_id and external_id.
Usage notes#
Requires invoices:read. Use limit/cursor and meta.has_more/meta.next_cursor; supported filters are status, currency, static_address_id, external_id, and refund_status. Filters combine as exact matches. External IDs are case-sensitive, not prefix searches. The static address filter is a UUID. There is no network or time-range filter.
Listed invoices carry the same payment rows as the detail read, each with its id and its own settlement. There is no filter on settlement state; select on the invoice fields and read payment settlement per row.
Store resource IDs and use GET plus webhook events to reconcile changes to older invoices. Keep the same filters when following a cursor. See pagination.
For example, request /v1/invoices?external_id=order-1001 to find your order, or /v1/invoices?static_address_id=00000000-0000-0000-0000-000000000003 for an address's invoices. URL-encode filter values.
refund_summary is independent of invoice payment status. Filter with refund_status=none|processing|partial|full|attention. Partial and processing can overlap; full excludes in-flight or attention cases. Attention includes unknown coverage. See refund visibility.
/v1/invoicescurl --request GET 'https://api.thehalfin.com/v1/invoices' \
--header "X-API-Key: $HALFIN_API_KEY"Authorization
X-API-KeystringRequiredAPI key issued by the merchant dashboard. The key's environment (live/test) determines which data the caller can access. Permissions on the key control which endpoints are reachable.Example:
$HALFIN_API_KEY
Query Parameters
refund_status"none" | "processing" | "partial" | "full" | "attention"OptionalFilter refund coverage independently of payment status. Partial and processing can overlap; attention includes unknown coverage. Full excludes in-flight or attention cases.Example:
nonestatus"pending" | "confirming" | "paid" | "overpaid" | "underpaid" | "expired" | "invalid" | "rejected"OptionalFilter by invoice status.- Maximum length: 255
Example:
pendingcurrencystringOptionalFilter by currency code.- Maximum length: 20
Example:
stringstatic_address_idstringOptionalExact static address UUID whose received invoices are returned.- Format: uuid
Example:
00000000-0000-0000-0000-000000000001external_idstringOptionalExact merchant-supplied external reference ID.- Minimum length: 1
- Maximum length: 255
Example:
stringlimitintegerOptionalMaximum number of items to return (default 20, max 100).- Minimum: 1
- Maximum: 100
- Default: 20
Example:
20cursorstringOptionalOpaque cursor from meta.next_cursor. Omit for the first page. Bound to the collection, scope, filters, and ordering.- Maximum length: 8192
Example:
string
Response Body
200 Paginated invoice list.
application/json
dataarray<object>RequiredExample:
[{"nominal_amount":"25.00","nominal_currency":"USD","nominal_network":null,"id":"00000000-0000-0000-0000-000000000003","merchant_id":"00000000-0000-0000-0000-000000000002","currency":null,"network":null,"amount_requested":null,"amount_paid":"0","status":"pending","invalid_reason":null,"environment":"test","deposit_address":null,"deposit_address_tag":null,"description":"Order 1001","external_id":"order-1001","metadata":{"order_id":"1001"},"redirect_url":null,"source":"api","static_address_id":null,"checkout_url":"https://checkout.thehalfin.com/pay/example-token","payments":[],"expires_at":null,"draft_expires_at":"2026-09-15T10:00:00Z","paid_at":null,"created_at":"2026-09-14T10:00:00Z","payer_email":null,"sent_at":null}]refund_summaryobjectOptionalCurrent refund coverage over confirmed source principal, independent of invoice payment status. Present on merchant invoice GET and list responses. A later confirmed payment can change full coverage to partial; unknown means coverage cannot be established reliably. Fees and delivered recipient amounts are separate.- Unknown properties are rejected
Example:
{"coverage":"none","has_inflight":false,"needs_attention":false,"amounts":[{"currency":"string","network":"string","principal_amount":"1","refunded_amount":"1","recipient_amount":"1","inflight_amount":"1","remaining_amount":"1"}]}coverage"none" | "partial" | "full" | "unknown"RequiredExample:
nonehas_inflightbooleanRequiredExample:
falseneeds_attentionbooleanRequiredExample:
falseamountsarray<object>RequiredExample:
[{"currency":"string","network":"string","principal_amount":"1","refunded_amount":"1","recipient_amount":"1","inflight_amount":"1","remaining_amount":"1"}]currencystringRequiredExample:
stringnetworkstringRequiredExample:
stringprincipal_amountstringRequiredConfirmed incoming principal in this currency/network, not invoice fiat nominal.- Format: decimal
- Pattern: ^\d+(\.\d+)?$
Example:
1refunded_amountstringRequiredCompleted refund principal; excludes refund fees and reversed executions.- Format: decimal
- Pattern: ^\d+(\.\d+)?$
Example:
1recipient_amountstringRequiredAmount delivered by completed returns, after any customer-paid fees.- Format: decimal
- Pattern: ^\d+(\.\d+)?$
Example:
1inflight_amountstringRequiredPrincipal reserved or in execution, including an unresolved outcome.- Format: decimal
- Pattern: ^\d+(\.\d+)?$
Example:
1remaining_amountstringRequiredPrincipal less completed and inflight principal, floored at zero; not an eligibility promise.- Format: decimal
- Pattern: ^\d+(\.\d+)?$
Example:
1
nominal_amountstringRequiredImmutable amount originally nominated by the merchant; for a static deposit, the received amount.Example:
stringnominal_currencystringRequiredCurrency of nominal_amount, including fiat USD/EUR.Example:
stringnominal_networkstring | nullRequiredFixed crypto network, or null for a fiat nomination.Example:
nullidstringRequiredInvoice UUID.- Format: uuid
Example:
00000000-0000-0000-0000-000000000001merchant_idstring | nullRequiredOwning merchant UUID.- Format: uuid
Example:
nullcurrencystring | nullRequiredCryptocurrency code.Example:
nullnetworkstring | nullRequiredBlockchain network key for explorer and gate routing.Example:
nullamount_requestedstring | nullRequiredSelected option total in crypto, including payer fees. Null before selection.Example:
nullamount_paidstringRequiredDecimal string of the total amount paid.Example:
1pricing_rateobject | nullRequiredThe rate the selected payment option was priced at, from the invoice's applied pricing snapshot; null while the invoice is a draft with no gate selected. A fixed-crypto or static-address invoice carries it with spread_rate "0" and equal rates.- Unknown properties are rejected
Example:
nullsnapshot_idstringRequiredPricing snapshot of the OFFER the rate is reproduced from; a late-payment re-lock does not change it.- Format: uuid
Example:
00000000-0000-0000-0000-000000000001reference_usdstringRequiredMarket reference, USD per one unit of the asset, at the moment the offer locked.- Format: decimal
- Pattern: ^\d+(\.\d+)?$
Example:
1quoted_usdstringRequiredRate applied to the payer, `reference_usd × (1 − spread_rate)`, before service fees.- Format: decimal
- Pattern: ^\d+(\.\d+)?$
Example:
1spread_ratestringRequiredPlatform conversion margin priced into the quoted rate, as a decimal fraction (0.02 = 2%); "0" when the payment is not auto-converted or the merchant bears the spread in the conversion.- Format: decimal
- Pattern: ^\d+(\.\d+)?$
Example:
1sourcestring | nullRequiredMarket-data adapter the reference was read from; null for a constant price.Example:
nullfetched_atstringRequiredWhen the reference observation was taken.- Format: date-time
Example:
2026-01-01T00:00:00Zlocked_untilstring | nullRequiredEnd of the price promise for the payer; null when the snapshot is not time-bound.- Format: date-time
Example:
nullsettlement_reference_usdstring | nullRequiredReference the credit was stamped at when the first payment arrived after locked_until and the invoice moved onto a refreshed snapshot; null otherwise. The quoted rate and the amount never move with it.- Format: decimal
- Pattern: ^\d+(\.\d+)?$
Example:
null
status"pending" | "confirming" | "paid" | "overpaid" | "underpaid" | "expired" | "invalid" | "rejected"RequiredInvoice status. A payment that is still being processed leaves the status as it is: `pending` while nothing is credited, `confirming` while part is credited. `rejected` (final): money arrived and will not be credited; it carries no reason.Example:
pendinginvalid_reason"payment_dropped" | "payment_reorged" | nullRequiredWhy a terminal `invalid` invoice closed: `payment_dropped` for an announced payment that was replaced, dropped or expired, `payment_reorged` for one whose block was orphaned. `null` for every other status.Example:
nullenvironment"live" | "test"RequiredEnvironment this invoice belongs to.Example:
livedeposit_addressstring | nullRequiredBlockchain deposit address.Example:
nulldeposit_address_tagstring | nullRequiredMemo/tag for chains that require it (e.g. XRP, XLM).Example:
nulldescriptionstring | nullRequiredInvoice description.Example:
nullexternal_idstring | nullRequiredMerchant-supplied external reference ID.Example:
nullmetadataobjectRequiredMerchant key-value metadata; omitted invoice metadata is stored and returned as an empty object.- Maximum properties: 50
Example:
{"key":"string"}[key]stringOptional- Maximum length: 500
Example:
string
redirect_urlstring | nullRequiredCustomer redirect URL.Example:
nullsource"api" | "dashboard" | "static"RequiredHow the invoice was created.Example:
apistatic_address_idstring | nullRequiredStatic address UUID if created from a static address deposit.- Format: uuid
Example:
nullcheckout_urlstring | nullRequiredHosted checkout URL, published on create, get and list. Null for static deposits or when the stored checkout token cannot be recovered.Example:
nullpaymentsarray<object>RequiredOn-chain payments detected for this invoice.Example:
[{"id":"00000000-0000-0000-0000-000000000001","currency":"string","network":"string","tx_hash":"string","amount":"1","confirmations":0,"required_confirmations":0,"status":"string","detected_at":"2026-01-01T00:00:00Z","settlement":null}]idstringRequiredPayment UUID. Stable across reads; use it to correlate settlement facts.- Format: uuid
Example:
00000000-0000-0000-0000-000000000001currencystringRequiredCurrency of this payment.Example:
stringnetworkstringRequiredNetwork on which this payment was received.Example:
stringtx_hashstringRequiredBlockchain transaction hash.Example:
stringamountstringRequiredDecimal string of the source payment amount.Example:
1confirmationsintegerRequiredNumber of blockchain confirmations.Example:
0required_confirmationsintegerRequiredRequired blockchain confirmations for this payment.Example:
0statusstringRequiredPayment status (observed, confirming, confirmed, converting, dropped).Example:
stringdetected_atstringRequiredWhen the payment was first detected.- Format: date-time
Example:
2026-01-01T00:00:00Zsettlementobject | nullRequiredThe payment's ACTUAL settlement: its own immutable ledger facts and the state of its conversion decision, independent of the receipt `status` and of the current wallet balance. `conversion` (where present) is the quote/execution view of the same payment; this object is the per-payment ledger view. Null only when the read path did not compute settlement for this row.- Unknown properties are rejected
Example:
nullconversion_status"not_applicable" | "pending" | "settled" | "source_restored" | "needs_review" | "unknown"RequiredState of the unfinished conversion decision, if one exists, otherwise the current acceptance's decision. Multiple unfinished decisions are contradictory and report `unknown`. `not_applicable`: no conversion target, or the decision refused conversion. `pending`: a target is frozen and the conversion has not completed (no decision row yet, execution pending, or batch-enrolled but not committed). `settled`: the payment's own target credit is committed (solo settled or batch member committed). `source_restored`: the conversion returned the source asset. `needs_review`: the conversion is quarantined for an operator. `unknown`: the stored facts are incomplete or contradictory for a credited payment; no amount is invented. Receipt `paid`/`confirming` is never mapped into this field. Consumers may receive new values in the future.Example:
not_applicablesourceobjectRequiredThe gate the payment arrived on. Always present.- Unknown properties are rejected
Example:
{"currency":"string","network":"string"}currencystringRequiredAsset code.Example:
stringnetworkstringRequiredBlockchain network key.Example:
string
targetobject | nullRequiredThe conversion target frozen for this payment: from its conversion decision when one exists, else the invoice's frozen auto-conversion target, else null. A refused (`not_applicable`) decision nulls the target even when the invoice froze one. Never the merchant's current setting.- Unknown properties are rejected
Example:
nullcurrencystringRequiredAsset code.Example:
stringnetworkstringRequiredBlockchain network key.Example:
string
accepted_source_amountstringRequiredThis payment's latest acceptance credit in the source asset. It remains after an acceptance reversal (the reversal appears in `reversed_credits`); zero only when no acceptance was ever booked.- Format: decimal
- Pattern: ^\d+(\.\d+)?$
Example:
1source_available_contributionstringRequiredSigned net of every entry this payment booked on the merchant's available balance in the source asset: acceptance, mirrors, conversion debits, restored source and fee true-ups. Not the wallet balance — a later payout may have spent the shared balance — and it may be negative after a reversal.- Format: decimal
- Pattern: ^-?\d+(\.\d+)?$
Example:
1credited_target_amountstringRequiredCumulative committed credit across this payment's conversion cycles in the selected target asset after gain/loss (dust already included). Published only when the selected decision is `settled`, otherwise zero. Zero in another state does not mean no earlier conversion credited money; consult the ledger history. A settled zero is an explicit zero-share batch allocation with no earlier credit in that target.- Format: decimal
- Pattern: ^\d+(\.\d+)?$
Example:
1pending_conversion_source_amountstring | nullRequiredThe unfinished gross source obligation of a `pending` conversion decision (its frozen source debit). Null in every other state and when no decision row exists yet. It is not a promise of physically unused or returnable source.- Format: decimal
- Pattern: ^\d+(\.\d+)?$
Example:
nullreserved_amountsarray<object>RequiredThis payment's own remaining positive reserved holds, per native gate, in canonical gate order. Empty when nothing is held.- Maximum items: 64
Example:
[{"currency":"string","network":"string","amount":"1"}]currencystringRequiredAsset code.Example:
stringnetworkstringRequiredBlockchain network key.Example:
stringamountstringRequiredPositive native amount as a decimal string.- Format: decimal
- Pattern: ^\d+(\.\d+)?$
Example:
1
reversed_creditsarray<object>RequiredCredits of this payment that were mirrored back (acceptance reversal, conversion credit reversal), per native gate, in canonical gate order. Each available credit is counted once.- Maximum items: 64
Example:
[{"currency":"string","network":"string","amount":"1"}]currencystringRequiredAsset code.Example:
stringnetworkstringRequiredBlockchain network key.Example:
stringamountstringRequiredPositive native amount as a decimal string.- Format: decimal
- Pattern: ^\d+(\.\d+)?$
Example:
1
conversion_execution"internal_fill" | "solo_external" | "batch" | nullOptionalHow the selected conversion decision was ACTUALLY carried out, as stamped when that decision was taken. `internal_fill`: filled from the platform's own position, with no venue and no chain leg. `solo_external`: this payment's own trade at an external venue. `batch`: enrolled into a group trade. Null while no decision row exists yet, and on payments that were never converted.Example:
nullconversion_route_idstring | nullOptionalThe route the conversion was admitted on, as recorded on its attempt. Null when no attempt exists — a decision that refused conversion, or a batch member before its group is sealed.- Maximum length: 200
Example:
nullconversion_providerstring | nullOptionalThe executor that carried the conversion: `inventory` for a fill from the platform's own position, otherwise the venue adapter (`kraken-delivery`, `nearintents`, …). Null under the same conditions as `conversion_route_id`. Open vocabulary: the provider roster grows without a contract change.- Maximum length: 100
Example:
null
expires_atstring | nullRequiredFixed deadline from first checkout activation, null before activation.- Format: date-time
Example:
nulldraft_expires_atstring | nullRequiredDraft deadline, null after activation.- Format: date-time
Example:
nullpaid_atstring | nullRequiredTimestamp when the invoice was fully paid.- Format: date-time
Example:
nullcreated_atstringRequiredCreation timestamp.- Format: date-time
Example:
2026-01-01T00:00:00Zpayer_emailstring | nullRequiredEmail address the invoice was sent to.Example:
nullsent_atstring | nullRequiredTimestamp when the invoice email was sent.- Format: date-time
Example:
null
metaobjectRequired- Unknown properties are rejected
Example:
{"request_id":"00000000-0000-0000-0000-000000000001","has_more":false,"next_cursor":null}request_idstringRequiredCorrelation identifier issued by the API, also returned in the X-Request-ID response header. An inbound value is adopted only from explicitly trusted ingress; public client values are replaced.Example:
stringhas_morebooleanRequiredTrue exactly when next_cursor is not null.Example:
falsenext_cursorstring | nullRequiredOpaque cursor for the next page. Null when this is the last page.Example:
null
{
"data": [
{
"nominal_amount": "25.00",
"nominal_currency": "USD",
"nominal_network": null,
"id": "00000000-0000-0000-0000-000000000003",
"merchant_id": "00000000-0000-0000-0000-000000000002",
"currency": null,
"network": null,
"amount_requested": null,
"amount_paid": "0",
"status": "pending",
"invalid_reason": null,
"environment": "test",
"deposit_address": null,
"deposit_address_tag": null,
"description": "Order 1001",
"external_id": "order-1001",
"metadata": {
"order_id": "1001"
},
"redirect_url": null,
"source": "api",
"static_address_id": null,
"checkout_url": "https://checkout.thehalfin.com/pay/example-token",
"payments": [],
"expires_at": null,
"draft_expires_at": "2026-09-15T10:00:00Z",
"paid_at": null,
"created_at": "2026-09-14T10:00:00Z",
"payer_email": null,
"sent_at": null
}
],
"meta": {
"request_id": "00000000-0000-0000-0000-000000000001",
"has_more": false,
"next_cursor": null
}
}400 `validation_error`: The request format, parameters, headers, or field values are invalid.
application/json
errorobjectRequiredThe error code and diagnostic message.- Unknown properties are rejected
Example:
{"code":"validation_error","message":"string","details":["string"]}code"validation_error"Required`validation_error`: The request format, parameters, headers, or field values are invalid.Example:
validation_errormessagestringRequiredHuman-readable description of the error.Example:
stringdetailsarray<string>OptionalOptional structured context (validation errors, etc.).Example:
["string"]
metaobjectRequired- Unknown properties are rejected
Example:
{"request_id":"00000000-0000-0000-0000-000000000001"}request_idstringRequiredCorrelation identifier issued by the API, also returned in the X-Request-ID response header. Client-supplied X-Request-ID values are replaced.Example:
string
{
"error": {
"code": "validation_error",
"message": "Request validation failed"
},
"meta": {
"request_id": "00000000-0000-0000-0000-000000000001"
}
}401 `unauthorized`: A valid API key is required.
application/json
errorobjectRequiredThe error code and diagnostic message.- Unknown properties are rejected
Example:
{"code":"unauthorized","message":"string","details":["string"]}code"unauthorized"Required`unauthorized`: A valid API key is required.Example:
unauthorizedmessagestringRequiredHuman-readable description of the error.Example:
stringdetailsarray<string>OptionalOptional structured context (validation errors, etc.).Example:
["string"]
metaobjectRequired- Unknown properties are rejected
Example:
{"request_id":"00000000-0000-0000-0000-000000000001"}request_idstringRequiredCorrelation identifier issued by the API, also returned in the X-Request-ID response header. Client-supplied X-Request-ID values are replaced.Example:
string
{
"error": {
"code": "unauthorized",
"message": "Invalid API key"
},
"meta": {
"request_id": "00000000-0000-0000-0000-000000000001"
}
}403 `forbidden`: The API key does not have permission for this operation. `api_key_ip_forbidden`: The request source address is not allowed by the API key.
application/json
errorobjectRequiredThe error code and diagnostic message.- Unknown properties are rejected
Example:
{"code":"forbidden","message":"string","details":["string"]}code"forbidden" | "api_key_ip_forbidden"Required`forbidden`: The API key does not have permission for this operation. `api_key_ip_forbidden`: The request source address is not allowed by the API key.Example:
forbiddenmessagestringRequiredHuman-readable description of the error.Example:
stringdetailsarray<string>OptionalOptional structured context (validation errors, etc.).Example:
["string"]
metaobjectRequired- Unknown properties are rejected
Example:
{"request_id":"00000000-0000-0000-0000-000000000001"}request_idstringRequiredCorrelation identifier issued by the API, also returned in the X-Request-ID response header. Client-supplied X-Request-ID values are replaced.Example:
string
{
"error": {
"code": "forbidden",
"message": "Permission denied"
},
"meta": {
"request_id": "00000000-0000-0000-0000-000000000001"
}
}500 `internal_error`: The API could not complete the request. Contact support with the request ID if the error persists.
application/json
errorobjectRequiredThe error code and diagnostic message.- Unknown properties are rejected
Example:
{"code":"internal_error","message":"string","details":["string"]}code"internal_error"Required`internal_error`: The API could not complete the request. Contact support with the request ID if the error persists.Example:
internal_errormessagestringRequiredHuman-readable description of the error.Example:
stringdetailsarray<string>OptionalOptional structured context (validation errors, etc.).Example:
["string"]
metaobjectRequired- Unknown properties are rejected
Example:
{"request_id":"00000000-0000-0000-0000-000000000001"}request_idstringRequiredCorrelation identifier issued by the API, also returned in the X-Request-ID response header. Client-supplied X-Request-ID values are replaced.Example:
string
{
"error": {
"code": "internal_error",
"message": "Internal server error"
},
"meta": {
"request_id": "00000000-0000-0000-0000-000000000001"
}
}503 `service_unavailable`: The service is temporarily unavailable. Retry later.
application/json
errorobjectRequiredThe error code and diagnostic message.- Unknown properties are rejected
Example:
{"code":"service_unavailable","message":"string","details":["string"]}code"service_unavailable"Required`service_unavailable`: The service is temporarily unavailable. Retry later.Example:
service_unavailablemessagestringRequiredHuman-readable description of the error.Example:
stringdetailsarray<string>OptionalOptional structured context (validation errors, etc.).Example:
["string"]
metaobjectRequired- Unknown properties are rejected
Example:
{"request_id":"00000000-0000-0000-0000-000000000001"}request_idstringRequiredCorrelation identifier issued by the API, also returned in the X-Request-ID response header. Client-supplied X-Request-ID values are replaced.Example:
string
{
"error": {
"code": "service_unavailable",
"message": "Service temporarily unavailable"
},
"meta": {
"request_id": "00000000-0000-0000-0000-000000000001"
}
}