Integrate a marketplace dispute
Connect an order dispute to People’s Court: an authorized buyer agent prepares the claim, the buyer accepts the packet, the seller responds, both parties exchange evidence, and the marketplace follows the signed Award and its separate execution status. This walkthrough uses the public HTTP API with curl and jq; it needs no SDK source checkout. The Python SDK wraps the supported filing, evidence and event operations.
The example is a USD 100 order, #1042, that buyer Maya Chen says never arrived. Northwind Goods is the seller and respondent. These are illustrative parties, not a recorded case or a predicted outcome. Replace them with the actual authorized identities and transaction facts.
1. Set up the integration and each party’s authority
Apply for partner access, then complete the partner integration checklist. Use the approved test tenant and matching non-production deployment while evaluating. Production confirmation opens a real proceeding; a test credential does not create a test environment on the production origin.
| Component | Authority and responsibility |
|---|---|
| Buyer’s agent | A claimant role credential, registered authority for this principal and transaction, and case-specific packet acceptance |
| Marketplace backend | A platform orchestrator credential for its permitted case reads, invitations and signed callbacks; credentials stay on the backend |
| Seller or seller’s agent | Its own verified account or separately authorized respondent integration; the buyer’s key cannot speak for it |
| Execution adapter | Separate approval, capability and provider configuration if the integration will carry out an Award |
Register the claimant’s actual authority using POST /api/partner/authority-grants with the claimant credential. Use the authority registration contract for the principal ID, order and transaction identifiers, allowed acts, maximum amount, source artifacts, hashes and expiry. Store the returned authorityGrantId with the underlying authorization evidence. Obtain the acts and case membership grants needed for the later filing, evidence and record-confirmation steps. A platform key alone, a payment authorization or an order’s existence supplies none of that authority.
This recipe uses claimant_initiated intake and hosted claimant acceptance. It does not assert that the respondent has agreed. If two agents already have separately verifiable bilateral authorizations, use Two-agent case; one application representing both sides uses Represent both parties.
Load the credentials and identifiers from your backend’s configuration and secret store:
set -eu
umask 077
WORK=$(mktemp -d)
: "${PC_ORIGIN:?Set the approved deployment origin, without /api}"
: "${PC_CLAIMANT_KEY:?Load the buyer agent credential}"
: "${PC_PLATFORM_KEY:?Load the marketplace orchestrator credential}"
: "${PC_AUTHORITY_GRANT_ID:?Use the registered claimant grant}"
: "${PC_CLAIMANT_PRINCIPAL_ID:?Use the grant principal ID}"
: "${PC_RESPONDENT_PRINCIPAL_ID:?Use the seller principal reference}"
: "${PC_ACTOR_ID:?Use the authorized buyer agent ID}"
: "${PC_TRANSACTION_ID:?Use the transaction bound to the grant}"
: "${PC_POLICY_VERSION:?Use the integration policy version}"
: "${PC_BUYER_EMAIL:?Use the claimant acceptance identity}"WORK holds sensitive response files, including show-once links. Store durable integration records in your own protected database, not only this temporary directory. Do not put credentials, invitation links or acceptance links into public logs or analytics.
2. Read the Rules and verify the credentials
curl --fail-with-body -sS "$PC_ORIGIN/api/rules/current" > "$WORK/rules.json"
curl --fail-with-body -sS "$PC_ORIGIN/api/partner" \
-H "Authorization: Bearer $PC_CLAIMANT_KEY" > "$WORK/claimant-role.json"
curl --fail-with-body -sS "$PC_ORIGIN/api/partner" \
-H "Authorization: Bearer $PC_PLATFORM_KEY" > "$WORK/platform-role.json"Check the returned roles and capabilities against the actions your application will perform. Read the current Rules tuple and procedure disclosures; the filing packet will pin the accepted terms. Offer AI-only or AI-assisted human. For AI-only, the server resolves the eligible procedure before acceptance; the API transport does not select or waive an appeal. This example retains the human appeal with appealWaived: false.
3. Prepare the buyer’s filing
Keep a durable mapping from your marketplace order and dispute-attempt ID to the Court draft, eventual case ID and request keys. Use one key per distinct operation; the keys below belong only to this example attempt.
jq -n \
--arg grant "$PC_AUTHORITY_GRANT_ID" \
--arg buyer "$PC_CLAIMANT_PRINCIPAL_ID" \
--arg seller "$PC_RESPONDENT_PRINCIPAL_ID" \
--arg transaction "$PC_TRANSACTION_ID" \
--arg policy "$PC_POLICY_VERSION" \
--arg email "$PC_BUYER_EMAIL" \
'{
externalCaseId: "order-1042-dispute-1",
transactionId: $transaction,
policyVersion: $policy,
authorityGrantId: $grant,
consentArtifactIds: {},
claimAmount: {currency: "USD", minorUnits: "10000"},
parties: {
claimant: {externalId: $buyer, name: "Maya Chen", principalKind: "individual"},
respondent: {externalId: $seller, name: "Northwind Goods", principalKind: "organization"}
},
summary: "Order #1042 was paid for and never delivered.",
claim: {statement: "I paid USD 100 for order #1042 and it never arrived.", requestedOutcome: "refund"},
caseTrack: "ai_standard",
appealWaived: false,
intakeMode: "claimant_initiated",
confirmationPolicy: {mode: "initiator_only"},
claimantAcceptanceIdentity: {email: $email}
}' > "$WORK/filing.json"
curl --fail-with-body -sS "$PC_ORIGIN/api/filings" \
-H "Authorization: Bearer $PC_CLAIMANT_KEY" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: order-1042-dispute-1-prepare' \
--data-binary @"$WORK/filing.json" > "$WORK/prepared.json"
DRAFT_ID=$(jq -er '.data.draftId' "$WORK/prepared.json")The empty consent map does not fabricate either party’s consent: this path obtains the claimant’s exact acceptance next, and the respondent joins separately. Read and retain the returned packet, resolved caseTrack, fee, Rules identity, draftDigest, expiry and confirmation requirements. Do not assume your requested track is the resolved one or reuse a prior transaction’s packet.
4. Obtain the buyer’s acceptance and confirm
Deliver data.hostedAcceptanceUrl privately to the buyer. The buyer opens it in the matching verified account, reviews the claim, amount, Rules, procedure, AI disclosures, appeal election and fee, and accepts. The agent must not click acceptance or assert it merely because the order was authorized. See Claimant acceptance for identity matching and alternative explicitly authorized acceptance proofs.
After acceptance, retrieve the current draft and build the confirmation from its exact returned requirements:
Check that PC_ACTOR_ID and PC_CLAIMANT_PRINCIPAL_ID match this draft’s registered authority grant and returned claimant participant. Another agent or principal with authority elsewhere cannot confirm this packet.
curl --fail-with-body -sS "$PC_ORIGIN/api/filings/$DRAFT_ID" \
-H "Authorization: Bearer $PC_CLAIMANT_KEY" > "$WORK/reviewed.json"
jq --arg actor "$PC_ACTOR_ID" --arg principal "$PC_CLAIMANT_PRINCIPAL_ID" \
'.data | {
participantId: (.participants[] | select(.side == "claimant") | .participantId),
draftDigest,
confirmationStatement: (.confirmations[] | select(.side == "claimant") | .confirmationStatement),
actorId: $actor, principalId: $principal,
confirmationMethod: "protocol_act", confirmationReference: "order-1042-dispute-1"
}' "$WORK/reviewed.json" > "$WORK/confirmation.json"
curl --fail-with-body -sS "$PC_ORIGIN/api/filings/$DRAFT_ID/confirmations" \
-H "Authorization: Bearer $PC_CLAIMANT_KEY" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: order-1042-dispute-1-confirm' \
--data-binary @"$WORK/confirmation.json" > "$WORK/opened.json"
CASE_ID=$(jq -er '.data.caseId' "$WORK/opened.json")Continue only when the response supplies the committed caseId. If acceptance, confirmation or fee requirements remain, present the returned action to its authorized owner and stop this branch until fulfilled. Do not substitute a reserved case ID, create a second filing to bypass a prerequisite, or infer payment from a fee quote. Replaying preparation or confirmation does not redisclose show-once links.
5. Invite the seller and receive its Answer
curl --fail-with-body -sS "$PC_ORIGIN/api/cases/$CASE_ID/invitations" \
-H "Authorization: Bearer $PC_PLATFORM_KEY" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: order-1042-dispute-1-invite' \
--data '{}' > "$WORK/invitation.json"Deliver data.hostedLink through the intended seller’s authenticated marketplace channel. A new invitation invalidates the previous one. The seller signs in, reviews the opening filing and applicable terms, and files its own Answer on People’s Court. Preserve that boundary in your product: “Invitation delivered” and “Answer filed” are different states. For a separately authorized seller agent, follow Respond for a party using its own credentials and the returned Answer requirements.
Read the case with each relevant credential before acting:
curl --fail-with-body -sS "$PC_ORIGIN/api/cases/$CASE_ID" \
-H "Authorization: Bearer $PC_CLAIMANT_KEY" > "$WORK/case.json"
jq '.data | {stage, revision, availableActions, waitingOn, processing}' "$WORK/case.json"Use availableActions and each action’s requirements and expectedRevision to drive the integration. Honor current deadlines and authorization on every write. Do not drive the case forward on an assumed timer or refiling loop.
6. Exchange evidence and rebuttal
When the claimant’s case view permits the filing, obtain its truthfulness affirmation, then submit its brief and original receipt:
curl --fail-with-body -sS "$PC_ORIGIN/api/cases/$CASE_ID/submissions" \
-H "Authorization: Bearer $PC_CLAIMANT_KEY" \
-H 'x-pc-party: claimant' \
-H 'Idempotency-Key: order-1042-dispute-1-claimant-evidence' \
-F 'party=claimant' \
-F 'brief=I paid USD 100 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'Use the actual declarant and location and the actual receipt bytes. Let curl set the multipart boundary. The seller submits its own shipping evidence and brief through its Case Page or separately authorized respondent agent. Each party receives only the material its case view permits; simultaneous filings may remain sealed until exchange. When a rebuttal phase is available, repeat the same submission operation with the party’s rebuttal, current requirements and a new operation key. Preserve source identities and original exhibit hashes in the marketplace’s transaction record.
7. Have each party review its Record
When confirm_record is available, each party reads its own GET /api/cases/{id}/record-summary. Show the returned summary to that party or its expressly authorized representative. If it is inaccurate, use the available correction procedure before confirming. Do not automatically accept a digest without reviewing the corresponding record.
For the claimant, after review:
curl --fail-with-body -sS "$PC_ORIGIN/api/cases/$CASE_ID/record-summary" \
-H "Authorization: Bearer $PC_CLAIMANT_KEY" \
-H 'x-pc-party: claimant' > "$WORK/claimant-record.json"
jq -e '.data | {recordDigest, confirmationStatement} |
select((.recordDigest | type) == "string" and (.confirmationStatement | type) == "string")' \
"$WORK/claimant-record.json" > "$WORK/claimant-record-confirmation.json"
curl --fail-with-body -sS "$PC_ORIGIN/api/cases/$CASE_ID/record-summary/confirmations" \
-H "Authorization: Bearer $PC_CLAIMANT_KEY" \
-H 'x-pc-party: claimant' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: order-1042-dispute-1-claimant-record' \
--data-binary @"$WORK/claimant-record-confirmation.json"The respondent separately reviews and responds through its own account or agent authority. One party’s confirmation never satisfies the other’s requirement. If preparation changes, refresh the view and review the new source-bound digest rather than altering it locally.
8. Keep the marketplace synchronized
Poll the authorized case event feed; account tokens require cases:read:
curl --fail-with-body -sS "$PC_ORIGIN/api/cases/$CASE_ID/events?limit=50" \
-H "Authorization: Bearer $PC_PLATFORM_KEY" > "$WORK/events.json"Process data.events in order, then commit data.nextCursor atomically with your handled-event records. On the next request supply that stored cursor as after, using URL encoding, and drain pages while data.hasMore is true. Deduplicate by event ID and retain the last committed checkpoint across restarts. Keep each credential’s authorized stream separate. If a cursor becomes invalid, refresh the case and restart that stream with event-ID deduplication.
For push notifications, register a public HTTPS receiver at POST /api/webhooks/endpoints with the orchestrator’s callbacks:manage capability, then complete signed endpoint verification as described in Partner integration. Configure it before the events you need. Verify Ed25519 signatures over the untouched bytes, timestamp and actual receiver path/query against your trusted key set. The Python callback verifier can perform this check. Durably deduplicate and enqueue the event before acknowledging; a worker fetches authoritative case state. Callbacks can arrive out of order and more than once; they must not advance the polling checkpoint past unprocessed events or authorize a payment.
9. Retrieve and verify the served Award
Follow the case until its decision is served, including any required service-side hold. Retrieve the Award with the case-authorized party credential:
curl --fail-with-body -sS "$PC_ORIGIN/api/cases/$CASE_ID/award" \
-H "Authorization: Bearer $PC_CLAIMANT_KEY" > "$WORK/award.json"
curl --fail-with-body -sS "$PC_ORIGIN/api/cases/$CASE_ID" \
-H "Authorization: Bearer $PC_CLAIMANT_KEY" > "$WORK/decided-case.json"Follow the returned artifact and attestation paths. Verify the exact artifact bytes, case identity, Award hash and revision with your configured signer trust policy. Callback verification is not Award verification. For a portable Record, explicitly prepare POST /api/cases/{id}/record-bundle with {"profile":"party"} and its own idempotency key, then follow the advertised polling GET and download links. See Decision and execution for the full artifact, appeal and correction contracts.
10. Hand off execution and track the receipt
Read decision.served, decision.finality, decision.executable, decision.holdReasons and the separate execution resource. Partner-origin cases without a settlement binding use partner_executed; a configured binding can select another supported mode. The marketplace must know who owns performance before offering an automated payment path.
curl --fail-with-body -sS "$PC_ORIGIN/api/cases/$CASE_ID/executions" \
-H "Authorization: Bearer $PC_PLATFORM_KEY" > "$WORK/executions.json"Follow each execution record’s links.self under the same authorized origin. An operational reader receives permitted status metadata, not private party receipts. If the marketplace executes, its separately authorized adapter follows partner execution and the provider-verified receipt contract. For the supported connected-account route, follow Stripe Connect execution. A decision-only integration leaves performance to the parties and reports that mode accurately.
Display “Award served,” “Execution pending” and “Payment confirmed” as separate facts. An appeal waiver removes only its applicable appeal wait; every other stay and execution condition still applies. An unknown provider result must reconcile through the original operation before another payment attempt. Neither a new HTTP key, a performance report nor a simulated receipt proves payment or authorizes a second debit.
Recovery and release checklist
| Situation | Integration response |
|---|---|
| Timeout after a mutation | Retry the identical request with its stored key; retain the original business operation identity |
| Changed digest, stale revision or closed phase | Refresh the authorized view, review changed requirements, and obtain any required fresh acceptance |
| Expired or revoked authority | Stop that actor’s writes and renew through the principal’s authorized process |
429 response | Honor Retry-After; bound retries and do not spin a polling loop |
| Lost callback or worker restart | Resume the saved event cursor and deduplicate already processed IDs |
| Technical failure or procedure hold | Show the returned processing state; do not refile or invent a merits outcome |
| Payment outcome unknown | Reconcile the existing provider operation; keep the marketplace’s payment status unresolved |
Before live access, demonstrate the tenant’s actual acceptance, Answer, signed callback and served-Award steps through the partner readiness process. Read-only hosted stage samples help build UI states but do not file a proceeding or satisfy real readiness milestones. Keep the immutable accepted packet, role and authority references, order-to-case mapping, durable keys, per-stream cursors, verified artifact identities and execution receipts for your authorized retention period. After transferring needed records into protected storage, remove the temporary response files according to your retention policy.