API reference
Funding Sources
Generated HTTP reference for the 1 operation the published OpenAPI document describes under funding-sources.
3 min read
Funding Sources
This page is generated from the published OpenAPI document. It is complete with respect to that document and says nothing about surfaces the document does not describe yet. See what is generated here for what that means.
Base URL: https://api.codespar.dev
Every operation below requires a Bearer token. See Authentication.
GET /v1/funding-sources/{id}
Read one consumer funding source
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | yes | The funding source id. |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
404 | object | Not Found. No funding source with this id in the caller's project. A row belonging to a sibling project, and a row the 0129 backfill left unattributed, both answer here. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
balance_minor | null | yes | ALWAYS null on this operation, and present so a caller does not have to tell an absent field from an unknown balance. Live balance left the canonical surface with D4: the balance lives in the ledger. This read is new enough to have no legacy alias that could be relying on the old behaviour, so it never calls the provider. |
consumer_id | string | yes | The consumer, in the caller's own namespace. |
created_at | string (date-time) | yes | — |
currency | "BRL" | "USD" | "MXN" | "COP" | "ARS" | "USDC" | "BRLA" | yes | Closed by consumer_funding_sources_currency_check. That constraint NAME appears in exactly one file under packages/api/src/migrations/, so nothing later drops, relaxes or replaces it — the instrument is the name, not a list of the migrations that came after, because the list is what rots while the conclusion holds. |
display_label | string,null | yes | Caller-supplied label, or null. |
expires_at | string,null (date-time) | yes | — |
id | string | yes | cfs_- or fs_celcoin_-prefixed, depending on which writer created it. |
metadata | object | yes | The raw column, echoed with nothing stripped — plan for personal data in it. provisionCelcoinFundingSource writes account, branch, provider and, when the onboarding carried one, documentNumber, which is the consumer's CPF or CNPJ. Treat this object as regulated personal data at rest and in logs, and do not echo it to an end user. What is NOT in it is the debit credential: that lives in the vault, and the row holds only an opaque provider_token_ref pointer, which this response does not carry. |
pix_key | string,null | yes | Lifted out of metadata.pixKey when that key holds a string, else null. It is the DICT entry registered for the account, not a credential. |
pix_key_type | string,null | yes | Lifted out of metadata.pixKeyType, else null. |
project_id | string | yes | Always a string here, never null. Rows the 0129 backfill could not attribute carry project_id IS NULL, and the resolving predicate is a strict = against the credential's project, which no NULL satisfies — so an unattributed row answers 404 on this path rather than returning with a null. |
provider | string | yes | The provider behind the rail. Derived, not chosen: celcoin from the onboarding writer, and rail.split("-")[0] from the consent writer, so it inherits the same openness rail has. |
rail | string | yes | An OPEN string, and deliberately not an enum here. consumer_funding_sources constrains it only with CHECK (length(rail) \> 0), and the writers do not agree on a closed set: celcoin-onboarding.ts writes the literal pix-celcoin, routes/consents.ts writes one of its own five-value RAILS list on the single-rail path, and its multi-slot path writes methodToRail(slot.rail) — where the slot's rail is validated as z.string().min(1).max(40) and methodToRail returns its argument unchanged when no mapping matches. So a caller who opened a consent with an unmapped slot rail reads that same string back here. The values a reader should expect in practice: pix-celcoin, pix-consent, card-token, ted-debit-auth, usd-ach-debit, usdc-onchain. Match on those and tolerate anything else. |
revoked_at | string,null (date-time) | yes | Non-null exactly when status is revoked; the table enforces the pair. |
status | "active" | "revoked" | "expired" | yes | Closed by consumer_funding_sources_status_check, whose name likewise appears in exactly one migration file. Read usability from status being active. A companion constraint keeps revoked_at and status = 'revoked' in step, so they cannot disagree. |
Example response
{
"id": "obj_0000000000000000",
"project_id": "prj_0000000000000000",
"consumer_id": "csm_0000000000000000",
"rail": "string",
"currency": "BRL",
"provider": "string",
"status": "active",
"created_at": "2026-01-15T12:00:00.000Z",
"metadata": {}
}Example request
curl -X GET https://api.codespar.dev/v1/funding-sources/{id} \
-H "Authorization: Bearer $CODESPAR_API_KEY"