Sellers
Generated HTTP reference for the 6 operations the published OpenAPI document describes under sellers.
Sellers
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.
POST /v1/sellers
Onboard a seller (KYB) and affiliate it at Rinne
Request body
| Field | Type | Required | Description |
|---|---|---|---|
address | object | yes | — |
allowed_capture_methods | array of string | no | — |
allowed_payment_methods | array of string | no | — |
company_logo_url | string | no | — |
contact | object | yes | — |
declared_income | number | no | — |
declared_revenue | number | no | — |
document_number | string | yes | — |
document_tax_type | "PJ" | "MEI" | "ME" | "PF" | yes | — |
document_type | "CNPJ" | "CPF" | yes | — |
fee_policy_id | string | no | — |
full_name | string | yes | — |
linked_consumer_id | string | no | — |
mcc | string | yes | — |
metadata | object | no | — |
name | string | no | — |
net_worth | number | no | — |
transfer_configurations | object | yes | — |
website_url | string | no | — |
Responses
| Status | Body | Description |
|---|---|---|
201 | object | OK |
400 | object | Bad Request — the body or query did not match the schema. |
502 | object | Bad Gateway. Provisioning did not complete. error carries the failing step's code when the throw had one (for example rinne_create_merchant_failed, rinne_merchant_ambiguous, rinne_credentials_unavailable, seller_document_required) and seller_provisioning_failed otherwise. The code set is not closed: the Rinne codes are built from the call's action name. Nothing was written locally when this is returned. |
Response 201
| Field | Type | Required | Description |
|---|---|---|---|
affiliation_status | string | yes | Rinne's own status string, stored verbatim (for example PENDING_APPROVAL, ACTIVE, REJECTED). This is the column with NO CHECK constraint, and that is deliberate: a status Rinne introduces later is stored as it came instead of turning into a hard write failure. Treat it as an open set. |
created_at | string (date-time) | yes | — |
document_number | string | yes | Digits only. Everything non-numeric is stripped before the row is written. |
full_name | string | yes | — |
linked_consumer_id | string,null | yes | — |
rinne_affiliation_id | string,null | yes | — |
rinne_merchant_id | string,null | yes | — |
seller_id | string | yes | slr_ + nanoid. Stable across a re-POST of the same document. |
status | string | yes | CodeSpar's normalized lifecycle, derived from affiliation_status by deriveSellerStatus. A CHECK constraint on the column admits exactly five values — pending, affiliation_pending, active, rejected, failed — and a write outside that set fails rather than being stored. Three of the five are what this API produces: ACTIVE maps to active, REJECTED to rejected, and every other Rinne string, recognized or not, to affiliation_pending rather than to a failure state. pending is the column default and no onboarding write leaves it in place; nothing writes failed. |
updated_at | string (date-time) | yes | — |
wallet_id | string,null | yes | The BRL wallet this seller's settlements credit. Null until the first settlement lands, because the wallet is provisioned lazily on that credit. |
Example response
{
"seller_id": "slr_0000000000000000",
"status": "string",
"affiliation_status": "string",
"document_number": "string",
"full_name": "Example",
"created_at": "2026-01-15T12:00:00.000Z",
"updated_at": "2026-01-15T12:00:00.000Z"
}Example request
curl -X POST https://api.codespar.dev/v1/sellers \
-H "Authorization: Bearer $CODESPAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"full_name": "Example",
"name": "Example",
"document_number": "string",
"document_type": "CNPJ",
"document_tax_type": "PJ",
"mcc": "string",
"contact": {},
"address": {},
"transfer_configurations": {
"automatic_transfer_enabled": true,
"transfer_frequency": "DAILY",
"rail": "PIX",
"utc_hour_of_day": 0,
"day_of_week": 0,
"day_of_month": 0,
"min_balance": 1000
},
"declared_revenue": 0,
"declared_income": 0,
"net_worth": 0,
"company_logo_url": "https://example.com/hook",
"website_url": "https://example.com/hook",
"fee_policy_id": "feepolicy_0000000000000000",
"metadata": {},
"linked_consumer_id": "linkedconsumer_0000000000000000",
"allowed_capture_methods": [
"string"
],
"allowed_payment_methods": [
"string"
]
}'GET /v1/sellers/{sellerId}
Read one seller
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
sellerId | string | yes | — |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
404 | object | Not Found. No seller with that id under the caller's org and project. A seller that exists in another tenant answers identically, so a 404 here is not evidence that the id was never minted. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
affiliation_status | string | yes | Rinne's own status string, stored verbatim (for example PENDING_APPROVAL, ACTIVE, REJECTED). This is the column with NO CHECK constraint, and that is deliberate: a status Rinne introduces later is stored as it came instead of turning into a hard write failure. Treat it as an open set. |
created_at | string (date-time) | yes | — |
document_number | string | yes | Digits only. Everything non-numeric is stripped before the row is written. |
full_name | string | yes | — |
linked_consumer_id | string,null | yes | — |
rinne_affiliation_id | string,null | yes | — |
rinne_merchant_id | string,null | yes | — |
seller_id | string | yes | slr_ + nanoid. Stable across a re-POST of the same document. |
status | string | yes | CodeSpar's normalized lifecycle, derived from affiliation_status by deriveSellerStatus. A CHECK constraint on the column admits exactly five values — pending, affiliation_pending, active, rejected, failed — and a write outside that set fails rather than being stored. Three of the five are what this API produces: ACTIVE maps to active, REJECTED to rejected, and every other Rinne string, recognized or not, to affiliation_pending rather than to a failure state. pending is the column default and no onboarding write leaves it in place; nothing writes failed. |
updated_at | string (date-time) | yes | — |
wallet_id | string,null | yes | The BRL wallet this seller's settlements credit. Null until the first settlement lands, because the wallet is provisioned lazily on that credit. |
Example response
{
"seller_id": "slr_0000000000000000",
"status": "string",
"affiliation_status": "string",
"document_number": "string",
"full_name": "Example",
"created_at": "2026-01-15T12:00:00.000Z",
"updated_at": "2026-01-15T12:00:00.000Z"
}Example request
curl -X GET https://api.codespar.dev/v1/sellers/{sellerId} \
-H "Authorization: Bearer $CODESPAR_API_KEY"GET /v1/sellers/{sellerId}/custody
Compare this seller's ledger against Rinne's custody
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
sellerId | string | yes | — |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
404 | object | Not Found. No seller with that id under the caller's org and project. |
409 | object | Conflict. The seller has no rinne_merchant_id yet, so there is no custody to compare against. |
502 | object | Bad Gateway. The balance read failed or could not be understood: rinne_get_balance_failed when Rinne answered non-ok, rinne_get_balance_unparseable when the response carried no balance field this code recognizes, seller_custody_failed as the fallback. The code set is not closed. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
difference_minor | string | yes | rinne_minor minus ledger_minor. Signed and never clamped: the negative direction is the dangerous one and has to survive to the reader. |
ledger_minor | string | yes | What the wallet ledger says is available, BRL minor units (centavos). |
note | string | yes | One sentence for the same three states, ready to render. |
rinne_merchant_id | string | yes | — |
rinne_minor | string | yes | What Rinne reports as this merchant's balance, BRL minor units. |
seller_id | string | yes | — |
state | "reconciled" | "unattributed_credit" | "ledger_exceeds_custody" | yes | reconciled when the difference is zero. unattributed_credit when Rinne holds more than the ledger attributed, which is the ordinary state while a settlement webhook is in flight. ledger_exceeds_custody when the ledger shows more than Rinne holds, which is the state a payout can fail on. |
Example response
{
"seller_id": "slr_0000000000000000",
"rinne_merchant_id": "rinnemerchant_0000000000000000",
"ledger_minor": "1000",
"rinne_minor": "1000",
"difference_minor": "1000",
"state": "reconciled",
"note": "string"
}Example request
curl -X GET https://api.codespar.dev/v1/sellers/{sellerId}/custody \
-H "Authorization: Bearer $CODESPAR_API_KEY"GET /v1/sellers/{sellerId}/ledger
This seller's wallet ledger, without learning the wallet id
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
sellerId | string | yes | — |
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
before_id | string | no | — |
kind | "fund" | "hold" | "release" | "debit" | "reconcile" | "reverse" | "fee" | no | — |
limit | integer | no | — |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
400 | object | Bad Request — the body or query did not match the schema. |
404 | object | Not Found. No seller with that id under the caller's org and project. A seller that exists in another tenant answers identically, so a 404 here is not evidence that the id was never minted. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
entries | array of object | yes | — |
next_before | string,null | yes | — |
Example response
{
"entries": [
{
"id": "obj_0000000000000000",
"wallet_id": "wlt_0000000000000000",
"org_id": "org_0000000000000000",
"currency": "BRL",
"amount_minor": "1000",
"kind": "fund",
"posted_at": "2026-01-15T12:00:00.000Z",
"metadata": {}
}
]
}Example request
curl -X GET https://api.codespar.dev/v1/sellers/{sellerId}/ledger \
-H "Authorization: Bearer $CODESPAR_API_KEY"GET /v1/sellers/{sellerId}/pending-settlement
What Rinne reports as sold but not yet settled
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
sellerId | string | yes | — |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
404 | object | Not Found. No seller with that id under the caller's org and project. |
409 | object | Conflict. The seller has no rinne_merchant_id yet, so it was never provisioned at Rinne and has no statement to read. |
502 | object | Bad Gateway. The statement read failed. error carries the failing step's code when the throw had one (for example rinne_get_statement_failed, rinne_credentials_unavailable) and seller_pending_settlement_failed otherwise. The code set is not closed. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
entries | array of object | yes | — |
parsed_entries | integer | yes | How many of those carried a settled field this code could read as a boolean. |
raw_entries | integer | yes | How many movements the statement returned, before any filtering. |
rinne_merchant_id | string | yes | — |
seller_id | string | yes | — |
total_pending_minor | string | yes | Sum of amount_minor over the entries below. Informational only: it is not a balance, it is not spendable, and nothing here is ever posted to the wallet ledger. |
unparsed_entries | integer | yes | raw_entries minus parsed_entries. Greater than zero means total_pending_minor understates what Rinne reported, so a total of 0 is not evidence that nothing is pending. |
Example response
{
"seller_id": "slr_0000000000000000",
"rinne_merchant_id": "rinnemerchant_0000000000000000",
"total_pending_minor": "1000",
"entries": [
{
"id": "obj_0000000000000000",
"currency": "BRL",
"raw": {}
}
],
"raw_entries": 0,
"parsed_entries": 0,
"unparsed_entries": 0
}Example request
curl -X GET https://api.codespar.dev/v1/sellers/{sellerId}/pending-settlement \
-H "Authorization: Bearer $CODESPAR_API_KEY"GET /v1/sellers/{sellerId}/status
Refresh a seller's affiliation status from Rinne
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
sellerId | string | yes | — |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
404 | object | Not Found. No seller with that id under the caller's org and project. A seller that exists in another tenant answers identically, so a 404 here is not evidence that the id was never minted. |
502 | object | Bad Gateway. The status refresh threw before a row could be rendered. error is always seller_status_failed; the underlying reason is in message. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
affiliation_status | string | yes | Rinne's own status string, stored verbatim (for example PENDING_APPROVAL, ACTIVE, REJECTED). This is the column with NO CHECK constraint, and that is deliberate: a status Rinne introduces later is stored as it came instead of turning into a hard write failure. Treat it as an open set. |
created_at | string (date-time) | yes | — |
document_number | string | yes | Digits only. Everything non-numeric is stripped before the row is written. |
full_name | string | yes | — |
linked_consumer_id | string,null | yes | — |
refresh_error | string,null | yes | Why the Rinne read did not land. Null on success and on a seller with nothing at Rinne yet. |
refreshed_at | string,null (date-time) | yes | When the Rinne read that produced this row landed. Null when no read landed, which covers both a failed read and a seller with nothing at Rinne yet. |
rinne_affiliation_id | string,null | yes | — |
rinne_merchant_id | string,null | yes | — |
seller_id | string | yes | slr_ + nanoid. Stable across a re-POST of the same document. |
stale | boolean | yes | Derived as refresh_error !== null, so it can never disagree with the field beside it. True means the body is the last known row, not what Rinne says right now. |
status | string | yes | CodeSpar's normalized lifecycle, derived from affiliation_status by deriveSellerStatus. A CHECK constraint on the column admits exactly five values — pending, affiliation_pending, active, rejected, failed — and a write outside that set fails rather than being stored. Three of the five are what this API produces: ACTIVE maps to active, REJECTED to rejected, and every other Rinne string, recognized or not, to affiliation_pending rather than to a failure state. pending is the column default and no onboarding write leaves it in place; nothing writes failed. |
updated_at | string (date-time) | yes | — |
wallet_id | string,null | yes | The BRL wallet this seller's settlements credit. Null until the first settlement lands, because the wallet is provisioned lazily on that credit. |
Example response
{
"seller_id": "slr_0000000000000000",
"status": "string",
"affiliation_status": "string",
"document_number": "string",
"full_name": "Example",
"created_at": "2026-01-15T12:00:00.000Z",
"updated_at": "2026-01-15T12:00:00.000Z",
"stale": true
}Example request
curl -X GET https://api.codespar.dev/v1/sellers/{sellerId}/status \
-H "Authorization: Bearer $CODESPAR_API_KEY"