Skip to main content
API reference

Sellers

Generated HTTP reference for the 6 operations the published OpenAPI document describes under sellers.

10 min read
View MarkdownEdit on GitHub

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

FieldTypeRequiredDescription
addressobjectyes
allowed_capture_methodsarray of stringno
allowed_payment_methodsarray of stringno
company_logo_urlstringno
contactobjectyes
declared_incomenumberno
declared_revenuenumberno
document_numberstringyes
document_tax_type"PJ" | "MEI" | "ME" | "PF"yes
document_type"CNPJ" | "CPF"yes
fee_policy_idstringno
full_namestringyes
linked_consumer_idstringno
mccstringyes
metadataobjectno
namestringno
net_worthnumberno
transfer_configurationsobjectyes
website_urlstringno

Responses

StatusBodyDescription
201objectOK
400objectBad Request — the body or query did not match the schema.
502objectBad 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

FieldTypeRequiredDescription
affiliation_statusstringyesRinne'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_atstring (date-time)yes
document_numberstringyesDigits only. Everything non-numeric is stripped before the row is written.
full_namestringyes
linked_consumer_idstring,nullyes
rinne_affiliation_idstring,nullyes
rinne_merchant_idstring,nullyes
seller_idstringyesslr_ + nanoid. Stable across a re-POST of the same document.
statusstringyesCodeSpar'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_atstring (date-time)yes
wallet_idstring,nullyesThe 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

NameTypeRequiredDescription
sellerIdstringyes

Responses

StatusBodyDescription
200objectOK
404objectNot 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

FieldTypeRequiredDescription
affiliation_statusstringyesRinne'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_atstring (date-time)yes
document_numberstringyesDigits only. Everything non-numeric is stripped before the row is written.
full_namestringyes
linked_consumer_idstring,nullyes
rinne_affiliation_idstring,nullyes
rinne_merchant_idstring,nullyes
seller_idstringyesslr_ + nanoid. Stable across a re-POST of the same document.
statusstringyesCodeSpar'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_atstring (date-time)yes
wallet_idstring,nullyesThe 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

NameTypeRequiredDescription
sellerIdstringyes

Responses

StatusBodyDescription
200objectOK
404objectNot Found. No seller with that id under the caller's org and project.
409objectConflict. The seller has no rinne_merchant_id yet, so there is no custody to compare against.
502objectBad 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

FieldTypeRequiredDescription
difference_minorstringyesrinne_minor minus ledger_minor. Signed and never clamped: the negative direction is the dangerous one and has to survive to the reader.
ledger_minorstringyesWhat the wallet ledger says is available, BRL minor units (centavos).
notestringyesOne sentence for the same three states, ready to render.
rinne_merchant_idstringyes
rinne_minorstringyesWhat Rinne reports as this merchant's balance, BRL minor units.
seller_idstringyes
state"reconciled" | "unattributed_credit" | "ledger_exceeds_custody"yesreconciled 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

NameTypeRequiredDescription
sellerIdstringyes

Query parameters

NameTypeRequiredDescription
before_idstringno
kind"fund" | "hold" | "release" | "debit" | "reconcile" | "reverse" | "fee"no
limitintegerno

Responses

StatusBodyDescription
200objectOK
400objectBad Request — the body or query did not match the schema.
404objectNot 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

FieldTypeRequiredDescription
entriesarray of objectyes
next_beforestring,nullyes

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

NameTypeRequiredDescription
sellerIdstringyes

Responses

StatusBodyDescription
200objectOK
404objectNot Found. No seller with that id under the caller's org and project.
409objectConflict. The seller has no rinne_merchant_id yet, so it was never provisioned at Rinne and has no statement to read.
502objectBad 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

FieldTypeRequiredDescription
entriesarray of objectyes
parsed_entriesintegeryesHow many of those carried a settled field this code could read as a boolean.
raw_entriesintegeryesHow many movements the statement returned, before any filtering.
rinne_merchant_idstringyes
seller_idstringyes
total_pending_minorstringyesSum 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_entriesintegeryesraw_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

NameTypeRequiredDescription
sellerIdstringyes

Responses

StatusBodyDescription
200objectOK
404objectNot 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.
502objectBad 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

FieldTypeRequiredDescription
affiliation_statusstringyesRinne'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_atstring (date-time)yes
document_numberstringyesDigits only. Everything non-numeric is stripped before the row is written.
full_namestringyes
linked_consumer_idstring,nullyes
refresh_errorstring,nullyesWhy the Rinne read did not land. Null on success and on a seller with nothing at Rinne yet.
refreshed_atstring,null (date-time)yesWhen 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_idstring,nullyes
rinne_merchant_idstring,nullyes
seller_idstringyesslr_ + nanoid. Stable across a re-POST of the same document.
stalebooleanyesDerived 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.
statusstringyesCodeSpar'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_atstring (date-time)yes
wallet_idstring,nullyesThe 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"
Sellers | CodeSpar