# Spoolis skill

Spoolis issues a signed, durable, portable Outcome Receipt: a verdict artifact, per unit for unitized work, that billing, audit, a counterparty's own systems, or another third party can fetch and independently verify. It makes the receipt by verifying delivered work against explicit acceptance criteria. You define what counts, provide the evidence, and choose the judge or checks. A Spool is the versioned acceptance policy around those inputs. The Outcome records what counted, what failed, what was uncertain, and what was earned. The consuming system decides what happens next.

Use Spoolis when delivered work must be checked against explicit acceptance criteria before another system pays, continues, retries, or acts on it.

## Use when

- a delivery can partially pass, and accepted units determine earned value
- another system needs a signed, portable result it can rely on
- the evidence and the judgment should survive outside the current workflow

## Do not use when

- delivery itself proves success
- the check is trivial and locally obvious
- no downstream system needs an explicit result

## Fastest agent path (no account, no API key)

POST https://spoolis.com/api/v1/verify/x402
Each keyless x402 call is quoted before execution from a $0.010 base component plus the units processed. The base component is not the full price of a call. An unpaid POST is free and returns the exact quote. No account or API key is required for the x402 path.
1. Send the request below with no payment. The response is HTTP 402 with a PAYMENT-REQUIRED header quoting the exact price for this request in USDC on Base (x402 v2, exact scheme). Send the request without payment first. The 402 response quotes the exact price for that request in USDC on Base. Pricing varies with the verification work required, up to the published maximum.
2. Sign the quoted amount with an x402 client and retry the same request with the PAYMENT-SIGNATURE header.
3. The same request now returns per-unit accepted/rejected/uncertain results, earned value for accepted units only, and a signed Outcome Receipt with a receipt id.

Minimal request body:

```json
{
  "settlement": "external",
  "max_amount_cents": 3,
  "unit": {
    "total_units": 3,
    "unit_amount_cents": 1
  },
  "conditions": [
    {
      "description": "Every row includes status",
      "deterministic_check": {
        "checker": "completeness",
        "required_fields": [
          "status"
        ]
      }
    }
  ],
  "evidence": {
    "type": "dataset",
    "provenance": "api_response",
    "rows": [
      {
        "id": 1,
        "status": "complete"
      },
      {
        "id": 2,
        "status": "complete"
      },
      {
        "id": 3
      }
    ]
  }
}
```

The signed Outcome Receipt is portable. Fetch it without a key at `GET /api/v1/receipts/{receipt_id}`, inspect the trust set at `/.well-known/spoolis-keys.json`, or verify it offline with `@spoolis/receipt-verifier` (npm) or `spoolis-receipt-verifier` (PyPI). `UNCERTAIN` is its own category, never folded into failures, and earns nothing until resolved.

## Free rehearsal (sandbox)

Mint a sandbox bearer token with `POST /api/sandbox/session`, then send it to the canonical `POST /api/v1/verify` route. The `/api/sandbox/*` tree remains a working compatibility alias.

## Start here: one-call acceptance

Spoolis issues a signed, durable, portable Outcome Receipt: a verdict artifact, per unit for unitized work, that billing, audit, a counterparty's own systems, or another third party can fetch and independently verify. It makes the receipt by verifying delivered work against explicit acceptance criteria. You define what counts, provide the evidence, and choose the judge you trust. A Spool is the versioned acceptance policy around those inputs. The Outcome records what counted, what failed, what was uncertain, and what was earned. Billing, payment, workflows, finance, or another agent can act on that result.

Use Spoolis when a workflow needs a reliable acceptance result before something consequential happens next. Do not use it when delivery alone is enough.

Call `POST /api/v1/verify` or the `verify_result` MCP tool. Supply plain-language conditions or explicit deterministic checks and evidence. Add `max_amount_cents` when the result has a value. It is required with `unit` because unit math needs the cap. Without it, Spoolis verifies the result with no earned-value semantics: `earned_cents` is zero and the receipt omits committed value. Spoolis creates an inspectable unilateral Spool, runs verification, and returns a signed Outcome Receipt in one response.

