Two ways to send it
Both roads lead to the same intake and the same dossier. The work door (POST /v1/requests) is the general one and is what agents use; the intake door (POST /v1/intakes) is the simplest possible call for a system that only ever creates cases — any body, any encoding.
A. The work door: open_matter
JSON with pasted text and signed links, or multipart with the files inline. Options ride in options.
curl -X POST https://api.codossier.com/v1/requests \
-H "Authorization: Bearer cdk_live_<id>_<secret>" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: matter-2026-0412" \
-d '{
"intent": "open_matter",
"text": "Client: Dana Reyes. Dismissed 2026-03-04, three weeks after reporting...",
"documents": [
{ "url": "https://files.yourfirm.com/signed/termination-letter.pdf", "filename": "termination-letter.pdf" },
{ "text": "Timeline as told by the client...", "title": "Timeline" }
],
"options": { "name": "Reyes v. Northwind", "external_id": "M-2026-0412", "language": "auto" }
}'curl -X POST https://api.codossier.com/v1/requests \
-H "Authorization: Bearer cdk_live_<id>_<secret>" \
-F 'request={"intent":"open_matter","options":{"external_id":"M-2026-0412"}};type=application/json' \
-F "[email protected]" \
-F "[email protected]"| Field | Where | Required | Meaning |
|---|---|---|---|
intent | body | yes | "open_matter". Omit it and the request is read from its shape (material → open_matter). |
text | body | no | The material in words: a narrative, notes, an email thread pasted in. |
documents[] | body | no | Each entry is one of: part (the name of a multipart part), url (https, a public host; add sha256 to have it checked), text + title (pasted content), or dms (a linked document system — none linked yet). |
options.name | body | no | The matter's name (≤200). Derived from the material when absent. |
options.external_id | body | no | Your own reference (≤128). Lets you find the matter later and stops duplicates. |
options.language | body | no | "en", "es" or "auto" (default). |
options.simulate | body | no | Sandbox keys only: "ready", "needs_input", "not_covered", "failed", "quota", "quote". |
estimate | body | no | true: price and plan the request; run nothing. |
Prefer | header | no | "wait=N" (≤60): hold the call up to N seconds for a result before answering 202. |
Idempotency-Key | header | no | Any string ≤128. A retry with the same key returns the same request. |
No material at all? Send open_matter with just a name and the request comes back needs_input with an upload link (questions[0].upload_url, valid 30 minutes, one use). Show it to the person; when they drop the files, the request continues on its own. This is how an agent in a chat window, which cannot attach files, opens a matter.
B. The intake door: POST /v1/intakes
Any body is valid: a multipart post with files, a plain form post (every field becomes a line of notes), a raw PDF, a text body, or JSON (with content_base64 entries for files). Options go in the query string or as form fields.
curl -X POST "https://api.codossier.com/v1/intakes?external_id=M-2026-0412&name=Reyes%20v.%20Northwind" \
-u "cdk_<id>:<secret>" \
-F "[email protected]" \
-F "[email protected]" \
-F "notes=Client dismissed 2026-03-04, three weeks after the billing complaint."curl -X POST https://api.codossier.com/v1/intakes -u "cdk_<id>:<secret>" \
-H "Content-Type: text/plain" --data-binary @narrative.txt| Field | Where | Required | Meaning |
|---|---|---|---|
external_id | query or form | no | Your reference (≤128). Same content again → the original intake (200); new content after not_processable → the next attempt; otherwise 409. |
name | query or form | no | The matter's name (≤200). |
language | query or form | no | "en", "es" or "auto" (default). |
check_only | query or form | no | "true": read and validate the material, create nothing, charge nothing. Answers valid or not_processable with the missing list. |
simulate | query or form | no | "ready", "not_processable", "not_covered" or "failed": a simulated outcome, no engine. |
files | multipart | no | Up to 20 files, 10 MB each, 50 MB per request: PDF (≤50 pages), images, text, email exports. Office documents and archives are refused. |
{
"id": "0199…",
"external_id": "M-2026-0412",
"status": "received",
"reason": null,
"attempt": 1,
"missing": [],
"case_url": "https://codossier.com/dossier/case?id=0199…",
"export_url": "https://api.codossier.com/v1/intakes/0199…/export",
"status_url": "https://api.codossier.com/v1/intakes/0199…",
"created_at": "2026-10-08T18:40:02Z",
"updated_at": "2026-10-08T18:40:02Z"
}| status | Meaning |
|---|---|
received | Stored; reading starts within a minute. |
interpreting | Documents are being read and the interview written from them. |
submitted | Sent to the engine; the dossier is building (20–30 minutes). |
valid | check_only: the material makes a complete intake. |
not_processable | Too thin to proceed; missing lists the questions. Send more under the same external_id. |
not_covered | No practice-area engine covers this matter. Final for this intake. |
failed | reason says why; not billed. |
deleted | Deleted by you. |
Follow it, then collect the dossier
- Poll
status_urlevery minute or so (or follow the request through the work door's events feed). You also get an email when the dossier is ready. - When the matter is ready,
GET /v1/intakes/{id}/exportorGET /v1/matters/{id}/dossierreturns the whole dossier as JSON (codossier.case-export/1): the intake conversation, the lodes, crests, rifts and levies, with ids. case_urlopens the same matter on the site, where the canvas, the PDF and the Lode CLI are.
Each office can open a set number of matters a day through the API (default 20, UTC). The refusal is daily_cap_reached; ask us to raise it.