{"openapi":"3.1.0","info":{"title":"Agent Work Evidence Network Customer API","version":"v1","description":"Deterministic evidence states only. Not a certification, guarantee, background check, or quality score.\nVerifier awen-verify-1.0.0. HTTP API version v1.\n\n## Versioning and deprecation\n`/api/v1` is the supported customer surface. Breaking changes require `/api/v2`. Additive fields may appear on v1 without a version bump.\n`GET /api/receipts/{receiptId}` is frozen H12 JSON. It sends `Deprecation: true` and `Link` to the v1 successor. Do not build new clients on it.\nOperator routes under `/api/admin/*` are not part of this document and are not a customer integration.\n\n## Authentication\nWorkspace API keys (`awen_…`) go in `Authorization: Bearer`. Keys are shown once; the server stores a hash and prefix only.\nBrowser portal calls use the `awen_session` cookie plus `X-Awen-Workspace-Id`. Cookie calls from a browser must match CSRF origin/host rules. Bearer calls skip CSRF.\nOther-tenant or missing receipts return `404 not_found`, never `403`.\n\n## CORS\nDeny-by-default. Set `AWEN_CORS_ORIGINS` to a comma-separated allowlist of exact origins. Preflight `OPTIONS` returns 204 for allowlisted origins and `403 cors_denied` otherwise.\nAllowed request headers: Authorization, Content-Type, X-Request-Id, X-Awen-Workspace-Id, Idempotency-Key.\nPrefer server-side API keys. CORS is not authorization.\n\n## Errors\nCustomer JSON errors use `{ \"error\", \"code\", \"requestId\" }` plus documented extras (`expectedReceiptId`).\n\n## Rate limits and quotas\nVerify and billed routes send `RateLimit-Limit` and `RateLimit-Remaining`. Exhausted windows add `Retry-After`. Degraded anonymous limiting sets `RateLimit-Policy: degraded`.\nAnonymous verify: 30/day. Workspace verify: 600/hour. Public search JSON: 60/min. Ingest: Pilot 500/day, API 5_000/day when entitlement is active. Public plan ingest quota is 0.\nBilling status is not a truth claim and does not change receipt id or digest.\n\n## 503 limiter_unavailable and retry\nWhen the workspace/admin rate-limiter backend is down, those requests fail closed with HTTP 503 `{ error, code: limiter_unavailable, requestId }` and `Retry-After: 5`.\nRetry rule: wait Retry-After seconds, then exponential backoff (5s, 10s, 20s, 40s, 60s cap). Do not retry in a tight loop. Do not map 503 to quota_exhausted (429).\nAnonymous limiter outages do **not** return 503: they degrade to an in-process 5/min ceiling and 429 `rate_limited` with `RateLimit-Policy: degraded`.\nRoutes that can return 503 limiter_unavailable: POST /api/v1/verify (API key), GET /api/v1/search (API key), POST /api/usage/verify (API key/session), POST /api/workspaces/{workspaceId}/invitations.\nGET /readyz 503 is `not_ready` (process probes), not limiter_unavailable.\n\n## Webhooks (inbound)\n`POST /api/billing/webhook` is called by Stripe (or the test helper). Customers do not send this. Duplicate deliveries return HTTP 200 with `duplicate: true`. Failed payment pauses paid features; receipts remain readable."},"servers":[{"url":"/","description":"Current origin"},{"url":"http://localhost:3000","description":"Local development"}],"tags":[{"name":"Verify","description":"Public verification. Does not store the bundle unless you ingest."},{"name":"Receipts","description":"Stored receipt views. Tenant isolation; other-tenant is 404."},{"name":"Ingest","description":"Production ingest and artifacts. Paid entitlement required."},{"name":"Library","description":"Workspace receipt list, public listing, share, export."},{"name":"Keys","description":"Workspace API keys. Secret shown once."},{"name":"Billing","description":"Checkout, portal, history. Not evidence truth."},{"name":"Account","description":"Magic link, session, workspaces, invitations."},{"name":"Ops","description":"Liveness and readiness."}],"paths":{"/healthz":{"get":{"operationId":"getHealthz","summary":"Liveness","tags":["Ops"],"description":"**Auth:** Public. No API key.\n\n**Limit:** Unauthenticated. No payload.","security":[],"x-awen-auth":"public","x-awen-limit":"Unauthenticated. No payload.","responses":{"200":{"description":"Process is up","content":{"application/json":{"examples":{"demo":{"value":{"ok":true,"name":"agent-work-evidence-network","version":"0.1.0"}}}}}},"500":{"description":"internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"internal error","code":"internal_error","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/readyz":{"get":{"operationId":"getReadyz","summary":"Readiness","tags":["Ops"],"description":"Demo mode is always ready. Production checks database, migrations, object store, limiter, billing config, and identity. HTTP 503 here is `not_ready` (probe failure), not `limiter_unavailable`.\n\n**Auth:** Public. No API key.\n\n**Limit:** Unauthenticated. No payload.","security":[],"x-awen-auth":"public","x-awen-limit":"Unauthenticated. No payload.","responses":{"200":{"description":"Ready","content":{"application/json":{"examples":{"demo":{"value":{"ready":true,"mode":"demo","label":"DEMO MODE — not a paid environment. DATABASE_URL and live billing are optional."}}}}}},"503":{"description":"not ready (production probes failed)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"not ready","code":"not_ready","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/status":{"get":{"operationId":"getStatus","summary":"Customer status page data is HTML; this path is the public status surface","tags":["Ops"],"description":"Customer-facing status. Billing outages are entitlement, not evidence-state changes.\n\n**Auth:** Public. No API key.\n\n**Limit:** Unauthenticated HTML. No secrets.","security":[],"x-awen-auth":"public","x-awen-limit":"Unauthenticated HTML. No secrets.","responses":{"200":{"description":"HTML status page","content":{"application/json":{"examples":{"demo":{"value":{"ok":true}}}}}},"500":{"description":"internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"internal error","code":"internal_error","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/feedback":{"post":{"operationId":"submitFeedback","summary":"Submit product feedback (no API key)","tags":["Account"],"description":"**Auth:** Public. No API key.\n\n**Limit:** 8 KiB JSON. 10 per hashed IP per hour. Message is hashed; API keys must not be sent.","security":[],"x-awen-auth":"public","x-awen-limit":"8 KiB JSON. 10 per hashed IP per hour. Message is hashed; API keys must not be sent.","requestBody":{"required":true,"content":{"application/json":{"examples":{"note":{"value":{"message":"Export button was hard to find on mobile."}}}}}},"responses":{"200":{"description":"Accepted","content":{"application/json":{"examples":{"demo":{"value":{"requestId":"00000000-0000-4000-8000-000000000001","ok":true,"message":"Received. Do not include API keys or session cookies."}}}}}},"422":{"description":"message required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"message required","code":"schema_invalid","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"429":{"description":"too many requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"too many requests","code":"rate_limited","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/v1/openapi.json":{"get":{"operationId":"getOpenApiV1","summary":"OpenAPI 3.1 description of the customer API","tags":["Ops"],"description":"Customer routes only. `/api/admin/*` is omitted.\n\n**Auth:** Public. No API key.\n\n**Limit:** Unauthenticated. Document size is bounded by this process.","security":[],"x-awen-auth":"public","x-awen-limit":"Unauthenticated. Document size is bounded by this process.","responses":{"200":{"description":"OpenAPI document","content":{"application/json":{"examples":{"demo":{"value":{"openapi":"3.1.0","info":{"version":"v1"}}}}}}},"500":{"description":"internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"internal error","code":"internal_error","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/v1/examples/evidence-bundle":{"get":{"operationId":"getExampleEvidenceBundle","summary":"Sample EvidenceBundleV0 for the 15-minute verify path","tags":["Verify"],"description":"Synthetic demo fixture. Not live platform data and not a certification.\n\n**Auth:** Public. No API key.\n\n**Limit:** Unauthenticated. Fixture size well under 256 KiB.","security":[],"x-awen-auth":"public","x-awen-limit":"Unauthenticated. Fixture size well under 256 KiB.","responses":{"200":{"description":"EvidenceBundleV0 JSON","content":{"application/json":{"examples":{"demo":{"value":{"schemaVersion":"EvidenceBundleV0","receiptId":"sha256:751f744d21be1f38defbc3abeac1b7deb71fc572fec9eb9b282e21b5763470c4"}}}}}},"500":{"description":"internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"internal error","code":"internal_error","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/v1/verify":{"post":{"operationId":"verifyBundleV1","summary":"Verify a submitted EvidenceBundleV0 JSON","tags":["Verify"],"description":"Recomputes the H01 canonical receiptId. Mismatch is 422 receipt_id_mismatch (body may include expectedReceiptId). Locators with credentials or secret query parameters are 422 locator_secret. Responses are byte-stable; no request timestamps are added. The bundle is not stored.\n\n**Auth:** Public. No API key.\n\n**Limit:** 256 KiB streamed body. Anonymous 30/day. Workspace API key 600/hour. RateLimit-* headers.\n\n**Limiter outage:** API key / workspace / admin → 503 limiter_unavailable with Retry-After: 5. Then exponential backoff, cap 60s. Anonymous → 429 with RateLimit-Policy: degraded (5/min in-process), not 503. Never a silent bypass.","security":[],"x-awen-auth":"public","x-awen-limit":"256 KiB streamed body. Anonymous 30/day. Workspace API key 600/hour. RateLimit-* headers.","x-awen-limiter-outage":"both","parameters":[{"name":"X-Request-Id","in":"header","required":false,"schema":{"type":"string"},"description":"Optional client correlation id. Echoed on errors as requestId."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"EvidenceBundleV0"},"examples":{"sample":{"summary":"Use GET /api/v1/examples/evidence-bundle for the full fixture","value":{"schemaVersion":"EvidenceBundleV0","receiptId":"sha256:751f744d21be1f38defbc3abeac1b7deb71fc572fec9eb9b282e21b5763470c4"}}}}}},"responses":{"200":{"description":"Verification view","content":{"application/json":{"examples":{"demo":{"value":{"apiVersion":"v1","verifierVersion":"awen-verify-1.0.0","receiptId":"sha256:751f744d21be1f38defbc3abeac1b7deb71fc572fec9eb9b282e21b5763470c4","sourceSystem":"synthetic","observedAt":"2026-08-01T12:00:00.000Z","jobSourceId":"job-gold-001","tier":"Silver","overallState":"platform_asserted","validReceipt":true,"areas":[{"area":"identity","state":"platform_asserted","reasons":["platform-asserted evidence only"]},{"area":"task","state":"platform_asserted","reasons":["platform-asserted evidence only"]},{"area":"deliverable","state":"unavailable","reasons":["no independent or platform evidence for this area"]},{"area":"settlement","state":"verified","reasons":["independent chain or artifact hash evidence"]},{"area":"evaluation","state":"platform_asserted","reasons":["platform-asserted evidence only"]}],"conflicts":[],"missing":[],"disclaimer":"Evidence state only. Not a certification, guarantee, background check, or quality score."}}}}}},"413":{"description":"payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"payload too large","code":"payload_too_large","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"415":{"description":"unsupported media type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"unsupported media type","code":"unsupported_media_type","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"422":{"description":"schema invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"schema invalid","code":"schema_invalid","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"429":{"description":"rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"rate limited","code":"rate_limited","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"500":{"description":"internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"internal error","code":"internal_error","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"503":{"description":"Workspace/API-key limiter outage. Fail closed. Retry using Retry-After then exponential backoff capped at 60s.","headers":{"Retry-After":{"schema":{"type":"integer","minimum":1,"example":5},"description":"Wait this many seconds before the first retry (runtime sends 5). Then exponential backoff (2s, 4s, 8s, …) capped at 60s. Do not retry immediately. Do not treat as quota_exhausted."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"rate limiter unavailable","code":"limiter_unavailable","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/v1/search":{"get":{"operationId":"searchPublicListedV1","summary":"Search public-listed receipts","tags":["Receipts"],"description":"Only receipts with public_listed=true. Filter/sort/page run in the search index (Postgres when configured). Exact identity keys only; names are not merged.\n\n**Auth:** Public. No API key.\n\n**Limit:** limit 1–50 (default 20). offset 0–10000. Anonymous 60 requests/minute.\n\n**Limiter outage:** API key / workspace / admin → 503 limiter_unavailable with Retry-After: 5. Then exponential backoff, cap 60s. Anonymous → 429 with RateLimit-Policy: degraded (5/min in-process), not 503. Never a silent bypass.","security":[],"x-awen-auth":"public","x-awen-limit":"limit 1–50 (default 20). offset 0–10000. Anonymous 60 requests/minute.","x-awen-limiter-outage":"both","parameters":[{"name":"X-Request-Id","in":"header","required":false,"schema":{"type":"string"},"description":"Optional client correlation id. Echoed on errors as requestId."},{"name":"agentId","in":"query","schema":{"type":"string"}},{"name":"providerAddress","in":"query","schema":{"type":"string"},"description":"0x-prefixed 20-byte address"},{"name":"sourceSystem","in":"query","schema":{"type":"string"}},{"name":"jobId","in":"query","schema":{"type":"string"}},{"name":"observedFrom","in":"query","schema":{"type":"string"}},{"name":"observedTo","in":"query","schema":{"type":"string"}},{"name":"tier","in":"query","schema":{"type":"string"}},{"name":"overallState","in":"query","schema":{"type":"string","enum":["verified","platform_asserted","unavailable","conflict"]}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":50}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"maximum":10000}}],"responses":{"200":{"description":"Public search page","content":{"application/json":{"examples":{"demo":{"value":{"requestId":"00000000-0000-4000-8000-000000000001","apiVersion":"v1","total":1,"limit":20,"offset":0,"hasMore":false,"hits":[{"receiptId":"sha256:751f744d21be1f38defbc3abeac1b7deb71fc572fec9eb9b282e21b5763470c4","sourceSystem":"synthetic","jobSourceId":"job-gold-001","observedAt":"2026-08-01T12:00:00.000Z","tier":"Silver","overallState":"platform_asserted"}],"note":"Public listed receipts only. Evidence state is not a certification."}}}}}},"422":{"description":"invalid query","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"invalid query","code":"schema_invalid","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"429":{"description":"rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"rate limited","code":"rate_limited","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"500":{"description":"internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"internal error","code":"internal_error","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"503":{"description":"Workspace/API-key limiter outage. Fail closed. Retry using Retry-After then exponential backoff capped at 60s.","headers":{"Retry-After":{"schema":{"type":"integer","minimum":1,"example":5},"description":"Wait this many seconds before the first retry (runtime sends 5). Then exponential backoff (2s, 4s, 8s, …) capped at 60s. Do not retry immediately. Do not treat as quota_exhausted."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"rate limiter unavailable","code":"limiter_unavailable","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/v1/receipts/{receiptId}":{"get":{"operationId":"getReceiptV1","summary":"Get a stored receipt view and evidence matrix","tags":["Receipts"],"description":"**Auth:** Public. No API key.\n\n**Limit:** Path id only. Accessible if owned, public_listed, or shared to the caller.","security":[],"x-awen-auth":"public","x-awen-limit":"Path id only. Accessible if owned, public_listed, or shared to the caller.","parameters":[{"name":"receiptId","in":"path","required":true,"schema":{"type":"string"},"description":"sha256:<64 hex> or sha256/<64 hex>","example":"sha256:751f744d21be1f38defbc3abeac1b7deb71fc572fec9eb9b282e21b5763470c4"},{"name":"X-Request-Id","in":"header","required":false,"schema":{"type":"string"},"description":"Optional client correlation id. Echoed on errors as requestId."}],"responses":{"200":{"description":"Receipt view","content":{"application/json":{"examples":{"demo":{"value":{"apiVersion":"v1","verifierVersion":"awen-verify-1.0.0","receiptId":"sha256:751f744d21be1f38defbc3abeac1b7deb71fc572fec9eb9b282e21b5763470c4","sourceSystem":"synthetic","observedAt":"2026-08-01T12:00:00.000Z","jobSourceId":"job-gold-001","tier":"Silver","overallState":"platform_asserted","validReceipt":true,"areas":[{"area":"identity","state":"platform_asserted","reasons":["platform-asserted evidence only"]},{"area":"task","state":"platform_asserted","reasons":["platform-asserted evidence only"]},{"area":"deliverable","state":"unavailable","reasons":["no independent or platform evidence for this area"]},{"area":"settlement","state":"verified","reasons":["independent chain or artifact hash evidence"]},{"area":"evaluation","state":"platform_asserted","reasons":["platform-asserted evidence only"]}],"conflicts":[],"missing":[],"disclaimer":"Evidence state only. Not a certification, guarantee, background check, or quality score."}}}}}},"400":{"description":"invalid receipt id","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"invalid receipt id","code":"invalid_receipt_id","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"404":{"description":"not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"not found","code":"not_found","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"500":{"description":"internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"internal error","code":"internal_error","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/v1/receipts/{receiptId}/evidence":{"get":{"operationId":"getReceiptEvidenceV1","summary":"Compact evidence references (no raw artifact bytes)","tags":["Receipts"],"description":"**Auth:** Public. No API key.\n\n**Limit:** Path id only. Locators are redacted of secrets.","security":[],"x-awen-auth":"public","x-awen-limit":"Path id only. Locators are redacted of secrets.","parameters":[{"name":"receiptId","in":"path","required":true,"schema":{"type":"string"},"description":"sha256:<64 hex> or sha256/<64 hex>","example":"sha256:751f744d21be1f38defbc3abeac1b7deb71fc572fec9eb9b282e21b5763470c4"}],"responses":{"200":{"description":"Evidence references","content":{"application/json":{"examples":{"demo":{"value":{"receiptId":"sha256:751f744d21be1f38defbc3abeac1b7deb71fc572fec9eb9b282e21b5763470c4","overallState":"platform_asserted","areas":[{"area":"identity","state":"platform_asserted","reasons":["platform-asserted evidence only"]},{"area":"task","state":"platform_asserted","reasons":["platform-asserted evidence only"]},{"area":"deliverable","state":"unavailable","reasons":["no independent or platform evidence for this area"]},{"area":"settlement","state":"verified","reasons":["independent chain or artifact hash evidence"]},{"area":"evaluation","state":"platform_asserted","reasons":["platform-asserted evidence only"]}],"evidence":[{"locator":"sha256:ab","evidenceType":"artifact"}]}}}}}},"400":{"description":"invalid receipt id","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"invalid receipt id","code":"invalid_receipt_id","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"404":{"description":"not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"not found","code":"not_found","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/receipts/{receiptId}":{"get":{"operationId":"getReceiptH12Compat","summary":"Deprecated H12 receipt JSON","tags":["Receipts"],"description":"Unchanged H12 JSON (no apiVersion / verifierVersion). Sends Deprecation: true and Link successor-version to /api/v1/receipts/{id}.\n\n**Auth:** Public. No API key.\n\n**Limit:** Same access rules as v1. Do not use for new clients.","security":[],"x-awen-auth":"public","x-awen-limit":"Same access rules as v1. Do not use for new clients.","deprecated":true,"parameters":[{"name":"receiptId","in":"path","required":true,"schema":{"type":"string"},"description":"sha256:<64 hex> or sha256/<64 hex>","example":"sha256:751f744d21be1f38defbc3abeac1b7deb71fc572fec9eb9b282e21b5763470c4"}],"responses":{"200":{"description":"H12 receipt JSON","content":{"application/json":{"examples":{"demo":{"value":{"receiptId":"sha256:751f744d21be1f38defbc3abeac1b7deb71fc572fec9eb9b282e21b5763470c4","sourceSystem":"synthetic","overallState":"platform_asserted","validReceipt":true}}}}}},"400":{"description":"invalid receipt id","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"invalid receipt id","code":"invalid_receipt_id","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"404":{"description":"not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"not found","code":"not_found","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/v1/ingest":{"post":{"operationId":"createIngestJob","summary":"Submit a bundle, generic JSON/CSV, or connector job","tags":["Ingest"],"description":"Connectors (inline JSON only; live fetch and fixturePath are rejected):\n- EvidenceBundleV0 (`schemaVersion` or `kind: bundle`)\n- GenericReceiptInputV0 JSON or `Content-Type: text/csv`\n- Taskmarket `{ kind: taskmarket, task, award }`\n- Virtuals `{ kind: virtuals, job }`\nOversized or malformed input is quarantined by digest only (no payload, no receipt row).\nSession callers need ingest permission. Use POST /api/v1/artifacts for blobs.\n\n**Auth:** Authorization: Bearer awen_… or session cookie + X-Awen-Workspace-Id.\n\n**Limit:** 1 MiB streamed. Idempotency-Key ≤ 128 chars. Pilot 500/day, API 5_000/day when active. Public plan quota 0. HTTP 600/min per workspace (60/min public).\n\n**Limiter outage:** 503 limiter_unavailable (fail closed) with Retry-After: 5. Exponential backoff, cap 60s. Not quota_exhausted.","security":[{"BearerApiKey":[]},{"SessionCookie":[]}],"x-awen-auth":"apiKeyOrSession","x-awen-limit":"1 MiB streamed. Idempotency-Key ≤ 128 chars. Pilot 500/day, API 5_000/day when active. Public plan quota 0. HTTP 600/min per workspace (60/min public).","x-awen-limiter-outage":"workspace","parameters":[{"name":"X-Request-Id","in":"header","required":false,"schema":{"type":"string"},"description":"Optional client correlation id. Echoed on errors as requestId."},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":128},"description":"Replay the original ingest or checkout job. Unique per workspace."}],"requestBody":{"required":true,"content":{"application/json":{"examples":{"bundle":{"value":{"schemaVersion":"EvidenceBundleV0","receiptId":"sha256:751f744d21be1f38defbc3abeac1b7deb71fc572fec9eb9b282e21b5763470c4"}},"generic":{"value":{"kind":"generic","schemaVersion":"GenericReceiptInputV0"}}}},"text/csv":{"examples":{"csv":{"value":"job.id,job.status\njob-1,completed\n"}}}}},"responses":{"200":{"description":"Job accepted or completed","content":{"application/json":{"examples":{"demo":{"value":{"requestId":"00000000-0000-4000-8000-000000000002","jobId":"job_01example0000000000000000","workspaceId":"ws_01example0000000000000000","kind":"bundle","state":"completed","createdAt":"2026-08-01T12:00:00.000Z","updatedAt":"2026-08-01T12:00:00.000Z","receiptId":"sha256:751f744d21be1f38defbc3abeac1b7deb71fc572fec9eb9b282e21b5763470c4","inputDigest":"sha256:31945942324f0000000000000000000000000000000000000000000000004b56"}}}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"unauthorized","code":"unauthorized","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"forbidden","code":"forbidden","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"413":{"description":"payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"payload too large","code":"payload_too_large","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"415":{"description":"unsupported media type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"unsupported media type","code":"unsupported_media_type","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"422":{"description":"schema invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"schema invalid","code":"schema_invalid","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"429":{"description":"rate_limited (HTTP window) or quota_exhausted (daily ingest)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"rate_limited (HTTP window) or quota_exhausted (daily ingest)","code":"rate_limited","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"503":{"description":"Workspace/API-key limiter outage. Fail closed. Retry using Retry-After then exponential backoff capped at 60s.","headers":{"Retry-After":{"schema":{"type":"integer","minimum":1,"example":5},"description":"Wait this many seconds before the first retry (runtime sends 5). Then exponential backoff (2s, 4s, 8s, …) capped at 60s. Do not retry immediately. Do not treat as quota_exhausted."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"rate limiter unavailable","code":"limiter_unavailable","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}},"get":{"operationId":"listIngestJobs","summary":"List recent ingest jobs for the workspace","tags":["Ingest"],"description":"**Auth:** Authorization: Bearer awen_… or session cookie + X-Awen-Workspace-Id.\n\n**Limit:** 20 most recent jobs.","security":[{"BearerApiKey":[]},{"SessionCookie":[]}],"x-awen-auth":"apiKeyOrSession","x-awen-limit":"20 most recent jobs.","parameters":[{"name":"X-Request-Id","in":"header","required":false,"schema":{"type":"string"},"description":"Optional client correlation id. Echoed on errors as requestId."}],"responses":{"200":{"description":"Job list","content":{"application/json":{"examples":{"demo":{"value":{"requestId":"00000000-0000-4000-8000-000000000001","jobs":[{"requestId":"00000000-0000-4000-8000-000000000002","jobId":"job_01example0000000000000000","workspaceId":"ws_01example0000000000000000","kind":"bundle","state":"completed","createdAt":"2026-08-01T12:00:00.000Z","updatedAt":"2026-08-01T12:00:00.000Z","receiptId":"sha256:751f744d21be1f38defbc3abeac1b7deb71fc572fec9eb9b282e21b5763470c4","inputDigest":"sha256:31945942324f0000000000000000000000000000000000000000000000004b56"}]}}}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"unauthorized","code":"unauthorized","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"404":{"description":"not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"not found","code":"not_found","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/v1/ingest/{jobId}":{"get":{"operationId":"getIngestJob","summary":"Get ingest job state","tags":["Ingest"],"description":"**Auth:** Authorization: Bearer awen_… or session cookie + X-Awen-Workspace-Id.\n\n**Limit:** Path id only. Other-workspace jobs are 404.","security":[{"BearerApiKey":[]},{"SessionCookie":[]}],"x-awen-auth":"apiKeyOrSession","x-awen-limit":"Path id only. Other-workspace jobs are 404.","parameters":[{"name":"X-Request-Id","in":"header","required":false,"schema":{"type":"string"},"description":"Optional client correlation id. Echoed on errors as requestId."},{"name":"jobId","in":"path","required":true,"schema":{"type":"string"},"example":"job_01example0000000000000000"}],"responses":{"200":{"description":"Job","content":{"application/json":{"examples":{"demo":{"value":{"requestId":"00000000-0000-4000-8000-000000000002","jobId":"job_01example0000000000000000","workspaceId":"ws_01example0000000000000000","kind":"bundle","state":"completed","createdAt":"2026-08-01T12:00:00.000Z","updatedAt":"2026-08-01T12:00:00.000Z","receiptId":"sha256:751f744d21be1f38defbc3abeac1b7deb71fc572fec9eb9b282e21b5763470c4","inputDigest":"sha256:31945942324f0000000000000000000000000000000000000000000000004b56"}}}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"unauthorized","code":"unauthorized","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"404":{"description":"not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"not found","code":"not_found","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/v1/artifacts":{"post":{"operationId":"uploadArtifact","summary":"Upload a content-addressed artifact blob","tags":["Ingest"],"description":"Stores sha256/<hex>. Does not create a receipt by itself. Paid ingest entitlement required.\n\n**Auth:** Authorization: Bearer awen_… or session cookie + X-Awen-Workspace-Id.\n\n**Limit:** 8 MiB. Allowed types: application/octet-stream, application/pdf, image/png, image/jpeg, text/plain. Zip/tar/gzip rejected. HTTP 600/min per workspace.\n\n**Limiter outage:** 503 limiter_unavailable (fail closed) with Retry-After: 5. Exponential backoff, cap 60s. Not quota_exhausted.","security":[{"BearerApiKey":[]},{"SessionCookie":[]}],"x-awen-auth":"apiKeyOrSession","x-awen-limit":"8 MiB. Allowed types: application/octet-stream, application/pdf, image/png, image/jpeg, text/plain. Zip/tar/gzip rejected. HTTP 600/min per workspace.","x-awen-limiter-outage":"workspace","parameters":[{"name":"X-Request-Id","in":"header","required":false,"schema":{"type":"string"},"description":"Optional client correlation id. Echoed on errors as requestId."}],"requestBody":{"required":true,"content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"responses":{"200":{"description":"Stored digest","content":{"application/json":{"examples":{"demo":{"value":{"requestId":"00000000-0000-4000-8000-000000000001","jobId":"job_01artifact00000000000000","state":"completed","digest":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","byteLength":12}}}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"unauthorized","code":"unauthorized","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"forbidden","code":"forbidden","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"413":{"description":"payload exceeds 8 MiB","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"payload exceeds 8 MiB","code":"payload_too_large","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"415":{"description":"unsupported file type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"unsupported file type","code":"unsupported_media_type","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"422":{"description":"empty body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"empty body","code":"schema_invalid","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"429":{"description":"rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"rate limited","code":"rate_limited","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"503":{"description":"Workspace/API-key limiter outage. Fail closed. Retry using Retry-After then exponential backoff capped at 60s.","headers":{"Retry-After":{"schema":{"type":"integer","minimum":1,"example":5},"description":"Wait this many seconds before the first retry (runtime sends 5). Then exponential backoff (2s, 4s, 8s, …) capped at 60s. Do not retry immediately. Do not treat as quota_exhausted."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"rate limiter unavailable","code":"limiter_unavailable","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/auth/magic-link":{"post":{"operationId":"requestMagicLink","summary":"Request a sign-in or recovery link","tags":["Account"],"description":"**Auth:** Public. No API key.\n\n**Limit:** 10 requests per IP per hour. Always returns the same message. Anonymous limiter outage degrades to 5/min (429 RateLimit-Policy: degraded), not 503.","security":[],"x-awen-auth":"public","x-awen-limit":"10 requests per IP per hour. Always returns the same message. Anonymous limiter outage degrades to 5/min (429 RateLimit-Policy: degraded), not 503.","requestBody":{"required":true,"content":{"application/json":{"examples":{"login":{"value":{"email":"ada@example.com","purpose":"login"}}}}}},"responses":{"200":{"description":"Accepted","content":{"application/json":{"examples":{"demo":{"value":{"ok":true,"message":"If that address can be used, we sent a link.","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"422":{"description":"email required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"email required","code":"schema_invalid","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"429":{"description":"too many requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"too many requests","code":"rate_limited","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/auth/logout":{"post":{"operationId":"logout","summary":"End the browser session","tags":["Account"],"description":"**Auth:** Session cookie + X-Awen-Workspace-Id. Workspace admin where noted.\n\n**Limit:** CSRF origin must match Host for cookie calls.","security":[{"SessionCookie":[]}],"x-awen-auth":"session","x-awen-limit":"CSRF origin must match Host for cookie calls.","responses":{"200":{"description":"Logged out","content":{"application/json":{"examples":{"demo":{"value":{"ok":true,"requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"403":{"description":"csrf rejected","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"csrf rejected","code":"csrf_rejected","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/me":{"get":{"operationId":"getMe","summary":"Current user and memberships","tags":["Account"],"description":"**Auth:** Session cookie + X-Awen-Workspace-Id. Workspace admin where noted.\n\n**Limit:** Session cookie required.","security":[{"SessionCookie":[]}],"x-awen-auth":"session","x-awen-limit":"Session cookie required.","responses":{"200":{"description":"Principal","content":{"application/json":{"examples":{"demo":{"value":{"requestId":"00000000-0000-4000-8000-000000000001","user":{"id":"usr_01","email":"ada@example.com"},"memberships":[{"workspaceId":"ws_01example0000000000000000","role":"admin"}]}}}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"unauthorized","code":"unauthorized","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/workspaces":{"get":{"operationId":"listWorkspaces","summary":"List workspaces for the session","tags":["Account"],"description":"**Auth:** Session cookie + X-Awen-Workspace-Id. Workspace admin where noted.\n\n**Limit:** Active memberships only.","security":[{"SessionCookie":[]}],"x-awen-auth":"session","x-awen-limit":"Active memberships only.","responses":{"200":{"description":"Workspaces","content":{"application/json":{"examples":{"demo":{"value":{"requestId":"00000000-0000-4000-8000-000000000001","workspaces":[{"id":"ws_01example0000000000000000","name":"Pilot Co","plan":"pilot","role":"admin"}]}}}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"unauthorized","code":"unauthorized","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}},"post":{"operationId":"createWorkspace","summary":"Create a workspace","tags":["Account"],"description":"**Auth:** Session cookie + X-Awen-Workspace-Id. Workspace admin where noted.\n\n**Limit:** Subject to workspace quota on the account.","security":[{"SessionCookie":[]}],"x-awen-auth":"session","x-awen-limit":"Subject to workspace quota on the account.","requestBody":{"required":true,"content":{"application/json":{"examples":{"named":{"value":{"name":"Pilot Co"}}}}}},"responses":{"200":{"description":"Created","content":{"application/json":{"examples":{"demo":{"value":{"requestId":"00000000-0000-4000-8000-000000000001","workspaceId":"ws_01example0000000000000000","role":"admin"}}}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"unauthorized","code":"unauthorized","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"429":{"description":"workspace limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"workspace limit","code":"quota_exhausted","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/workspaces/{workspaceId}/invitations":{"post":{"operationId":"inviteMember","summary":"Invite a member","tags":["Account"],"description":"**Auth:** Session cookie + X-Awen-Workspace-Id. Workspace admin where noted.\n\n**Limit:** 20 invites per workspace per hour.\n\n**Limiter outage:** 503 limiter_unavailable (fail closed) with Retry-After: 5. Exponential backoff, cap 60s. Not quota_exhausted.","security":[{"SessionCookie":[]}],"x-awen-auth":"session","x-awen-limit":"20 invites per workspace per hour.","x-awen-limiter-outage":"workspace","parameters":[{"name":"workspaceId","in":"path","required":true,"schema":{"type":"string"},"example":"ws_01example0000000000000000"}],"requestBody":{"required":true,"content":{"application/json":{"examples":{"member":{"value":{"email":"eng@example.com","role":"member"}}}}}},"responses":{"200":{"description":"Invitation created","content":{"application/json":{"examples":{"demo":{"value":{"requestId":"00000000-0000-4000-8000-000000000001","invitationId":"inv_01"}}}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"unauthorized","code":"unauthorized","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"422":{"description":"email required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"email required","code":"schema_invalid","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"429":{"description":"too many requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"too many requests","code":"rate_limited","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"503":{"description":"Workspace/API-key limiter outage. Fail closed. Retry using Retry-After then exponential backoff capped at 60s.","headers":{"Retry-After":{"schema":{"type":"integer","minimum":1,"example":5},"description":"Wait this many seconds before the first retry (runtime sends 5). Then exponential backoff (2s, 4s, 8s, …) capped at 60s. Do not retry immediately. Do not treat as quota_exhausted."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"rate limiter unavailable","code":"limiter_unavailable","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/workspaces/{workspaceId}/keys":{"get":{"operationId":"listWorkspaceKeys","summary":"List API key prefixes","tags":["Keys"],"description":"**Auth:** Session cookie + X-Awen-Workspace-Id. Workspace admin where noted.\n\n**Limit:** Pilot 2 keys, API plan 10. Secrets are never listed.","security":[{"SessionCookie":[]}],"x-awen-auth":"session","x-awen-limit":"Pilot 2 keys, API plan 10. Secrets are never listed.","parameters":[{"name":"workspaceId","in":"path","required":true,"schema":{"type":"string"},"example":"ws_01example0000000000000000"}],"responses":{"200":{"description":"Prefixes","content":{"application/json":{"examples":{"demo":{"value":{"requestId":"00000000-0000-4000-8000-000000000001","keys":[{"prefix":"awen_AbCdEf","createdAt":"2026-08-01T12:00:00.000Z"}]}}}}}},"404":{"description":"not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"not found","code":"not_found","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}},"post":{"operationId":"createWorkspaceKey","summary":"Create an API key (secret returned once)","tags":["Keys"],"description":"**Auth:** Session cookie + X-Awen-Workspace-Id. Workspace admin where noted.\n\n**Limit:** Workspace admin. Pilot 2 keys, API plan 10.","security":[{"SessionCookie":[]}],"x-awen-auth":"session","x-awen-limit":"Workspace admin. Pilot 2 keys, API plan 10.","parameters":[{"name":"workspaceId","in":"path","required":true,"schema":{"type":"string"},"example":"ws_01example0000000000000000"}],"responses":{"200":{"description":"Secret shown once","content":{"application/json":{"examples":{"demo":{"value":{"requestId":"00000000-0000-4000-8000-000000000001","prefix":"awen_AbCdEf","createdAt":"2026-08-01T12:00:00.000Z","apiKey":"awen_REDACTED_EXAMPLE_NOT_A_REAL_KEY","note":"Store this API key now. We only keep a hash."}}}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"forbidden","code":"forbidden","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"429":{"description":"API key limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"API key limit","code":"quota_exhausted","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/workspaces/{workspaceId}/keys/rotate":{"post":{"operationId":"rotateWorkspaceKey","summary":"Revoke a key and issue a replacement","tags":["Keys"],"description":"**Auth:** Session cookie + X-Awen-Workspace-Id. Workspace admin where noted.\n\n**Limit:** Workspace admin. New secret returned once.","security":[{"SessionCookie":[]}],"x-awen-auth":"session","x-awen-limit":"Workspace admin. New secret returned once.","parameters":[{"name":"workspaceId","in":"path","required":true,"schema":{"type":"string"},"example":"ws_01example0000000000000000"}],"requestBody":{"required":true,"content":{"application/json":{"examples":{"rotate":{"value":{"keyHash":"sha256:…"}}}}}},"responses":{"200":{"description":"New secret shown once","content":{"application/json":{"examples":{"demo":{"value":{"requestId":"00000000-0000-4000-8000-000000000001","prefix":"awen_NewPrefx","apiKey":"awen_REDACTED_EXAMPLE_NOT_A_REAL_KEY","note":"Store this API key now. We only keep a hash."}}}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"forbidden","code":"forbidden","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"422":{"description":"keyHash required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"keyHash required","code":"schema_invalid","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/workspaces/{workspaceId}/keys/revoke":{"post":{"operationId":"revokeWorkspaceKey","summary":"Revoke an API key immediately","tags":["Keys"],"description":"**Auth:** Session cookie + X-Awen-Workspace-Id. Workspace admin where noted.\n\n**Limit:** Workspace admin.","security":[{"SessionCookie":[]}],"x-awen-auth":"session","x-awen-limit":"Workspace admin.","parameters":[{"name":"workspaceId","in":"path","required":true,"schema":{"type":"string"},"example":"ws_01example0000000000000000"}],"requestBody":{"required":true,"content":{"application/json":{"examples":{"revoke":{"value":{"keyHash":"sha256:…"}}}}}},"responses":{"200":{"description":"Revoked","content":{"application/json":{"examples":{"demo":{"value":{"requestId":"00000000-0000-4000-8000-000000000001","ok":true,"revoked":true}}}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"forbidden","code":"forbidden","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"422":{"description":"keyHash required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"keyHash required","code":"schema_invalid","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/workspaces/{workspaceId}/receipts":{"get":{"operationId":"listWorkspaceReceipts","summary":"List receipts owned by the workspace","tags":["Library"],"description":"**Auth:** Session cookie + X-Awen-Workspace-Id. Workspace admin where noted.\n\n**Limit:** limit 1–50 (default 20). Active members only. Other workspace id is 404.","security":[{"SessionCookie":[]}],"x-awen-auth":"session","x-awen-limit":"limit 1–50 (default 20). Active members only. Other workspace id is 404.","parameters":[{"name":"workspaceId","in":"path","required":true,"schema":{"type":"string"},"example":"ws_01example0000000000000000"},{"name":"sourceSystem","in":"query","schema":{"type":"string"}},{"name":"overallState","in":"query","schema":{"type":"string"}},{"name":"receiptId","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer"}},{"name":"offset","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"Library page","content":{"application/json":{"examples":{"demo":{"value":{"requestId":"00000000-0000-4000-8000-000000000001","total":1,"limit":20,"offset":0,"hasMore":false,"receipts":[{"receiptId":"sha256:751f744d21be1f38defbc3abeac1b7deb71fc572fec9eb9b282e21b5763470c4","publicListed":false,"overallState":"platform_asserted","tier":"Silver"}]}}}}}},"404":{"description":"not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"not found","code":"not_found","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"422":{"description":"invalid query","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"invalid query","code":"schema_invalid","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/workspaces/{workspaceId}/receipts/public":{"post":{"operationId":"setReceiptPublicListed","summary":"Set public_listed on an owned receipt","tags":["Library"],"description":"**Auth:** Session cookie + X-Awen-Workspace-Id. Workspace admin where noted.\n\n**Limit:** Workspace admin.","security":[{"SessionCookie":[]}],"x-awen-auth":"session","x-awen-limit":"Workspace admin.","parameters":[{"name":"workspaceId","in":"path","required":true,"schema":{"type":"string"},"example":"ws_01example0000000000000000"}],"requestBody":{"required":true,"content":{"application/json":{"examples":{"list":{"value":{"receiptId":"sha256:751f744d21be1f38defbc3abeac1b7deb71fc572fec9eb9b282e21b5763470c4","publicListed":true}}}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"examples":{"demo":{"value":{"requestId":"00000000-0000-4000-8000-000000000001","receiptId":"sha256:751f744d21be1f38defbc3abeac1b7deb71fc572fec9eb9b282e21b5763470c4","publicListed":true}}}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"forbidden","code":"forbidden","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"404":{"description":"not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"not found","code":"not_found","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"422":{"description":"receiptId and publicListed required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"receiptId and publicListed required","code":"schema_invalid","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/billing/status":{"get":{"operationId":"getBillingStatus","summary":"Workspace entitlement status","tags":["Billing"],"description":"Billing status is not a truth claim. Evidence states remain verified, platform_asserted, unavailable, or conflict.\n\n**Auth:** Authorization: Bearer awen_… or session cookie + X-Awen-Workspace-Id.\n\n**Limit:** No payload.","security":[{"BearerApiKey":[]},{"SessionCookie":[]}],"x-awen-auth":"apiKeyOrSession","x-awen-limit":"No payload.","responses":{"200":{"description":"Entitlement","content":{"application/json":{"examples":{"demo":{"value":{"requestId":"00000000-0000-4000-8000-000000000001","tenantId":"ws_01example0000000000000000","plan":"pilot","status":"active","exportEnabled":true,"message":"active","evidenceNote":"Billing status is not a truth claim. Evidence states remain verified, platform_asserted, unavailable, or conflict."}}}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"unauthorized","code":"unauthorized","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/billing/checkout":{"post":{"operationId":"createCheckout","summary":"Start Stripe Checkout (or fake checkout in demo)","tags":["Billing"],"description":"**Auth:** Authorization: Bearer awen_… or session cookie + X-Awen-Workspace-Id.\n\n**Limit:** Idempotency-Key ≤ 128 chars. Workspace admin for session callers. Does not set active; webhook does.","security":[{"BearerApiKey":[]},{"SessionCookie":[]}],"x-awen-auth":"apiKeyOrSession","x-awen-limit":"Idempotency-Key ≤ 128 chars. Workspace admin for session callers. Does not set active; webhook does.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":128},"description":"Replay the original ingest or checkout job. Unique per workspace."},{"name":"X-Request-Id","in":"header","required":false,"schema":{"type":"string"},"description":"Optional client correlation id. Echoed on errors as requestId."}],"requestBody":{"required":true,"content":{"application/json":{"examples":{"pilot":{"value":{"plan":"pilot"}}}}}},"responses":{"200":{"description":"Checkout session","content":{"application/json":{"examples":{"demo":{"value":{"checkoutId":"cs_test_example","url":"https://checkout.stripe.com/c/pay/cs_test_example","requestId":"00000000-0000-4000-8000-000000000001","message":"payment received, activation pending"}}}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"unauthorized","code":"unauthorized","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"forbidden","code":"forbidden","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"409":{"description":"idempotency conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"idempotency conflict","code":"conflict","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"422":{"description":"plan must be pilot or api","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"plan must be pilot or api","code":"schema_invalid","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/billing/history":{"get":{"operationId":"listBillingHistory","summary":"Recent invoices and billing events","tags":["Billing"],"description":"**Auth:** Authorization: Bearer awen_… or session cookie + X-Awen-Workspace-Id.\n\n**Limit:** 20 items. Active members.","security":[{"BearerApiKey":[]},{"SessionCookie":[]}],"x-awen-auth":"apiKeyOrSession","x-awen-limit":"20 items. Active members.","responses":{"200":{"description":"History","content":{"application/json":{"examples":{"demo":{"value":{"requestId":"00000000-0000-4000-8000-000000000001","invoices":[]}}}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"unauthorized","code":"unauthorized","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"404":{"description":"not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"not found","code":"not_found","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/billing/portal":{"post":{"operationId":"createBillingPortal","summary":"Open Stripe Billing Portal (or fake portal URL in demo)","tags":["Billing"],"description":"**Auth:** Authorization: Bearer awen_… or session cookie + X-Awen-Workspace-Id.\n\n**Limit:** Workspace admin for session callers.","security":[{"BearerApiKey":[]},{"SessionCookie":[]}],"x-awen-auth":"apiKeyOrSession","x-awen-limit":"Workspace admin for session callers.","responses":{"200":{"description":"Portal URL","content":{"application/json":{"examples":{"demo":{"value":{"requestId":"00000000-0000-4000-8000-000000000001","url":"https://billing.stripe.com/p/session/example"}}}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"unauthorized","code":"unauthorized","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"forbidden","code":"forbidden","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/billing/webhook":{"post":{"operationId":"billingWebhook","summary":"Inbound Stripe (or test) billing webhook","tags":["Billing"],"description":"Customers do not call this. Configure Stripe to POST here. Signature required. payment_failed pauses paid features; receipts stay readable. invoice.paid restores lastPlan. Billing is not evidence truth.\n\n**Auth:** Stripe-Signature (or X-Awen-Billing-Signature in test). Not a customer API key.\n\n**Limit:** 1 MiB body. 120 requests/min per hashed IP (fail closed). Duplicate event ids return 200 duplicate:true. Unknown tenant_id does not write entitlement_ledger.\n\n**Limiter outage:** 503 limiter_unavailable (fail closed) with Retry-After: 5. Exponential backoff, cap 60s. Not quota_exhausted.","security":[{"StripeSignature":[]}],"x-awen-auth":"stripe","x-awen-limit":"1 MiB body. 120 requests/min per hashed IP (fail closed). Duplicate event ids return 200 duplicate:true. Unknown tenant_id does not write entitlement_ledger.","x-awen-limiter-outage":"workspace","parameters":[{"name":"Stripe-Signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"examples":{"event":{"value":{"id":"evt_test","type":"invoice.paid"}}}}}},"responses":{"200":{"description":"Accepted","content":{"application/json":{"examples":{"demo":{"value":{"ok":true,"duplicate":false,"type":"invoice.paid","eventId":"evt_test","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"400":{"description":"invalid signature","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"invalid signature","code":"schema_invalid","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"413":{"description":"payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"payload too large","code":"payload_too_large","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"429":{"description":"rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"rate limited","code":"rate_limited","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"503":{"description":"Workspace/API-key limiter outage. Fail closed. Retry using Retry-After then exponential backoff capped at 60s.","headers":{"Retry-After":{"schema":{"type":"integer","minimum":1,"example":5},"description":"Wait this many seconds before the first retry (runtime sends 5). Then exponential backoff (2s, 4s, 8s, …) capped at 60s. Do not retry immediately. Do not treat as quota_exhausted."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"rate limiter unavailable","code":"limiter_unavailable","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/exports/{receiptId}":{"get":{"operationId":"exportReceiptZip","summary":"Download a portable receipt zip","tags":["Library"],"description":"**Auth:** Authorization: Bearer awen_… or session cookie + X-Awen-Workspace-Id.\n\n**Limit:** Requires active paid entitlement (except local demo public bypass). Zip of one receipt. HTTP 600/min per workspace.\n\n**Limiter outage:** 503 limiter_unavailable (fail closed) with Retry-After: 5. Exponential backoff, cap 60s. Not quota_exhausted.","security":[{"BearerApiKey":[]},{"SessionCookie":[]}],"x-awen-auth":"apiKeyOrSession","x-awen-limit":"Requires active paid entitlement (except local demo public bypass). Zip of one receipt. HTTP 600/min per workspace.","x-awen-limiter-outage":"workspace","parameters":[{"name":"receiptId","in":"path","required":true,"schema":{"type":"string"},"description":"sha256:<64 hex> or sha256/<64 hex>","example":"sha256:751f744d21be1f38defbc3abeac1b7deb71fc572fec9eb9b282e21b5763470c4"}],"responses":{"200":{"description":"application/zip","content":{"application/zip":{"schema":{"type":"string","format":"binary"},"examples":{"file":{"summary":"Content-Disposition attachment; X-Awen-Receipt-Id set"}}}}},"400":{"description":"invalid receipt id","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"invalid receipt id","code":"invalid_receipt_id","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"403":{"description":"export requires an active paid entitlement","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"export requires an active paid entitlement","code":"forbidden","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"404":{"description":"not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"not found","code":"not_found","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"429":{"description":"rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"rate limited","code":"rate_limited","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"503":{"description":"Workspace/API-key limiter outage. Fail closed. Retry using Retry-After then exponential backoff capped at 60s.","headers":{"Retry-After":{"schema":{"type":"integer","minimum":1,"example":5},"description":"Wait this many seconds before the first retry (runtime sends 5). Then exponential backoff (2s, 4s, 8s, …) capped at 60s. Do not retry immediately. Do not treat as quota_exhausted."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"rate limiter unavailable","code":"limiter_unavailable","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/share":{"post":{"operationId":"createShareLink","summary":"Create a read-only share URL","tags":["Library"],"description":"An unguessable URL is not access control. Revoke from the owning workspace. Other-tenant receiptId is 404.\n\n**Auth:** Authorization: Bearer awen_… or session cookie + X-Awen-Workspace-Id.\n\n**Limit:** Pilot 50 active links, API 500. Paid entitlement required. 1 MiB JSON body. HTTP 600/min per workspace.\n\n**Limiter outage:** 503 limiter_unavailable (fail closed) with Retry-After: 5. Exponential backoff, cap 60s. Not quota_exhausted.","security":[{"BearerApiKey":[]},{"SessionCookie":[]}],"x-awen-auth":"apiKeyOrSession","x-awen-limit":"Pilot 50 active links, API 500. Paid entitlement required. 1 MiB JSON body. HTTP 600/min per workspace.","x-awen-limiter-outage":"workspace","requestBody":{"required":true,"content":{"application/json":{"examples":{"create":{"value":{"receiptId":"sha256:751f744d21be1f38defbc3abeac1b7deb71fc572fec9eb9b282e21b5763470c4"}}}}}},"responses":{"200":{"description":"Share token","content":{"application/json":{"examples":{"demo":{"value":{"url":"http://localhost:3000/share/exampletoken","token":"exampletoken","receiptId":"sha256:751f744d21be1f38defbc3abeac1b7deb71fc572fec9eb9b282e21b5763470c4","createdAt":"2026-08-01T12:00:00.000Z","note":"An unguessable URL is not access control. Revoke from the owning workspace."}}}}}},"400":{"description":"receiptId required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"receiptId required","code":"invalid_share_token","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"403":{"description":"share requires an active paid entitlement","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"share requires an active paid entitlement","code":"forbidden","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"404":{"description":"not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"not found","code":"not_found","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"429":{"description":"rate_limited or share link quota_exhausted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"rate_limited or share link quota_exhausted","code":"rate_limited","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"503":{"description":"Workspace/API-key limiter outage. Fail closed. Retry using Retry-After then exponential backoff capped at 60s.","headers":{"Retry-After":{"schema":{"type":"integer","minimum":1,"example":5},"description":"Wait this many seconds before the first retry (runtime sends 5). Then exponential backoff (2s, 4s, 8s, …) capped at 60s. Do not retry immediately. Do not treat as quota_exhausted."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"rate limiter unavailable","code":"limiter_unavailable","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/share/{token}":{"get":{"operationId":"resolveShareLink","summary":"Resolve a share token to receipt JSON","tags":["Library"],"description":"**Auth:** Public. No API key.\n\n**Limit:** Token in path. Expired or revoked is 410.","security":[],"x-awen-auth":"public","x-awen-limit":"Token in path. Expired or revoked is 410.","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Shared receipt","content":{"application/json":{"examples":{"demo":{"value":{"receipt":{"apiVersion":"v1","verifierVersion":"awen-verify-1.0.0","receiptId":"sha256:751f744d21be1f38defbc3abeac1b7deb71fc572fec9eb9b282e21b5763470c4","sourceSystem":"synthetic","observedAt":"2026-08-01T12:00:00.000Z","jobSourceId":"job-gold-001","tier":"Silver","overallState":"platform_asserted","validReceipt":true,"areas":[{"area":"identity","state":"platform_asserted","reasons":["platform-asserted evidence only"]},{"area":"task","state":"platform_asserted","reasons":["platform-asserted evidence only"]},{"area":"deliverable","state":"unavailable","reasons":["no independent or platform evidence for this area"]},{"area":"settlement","state":"verified","reasons":["independent chain or artifact hash evidence"]},{"area":"evaluation","state":"platform_asserted","reasons":["platform-asserted evidence only"]}],"conflicts":[],"missing":[],"disclaimer":"Evidence state only. Not a certification, guarantee, background check, or quality score."},"evidence":{"receiptId":"sha256:751f744d21be1f38defbc3abeac1b7deb71fc572fec9eb9b282e21b5763470c4"}}}}}}},"404":{"description":"not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"not found","code":"not_found","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"410":{"description":"share disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"share disabled","code":"share_disabled","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/share/{token}/revoke":{"post":{"operationId":"revokeShareLink","summary":"Revoke a share token","tags":["Library"],"description":"**Auth:** Authorization: Bearer awen_… or session cookie + X-Awen-Workspace-Id.\n\n**Limit:** Owning workspace only.","security":[{"BearerApiKey":[]},{"SessionCookie":[]}],"x-awen-auth":"apiKeyOrSession","x-awen-limit":"Owning workspace only.","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Revoked","content":{"application/json":{"examples":{"demo":{"value":{"ok":true,"code":"share_disabled","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"unauthorized","code":"unauthorized","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"404":{"description":"not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"not found","code":"not_found","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/usage":{"get":{"operationId":"getUsage","summary":"Workspace usage events","tags":["Account"],"description":"**Auth:** Authorization: Bearer awen_… or session cookie + X-Awen-Workspace-Id.\n\n**Limit:** Tenant-scoped events only. No admin query string on this customer contract.","security":[{"BearerApiKey":[]},{"SessionCookie":[]}],"x-awen-auth":"apiKeyOrSession","x-awen-limit":"Tenant-scoped events only. No admin query string on this customer contract.","responses":{"200":{"description":"Usage","content":{"application/json":{"examples":{"demo":{"value":{"requestId":"00000000-0000-4000-8000-000000000001","tenantId":"ws_01example0000000000000000","plan":"pilot","events":[{"action":"verify","at":"2026-08-01T12:00:00.000Z","units":1,"receiptId":"sha256:751f744d21be1f38defbc3abeac1b7deb71fc572fec9eb9b282e21b5763470c4"}]}}}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"unauthorized","code":"unauthorized","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/usage/verify":{"post":{"operationId":"verifyWithQuota","summary":"Verify a bundle against workspace daily quota","tags":["Verify"],"description":"**Auth:** Authorization: Bearer awen_… or session cookie + X-Awen-Workspace-Id.\n\n**Limit:** 1 MiB body. Public 30/day, Pilot 10_000/day, API 100_000/day. RateLimit-* plus quotaRemaining in the body.\n\n**Limiter outage:** API key / workspace / admin → 503 limiter_unavailable with Retry-After: 5. Then exponential backoff, cap 60s. Anonymous → 429 with RateLimit-Policy: degraded (5/min in-process), not 503. Never a silent bypass.","security":[{"BearerApiKey":[]},{"SessionCookie":[]}],"x-awen-auth":"apiKeyOrSession","x-awen-limit":"1 MiB body. Public 30/day, Pilot 10_000/day, API 100_000/day. RateLimit-* plus quotaRemaining in the body.","x-awen-limiter-outage":"both","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"EvidenceBundleV0"}}}},"responses":{"200":{"description":"Verification with quota","content":{"application/json":{"examples":{"demo":{"value":{"apiVersion":"v1","verifierVersion":"awen-verify-1.0.0","receiptId":"sha256:751f744d21be1f38defbc3abeac1b7deb71fc572fec9eb9b282e21b5763470c4","sourceSystem":"synthetic","observedAt":"2026-08-01T12:00:00.000Z","jobSourceId":"job-gold-001","tier":"Silver","overallState":"platform_asserted","validReceipt":true,"areas":[{"area":"identity","state":"platform_asserted","reasons":["platform-asserted evidence only"]},{"area":"task","state":"platform_asserted","reasons":["platform-asserted evidence only"]},{"area":"deliverable","state":"unavailable","reasons":["no independent or platform evidence for this area"]},{"area":"settlement","state":"verified","reasons":["independent chain or artifact hash evidence"]},{"area":"evaluation","state":"platform_asserted","reasons":["platform-asserted evidence only"]}],"conflicts":[],"missing":[],"disclaimer":"Evidence state only. Not a certification, guarantee, background check, or quality score.","quotaRemaining":9999}}}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"unauthorized","code":"unauthorized","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"413":{"description":"payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"payload too large","code":"payload_too_large","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"422":{"description":"schema invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"schema invalid","code":"schema_invalid","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"429":{"description":"daily verify quota exhausted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"daily verify quota exhausted","code":"quota_exhausted","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"503":{"description":"Workspace/API-key limiter outage. Fail closed. Retry using Retry-After then exponential backoff capped at 60s.","headers":{"Retry-After":{"schema":{"type":"integer","minimum":1,"example":5},"description":"Wait this many seconds before the first retry (runtime sends 5). Then exponential backoff (2s, 4s, 8s, …) capped at 60s. Do not retry immediately. Do not treat as quota_exhausted."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"rate limiter unavailable","code":"limiter_unavailable","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/workspaces/{workspaceId}/deletion":{"get":{"operationId":"getWorkspaceDeletion","summary":"Deletion freeze status","tags":["Account"],"description":"**Auth:** Session cookie + X-Awen-Workspace-Id. Workspace admin where noted.\n\n**Limit:** Workspace admin. No payload.","security":[{"SessionCookie":[]}],"x-awen-auth":"session","x-awen-limit":"Workspace admin. No payload.","parameters":[{"name":"workspaceId","in":"path","required":true,"schema":{"type":"string"},"example":"ws_01example0000000000000000"}],"responses":{"200":{"description":"Freeze status","content":{"application/json":{"examples":{"demo":{"value":{"requestId":"00000000-0000-4000-8000-000000000001","frozen":false}}}}}},"404":{"description":"not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"not found","code":"not_found","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}},"post":{"operationId":"requestWorkspaceDeletion","summary":"Start a 30-day deletion freeze","tags":["Account"],"description":"**Auth:** Session cookie + X-Awen-Workspace-Id. Workspace admin where noted.\n\n**Limit:** Workspace admin. Receipts and digests are not deleted.","security":[{"SessionCookie":[]}],"x-awen-auth":"session","x-awen-limit":"Workspace admin. Receipts and digests are not deleted.","parameters":[{"name":"workspaceId","in":"path","required":true,"schema":{"type":"string"},"example":"ws_01example0000000000000000"}],"requestBody":{"required":true,"content":{"application/json":{"examples":{"confirm":{"value":{"confirm":"DELETE"}}}}}},"responses":{"200":{"description":"Freeze started","content":{"application/json":{"examples":{"demo":{"value":{"requestId":"00000000-0000-4000-8000-000000000001","status":"frozen","executeAt":"2026-10-10T00:00:00.000Z","note":"30-day freeze. Receipts and digests are not deleted. Payment failure never deletes receipts."}}}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"forbidden","code":"forbidden","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"422":{"description":"confirm must be \"DELETE\"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"confirm must be \"DELETE\"","code":"schema_invalid","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}},"/api/abuse":{"post":{"operationId":"reportAbuse","summary":"Report abuse (no API key)","tags":["Account"],"description":"**Auth:** Public. No API key.\n\n**Limit:** 16 KiB JSON. 10 reports per hashed IP per hour. Details are hashed; API keys must not be sent.","security":[],"x-awen-auth":"public","x-awen-limit":"16 KiB JSON. 10 reports per hashed IP per hour. Details are hashed; API keys must not be sent.","requestBody":{"required":true,"content":{"application/json":{"examples":{"spam":{"value":{"kind":"spam","details":"unsolicited listing","target":"https://example.invalid/r/x"}}}}}},"responses":{"200":{"description":"Accepted","content":{"application/json":{"examples":{"demo":{"value":{"requestId":"00000000-0000-4000-8000-000000000001","ok":true,"id":"ab_01","message":"Report received. Do not include API keys or session cookies."}}}}}},"422":{"description":"kind required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"kind required","code":"schema_invalid","requestId":"00000000-0000-4000-8000-000000000001"}}}}}},"429":{"description":"too many requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"default":{"value":{"error":"too many requests","code":"rate_limited","requestId":"00000000-0000-4000-8000-000000000001"}}}}}}}}}},"components":{"securitySchemes":{"BearerApiKey":{"type":"http","scheme":"bearer","description":"Workspace API key. Prefix awen_. Shown once at create/rotate."},"SessionCookie":{"type":"apiKey","in":"cookie","name":"awen_session","description":"Browser session. Send X-Awen-Workspace-Id. CSRF origin must match Host."},"StripeSignature":{"type":"apiKey","in":"header","name":"Stripe-Signature","description":"Inbound Stripe webhook. Customers do not send this."}},"schemas":{"Error":{"type":"object","additionalProperties":true,"required":["error","code"],"properties":{"error":{"type":"string"},"code":{"type":"string","enum":["invalid_receipt_id","schema_invalid","receipt_id_mismatch","locator_secret","not_found","conflict","payload_too_large","unsupported_media_type","unauthorized","forbidden","csrf_rejected","cors_denied","rate_limited","quota_exhausted","limiter_unavailable","not_ready","share_disabled","invalid_share_token","idempotency_conflict","body_aborted","invalid_generic","live_unsupported","internal_error"]},"requestId":{"type":"string"},"expectedReceiptId":{"type":"string"}}}},"parameters":{"ReceiptId":{"name":"receiptId","in":"path","required":true,"schema":{"type":"string"},"description":"sha256:<64 hex> or sha256/<64 hex>","example":"sha256:751f744d21be1f38defbc3abeac1b7deb71fc572fec9eb9b282e21b5763470c4"},"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":128},"description":"Replay the original ingest or checkout job. Unique per workspace."}}}}