Send exactly one of `conditions` or `recipe`. A recipe input has `slug` and `hash`. Spoolis resolves it only from the local hosted registry, recomputes the conditions hash, and fails without verification if the slug is unknown or the hash differs. On a match, the signed receipt includes the recipe slug, hash, and exact hosted conditions.

External settlement is the default. The external provider is identified but does not accept conditions in Spoolis. The receipt carries `agreement.acceptance` with unilateral mode, `provider_accepted_in_spoolis: false`, and `accepted_by: initiator`. It does not prove mutual agreement or payment execution.

The same `POST /api/v1/verify` route works after minting a short-lived sandbox bearer token. The credential selects the environment, and sandbox credentials can reach only sandbox handlers and state. The `/api/sandbox/*` tree remains a working compatibility alias.

```json
{
  "conditions": [{
    "description": "Every row includes status",
    "deterministic_check": {
      "checker": "completeness",
      "required_fields": ["status"]
    }
  }],
  "max_amount_cents": 3,
  "unit": { "total_units": 3, "unit_amount_cents": 1 },
  "evidence": {
    "type": "dataset",
    "rows": [
      { "id": 1, "status": "complete" },
      { "id": 2, "status": "complete" },
      { "id": 3 }
    ],
    "provenance": "api_response"
  }
}
```

The response has these top-level fields: `spool_id`, `earned_cents`, `accepted`, `rejected`, `rejections` with `unit` and `reason`, `receipt`, `receipt_url`, `verification_run_id`, `terminal`, `settlement_eligible`, `can_resubmit_evidence`, `can_rerun`, `next_step`, and `decision_authority`. This example returns 2 accepted, 1 rejected, and 2 cents earned.

The one-call recipe is: criteria plus evidence -> unilateral Spool -> verify -> Outcome Receipt -> verifyReceipt -> optional status check -> consumer acts on earned.

Use `GET /api/v1/receipts/{receipt_id}/status` for the optional status check. Offline signature verification proves authenticity without Spoolis uptime. The status check is optional and only adds correction, revocation, or advisory state.

## Outcome Receipt

- The canonical schema is `spoolis/outcome-receipt@1`.
- Conditions may declare hash-covered `evidence_requirements`. Receipt rows report `present`, `missing`, `stale`, `unavailable`, or `provenance_unsatisfied`; unsatisfied required evidence defaults the criterion to `uncertain`.
- Unitized receipts may publish a salted per-unit `identity.id`. The random per-Spool salt is not present in the public receipt; label visibility additionally publishes the original unit value.
- Verify receipt authenticity with `@spoolis/receipt-verifier` and pinned receipt entries from `https://spoolis.com/.well-known/spoolis-keys.json`. A valid Ed25519 signature proves the receipt is genuine and unaltered. It does not prove every underlying check is reproducible or that the evidence reflects real-world truth.
- Repository source includes `requireOutcome(receipt, policy, options)` and CLI `--require` for consumer checks such as minimum status, earned amount, and satisfied evidence requirements. requireOutcome ships in @spoolis/receipt-verifier 0.1.3+ and --require in @spoolis/cli 0.1.5+.
- Pass require_current with a status source from fetchReceiptStatus when the consumer must not act on a superseded receipt; get_receipt_status is the MCP equivalent.
- The agreement block names the policy version that governed the Outcome: spool_id, agreement_version, and agreement_hash, plus recipe slug and hash when a hosted recipe was used; pin agreement_hash in requireOutcome when the consumer must act only under one accepted policy.
- The signed attestation is the lower-level in-band verdict underneath the receipt. Use `POST /api/v1/attestations/verify` only when that lower-level layer is needed.
- Receipt validity records what was earned. It does not grant payment authority or prove that a payment was executed.

## REST

- Verify a result in one call: `POST /api/v1/verify`
- Try the same `POST /api/v1/verify` route with a sandbox bearer token.
- Compatibility alias: `POST /api/sandbox/verify` remains fully working for existing integrations.

## When both parties agree in Spoolis

