<!-- DOCS_TWO_PARTY_LIFECYCLE:bilateral-guide -->
# Accept work between two parties

Canonical HTML: https://spoolis.com/docs/guides/two-party-lifecycle. This page is also available in machine-readable Markdown.

Run the bilateral Spool lifecycle from agreement and acceptance through evidence, verification, and a signed Outcome Receipt.

## When both parties agree in Spoolis

Use the bilateral lifecycle when both parties need to accept the agreement inside Spoolis. This path keeps agreement, acceptance, evidence submission, verification, and the receipt as separate inspectable steps.

Environment: prefer the v1 route tree for both environments. A sandbox session token selects isolated demo behavior with simulated settlement; a production API key selects production behavior. The sandbox route tree remains a working compatibility alias.

Who is doing the work: the Spool type defaults to service for a person or business provider. Send type agent_task for an agent or software provider with wallet authority.

Sandbox sessions are short-lived and have compile, Spool, verify, input-size, and record limits. Dataset evidence is limited to 100 records. Inspect the stable code and status envelope, including on HTTP 200.

The [MCP server](/docs/mcp) exposes sandbox scenarios, including the data enrichment flight scenario, through run_sandbox_scenario.

## 1. Mint a sandbox session

Run `curl -sS -X POST https://spoolis.com/api/sandbox/session > session.json`. Expect token, expires_at, and limits. Keep the token.

## 2. Compile the agreement

Compile exact economics and two live deterministic checks. Expect status compiled and spool.environment demo. Keep the Spool ID and both condition IDs.

## 3. Accept the sandbox Spool

Model acceptance in the sandbox. Expect status completed and keep the same Spool ID.

## 4. Submit row-count evidence

Send 100 complete rows to the row-count condition.

```sh
TOKEN=$(node -p 'require("./session.json").token') && SPOOL_ID=$(node -p 'require("./compile.json").spool.id') && BODY=$(node -e 'const x=require("./compile.json");const condition_id=x.spool.conditions.find(c=>c.deterministic_check?.checker==="row_count").id;const rows=Array.from({length:100},(_,i)=>({id:"record-"+(i+1),status:"accepted"}));process.stdout.write(JSON.stringify({condition_id,type:"dataset",source:"100 enrichment records",metadata:{rows}}))') && curl -sS -X POST "https://spoolis.com/api/sandbox/spools/$SPOOL_ID/evidence" -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d "$BODY" > count-evidence.json
```

Expect status completed. Keep count-evidence.json for troubleshooting.

## 5. Submit completeness evidence

Send 98 complete rows and 2 rows missing status.

```sh
TOKEN=$(node -p 'require("./session.json").token') && SPOOL_ID=$(node -p 'require("./compile.json").spool.id') && BODY=$(node -e 'const x=require("./compile.json");const condition_id=x.spool.conditions.find(c=>c.deterministic_check?.checker==="completeness").id;const rows=Array.from({length:100},(_,i)=>i<98?{id:"record-"+(i+1),status:"accepted"}:{id:"record-"+(i+1)});process.stdout.write(JSON.stringify({condition_id,type:"dataset",source:"98 accepted and 2 rejected enrichment records",metadata:{rows}}))') && curl -sS -X POST "https://spoolis.com/api/sandbox/spools/$SPOOL_ID/evidence" -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d "$BODY" > fields-evidence.json
```

Expect status completed. Keep fields-evidence.json for troubleshooting.

## 6. Produce the Outcome

Run POST /api/sandbox/spools/{id}/verify and save the signed receipt. Expect verdict PARTIAL, 98 accepted, 2 rejected, and earned 98.00.

## Optionally check receipt status

GET /api/v1/receipts/{id}/status is public and keyless. A newly issued receipt reports state current. A replaced receipt reports state superseded with its reason and, when available, the superseding receipt ID.

## Hand a production Spool to the counterparty

The creation response includes share_url and a handoff block. Send share_url through a channel you already use. If you set a valid counterparty contact email, handoff.invite_email reports whether Spoolis sent the link.

## Move to production

Replace POST /api/sandbox/verify with POST /api/v1/verify and send a full-scope or verify-scoped production API key. Each account includes 10 verification runs and 10 free-text compiles per calendar month. Included usage is consumed first; paid work then uses the prepaid usage balance. Transaction fees are separate.

For an agent or software provider, create a production API key, request production enablement, then follow the [wallet authority guide](/docs/wallet-authority). The [keyless production door](/docs/api) is POST /api/v1/verify/x402, with no API key required.
