Get started
File a claim through the hosted API at https://peoplescourt.ai: get an account token, prepare the filing, open the case, invite the respondent, submit evidence, and follow the case to its Award. All you need is curl, openssl, a browser, and a People’s Court account.
The example dispute runs through every step. A buyer, Maya Chen, paid USD 100 for order #1042 from Northwind Goods, and it never arrived. She files as claimant and asks for a refund.
Every request below acts on production. A confirmed filing is a real case served on a real respondent, so while you evaluate, name a respondent you control and deliver the invitation to a second account of your own.
1. Read the current Rules
Every case is governed by a pinned version of the Rules. GET /api/rules/current is public and needs no credentials:
curl --fail-with-body -sS https://peoplescourt.ai/api/rules/currentThe following excerpt shows the Rules identity fields; the full response also includes the procedure templates described below.
{
"data": {
"rulesVersion": "1.1",
"rulesHash": "a90617f9985d69016ec753c91d555b449ad61378c60f29a8412216fe156b0a40",
"rulesetId": "arbitral-rules-v1.1",
"dynamicRulesetId": "arbitral-rules-current",
"apiCompatibilityVersion": "2026-08-30",
"application": "prospective_and_case_pinned"
},
"requestId": "req_88533434-c539-4c1c-8886-a42c5319e38e"
}Pin the returned rulesetId, rulesVersion, and rulesHash to the transaction terms presented for acceptance. Once accepted, a transaction keeps its pinned Rules tuple even if a later Rules version becomes current. Read the tuple for each new transaction rather than hard-coding it. dynamicRulesetId is a discovery alias, and apiCompatibilityVersion versions the API separately from the Rules.
The response also includes caseProcedures: the fast, standard and human procedure templates, their disclosure text, the separate appeal-waiver disclosure, and exact terms.appealRetained and terms.appealWaived tuples. Offer two tiers: AI-only and AI-assisted human. The Court resolves the fast or standard AI-only procedure from the claim at the same price; reading a tuple records no consent. Omitting caseTrack, or supplying ai_standard or ai_fast, requests AI-only. Before consent, the server resolves eligible monetary cases below USD 100 to ai_fast, and cases of USD 100 or more or nonmonetary relief to ai_standard. Accept the exact resolved packet, including its disclosure and terms hash. appealWaived defaults to false. Both parties must accept a different election before final case-opening confirmation. Both parties must accept the same pinned tuple.
2. Get an access token
This guide uses account OAuth, which any verified account can set up without review. A platform credential follows the separate partner integration guide and claimant workflow, with role credentials and each principal’s registered authority. Signed webhook registration requires a platform credential; an account OAuth token cannot register a partner callback. For a registered autonomous agent, see Get access.
- Create an account and verify its email. See Authentication for the hosted account setup flow.
- At /account/authorizations, register a personal client with the redirect URI
http://127.0.0.1:8080/callbackand these scopes:cases:read,filings:write,consents:write,invitations:write,submissions:write,offline_access. Copy its client ID.
Create a PKCE verifier and challenge, then print the authorization URL:
CLIENT_ID=client_… # from /account/authorizations
CODE_VERIFIER=$(openssl rand -hex 32)
CODE_CHALLENGE=$(printf '%s' "$CODE_VERIFIER" | openssl dgst -sha256 -binary | openssl base64 -A | tr '+/' '-_' | tr -d '=')
STATE=$(openssl rand -hex 16)
echo "https://peoplescourt.ai/oauth/authorize?response_type=code&client_id=$CLIENT_ID\
&redirect_uri=http%3A%2F%2F127.0.0.1%3A8080%2Fcallback\
&scope=cases%3Aread%20filings%3Awrite%20consents%3Awrite%20invitations%3Awrite%20submissions%3Awrite%20offline_access\
&resource=https%3A%2F%2Fpeoplescourt.ai%2Fapi\
&code_challenge_method=S256&code_challenge=$CODE_CHALLENGE&state=$STATE"Open the URL, review the consent screen, and approve. Your browser then goes to http://127.0.0.1:8080/callback?code=…&state=…&iss=https://peoplescourt.ai. Nothing needs to listen on that port; copy code from the address bar and check that state matches. Exchange it within two minutes:
CODE=… # from the callback URL
curl --fail-with-body -sS https://peoplescourt.ai/api/oauth/token \
-d grant_type=authorization_code \
-d client_id="$CLIENT_ID" \
-d code="$CODE" \
-d code_verifier="$CODE_VERIFIER" \
--data-urlencode redirect_uri=http://127.0.0.1:8080/callback \
--data-urlencode resource=https://peoplescourt.ai/api{
"access_token": "…",
"token_type": "Bearer",
"expires_in": 300,
"scope": "cases:read filings:write consents:write invitations:write submissions:write offline_access",
"refresh_token": "…"
}TOKEN=… # access_token
REFRESH_TOKEN=… # refresh_tokenAccess tokens last five minutes. When one expires, refresh it; each refresh returns a new refresh token as well:
curl --fail-with-body -sS https://peoplescourt.ai/api/oauth/token \
-d grant_type=refresh_token \
-d client_id="$CLIENT_ID" \
-d refresh_token="$REFRESH_TOKEN" \
--data-urlencode resource=https://peoplescourt.ai/apiMake a first authenticated request by listing your cases:
curl --fail-with-body -sS https://peoplescourt.ai/api/cases \
-H "Authorization: Bearer $TOKEN"A new account returns {"data": {"cases": []}}.
3. Prepare the filing
Preparing creates a draft and its review packet. Nothing is filed yet.
curl --fail-with-body -sS https://peoplescourt.ai/api/filings \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: order-1042-prepare' \
--data '{
"caseTrack": "ai_standard",
"appealWaived": false,
"parties": {
"respondent": {
"name": "Northwind Goods",
"principalKind": "organization",
"email": "orders@northwind.example",
"emailIsProper": true,
"emailSource": "claimant_attested"
}
},
"summary": "Order #1042 was paid for and never delivered.",
"claim": {
"statement": "I paid USD 100 for order #1042 on 1 September. It was due on 5 September and never arrived.",
"requestedItems": [{ "kind": "monetary", "text": "Refund USD 100." }]
},
"claimAmount": { "currency": "USD", "minorUnits": "10000" },
"declaration": {
"declarantName": "Maya Chen",
"declarantCapacity": "Individual party",
"executionLocation": "Brussels, Belgium"
}
}'| Field | Rules |
|---|---|
caseTrack | Optional (default ai_standard): ai_fast, ai_standard, or ai_assisted_human. Both AI values request automatic AI-only routing before acceptance. Eligible monetary claims below USD 100 use fast; other claims use standard. Later structural ineligibility requires a consented change or termination/refund. |
appealWaived | Optional boolean, default false. A waiver requires each party’s explicit acceptance of the separate waiver disclosure. |
parties.respondent | name and principalKind (individual, organization, or autonomous_agent). An email needs emailIsProper: true; emailSource is claimant_attested, agreement, or notice_designation. |
claim.requestedItems | One to three items, at most one per kind: monetary, declaratory, or order. A monetary item needs a positive claimAmount. |
claimAmount.minorUnits | A string of minor units: "10000" is USD 100.00 |
declaration.declarantCapacity | Individual party, Authorized representative of an entity, or Other: followed by a description |
The claimant is always the account behind the token. The response is 201:
{
"data": {
"schemaVersion": "account-filing-v1",
"filingId": "afd_…",
"status": "awaiting_acceptance",
"acceptance": { "required": true, "method": "hosted_clickwrap", "recorded": false },
"reviewPacket": { "…": "…" },
"hostedAcceptanceUrl": "https://peoplescourt.ai/accept/filing/afd_…#token=…"
}
}FILING_ID=afd_… # data.filingIdhostedAcceptanceUrl is shown once. A replay with the same idempotency key returns the draft without it.
4. Accept the terms
Open hostedAcceptanceUrl in a browser signed in as the claimant. Review the claim, amount, Rules, AI disclosure, procedure, and fees, then accept. Acceptance is the claimant’s own act on People’s Court; no API request can make it for them.
5. Open the case
curl --fail-with-body -sS -X POST "https://peoplescourt.ai/api/filings/$FILING_ID/confirmations" \
-H "Authorization: Bearer $TOKEN" \
-H 'Idempotency-Key: order-1042-confirm'With no fee payable, this returns 201 with data.caseId and opens the case:
CASE_ID=… # data.caseIdWhen a filing fee applies, it returns 409 filing_fee_required with details.quotedFeeUsd and details.filingPath, and opens nothing: the API does not take payment, so complete that filing on People’s Court and then find its ID with GET /api/cases. Before acceptance is recorded, it returns 409 acceptance_required.
6. Invite the respondent
curl --fail-with-body -sS -X POST "https://peoplescourt.ai/api/cases/$CASE_ID/invitations" \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: order-1042-invite' \
--data '{}'The response carries a show-once data.hostedLink. Deliver it only through the respondent’s authenticated channel; issuing a new invitation invalidates the previous one. The respondent opens the link, signs in, reviews the opening filing, and files the Answer on People’s Court. That is the respondent’s own act, so it has no request in this guide.
7. Read the case
curl --fail-with-body -sS "https://peoplescourt.ai/api/cases/$CASE_ID" \
-H "Authorization: Bearer $TOKEN"{
"data": {
"stage": { "code": "exchange", "phase": "evidence", "recordRevision": 5 },
"revision": 5,
"availableActions": [ "…" ],
"waitingOn": [
{ "kind": "deadline", "reason": "filing_window", "dueAt": "2026-09-30T03:59:00.000Z" }
],
"processing": { "blocker": null, "lastProgress": null, "nextActor": null }
}
}availableActions lists what this token may do next, with each action’s requirements and expectedRevision. Read it before every write.
8. Submit evidence
Once the Answer is filed, the case opens for evidence. File the buyer’s brief and receipt:
printf '%s\n' 'Receipt: order #1042, USD 100.00 paid 1 September. Delivery due 5 September.' > receipt.txt
curl --fail-with-body -sS "https://peoplescourt.ai/api/cases/$CASE_ID/submissions" \
-H "Authorization: Bearer $TOKEN" \
-H 'Idempotency-Key: order-1042-evidence' \
-F 'party=claimant' \
-F 'brief=I paid for order #1042 and it never arrived.' \
-F 'attest=true' \
-F 'declarantName=Maya Chen' \
-F 'declarantCapacity=Individual party' \
-F 'executionLocation=Brussels, Belgium' \
-F 'files=@receipt.txt;type=text/plain'Returns 201. Send attest=true only after the person has affirmed the truthfulness of the submission. Let curl set the multipart boundary.
9. Follow the case
Page through the case’s events and keep the last cursor you processed:
curl --fail-with-body -sS "https://peoplescourt.ai/api/cases/$CASE_ID/events?limit=50" \
-H "Authorization: Bearer $TOKEN"The response has data.events, nextCursor, and hasMore. Pass the cursor back as after to continue. Signed webhooks push the same changes, but registering a webhook endpoint requires a platform credential from partner access; see Keeping in sync.
After the record closes, the Tribunal decides and the Award is served. Read it with the same token:
curl --fail-with-body -sS "https://peoplescourt.ai/api/cases/$CASE_ID/award" \
-H "Authorization: Bearer $TOKEN"Follow the decision and execution covers service, appeal, finality, and payment.
Track progress
While a case is under_review, processing explains the pending work, and waitingOn[].reason uses the same code as processing.blocker:
| Field | Values |
|---|---|
processing.blocker | queued, adjudication, technical_failure, procedure_hold, ai_correction, configuration_review, operational_hold, legacy_review, award_service, award_validation, awaiting_start, or null |
processing.lastProgress | {code, at} or null. code is queued, started, completed, failed, interrupted, timed_out, or cancelled. |
processing.nextActor | service, administrator, tribunal, legacy_reviewer, or null |
Outside under_review, all three fields are null. Progress reports recorded milestones. It does not report heartbeats, merits conclusions, or completion estimates. Technical failures and holds are resolved on the service side, so do not refile to clear them.
An authorized party or guest may also receive the optional fixed delayNotice: “This is taking longer than usual. No action is needed from you.” It appears when service of the decision is delayed, requires no action and disappears when the Award is served.
List cases
GET /api/cases accepts limit (1–100, default 50), side (claimant or respondent), and status, which filters the stored status code rather than stage.code. The body is {"data": {"cases": [{"id", "side", "status", "revision"}]}}. Follow the Link: <…>; rel="next" header until it is absent; the body has no cursor, and the link’s cursor is bound to the same account and filters. Invalid filters or cursors return 422. Case-event cursors and case-list cursors are not interchangeable.
Retry safely
Send one durable Idempotency-Key per distinct mutation. After a timeout or uncertain response, retry the same body with the same key. A replay never returns a show-once link again. A changed digest or revision means the case moved: read it again and send a new, reviewed request with a new key. On 429, honor Retry-After. See Errors.
Next steps
- File for the claimant: other acceptance methods, record correction, and confirmation
- Respond for a party: the respondent side with delegated credentials
- Authentication: client credentials for agents, partner roles, and scopes
- Endpoint reference: every operation, with request and response schemas