- Compile a task: `POST /api/compile`. Use `action: "create"` to persist the compiled Spool as a proposed draft; inspect its verification_summary, amend conditions or unitization with `POST /api/v1/spools/{id}/amend` while proposed, then accept to confirm.
- Create a structured Spool: `POST /api/v1/spools`
- Read a Spool: `GET /api/v1/spools/{id}`
- Submit evidence: `POST /api/v1/spools/{id}/evidence`
- Run verification: `POST /api/v1/spools/{id}/verify`
- Check optional receipt status: `GET /api/v1/receipts/{receipt_id}/status`
- Read events: `GET /api/v1/spools/{id}/events`
- Create a counterparty invitation: `POST /api/v1/spools/{id}/invite` with the initiator's full-scope key.
- Exchange the returned one-time grant: `POST /api/v1/keys/exchange`. The counterparty key can read its bound Spool and can accept, decline, or submit evidence while the outcome is active.

## MCP

Connect to the zero-install hosted MCP endpoint at https://spoolis.com/api/mcp from Claude custom connectors or any remote MCP client; it uses the anonymous sandbox by default and accepts a bearer API key for production. Run the published npm package with `npx @spoolis/mcp` when a local stdio server is preferred. The server is listed on the official MCP Registry as `com.spoolis/mcp`, so registry-aware clients can discover it by name. Start with `verify_result` for one-call acceptance using criteria plus evidence plus your chosen judge or checks. Use `create_spool` and the lifecycle tools only when both parties need to accept inside Spoolis.

### MCP tools

