Developer docs
REST API
Versioned JSON endpoints for proof, collection and the wider Customer Loop. The endpoint list below is generated from the same catalog a test checks against the route files, so it cannot silently drift.
Authentication
Server-to-server endpoints take a product-scoped service API key:
Authorization: Bearer yswld_<43 characters>- A key belongs to one organization, one product and one environment, and carries up to five scopes. The tenant and product always come from the key, never from the request body.
- Keys expire (180 days by default, at most 365) and are shown once. Rotating a key keeps its scopes; to change scopes, issue a new key.
- Browser session cookies are never accepted on these endpoints, and the /api/v1/proof endpoints send no CORS headers. Call them from your server.
- Availability: service API keys are currently issued only to sponsored internal workspaces. Other workspaces receive 403 when creating one. MCP credentials, the SDK identity flow and the Web Components are available to every workspace.
Endpoints the SDK calls from the browser take the signed end-user identity instead (see SDK). Customer-facing collection and control endpoints take the secret from the customer's own link, sent in a header, never in the URL.
Proof scopes
| Scope | Allows |
|---|---|
| yousaid:proof:read | Read approved proof, placements, consent summaries, assets and ledger events. |
| yousaid:proof:read_private | Also read unapproved versions and private source content. |
| yousaid:proof:write | Draft versions and asks, queue items for review, file revocation requests, report value events, generate draft assets and case studies. |
| yousaid:proof:publish | Create, change and publish placements with owned proof. |
| yousaid:proof:export | Approved-only export with a digest. |
| yousaid:proof:submissions:write | Headless capture: POST /api/v1/proof/submissions and /submissions/sessions. |
A key acts as a non-human integration. Approving, rejecting, managing consent, revoking directly, publishing paid use and exporting raw originals stay with people: those calls answer HUMAN_APPROVAL_REQUIRED or FORBIDDEN, and revocation calls file a request that a teammate completes (HTTP 202).
Idempotency
Send an Idempotency-Key header on any write to /api/v1/proof/*:
- 8 to 200 characters of letters, digits, period, underscore, colon or hyphen.
- Kept for 24 hours per key and credential. A retry with the same key, method, path and body replays the stored response with the header idempotent-replayed: true.
- The same key with a different request answers 409 IDEMPOTENCY_KEY_REUSED. A retry while the first call is still running answers 409 IDEMPOTENCY_IN_PROGRESS.
- Only successful responses are stored; after an error the key is released and you can retry.
- POST /api/v1/proof/submissions requires the header. A conflicting reuse there answers 409 CONFLICT.
Other writes use their own idempotency fields: signals take idempotencyKey in the body and value events are stored once per eventId.
Errors
Service-key endpoints return a typed envelope. The requestId is also sent as x-request-id.
{
"error": {
"code": "VALIDATION_FAILED",
"message": "The request did not match the schema.",
"requestId": "req_...",
"details": [{ "path": "placementId", "message": "Required" }]
}
}| Code | HTTP | When |
|---|---|---|
| INVALID_API_KEY | 401 | Missing, malformed, expired or revoked key. |
| KEY_AUDIENCE_MISMATCH, ENVIRONMENT_SCOPE_MISMATCH | 403 | The key is for another audience or environment. |
| PRODUCT_SCOPE_REQUIRED, PRODUCT_SCOPE_UNAVAILABLE | 403 | The key has no product, or the product is inactive. |
| INSUFFICIENT_SCOPE, FORBIDDEN | 403 | The key lacks the scope or permission. |
| HUMAN_APPROVAL_REQUIRED | 403 | Only a person in the workspace can do this. |
| VALIDATION_FAILED | 400 | The body or query did not match the schema. Bodies are limited to 256 KB of JSON on /api/v1/proof. |
| NOT_FOUND | 404 | Unknown id, or an id from another tenant or product (they are indistinguishable). |
| RECOVERY_WINDOW_CLOSED | 410 | A deleted item is past its 30-day recovery window. |
| CONFLICT, REVOKED_FINAL, CONSENT_INVALID, IDEMPOTENCY_KEY_REUSED, IDEMPOTENCY_IN_PROGRESS | 409 | The request conflicts with current state. Revocation is final. |
| NOT_ELIGIBLE, SOURCE_POLICY_BLOCKED, CITATION_VALIDATION_FAILED | 422 | Consent, source policy or citation rules refuse the action. |
| RATE_LIMITED, QUOTA_EXCEEDED, AI_BUDGET_EXCEEDED | 429 | Too many requests, or an allowance for a costly operation (AI generation, renders) is used up. Customer submissions are never refused for a used-up allowance. |
| INTAKE_SAFETY_CEILING | 429 | The workspace reached its daily safety ceiling on customer submissions. Retry-After points at the next UTC day. See Allowances and limits. |
| SERVICE_UNAVAILABLE, AI_UNAVAILABLE | 503 | A dependency is down. AI endpoints never substitute generated text for a failed call. |
Customer collection and control endpoints (/api/proof/*) use a simpler shape, { "error": "message", "code": "INVALID_INPUT" }, because their messages are shown to customers.
Pagination
List endpoints take limit (default 50, 1 to 100) and cursor, and return:
{ "data": [ ... ], "nextCursor": "WyIyMDI2LTA5..." }Pass nextCursor back unchanged until it is null. Cursors are opaque. Proof items and signals are newest first; ledger events are oldest first. Items filter by status (repeat it or separate with commas) and type; events filter by proofItemId, eventType and eventId.
Expansion
Some proof endpoints take expand to inline data you would otherwise fetch from a sub-resource. Repeat it or separate relations with commas:
GET /api/v1/proof/items?expand=versions,consent&limit=20
{ "data": [ { "id": "...", "status": "approved", ...,
"expanded": {
"versions": { "data": [ ... ], "hasMore": false },
"consent": { "data": { "proofItemId": "...", "status": "approved", "grants": [ ... ] }, "hasMore": false }
} } ],
"nextCursor": null }- Each relation's data has exactly the shape of its sub-resource and needs the same scope and permission. Unapproved versions appear only with yousaid:proof:read_private, as on /versions.
- At most 2 relations per request. An unknown, repeated or extra relation answers 400 VALIDATION_FAILED with the allowed values in details.
- Each relation is capped per parent; hasMore is true when the cap cut it. Read the sub-resource for the rest.
- On a list, each relation costs one query for the whole page, and the page size is capped at 50 while expanding.
| Endpoint | expand | Same data as | Cap | Notes |
|---|---|---|---|---|
/api/v1/proof/items, /api/v1/proof/items/{id} | versions | /api/v1/proof/items/{id}/versions | 10 | Latest versions, oldest first. Unapproved versions (including the original) appear only with yousaid:proof:read_private, as on the sub-resource. |
/api/v1/proof/items, /api/v1/proof/items/{id} | consent | /api/v1/proof/items/{id}/consent | 20 | Latest consent grants with scope, state and receipt. Evidence is never returned. |
/api/v1/proof/placements/{id} | items | /api/v1/proof/placements/{id}/items | 50 | Placed items in position order with the live eligibility decision. |
Rate limits
Each service key has 120 requests per minute. Every response carries x-ratelimit-limit, x-ratelimit-remaining and x-ratelimit-reset (unix seconds). A 429 adds retry-after.
Endpoints
Paths use {id} for identifiers. The machine-readable contracts are /openapi-v1.yaml and /openapi-rooms-v1.5.yaml.
Proof API
Server-to-server access to proof items, versions, consent, placements, assets and exports. Service API key with a proof scope.
| Method | Path | Auth | Summary |
|---|---|---|---|
| GET | /api/v1/proof/items | Service API key: yousaid:proof:read | Proof items in the key's product, newest first. Cursor paginated. expand=versions,consent inlines those sub-resources. |
| GET | /api/v1/proof/items/{id} | Service API key: yousaid:proof:read | One item, its approved public version and per-channel eligibility. expand=versions,consent inlines those sub-resources. |
| GET, POST | /api/v1/proof/items/{id}/versions | Service API key: yousaid:proof:read (GET), yousaid:proof:write (POST) | List versions oldest first, or add a draft derivative with a semantic diff. The original never changes. Unapproved content needs yousaid:proof:read_private. |
| POST | /api/v1/proof/items/{id}/request-approval | Service API key: yousaid:proof:write | Queue a version for human review. Requesting is not approving. |
| POST | /api/v1/proof/items/{id}/approve | Service API key: yousaid:proof:write | Always answers HUMAN_APPROVAL_REQUIRED for service keys. Approval is a human decision in the workspace. |
| POST | /api/v1/proof/items/{id}/reject | Service API key: yousaid:proof:write | Always answers HUMAN_APPROVAL_REQUIRED for service keys. |
| GET | /api/v1/proof/items/{id}/consent | Service API key: yousaid:proof:read | Consent grants with scope, state and receipt. Read only. |
| POST | /api/v1/proof/items/{id}/revoke | Service API key: yousaid:proof:write | Files a revocation request for a human with consent authority. Answers 202. |
| POST | /api/v1/proof/rewards/{id}/confirm | Service API key: yousaid:proof:write | Confirm that your product switched on a feature unlock reward (after the proof.reward.feature_unlock webhook). Idempotent: a repeat answers the same fulfilled reward. |
| POST | /api/v1/proof/items/{id}/summarize | Service API key: yousaid:proof:write | AI summary of one item. Caveats always state any incentive, the verification state and the consent limits (`validation` lists what was removed or added). `needsHumanReview` and `reviewMessage` flag a model we haven't evaluated yet. Answers AI_UNAVAILABLE when the model provider is down. |
| POST | /api/v1/proof/consents/{id}/revoke | Service API key: yousaid:proof:write | Files a revocation request for the grant's item. Answers 202. |
| GET, POST | /api/v1/proof/placements | Service API key: yousaid:proof:read (GET), yousaid:proof:publish (POST) | List or create placements (walls, carousels, cards, badges, pages, video). |
| GET, PATCH, DELETE | /api/v1/proof/placements/{id} | Service API key: yousaid:proof:read (GET), yousaid:proof:publish (PATCH, DELETE) | Read, rename, pause, reactivate or re-theme a placement. DELETE archives it and keeps history. GET takes expand=items. |
| GET, POST | /api/v1/proof/placements/{id}/items | Service API key: yousaid:proof:read (GET), yousaid:proof:publish (POST) | Placed items with the live eligibility decision, or place an approved version. |
| DELETE | /api/v1/proof/placements/{id}/items/{itemId} | Service API key: yousaid:proof:publish | Remove one item from a placement. |
| POST | /api/v1/proof/placements/{id}/publish | Service API key: yousaid:proof:publish | Activate a placement. Ineligible items are excluded and counted. |
| GET, POST | /api/v1/proof/events | Service API key: yousaid:proof:read (GET), yousaid:proof:write (POST) | Read Trust Ledger events oldest first, or report a verified value event (milestone, resolved ticket, score, shipped feature). Stored once per eventId. |
| POST | /api/v1/proof/exports | Service API key: yousaid:proof:export | Approved-only JSON export with a sha256 digest. Raw originals are exported by a workspace owner. |
| POST | /api/v1/proof/requests | Service API key: yousaid:proof:write | Create a draft proof request. Sending needs a human. |
| POST | /api/v1/proof/requests/draft | Service API key: yousaid:proof:write | AI-drafted ask message. Never sends. `needsHumanReview` and `reviewMessage` flag a model we haven't evaluated yet. |
| POST | /api/v1/proof/submissions | Service API key: yousaid:proof:submissions:write | Headless capture from your own UI. Idempotency-Key required. Always stored, even over a plan limit. |
| POST | /api/v1/proof/submissions/sessions | Service API key: yousaid:proof:submissions:write | Start a request session for a custom UI: questions, consent policy and a draft session token for resumable uploads. |
| POST | /api/v1/proof/assets/generate | Service API key: yousaid:proof:write | Deterministic quote card (SVG) from an eligible approved version, saved as a draft asset. |
| GET | /api/v1/proof/assets/{id} | Service API key: yousaid:proof:read | An asset with its lineage (items, versions, grant, template) and approval state. |
| POST | /api/v1/proof/case-studies | Service API key: yousaid:proof:write | Compile a source-cited case study draft. Uncited statements are rejected. |
| POST | /api/v1/proof/crm/deals | Service API key: yousaid:proof:write | Push deal records (hubspot, salesforce or api shape) for proof influence reporting. |
Customer collection and control
What the hosted page, the embedded form and the SDK prompt call on the customer's behalf. No YouSaid account is needed.
| Method | Path | Auth | Summary |
|---|---|---|---|
| POST | /api/proof/collect/drafts | Public | Start or reopen a draft. No account needed. Returns the draft session secret once. |
| GET, PATCH | /api/proof/collect/drafts/{id} | Draft session header | Resume a draft, or auto-save answers, identity choices and publication preferences. |
| POST | /api/proof/collect/drafts/{id}/submit | Draft session header | Submit. Always stored first; the private control link is returned exactly once. |
| POST | /api/proof/collect/drafts/{id}/continuation | Draft session header | A single-use link to continue on another device (valid 7 days). |
| POST | /api/proof/collect/continue | Personal link token | Redeem a continuation link for a fresh draft session on this device. |
| POST | /api/proof/collect/drafts/{id}/uploads | Draft session header | Open a signed, resumable multipart upload for a recording (voice, camera or screen) or image. A screen recording needs capture.screenConsent and the consent wording version. |
| GET, PUT, POST, DELETE | /api/proof/collect/drafts/{id}/uploads/{sessionId} | Signed upload token | Resume state (GET), send one part (PUT ?part=n), assemble the immutable original (POST) or cancel (DELETE). |
| GET | /api/proof/collect/drafts/{id}/uploads/{sessionId}/preview | Signed upload token | The customer's private preview of their own recording or its captions (?t= signed preview token). |
| GET, POST, PUT | /api/proof/collect/drafts/{id}/uploads/{sessionId}/captions | Draft session header | Caption state, automatic captions, or the customer's own corrected captions. Answers unavailable when transcription is off. |
| POST | /api/proof/collect/nojs | Public | The no-JavaScript form (application/x-www-form-urlencoded). Answers with a plain HTML receipt. |
| GET | /api/proof/collect/welcome/{videoId} | Public | A live flow's welcome video (Range supported). Served only while the published flow references it and it passed the safety check or a person cleared it. |
| POST | /api/proof/collect/opt-out | Personal link token | Stop all story requests to this recipient. |
| GET, POST | /api/proof/collect/control | Customer control link | The customer's stories, pending approvals and active uses; approve or decline exact wording, request a correction, pause, or withdraw everywhere. |
| GET, POST | /api/proof/collect/control/passport | Customer control link | Consent Passport: usage map across products and per-story or global controls. ?download=1 returns the signed file. |
| GET | /api/proof/collect/control/receipt | Customer control link | Downloadable JSON receipt of versions, consent receipts, uses and revocations for one story. |
| GET, POST | /api/proof/review | Customer control link | Drafts and clips that quote this customer; approve or decline the exact words or clip shown. |
| GET, POST | /api/proof/interview | Interview link | Async case-study interview: answers, uploads, submission with consent and decisions on drafted quotes. |
| PUT | /api/proof/interview/uploads/{sessionId} | Signed upload token | Raw bytes of a recorded interview answer, written once after type checks. |
In-app SDK
Endpoints the SDK calls with the signed end-user identity your server mints.
| Method | Path | Auth | Summary |
|---|---|---|---|
| POST | /api/proof/collect/sessions | Signed end-user identity | Known-customer session for the embedded or in-app prompt. Needs the signed identity token (single-use nonce, product-bound, origin-checked). |
| GET, POST | /api/proof/collect/prompt | Signed end-user identity | May the prompt show now (server-side caps across devices and products)? POST records not now, never ask, or a channel preference. |
| GET | /api/v1/installation | Signed end-user identity | SDK install check. Verifies the signed test user without consuming its nonce. |
| POST | /api/v1/identity/merge | Signed end-user identity | Link this browser's anonymous history to the signed end user. Same organization and product only. |
| POST | /api/v1/releases/{id}/confirmation | Signed end-user identity | The end user says whether a release fixed their problem. |
Public proof delivery
Render manifests, media, the engagement beacon, receipts and inbound value-event hooks.
| Method | Path | Auth | Summary |
|---|---|---|---|
| GET | /api/public/proof/render/{placementId} | Public | Signed render manifest (schema yousaid-proof-render-v1). ETag and 304 supported. Eligibility is evaluated on every build. |
| GET | /api/public/proof/media/{placementId}/{assetId} | Public | Media for an item in the current eligible manifest (Range supported). Anything else is 404. |
| POST | /api/public/proof/events | Public | Cookie-free engagement beacon. text/plain so sendBeacon needs no preflight. Needs the signed event token from the manifest. |
| GET | /api/public/proof/stream/source/{token} | Secret URL | Short-lived signed source link that Cloudflare Stream fetches to copy an approved recording. Not for direct use. |
| POST | /api/public/proof/stream/webhook | Public | Cloudflare Stream readiness webhook. Requests must carry a valid Stream signature; enabled only when CF_STREAM_WEBHOOK_SECRET is set. |
| GET | /api/public/proof/receipts/{id} | Public | Portable signed Proof Receipt. |
| GET | /api/public/proof/receipts/keys | Public | Public JWKS for verifying receipts offline. |
| POST | /api/public/proof/receipts/verify | Public | Verify a receipt's signature, then its live status. Revocation always wins. |
| POST | /api/public/proof/hooks/{token} | Secret URL | Inbound value-event hook for Zapier, Make, n8n or help desks. Same body as POST /api/v1/proof/events. Proposes an ask candidate only. |
| GET | /api/public/proof/automation-templates | Public | Zapier, Make and n8n trigger, action and template catalog (JSON). |
| POST | /api/public/proof/stripe/{token} | Secret URL | Native Stripe connector endpoint for one product. Verifies Stripe-Signature with the connection's own signing secret, stores each Stripe event id once and maps paid checkouts, plan upgrades and paid-invoice milestones to value events. Proposes ask candidates only. |
Collection setup
Flows, requests, consent templates and follow-ups used by the workspace. These answer only to a signed-in teammate.
| Method | Path | Auth | Summary |
|---|---|---|---|
| GET, POST | /api/proof/collect/forms | Workspace session | List flows with consent templates and allowance, or create a flow. |
| GET, PATCH, POST | /api/proof/collect/forms/{id} | Workspace session | Read or save a draft flow. POST publishes a new immutable flow version. |
| GET, POST, DELETE | /api/proof/collect/forms/{id}/domains | Workspace session | Custom collection domains and the DNS records to publish. |
| GET, POST, DELETE | /api/proof/collect/forms/{id}/welcome-video | Workspace session | The flow's uploaded welcome video: start a signed resumable upload, record a person's review of a held video, or remove it (stops serving at once). |
| GET, PUT, POST | /api/proof/collect/forms/{id}/welcome-video/{videoId} | Workspace session | Resume state (GET), send one part (PUT ?part=n with the upload token), or assemble, screen and attach the video to the draft flow (POST). |
| GET, POST | /api/proof/collect/questions | Workspace session | Saved question library with usage across flows, or save a question for reuse (version 1). |
| GET, PATCH, POST | /api/proof/collect/questions/{id} | Workspace session | A saved question with every immutable version; PATCH writes a new version; POST archives, restores or builds a flow question pinned to a version. |
| GET | /api/proof/collect/forms/{id}/qr | Workspace session | Printable QR code (SVG) of a live flow's public link, on its verified custom domain when there is one. ?download=1 saves it. |
| PUT | /api/proof/collect/forms/{id}/incentive | Workspace session | Set or clear the flow's participation reward. Sentiment-conditioned rules are rejected. |
| GET, POST | /api/proof/collect/consent-templates | Workspace session | List consent template versions, or publish the next immutable version (owner or admin). |
| GET, POST | /api/proof/collect/requests | Workspace session | Personal request links. The secret is returned once; only its hash is stored. |
| POST | /api/proof/collect/requests/{id} | Workspace session | Send, send the single reminder, or cancel a request. |
| POST | /api/proof/collect/requests/bulk | Workspace session | Create personal request links for many customers at once. Each secret is returned once; nothing is sent without an operator action. |
| GET, POST | /api/proof/collect/requests/outcome | Workspace session | Outcome-based ask candidates (release receipts, promoters). Nothing is sent without an operator action. |
| GET | /api/proof/collect/routing | Workspace session | Every scored response with its band and follow-up path. All responses stay visible. |
| PATCH | /api/proof/collect/routing/{id} | Workspace session | Move a follow-up along or link the Room opened for it. |
| GET | /api/proof/collect/corrections | Workspace session | Customer correction requests (operator tasks). |
| PATCH | /api/proof/collect/corrections/{id} | Workspace session | Close a correction task. The customer sees the note on their control page. |
| POST | /api/proof/collect/items/{id}/approval-link | Workspace session | Issue the customer's approval link for a pending consent request, optionally by email or in-app inbox. |
Signals, threads, features and inbox
The Customer Loop API that proof links back to.
| Method | Path | Auth | Summary |
|---|---|---|---|
| GET, POST | /api/v1/signals | Service API key: yousaid:signals:read (GET), yousaid:signals:write (POST) | List signals newest first, or capture one on behalf of an end user (idempotent by idempotencyKey). A used-up monthly allowance never refuses a signal: it is stored and listed with `overAllowance: true` while its AI analysis waits. Only the daily safety ceiling answers 429 INTAKE_SAFETY_CEILING. |
| GET | /api/v1/signals/{id} | Service API key: yousaid:signals:read | One signal. |
| GET | /api/v1/threads | Service API key: yousaid:threads:read | Threads; owner accepts a teammate id or unassigned. |
| GET, PATCH | /api/v1/threads/{id} | Service API key: yousaid:threads:read (GET), yousaid:threads:write (PATCH) | Customer-visible messages only, or update state and assignment. |
| GET | /api/v1/features | Service API key: yousaid:features:read | Feature candidates ordered by evidence-weighted score. |
| GET | /api/v1/features/{id} | Service API key: yousaid:features:read | One feature candidate. |
| POST, DELETE | /api/v1/features/{id}/votes | Service API key: yousaid:features:write | Record or withdraw an end user's vote (idempotent). |
| GET | /api/v1/inbox | Service API key or signed identity: yousaid:inbox:read | The end user's in-app inbox, newest first. Service keys must pass endUserId. |
| POST | /api/v1/inbox/read | Signed end-user identity | Mark items or everything read. End-user identity only. |
| GET | /api/v1/inbox/stream | Signed end-user identity | Server-Sent Events: ready, item and unread. |
Rooms
Rooms, agent runs and approvals. The full contract is in /openapi-rooms-v1.5.yaml.
| Method | Path | Auth | Summary |
|---|---|---|---|
| GET, POST | /api/v1/rooms | Signed end-user identity | Rooms the end user can read, or open one. |
| GET | /api/v1/rooms/search | Service API key or signed identity: yousaid:rooms:read | Search messages and canonical answers in readable Rooms. |
| GET, PATCH | /api/v1/rooms/{id} | Signed end-user identity | One Room, or update the end user's settings in it. |
| GET | /api/v1/rooms/{id}/events | Signed end-user identity | Catch-up by event sequence, with a snapshot when the client is too far behind. |
| GET | /api/v1/rooms/{id}/catch-up | Signed end-user identity | Summary of what changed since the end user last read. |
| POST | /api/v1/rooms/{id}/join | Signed end-user identity | Join a Room. |
| POST | /api/v1/rooms/{id}/leave | Signed end-user identity | Leave a Room. |
| POST | /api/v1/rooms/{id}/messages | Signed end-user identity | Post a message. |
| PATCH, DELETE | /api/v1/rooms/{id}/messages/{messageId} | Signed end-user identity | Edit or delete the end user's own message. |
| POST | /api/v1/rooms/{id}/messages/{messageId}/reactions | Signed end-user identity | Toggle a reaction. |
| POST | /api/v1/rooms/{id}/attachments | Signed end-user identity | Upload an attachment. |
| GET | /api/v1/rooms/{id}/attachments/{attachmentId} | Signed end-user identity | Download an attachment the end user may read. |
| PUT | /api/v1/rooms/{id}/polls/{pollId}/responses | Signed end-user identity | Answer a poll. |
| POST | /api/v1/rooms/{id}/moderation/reports | Signed end-user identity | Report content. |
| POST | /api/v1/rooms/{id}/moderation/{caseId}/appeals | Signed end-user identity | Appeal a moderation decision. |
| POST | /api/v1/rooms/{id}/solve-sessions/{sessionId}/join | Signed end-user identity | Join a live solve session after consenting to its recording terms. |
| GET, POST, DELETE | /api/v1/rooms/{id}/handoff | Service API key or signed identity: yousaid:rooms:read (GET), yousaid:rooms:write (POST, DELETE) | Ask for a person, read the current request, or withdraw it. |
| GET, PATCH | /api/v1/rooms/{id}/canvas | Service API key or signed identity: yousaid:rooms:read (GET), yousaid:rooms:write (PATCH, service keys only) | Read the Canvas, or make a versioned, idempotent update. |
| GET, POST | /api/v1/rooms/{id}/members | Service API key or signed identity: yousaid:rooms:read (GET), yousaid:rooms:write (POST, service keys only) | Members, or add a customer principal with external visibility. |
| DELETE | /api/v1/rooms/{id}/members/{principalId} | Service API key: yousaid:rooms:write | Remove a member. |
| POST | /api/v1/rooms/{id}/compile | Service API key: yousaid:rooms:write | Compile a cited PRD from customer-visible evidence. |
| POST | /api/v1/rooms/{id}/promote | Service API key: yousaid:rooms:write | Propose an answer as canonical knowledge. Publishing stays a human approval. |
| POST | /api/v1/rooms/{id}/jobs | Service API key: yousaid:rooms:write | Start a durable Room job. |
| GET | /api/v1/rooms/{id}/jobs/{jobId} | Service API key: yousaid:rooms:read | Step-level job progress. |
| POST | /api/v1/rooms/{id}/agents/{alias}/invoke | Service API key or signed identity: yousaid:rooms:write | Ask a labeled first-party agent; the request is posted to the Room as a visible message. |
| GET | /api/v1/rooms/{id}/agent-runs | Service API key or signed identity: yousaid:rooms:read | Agent runs in a Room. Customers see only runs they started. |
| GET | /api/v1/agent-runs/{runId} | Service API key or signed identity: yousaid:rooms:read | One agent run. Unknown and unauthorized runs both answer 404. |
| POST | /api/v1/agent-runs/{runId}/cancel | Service API key or signed identity: yousaid:rooms:write | Cancel a run. A cancelled run never executes a side effect later. |
| GET | /api/v1/approvals | Service API key or signed identity: yousaid:rooms:read | Pending and decided agent approvals with the exact staged preview. |
| POST | /api/v1/approvals/{approvalId}/approve | Workspace session | A signed-in owner or admin approves the exact staged payload. |
| POST | /api/v1/approvals/{approvalId}/reject | Workspace session | A signed-in owner or admin rejects the staged action. |
Sources and identity
Attributed source records and key introspection.
| Method | Path | Auth | Summary |
|---|---|---|---|
| GET | /api/v1/sources | Service API key: yousaid:sources:read | Search genuine attributed source records. |
| GET | /api/v1/sources/{id} | Service API key: yousaid:sources:read | One source record with its provenance. |
| GET | /api/v1/auth/whoami | Service API key | Safe identity of the calling key (never the key or its digest). |