GuidesGet started

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:

Shell
curl --fail-with-body -sS https://peoplescourt.ai/api/rules/current

The following excerpt shows the Rules identity fields; the full response also includes the procedure templates described below.

JSON
{
  "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.

  1. Create an account and verify its email. See Authentication for the hosted account setup flow.
  2. At /account/authorizations, register a personal client with the redirect URI http://127.0.0.1:8080/callback and 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:

Shell
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:

Shell
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
JSON
{
  "access_token": "…",
  "token_type": "Bearer",
  "expires_in": 300,
  "scope": "cases:read filings:write consents:write invitations:write submissions:write offline_access",
  "refresh_token": "…"
}
Shell
TOKEN=…           # access_token
REFRESH_TOKEN=…   # refresh_token

Access tokens last five minutes. When one expires, refresh it; each refresh returns a new refresh token as well:

Shell
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/api

Make a first authenticated request by listing your cases:

Shell
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.

Shell
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"
    }
  }'
FieldRules
caseTrackOptional (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.
appealWaivedOptional boolean, default false. A waiver requires each party’s explicit acceptance of the separate waiver disclosure.
parties.respondentname and principalKind (individual, organization, or autonomous_agent). An email needs emailIsProper: true; emailSource is claimant_attested, agreement, or notice_designation.
claim.requestedItemsOne to three items, at most one per kind: monetary, declaratory, or order. A monetary item needs a positive claimAmount.
claimAmount.minorUnitsA string of minor units: "10000" is USD 100.00
declaration.declarantCapacityIndividual 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:

JSON
{
  "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=…"
  }
}
Shell
FILING_ID=afd_…   # data.filingId

hostedAcceptanceUrl 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

Shell
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:

Shell
CASE_ID=…   # data.caseId

When 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

Shell
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

Shell
curl --fail-with-body -sS "https://peoplescourt.ai/api/cases/$CASE_ID" \
  -H "Authorization: Bearer $TOKEN"
JSON
{
  "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:

Shell
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:

Shell
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:

Shell
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:

FieldValues
processing.blockerqueued, 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.nextActorservice, 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