- `verify_result`: Get a signed, durable, portable Outcome Receipt: a verdict artifact, per unit for unitized work, another system can fetch and independently verify. Spoolis makes it by verifying returned work against explicit acceptance criteria. Use when an agent, vendor, or tool reports work as done and the next action depends on whether the delivery actually met the agreed criteria. This runs in one call using exactly one of inline conditions or a locally registered recipe slug and hash, creating an inspectable unilateral Spool, the versioned acceptance policy. The maximum amount field is optional for verification-only runs. Omit it when nobody is paying; the earned amount is then zero and the receipt omits committed value. The maximum amount field is required when unit is present because unit math needs the cap. Recipe verification uses the hosted conditions exactly as written and fails closed when the hash differs. The external provider does not accept conditions in Spoolis. For a batch delivery where items can pass, fail, or remain uncertain individually, pass unit (its unit count matching the item count) AND evidence type dataset with exactly one row per delivered item, keeping a field present with a null value when it is missing; that returns distinct per-unit verdicts and earned value only for passing units. Text evidence with unit is batch-only and settles all-or-nothing. For a keyless production alternative, use POST /api/v1/verify/x402. Sandbox dataset evidence is limited to 100 records. Works in the no-key sandbox.
- `run_sandbox_scenario`: Evaluate Spoolis without a key or account: run a seeded synthetic scenario through a real demo Spool (the agreement object), verification, and a signed demo Outcome Receipt. Use to observe which units may continue after verification and inspect seeded truth only after the Outcome exists. Scenarios: data_enrichment, external_judge_two_consumers, qualified_meetings, production_migration, review_and_dispute, and sources_and_matching. This persists only run parameters and aggregate results; modeled economics are labeled modeled. commercial_state opens and resolves a blocking discrepancy, proving the Outcome moves from uncertain back to accepted. Works in the no-key sandbox.
- `compile_spool`: Turn purchase intent into a proposed DRAFT Spool (the agreement object) with explicit acceptance criteria and earned-value rules. Use before both parties confirm terms; do not use for one-call unilateral result verification. This creates a persisted draft to inspect, then accept_spool confirms it, amend_spool changes conditions or unitization, and abandon_spool discards it. Works in the no-key sandbox.
- `create_spool`: Create a production Spool (the agreement object) from structured terms and acceptance criteria. Use when both parties will participate in the agreement lifecycle; do not use for one-call unilateral verification. This persists a proposed agreement and may send the counterparty invite reported in the response handoff block. The type field defaults to the person or business service path, while agent selects the agent settlement rail. Conditions may declare verification_method third_party with an external_judge so verification consumes your own evaluator's bound result instead of Spoolis judging those conditions. Production only: set SPOOLIS_API_KEY; not available in the no-key sandbox.
- `get_spool`: Read a Spool (the agreement object), including hash-covered evidence requirements, dispute policy, and salted unit identity configuration. Use for status checks; it has no side effects. A party named in who_may_dispute can supersede an issued receipt through POST /api/v1/receipts/{receipt_id}/supersede. There is no review queue or UI. Works in the no-key sandbox.
- `get_receipt_status`: Check whether an Outcome Receipt is still current or has been superseded, before acting on it. Returns state (current, superseded, unknown) and status (active, corrected, revoked). Production only: set SPOOLIS_API_KEY; not available in the no-key sandbox.
- `request_review`: Route receipt units from a Spool (the agreement object) or its whole outcome to a named reviewer. Use when a human decision is required; this creates a review request and hosted link but does not decide it. Production only: set SPOOLIS_API_KEY; not available in the no-key sandbox.
- `get_review`: Read the review request for a Spool (the agreement object). Use to poll its state; it has no side effects. Production only: set SPOOLIS_API_KEY; not available in the no-key sandbox.
- `decide_review`: Decide a pending review for a Spool (the agreement object). Use after inspecting its evidence; this records confirmation or creates a dispute and does not settle payment. Production only: set SPOOLIS_API_KEY; not available in the no-key sandbox.
- `open_dispute`: Open a dispute for a Spool (the agreement object). Use inside its declared window; this records counter-evidence and marks policy-defined value as not currently final or payable. It does not restrict money. Production only: set SPOOLIS_API_KEY; not available in the no-key sandbox.
- `get_dispute`: Read a dispute for a Spool (the agreement object). Use to inspect claimed, accepted, disputed, final, and payable figures plus resolution state; it has no side effects. Production only: set SPOOLIS_API_KEY; not available in the no-key sandbox.
- `list_discrepancies`: Read discrepancies for a Spool (the agreement object). Use for inspecting differences; it has no side effects. Production only: set SPOOLIS_API_KEY; not available in the no-key sandbox.
- `open_discrepancy`: Open a discrepancy for a Spool (the agreement object). Use when expected and observed figures do not reconcile; this records the difference and does not assume either source is wrong. Production only: set SPOOLIS_API_KEY; not available in the no-key sandbox.
- `resolve_discrepancy`: Resolve a discrepancy for a Spool (the agreement object). Use after authority determines the outcome; this records the resolution and does not initiate settlement. Production only: set SPOOLIS_API_KEY; not available in the no-key sandbox.
- `list_sources`: Read source connections for a Spool (the agreement object). Use for source health inspection; it has no side effects. Production only: set SPOOLIS_API_KEY; not available in the no-key sandbox.
- `add_source`: Add a source connection for a Spool (the agreement object). Use before ingestion; this creates a connection and does not ingest evidence. Production only: set SPOOLIS_API_KEY; not available in the no-key sandbox.
- `sync_source`: Sync a source for a Spool (the agreement object). Use after configuration; this creates an idempotent checkpointed job. Production only: set SPOOLIS_API_KEY; not available in the no-key sandbox.
- `list_facts`: Read typed facts for a Spool (the agreement object). Use to inspect observed evidence; it has no side effects. Production only: set SPOOLIS_API_KEY; not available in the no-key sandbox.
- `run_matching`: Run matching for a Spool (the agreement object). Use after claims and facts exist; this records explainable results and discrepancies. Production only: set SPOOLIS_API_KEY; not available in the no-key sandbox.
- `list_matches`: Read matches for a Spool (the agreement object). Use to inspect outcomes and explanations; it has no side effects. Production only: set SPOOLIS_API_KEY; not available in the no-key sandbox.
- `create_counterparty_invite`: Create a 15-minute, single-use grant that lets the other party join a Spool (the agreement object). Use when a counterparty needs scoped access without signing in; do not use as payment authority. This creates a credential that expires after use or 15 minutes. Requires the initiator's full-scope key. Production only: set SPOOLIS_API_KEY; not available in the no-key sandbox.
- `propose_spool`: Move a draft Spool (the agreement object) into the proposed state so the counterparty can review it. Use after the acceptance criteria are ready; this changes agreement state and does not accept terms or settle payment. Production only: set SPOOLIS_API_KEY; not available in the no-key sandbox.
- `accept_spool`: Confirm the compiled contract by accepting a proposed Spool (the agreement object). Use only after reviewing its terms and acceptance criteria; this records agreement acceptance but does not verify fulfillment or settle payment. Production agent agreements require the current quote digest. Works in the no-key sandbox.
- `amend_spool`: Change acceptance criteria or unit-based earned-value rules on a proposed Spool (the agreement object). Use before acceptance when the draft does not match the intended purchase; this replaces proposal details and does not accept or verify the work. Works in the no-key sandbox.
- `abandon_spool`: Abandon an active Spool (the agreement object) before payment is committed. Use when the initiator no longer wants to proceed; this ends the agreement and cannot verify work or settle value. Works in the no-key sandbox.
- `decline_spool`: Decline a proposed Spool (the agreement object). Use when the counterparty rejects its terms; this ends the proposal without accepting it, verifying work, or settling payment. Production only: set SPOOLIS_API_KEY; not available in the no-key sandbox.
- `cancel_spool`: Cancel a Spool (the agreement object) that should not continue. Use only when cancellation is an allowed action; this changes lifecycle state and does not verify fulfillment or settle payment. Production only: set SPOOLIS_API_KEY; not available in the no-key sandbox.
- `commit_payment`: Ask the configured settlement adapter to authorize and, where supported, hold the maximum value for a Spool (the agreement object). Use after terms are accepted when the selected payment path requires commitment; this may create a payment authorization or hold, but does not verify work or determine earned value. Production only: set SPOOLIS_API_KEY; not available in the no-key sandbox.
- `submit_evidence`: Attach fulfillment evidence to an acceptance criterion in a Spool (the agreement object). Use after work is delivered and before verification; this persists evidence but does not decide whether it passes or what was earned. Works in the no-key sandbox.
- `verify_spool`: Issue a signed, durable, portable Outcome Receipt from this Spool, the versioned acceptance policy. The receipt is a verdict artifact, per unit for unitized work, another system can fetch and independently verify. Spoolis makes it by evaluating submitted evidence against the acceptance criteria and determining what was earned. Use after evidence is attached; this records the verdict and required evidence as present, missing, stale, unavailable, or provenance unsatisfied. Missing required evidence defaults to uncertain. Conditions with verification_method third_party keep your own judge: verification consumes the declared external evaluator's result, bound to this agreement and evidence per its declared proof requirement, instead of Spoolis judging those conditions itself. Unitized receipts may include salted public unit identities. Sandbox dataset evidence is limited to 100 records. Canonical recipe: compile -> verify -> Outcome Receipt -> verifyReceipt -> optional status check -> consumer acts on earned. Works in the no-key sandbox.
- `complete_spool`: Read a Spool (the agreement object) whose outcome is already completed. Use for compatibility when a completed result is expected; it has no side effects and does not run verification or settlement. Production only: set SPOOLIS_API_KEY; not available in the no-key sandbox.
- `get_spool_events`: Read the canonical audit history for a Spool (the agreement object), including agreement, fulfillment, verification, and settlement events. Use to reconstruct what happened; it has no side effects. Works in the no-key sandbox.

## Discovery

- Read `/llms.txt` for the concise machine index.
- Read `/llms-full.txt` for the complete public-page dump.
- Every public marketing and content page has a Markdown twin at `<path>.md`, such as `/index.md`.

## Authentication and settlement

Create production API keys after signing in at `/dashboard/api-keys`, then send them as bearer tokens. A machine counterparty can instead exchange a Spool-bound invitation grant without signing in. This credential is agreement identity only. It does not grant settlement or payment authority. Spoolis determines what was earned. The payment authority and configured rail or adapter move money according to their own authorization and execution semantics. A sample or demo transaction is not proof of a real payment.

An agreement may include a hash-covered `dispute_policy`. A party named in `who_may_dispute` can supersede an issued receipt through `POST /api/v1/receipts/{receipt_id}/supersede`. There is no review queue or UI.

## Billing and included usage

The customer model is a free sandbox, then usage-based production acceptance.

Each account includes 10 verification runs and 10 free-text compiles per calendar month. Included usage is consumed first. Paid compile and verification work uses the prepaid usage balance after the allowance is exhausted. Every paid compile or verification is quoted before it runs. Transaction fees are separate.
