The Accounts API is currently a draft. Shapes, field names, and field sets may change before it is finalized.
The Two-Identifier System
Slate uses two identifiers for every account, and understanding both are essential for a reliable integration.accountId is a UUID that Slate assigns when an account is first created. It is stable, canonical, and used in all Slate URLs and relationships (for example, GET /v1/accounts/{accountId}). You will not know this value before the account exists. Slate returns it in the create/upsert response.
crid is the account number from your own system. You supply this value, and it must be unique within your owner. Use it as your lookup key when you do not yet have a Slate accountId. For example, on your first upsert or when reconciling records.
The Upsert Pattern
POST /v1/accounts is idempotent. Send an account by crid and Slate will create it if it does not exist, or update it if it does. The response always includes the Slate-assigned accountId.
Identify the account’s creditor with either creditorId — the Slate UUID of a creditor you register beforehand via POST /v1/creditors (list them with GET /v1/creditors) — or creditorCode, one of your own partner codes registered to that creditor via POST /v1/creditors/{creditorId}/externalRefs. A placement identifies its firm the same way, with firmId or firmCode, against firms you register via POST /v1/firms.
Targeted Partial Updates
When you need to update a single field on a known account without re-sending the full record, usePATCH /v1/accounts/{accountId}:
Placement
Theplacement field carries three distinct states, and an omitted field is not the same as an explicit null. This holds on both POST /v1/accounts and PATCH /v1/accounts/{accountId}, so the same body means the same thing on either endpoint.
A placement is identified by its firm and placement date. Re-sending the same firm and date is a no-op, so a daily snapshot does not accumulate placements.
Legal Records
Thelegal field carries the account’s legal activity: the suit filed on it, the judgment entered on that suit, and the venue the suit sits in. It is null until a suit is filed, and a judgment always belongs to a suit — an account cannot carry a judgment without one.
Every field on a suit and a judgment is optional. A record is written under whichever of them your source system knows, so you can send a filedDate alone or a full docket. The Upsert Account reference lists the complete set.
Legal records merge; they never replace. This holds on both POST /v1/accounts and PATCH /v1/accounts/{accountId}. Only the fields you send are stored, and a field you leave out keeps the value it already has.
Merging rather than replacing matters because legal records are shared with Slate’s legal systems, which populate fields this API does not expose. An omitted field means “leave it as it is”, not “clear it”, so a partial update cannot blank out a docket Slate’s own systems filled in.
venue is read-only. Venues are maintained by Slate’s legal systems; anything you send there is ignored, and it reads null until a venue has been recorded for the suit.
Two writes are rejected with a 400:
- A judgment on an account with no suit. Send
legal.suiton the account first, or send the suit alongside the judgment in the same request. - A legal record on an account Slate holds no legal file for. Upsert the account via
POST /v1/accountsfirst, which opens one.
Creditor Roles
creditorId is the account’s creditor — the one that holds it now, and the one that scopes it inside Slate. Alongside it, an account can carry three more creditors that describe the debt’s history:
All three are optional, and each is named by Slate UUID or by one of your partner codes —
chargeOffCreditorId or chargeOffCreditorCode, and so on — exactly like creditorId. Every one must resolve to a creditor your owner manages. On paper that never changed hands, all four are the same creditor.
Because POST /v1/accounts is a full snapshot, a role you leave out is cleared: send every role you know on every sync. PATCH /v1/accounts/{accountId} only changes the roles it names.
filter[originatingCreditorId]=7e6d5c4b-3a29-1807-6f5e-4d3c2b1a0987. filter[creditorId] narrows on the creditor.
Account Lifecycle
Every account has astatus field with two possible values:
Update
status to CLOSED via upsert or PATCH when an account is paid, recalled, or otherwise resolved.
Money Format
All monetary amounts in Slate are expressed as US dollars with two decimal places, sent and returned as decimal strings — for example,
"1250.75". Slate does not use cents, integers, or bare JSON numbers. Strings avoid floating-point rounding. Sending "125075" when you mean $1,250.75 will result in an incorrect balance nearly 100 times too large."4872.50", not 4872.50, "487250", or "$4,872.50".
