{"openapi":"3.1.0","info":{"title":"XRAY Platform API","version":"1.0.0","description":"The complete integration surface of the XRAY platform: the endpoints a\nmicroservice calls on the **XR Workspace** (signed events, subject\ncontext, service data plane), the **uniform service contract** every\nfirst-party microservice implements, and each service's own machine API\n(**Blob**, **Guardian**, **Decide**, **Dictate**, **ForLoCo**).\n\n### Envelope\nSuccess responses are `{ \"data\": ... }`; failures are\n`{ \"error\": { \"code\", \"message\", \"details?\" } }` (see `ErrorEnvelope`\nand the `x-error-codes` taxonomy). A handful of legacy Blob routes still\nreturn `{ \"error\": \"message\" }` — marked `x-legacy-envelope: true`.\n\n### Auth planes\n* **AUTH-1** — static per-service transport key header\n  (`X-Blob-Api-Key`, `X-Guardian-Api-Key`, `X-Decide-Api-Key`,\n  `x-dictate-api-key`). Fail-closed: production answers 503 when unset.\n* **AUTH-2** — HMAC event signature on the workspace event bus.\n* **AUTH-4** — `X-Workspace-Token`: HS256 JWT minted by the workspace\n  (iss `workspace.xray.tech`, aud = the service id, exp−iat ≤ 300s).\n* **AUTH-5** — cron secrets for scheduled internal jobs.\n* **AUTH-6** — HMAC context signature for workspace pull APIs.\nAdditional planes: Decide caller keys (`Bearer dcd_…`), Guardian public\nconsumer keys (`Bearer xrg_live_…`), Guardian admin allowlist,\nForLoCo's internal shared key, provider-signed webhooks.\n\nDownload: JSON at `/api/v1/openapi`, YAML at `/api/v1/openapi?format=yaml`.\n","contact":{"name":"XRAY Platform","url":"https://workspace.xray.tech/api"}},"servers":[{"url":"https://workspace.xray.tech","description":"XR Workspace (hub) — every path without a servers override"}],"tags":[{"name":"workspace","description":"Service-facing endpoints the workspace exposes to microservices."},{"name":"service-contract","description":"The uniform /api/v1 plane every first-party microservice implements (health, ready, manifest, version, summary, activity, search, facts, pages, actions). Documented once; `x-service` lists the implementers and the path-level `servers` array carries each base URL. Dictate does not implement this plane yet."},{"name":"blob","description":"Blob — data-source schema indexing & insights (aud `blob`)."},{"name":"guardian","description":"Guardian — error & automation monitoring (aud `guardian`)."},{"name":"guardian-admin","description":"Guardian consumer-key administration (admin email allowlist)."},{"name":"guardian-public","description":"Guardian public read-only consumer API (Bearer xrg_live_…; default OFF)."},{"name":"decide-caller","description":"Decide caller plane — external services request human decisions (Bearer dcd_…)."},{"name":"decide-workspace","description":"Decide workspace plane — inbox, decisions, roles, keys (AUTH-1 + AUTH-4)."},{"name":"dictate","description":"Dictate — voice sessions → extracted actions (AUTH-1 + user-email header)."},{"name":"forloco","description":"ForLoCo (Hourly) machine surface — embed SSO mint, roster, provider webhooks."},{"name":"internal-cron","description":"Scheduled internal jobs (AUTH-1/AUTH-5) — not for integrators."}],"x-error-codes":[{"code":"VALIDATION_ERROR","http":400,"meaning":"Body or query failed validation"},{"code":"INVALID_JSON","http":400,"meaning":"Request body isn't valid JSON"},{"code":"UNKNOWN_EVENT_TYPE","http":400,"meaning":"Event type isn't in the workspace catalog"},{"code":"UNAUTHORIZED","http":401,"meaning":"Missing/invalid credential"},{"code":"FORBIDDEN","http":403,"meaning":"Authenticated but not entitled"},{"code":"NOT_FOUND","http":404,"meaning":"Missing or not owned — never reveal which"},{"code":"RATE_LIMITED","http":429,"meaning":"Throttled; retry with backoff"},{"code":"INTERNAL_ERROR","http":500,"meaning":"Unexpected; message stays user-safe"},{"code":"NOT_CONFIGURED","http":501,"meaning":"Service env not set — degrade, don't crash (permanent, never retried)"},{"code":"UPSTREAM_ERROR","http":502,"meaning":"A dependency is down"}],"components":{"securitySchemes":{"blobApiKey":{"type":"apiKey","in":"header","name":"X-Blob-Api-Key","description":"AUTH-1: Blob's static transport key. Fail-closed (503 in prod when unset)."},"guardianApiKey":{"type":"apiKey","in":"header","name":"X-Guardian-Api-Key","description":"AUTH-1: Guardian's static transport key. Fail-closed."},"decideApiKey":{"type":"apiKey","in":"header","name":"X-Decide-Api-Key","description":"AUTH-1: Decide's static transport key (workspace plane + internal cron)."},"dictateApiKey":{"type":"apiKey","in":"header","name":"x-dictate-api-key","description":"AUTH-1: Dictate's static transport key. Fail-closed."},"workspaceToken":{"type":"apiKey","in":"header","name":"X-Workspace-Token","description":"AUTH-4 identity JWT minted by the workspace: HS256, iss `workspace.xray.tech`, aud = the target service id (`blob`, `guardian`, `decide`), subject email (+ `companyId` where the service is org-scoped), exp−iat ≤ 300s. Services verify with a constant-time signature check, reject `alg:none`/algorithm confusion, and never trust a forgeable `?email=` in its place."},"eventSignature":{"type":"apiKey","in":"header","name":"X-XR-Signature","description":"AUTH-2: v1=<hex HMAC-SHA256 of `<X-XR-Timestamp>.<raw body>`> with the producer's own signing key; timestamp within ±300s."},"contextSignature":{"type":"apiKey","in":"header","name":"X-XR-Signature","description":"AUTH-6: v1=<hex HMAC-SHA256 of `<X-XR-Timestamp>.<raw query string>`> with the service's own context key; the service names itself in X-Workspace-Service-Id."},"cronSecret":{"type":"apiKey","in":"header","name":"X-Cron-Secret","description":"AUTH-5: shared secret for scheduled internal jobs."},"decideCallerKey":{"type":"http","scheme":"bearer","bearerFormat":"dcd_…","description":"Decide-issued org-scoped caller API key (hashed at rest)."},"guardianPublicKey":{"type":"http","scheme":"bearer","bearerFormat":"xrg_live_…","description":"Guardian public consumer key, scoped to the key owner's org. The whole plane is OFF unless GUARDIAN_PUBLIC_API_ENABLED=true (404 when off)."},"guardianAdminEmail":{"type":"apiKey","in":"header","name":"x-guardian-admin-email","description":"Guardian admin allowlist (GUARDIAN_ADMIN_EMAILS) for consumer-key administration."},"dictateUserEmail":{"type":"apiKey","in":"header","name":"X-Dictate-User-Email","description":"Dictate's subject scoping — the acting user's email (header, `?email=` or JSON body). Dictate has no AUTH-4 JWT yet; combine with `dictateApiKey`."},"forlocoInternalAuth":{"type":"apiKey","in":"header","name":"internalauthorization","description":"ForLoCo's internal shared key (HOURLY_INTERNAL_KEY twin), constant-time compared; the plane is feature-gated (404 when FEATURE_WORKSPACE_EMBED is off, 503 when the key is unset)."}},"schemas":{"ErrorEnvelope":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"One of the x-error-codes taxonomy (service-specific codes allowed)."},"message":{"type":"string"},"details":{"description":"Optional structured validation detail (Blob/Decide)."}}}}},"InboundEvent":{"type":"object","required":["id","type","service","occurredAt","subject","data","contractVersion"],"properties":{"id":{"type":"string","description":"Producer ULID; the dedupe key."},"type":{"type":"string","description":"A type the catalog assigns to `service`."},"service":{"type":"string"},"occurredAt":{"type":"string","format":"date-time"},"subject":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"},"companyId":{"type":"string"}}},"data":{"description":"Validated against the per-type schema (spec §7.3)."},"contractVersion":{"const":"v1"}}},"SubjectContextOrgUnitRef":{"type":"object","description":"A department or department-role reference (id + stable slug + display name).","required":["id","slug","name"],"properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"}}},"SubjectContext":{"type":"object","required":["subject","permissions","preferences","asOf"],"properties":{"subject":{"type":"object","required":["email","tier"],"properties":{"email":{"type":"string","format":"email"},"companyId":{"type":"string"},"tier":{"type":"string","enum":["free","hourly","monthly"]}}},"permissions":{"type":"object","description":"Org role, workspace-admin flag, per-service access/maxScope."},"access":{"type":"object","description":"OMITTED unless the caller's field profile includes it (and the FEATURE_ACCESS_CLAIMS rollout flag is on). The subject's own access facts — full department/custom-role assignment set (slugs) and effective permission keys, tier-intersected and filtered to the calling service's namespace (mirrors the AUTH-4 `perms` claim). Advisory: services re-check, never widen.","required":["orgRole","departments","roles","permissions"],"properties":{"orgRole":{"type":"string","description":"Workspace org role (OWNER/ADMIN/MEMBER/VIEWER)."},"departments":{"type":"array","items":{"type":"string"}},"roles":{"type":"array","items":{"type":"string"}},"permissions":{"type":"array","items":{"type":"string"}}}},"toolBelt":{"type":"array","items":{"type":"string"},"description":"OMITTED unless the caller's field profile includes it."},"team":{"type":"object","description":"OMITTED unless the caller's profile includes it.","required":["organizationId","name","members"],"properties":{"organizationId":{"type":"string"},"name":{"type":"string"},"members":{"type":"array","items":{"type":"object","required":["email","name","role","department","departmentRole"],"properties":{"email":{"type":["string","null"]},"name":{"type":["string","null"]},"role":{"type":"string","description":"Workspace org role (OWNER/ADMIN/MEMBER/VIEWER)."},"department":{"description":"Primary department (dept-roles plan §3 Phase B); null when unassigned.","oneOf":[{"$ref":"#/components/schemas/SubjectContextOrgUnitRef"},{"type":"null"}]},"departmentRole":{"description":"Role held inside `department`; never non-null while `department` is null.","oneOf":[{"$ref":"#/components/schemas/SubjectContextOrgUnitRef"},{"type":"null"}]}}}}}},"preferences":{"type":"object","properties":{"serviceVisible":{"type":"object"}}},"asOf":{"type":"string","format":"date-time"}}},"EventCatalogEntry":{"type":"object","required":["type","producer"],"properties":{"type":{"type":"string","description":"e.g. `guardian.ticket.detected`."},"producer":{"type":"string","description":"One of the registered producer service ids."},"isNotification":{"type":"boolean"}}},"ServiceManifestFirstParty":{"type":"object","description":"The manifest shape first-party services (blob, guardian, decide) serve today and the workspace's manifest cache consumes (src/lib/workspace/service-manifest.ts).","required":["service","displayName","contractVersion","requiredTier"],"properties":{"service":{"type":"string"},"displayName":{"type":"string"},"tagline":{"type":"string","maxLength":140},"contractVersion":{"const":"v1"},"requiredTier":{"type":"string","enum":["free","hourly","monthly"]},"addOn":{"type":"boolean"},"workspaceRoute":{"type":"string","description":"Must start with `/`."},"capabilities":{"type":"object","properties":{"summary":{"type":"boolean"},"activity":{"type":"boolean"},"search":{"type":"boolean"},"notifications":{"type":"boolean"},"deepLinks":{"type":"boolean"},"pages":{"type":"boolean"},"embed":{"type":["object","null"],"properties":{"url":{"type":"string"}}}}},"emittedEvents":{"type":"array","items":{"type":"string"}},"consumesFacts":{"type":"array","items":{"type":"string"}},"webhook":{"type":"object","properties":{"retrySchedule":{"type":"array","items":{"type":"integer"},"description":"Seconds between redelivery attempts."}}}}},"ServiceManifestSelfServe":{"type":"object","description":"The manifest shape SELF-SERVE registered services submit (src/lib/platform/manifest-schema.ts) — author-controlled REQUESTS the platform validates and admins grant. NOTE — the first-party and self-serve manifest schemas have not been reconciled yet; a service's GET /api/v1/manifest answers with one of the two shapes.","required":["service","displayName","contractVersion","capabilities","certification"],"properties":{"service":{"type":"string","description":"Must equal the registered slug (TRUST-1 anti-spoofing)."},"displayName":{"type":"string"},"contractVersion":{"const":"v1"},"tagline":{"type":"string"},"description":{"type":"string"},"requiredTier":{"type":"string","enum":["free","hourly","monthly"]},"capabilities":{"type":"object","properties":{"pages":{"type":"boolean"},"events":{"type":"boolean"},"ai":{"type":"object","properties":{"paths":{"type":"array","items":{"type":"string"}}}}}},"requestedGrants":{"type":"object","properties":{"identity":{"type":"object","properties":{"companyId":{"type":"boolean"},"tier":{"type":"boolean"},"tools":{"type":"boolean"}}},"facts":{"type":"array","items":{"type":"string"}},"events":{"type":"array","items":{"type":"string"}},"embed":{"type":"boolean"},"byokRelayPaths":{"type":"array","items":{"type":"string"}}}},"certification":{"type":"object","required":["resourcePath","healthPath"],"properties":{"resourcePath":{"type":"string"},"recordPathTemplate":{"type":"string","description":"Contains `{id}`."},"healthPath":{"type":"string"}}}}},"HealthStatus":{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["ok"]}}}}},"VersionInfo":{"type":"object","properties":{"data":{"type":"object","properties":{"service":{"type":"string"},"contractVersion":{"type":"string"},"build":{"type":"string"}}}}},"PageDocument":{"type":"object","description":"Server-driven UI page (BLOCK-CONTRACT.md; executable truth src/lib/platform/sdui/block-schema.ts). Summary depth here — blocks are a discriminated union on `type`.","required":["id","title","blocks"],"properties":{"id":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"blocks":{"type":"array","items":{"$ref":"#/components/schemas/SduiBlock"}}}},"SduiBlock":{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["heading","text","stat","list","table","form","actionRow","callout"],"description":"heading/text — copy; stat — labeled figure; list/table — rows; form — inputs posting to an actionId; actionRow — buttons invoking POST /api/v1/actions/{actionId}; callout — highlighted notice."}},"additionalProperties":true},"Ticket":{"type":"object","description":"Guardian error ticket (core fields; org-scoped).","required":["id","status"],"properties":{"id":{"type":"string"},"status":{"type":"string","enum":["open","acknowledged","resolved"]},"summary":{"type":"string"},"automationId":{"type":"string"},"groupId":{"type":"string"},"assignee":{"type":"string"},"detectedAt":{"type":"string","format":"date-time"}}},"DecisionStatus":{"type":"string","enum":["pending","needs_info","resolved","expired","cancelled"]},"Urgency":{"type":"string","enum":["normal","urgent"]},"ResolutionKind":{"type":"string","enum":["chosen","declined","expired","expired_default"]},"DecisionOptionCreate":{"type":"object","required":["label"],"properties":{"label":{"type":"string","minLength":1,"maxLength":120},"description":{"type":"string","maxLength":1000},"consequence":{"type":"string","maxLength":1000,"description":"e.g. 'Choosing this will…'"},"default":{"type":"boolean","description":"At most one option; requires expiresAt on the decision."}}},"DecisionOption":{"allOf":[{"$ref":"#/components/schemas/DecisionOptionCreate"},{"type":"object","required":["id"],"properties":{"id":{"type":"string"}}}]},"Fact":{"type":"object","required":["label","value"],"properties":{"label":{"type":"string","maxLength":80},"value":{"type":"string","maxLength":400}}},"Link":{"type":"object","required":["label","url"],"properties":{"label":{"type":"string","maxLength":80},"url":{"type":"string","format":"uri","description":"https only"}}},"DecisionCreate":{"type":"object","required":["title","roleSlug","options"],"properties":{"title":{"type":"string","minLength":1,"maxLength":200},"roleSlug":{"type":"string","pattern":"^[a-z0-9]+(-[a-z0-9]+)*$","maxLength":50},"body":{"type":"string","maxLength":32768,"description":"Markdown (rendered sanitized; raw HTML never rendered)"},"facts":{"type":"array","maxItems":20,"items":{"$ref":"#/components/schemas/Fact"}},"links":{"type":"array","maxItems":10,"items":{"$ref":"#/components/schemas/Link"}},"options":{"type":"array","minItems":2,"maxItems":5,"items":{"$ref":"#/components/schemas/DecisionOptionCreate"}},"urgency":{"$ref":"#/components/schemas/Urgency"},"expiresAt":{"type":"string","format":"date-time"}}},"InfoRequest":{"type":"object","required":["id","question","askedBy","askedAt"],"properties":{"id":{"type":"string"},"question":{"type":"string","maxLength":2000},"askedBy":{"type":"string","format":"email"},"askedAt":{"type":"string","format":"date-time"},"answer":{"type":"string","maxLength":8192},"answeredAt":{"type":"string","format":"date-time"}}},"Resolution":{"type":"object","required":["kind"],"properties":{"kind":{"$ref":"#/components/schemas/ResolutionKind"},"optionId":{"type":"string"},"rationale":{"type":"string","maxLength":2000},"decidedBy":{"type":"string","description":"email, or system:expiry"},"decidedAt":{"type":"string","format":"date-time"}}},"AssignmentChange":{"type":"object","required":["actor","at"],"properties":{"fromRole":{"type":"string"},"toRole":{"type":"string"},"toEmail":{"type":"string","format":"email"},"actor":{"type":"string"},"at":{"type":"string","format":"date-time"},"note":{"type":"string","maxLength":500}}},"Decision":{"type":"object","required":["id","organizationId","callerName","roleSlug","status","title","options","urgency","createdAt","updatedAt"],"properties":{"id":{"type":"string","description":"ULID"},"organizationId":{"type":"string"},"callerName":{"type":"string"},"roleSlug":{"type":"string"},"status":{"$ref":"#/components/schemas/DecisionStatus"},"title":{"type":"string"},"body":{"type":"string"},"facts":{"type":"array","items":{"$ref":"#/components/schemas/Fact"}},"links":{"type":"array","items":{"$ref":"#/components/schemas/Link"}},"options":{"type":"array","items":{"$ref":"#/components/schemas/DecisionOption"}},"urgency":{"$ref":"#/components/schemas/Urgency"},"expiresAt":{"type":"string","format":"date-time"},"defaultOptionId":{"type":"string"},"directAssigneeEmail":{"type":"string","format":"email"},"resolution":{"$ref":"#/components/schemas/Resolution"},"infoRequests":{"type":"array","items":{"$ref":"#/components/schemas/InfoRequest"}},"assignmentHistory":{"type":"array","items":{"$ref":"#/components/schemas/AssignmentChange"}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"Role":{"type":"object","required":["id","slug","name","createdAt"],"properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"memberCount":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"},"archivedAt":{"type":"string","format":"date-time"}}},"RoleCreate":{"type":"object","required":["slug","name"],"properties":{"slug":{"type":"string","pattern":"^[a-z0-9]+(-[a-z0-9]+)*$","maxLength":50},"name":{"type":"string","minLength":1,"maxLength":80},"description":{"type":"string","maxLength":400}}},"Assignment":{"type":"object","required":["memberEmail","addedBy","addedAt"],"properties":{"memberEmail":{"type":"string","format":"email"},"addedBy":{"type":"string","format":"email"},"addedAt":{"type":"string","format":"date-time"}}},"ApiKey":{"type":"object","required":["id","name","keyPrefix","createdBy","createdAt"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"keyPrefix":{"type":"string","description":"e.g. dcd_a1b2"},"createdBy":{"type":"string","format":"email"},"createdAt":{"type":"string","format":"date-time"},"lastUsedAt":{"type":"string","format":"date-time"},"revokedAt":{"type":"string","format":"date-time"}}},"DecisionEnvelope":{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["decision"],"properties":{"decision":{"$ref":"#/components/schemas/Decision"}}}}},"DecisionListEnvelope":{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["decisions"],"properties":{"decisions":{"type":"array","items":{"$ref":"#/components/schemas/Decision"}},"nextCursor":{"type":"string"}}}}},"RoleEnvelope":{"type":"object","properties":{"data":{"type":"object","properties":{"role":{"$ref":"#/components/schemas/Role"}}}}},"RoleListEnvelope":{"type":"object","properties":{"data":{"type":"object","properties":{"roles":{"type":"array","items":{"$ref":"#/components/schemas/Role"}}}}}},"AssignmentListEnvelope":{"type":"object","properties":{"data":{"type":"object","properties":{"assignments":{"type":"array","items":{"$ref":"#/components/schemas/Assignment"}}}}}},"KeyEnvelope":{"type":"object","properties":{"data":{"type":"object","properties":{"key":{"$ref":"#/components/schemas/ApiKey"}}}}},"KeyListEnvelope":{"type":"object","properties":{"data":{"type":"object","properties":{"keys":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}}}}}},"KeyCreatedEnvelope":{"type":"object","properties":{"data":{"type":"object","properties":{"key":{"$ref":"#/components/schemas/ApiKey"},"plaintext":{"type":"string","description":"Full key value — returned ONLY in create/rotate responses."}}}}},"WebhookEndpoint":{"type":"object","required":["id","url","createdAt"],"properties":{"id":{"type":"string"},"url":{"type":"string","format":"uri"},"createdAt":{"type":"string","format":"date-time"},"disabledAt":{"type":"string","format":"date-time"}}},"WebhookCreatedEnvelope":{"type":"object","properties":{"data":{"type":"object","properties":{"webhook":{"$ref":"#/components/schemas/WebhookEndpoint"},"secret":{"type":"string","description":"Signing secret — returned ONCE."}}}}},"WebhookListEnvelope":{"type":"object","properties":{"data":{"type":"object","properties":{"webhooks":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEndpoint"}}}}}}},"parameters":{"XrTimestamp":{"name":"X-XR-Timestamp","in":"header","required":true,"schema":{"type":"string"},"description":"Unix-seconds timestamp bound into the HMAC; ±300s skew."},"WorkspaceServiceId":{"name":"X-Workspace-Service-Id","in":"header","required":true,"schema":{"type":"string","enum":["guardian","blob","tasks"]},"description":"The calling service names itself; paired with its context key."},"DecisionId":{"name":"id","in":"path","required":true,"schema":{"type":"string","description":"ULID"}},"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","maxLength":255}},"Cursor":{"name":"cursor","in":"query","schema":{"type":"string"}},"Limit":{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}}},"responses":{"ErrorUnauthorized":{"description":"Missing/invalid credential (UNAUTHORIZED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"ErrorNotFound":{"description":"Missing or not owned — never reveal which (NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"ErrorRateLimited":{"description":"Throttled; retry with backoff (RATE_LIMITED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"ErrorNotConfigured":{"description":"Service env not set (NOT_CONFIGURED, permanent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"Unauthorized":{"description":"Missing/invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"NotFound":{"description":"Not found (or not owned by this org)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"Conflict":{"description":"invalid_transition or idempotency_conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"RateLimited":{"description":"Rate limited (Retry-After set)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"PayloadTooLarge":{"description":"Body exceeds bounds (e.g. markdown > 32KiB)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"ValidationOrUnknownRole":{"description":"validation_error, or unknown_role with `details.validRoles: string[]`.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}},"paths":{"/api/webhooks/events":{"post":{"operationId":"workspaceDeliverEvent","tags":["workspace"],"summary":"Deliver one signed event (at-least-once; dedupe on (service, id))","security":[{"eventSignature":[]}],"parameters":[{"$ref":"#/components/parameters/XrTimestamp"},{"name":"X-XR-Event-Id","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-XR-Delivery","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InboundEvent"}}}},"responses":{"200":{"description":"Duplicate — already processed; stop retrying."},"202":{"description":"Accepted (handled after ack)."},"400":{"description":"Permanent (unknown type, invalid data) — alert, never retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Bad/stale signature."},"413":{"description":"Body over 64KB."},"429":{"description":"Per-service quota; retry with backoff."}}}},"/api/v1/subject-context":{"get":{"operationId":"workspaceGetSubjectContext","tags":["workspace"],"summary":"Pull one user's cross-service context (field-filtered per caller)","security":[{"contextSignature":[]}],"parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string","format":"email"}},{"$ref":"#/components/parameters/WorkspaceServiceId"},{"$ref":"#/components/parameters/XrTimestamp"}],"responses":{"200":{"description":"The caller's field-entitled view; cache on `asOf`.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/SubjectContext"}}}}}},"401":{"description":"Bad/stale signature or unknown service (identical — no oracle)."},"404":{"description":"No workspace user with that email."},"429":{"description":"Per-service quota."},"501":{"description":"No context keys configured."}}}},"/api/v1/event-catalog":{"get":{"operationId":"workspaceGetEventCatalog","tags":["workspace"],"summary":"The event-type registry (public, schema-only)","security":[],"parameters":[{"name":"service","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Registered types and their owning producers.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"contractVersion":{"const":"v1"},"producers":{"type":"array","items":{"type":"string"}},"types":{"type":"array","items":{"$ref":"#/components/schemas/EventCatalogEntry"}}}}}}}}}}}},"/api/v1/service-data/{provider}":{"get":{"operationId":"workspaceGetServiceData","tags":["workspace"],"summary":"Cross-service data plane: read search/blob/guardian data through the workspace (AUTH-6 signed, per-caller provider profile, subject-entitlement gated)","security":[{"contextSignature":[]}],"parameters":[{"name":"provider","in":"path","required":true,"schema":{"type":"string","enum":["search","blob","guardian"]}},{"name":"email","in":"query","required":false,"description":"Subject email — required for the user-scoped providers (blob, guardian).","schema":{"type":"string","format":"email"}},{"name":"q","in":"query","required":false,"description":"Catalog query (min 2 chars) — required for provider `search`.","schema":{"type":"string","minLength":2,"maxLength":200}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":25}},{"$ref":"#/components/parameters/WorkspaceServiceId"},{"$ref":"#/components/parameters/XrTimestamp"}],"responses":{"200":{"description":"Provider payload: `search` → catalog results; `blob` → summary + schema-only data-source index; `guardian` → summary + org metrics."},"401":{"description":"Bad/stale signature or unknown service (identical — no oracle)."},"403":{"description":"Caller's provider profile excludes this provider, or the subject is not entitled to the product."},"404":{"description":"Unknown provider or no workspace user with that email."},"429":{"description":"Per-service quota."},"501":{"description":"No context keys configured."}}}},"/api/v1/service-data/recordings/grant":{"post":{"operationId":"workspaceGrantRecordingAccess","tags":["workspace"],"summary":"Grant or revoke a prospect's playback access to a Debrief recording, on behalf of the extracted Onboarding service (AUTH-2 inbound signature)","description":"The onboarding portal runs as its own service, but `RecordingInvite` and `RecordingShareSettings` belong to Debrief and stayed in the workspace — so arming an invite, previously a local insert, is now an authenticated call in. Only `onboarding-portal` may call it; any other service id gets the same opaque 401 as a bad signature. Every action is idempotent, because the caller retries a grant whose response it never saw rather than shipping a portal whose recording will not play.","security":[{"contextSignature":[]}],"parameters":[{"$ref":"#/components/parameters/WorkspaceServiceId"},{"$ref":"#/components/parameters/XrTimestamp"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["recordingId","email","grantedByEmail"],"properties":{"recordingId":{"type":"string","minLength":1,"maxLength":64},"email":{"type":"string","format":"email","maxLength":254,"description":"The prospect the grant is issued to."},"grantedByEmail":{"type":"string","format":"email","maxLength":254,"description":"The operator who armed or revoked the invite. Recorded as the audit actor — attribution must survive the extraction."},"action":{"type":"string","enum":["grant","revoke"],"default":"grant"}}}}}},"responses":{"200":{"description":"Applied (or already in that state — the call is idempotent)."},"400":{"description":"Body is not JSON","or fails validation.":null},"401":{"description":"Bad/stale signature or unknown service (identical — no oracle)."},"429":{"description":"Per-caller rate limit."},"501":{"description":"No signing key configured — fails closed","accepting nothing.":null}}}},"/api/v1/openapi":{"get":{"operationId":"workspaceGetOpenApi","tags":["workspace"],"summary":"This document (JSON by default; `?format=yaml` or Accept application/yaml)","security":[],"parameters":[{"name":"format","in":"query","required":false,"schema":{"type":"string","enum":["json","yaml"]}}],"responses":{"200":{"description":"The canonical platform OpenAPI document.","content":{"application/json":{},"application/yaml":{}}},"429":{"description":"Rate limited (60/min)."}}}},"/api/v1/health":{"x-service":["blob","guardian","decide"],"servers":[{"url":"{blobBaseUrl}","description":"Blob","variables":{"blobBaseUrl":{"default":"https://xr-blob.up.railway.app"}}},{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}},{"url":"{decideBaseUrl}","description":"Decide","variables":{"decideBaseUrl":{"default":"https://xr-decide-production.up.railway.app"}}}],"get":{"operationId":"serviceHealth","tags":["service-contract"],"summary":"Liveness (unauthenticated)","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatus"}}}}}}},"/api/v1/ready":{"x-service":["blob","guardian","decide"],"servers":[{"url":"{blobBaseUrl}","description":"Blob","variables":{"blobBaseUrl":{"default":"https://xr-blob.up.railway.app"}}},{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}},{"url":"{decideBaseUrl}","description":"Decide","variables":{"decideBaseUrl":{"default":"https://xr-decide-production.up.railway.app"}}}],"get":{"operationId":"serviceReady","tags":["service-contract"],"summary":"Readiness — dependencies reachable (unauthenticated)","security":[],"responses":{"200":{"description":"Ready."},"503":{"description":"Not ready (envelope)."}}}},"/api/v1/manifest":{"x-service":["blob","guardian","decide"],"servers":[{"url":"{blobBaseUrl}","description":"Blob","variables":{"blobBaseUrl":{"default":"https://xr-blob.up.railway.app"}}},{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}},{"url":"{decideBaseUrl}","description":"Decide","variables":{"decideBaseUrl":{"default":"https://xr-decide-production.up.railway.app"}}}],"get":{"operationId":"serviceManifest","tags":["service-contract"],"summary":"Capability manifest (AUTH-1; keyless answers 401 in the error envelope)","security":[{"blobApiKey":[]},{"guardianApiKey":[]},{"decideApiKey":[]}],"responses":{"200":{"description":"The service's manifest (one of the two platform shapes).","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"oneOf":[{"$ref":"#/components/schemas/ServiceManifestFirstParty"},{"$ref":"#/components/schemas/ServiceManifestSelfServe"}]}}}}}},"401":{"$ref":"#/components/responses/ErrorUnauthorized"},"503":{"description":"AUTH-1 key unset in production (fail-closed)."}}}},"/api/v1/version":{"x-service":["blob","guardian","decide"],"servers":[{"url":"{blobBaseUrl}","description":"Blob","variables":{"blobBaseUrl":{"default":"https://xr-blob.up.railway.app"}}},{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}},{"url":"{decideBaseUrl}","description":"Decide","variables":{"decideBaseUrl":{"default":"https://xr-decide-production.up.railway.app"}}}],"get":{"operationId":"serviceVersion","tags":["service-contract"],"summary":"Build/contract diagnostics","security":[],"responses":{"200":{"description":"Version info.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfo"}}}}}}},"/api/v1/summary":{"x-service":["blob","guardian"],"servers":[{"url":"{blobBaseUrl}","description":"Blob","variables":{"blobBaseUrl":{"default":"https://xr-blob.up.railway.app"}}},{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}},{"url":"{decideBaseUrl}","description":"Decide","variables":{"decideBaseUrl":{"default":"https://xr-decide-production.up.railway.app"}}}],"get":{"operationId":"serviceSummary","tags":["service-contract"],"summary":"Workspace summary card for the acting subject","security":[{"blobApiKey":[],"workspaceToken":[]},{"guardianApiKey":[],"workspaceToken":[]}],"responses":{"200":{"description":"`{ data: … }` summary payload."},"401":{"$ref":"#/components/responses/ErrorUnauthorized"}}}},"/api/v1/activity":{"x-service":["blob","guardian"],"servers":[{"url":"{blobBaseUrl}","description":"Blob","variables":{"blobBaseUrl":{"default":"https://xr-blob.up.railway.app"}}},{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}},{"url":"{decideBaseUrl}","description":"Decide","variables":{"decideBaseUrl":{"default":"https://xr-decide-production.up.railway.app"}}}],"get":{"operationId":"serviceActivity","tags":["service-contract"],"summary":"Recent activity feed for the acting subject","security":[{"blobApiKey":[],"workspaceToken":[]},{"guardianApiKey":[],"workspaceToken":[]}],"responses":{"200":{"description":"`{ data: … }` activity payload."},"401":{"$ref":"#/components/responses/ErrorUnauthorized"}}}},"/api/v1/search":{"x-service":["blob","guardian"],"servers":[{"url":"{blobBaseUrl}","description":"Blob","variables":{"blobBaseUrl":{"default":"https://xr-blob.up.railway.app"}}},{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}},{"url":"{decideBaseUrl}","description":"Decide","variables":{"decideBaseUrl":{"default":"https://xr-decide-production.up.railway.app"}}}],"get":{"operationId":"serviceSearch","tags":["service-contract"],"summary":"Federated search within the service, scoped to the acting subject","security":[{"blobApiKey":[],"workspaceToken":[]},{"guardianApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"`{ data: … }` scored hits."},"401":{"$ref":"#/components/responses/ErrorUnauthorized"}}}},"/api/v1/facts":{"x-service":["blob","guardian"],"servers":[{"url":"{blobBaseUrl}","description":"Blob","variables":{"blobBaseUrl":{"default":"https://xr-blob.up.railway.app"}}},{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}},{"url":"{decideBaseUrl}","description":"Decide","variables":{"decideBaseUrl":{"default":"https://xr-decide-production.up.railway.app"}}}],"post":{"operationId":"serviceConsumeFacts","tags":["service-contract"],"summary":"Consume brokered workspace facts (e.g. user.tier.changed)","security":[{"eventSignature":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["fact"],"properties":{"fact":{"type":"string"},"subject":{"type":"object","properties":{"email":{"type":"string","format":"email"},"companyId":{"type":"string"}}},"data":{"type":"object"}}}}}},"responses":{"202":{"description":"Fact accepted."},"400":{"description":"Unknown fact (envelope)."},"401":{"$ref":"#/components/responses/ErrorUnauthorized"}}}},"/api/v1/pages":{"x-service":["blob","guardian"],"servers":[{"url":"{blobBaseUrl}","description":"Blob","variables":{"blobBaseUrl":{"default":"https://xr-blob.up.railway.app"}}},{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}},{"url":"{decideBaseUrl}","description":"Decide","variables":{"decideBaseUrl":{"default":"https://xr-decide-production.up.railway.app"}}}],"get":{"operationId":"serviceListPages","tags":["service-contract"],"summary":"Server-driven UI — list available PageDocuments","security":[{"blobApiKey":[],"workspaceToken":[]},{"guardianApiKey":[],"workspaceToken":[]}],"responses":{"200":{"description":"`{ data: PageDocument[] }` (see PageDocument)."},"401":{"$ref":"#/components/responses/ErrorUnauthorized"}}}},"/api/v1/pages/{id}":{"x-service":["blob","guardian"],"servers":[{"url":"{blobBaseUrl}","description":"Blob","variables":{"blobBaseUrl":{"default":"https://xr-blob.up.railway.app"}}},{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}},{"url":"{decideBaseUrl}","description":"Decide","variables":{"decideBaseUrl":{"default":"https://xr-decide-production.up.railway.app"}}}],"get":{"operationId":"serviceGetPage","tags":["service-contract"],"summary":"Server-driven UI — one PageDocument","security":[{"blobApiKey":[],"workspaceToken":[]},{"guardianApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The page.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PageDocument"}}}}}},"404":{"$ref":"#/components/responses/ErrorNotFound"}}}},"/api/v1/actions/{actionId}":{"x-service":["blob","guardian"],"servers":[{"url":"{blobBaseUrl}","description":"Blob","variables":{"blobBaseUrl":{"default":"https://xr-blob.up.railway.app"}}},{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}},{"url":"{decideBaseUrl}","description":"Decide","variables":{"decideBaseUrl":{"default":"https://xr-decide-production.up.railway.app"}}}],"post":{"operationId":"serviceExecuteAction","tags":["service-contract"],"summary":"Execute a workspace action declared by an SDUI page","security":[{"blobApiKey":[],"workspaceToken":[]},{"guardianApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"actionId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","description":"Action input (validated per action)."}}}},"responses":{"200":{"description":"`{ data: … }` action result."},"400":{"description":"Validation failure (envelope)."},"401":{"$ref":"#/components/responses/ErrorUnauthorized"},"404":{"$ref":"#/components/responses/ErrorNotFound"}}}},"/api/webhooks/tier-sync":{"post":{"operationId":"workspaceTierSync","tags":["workspace"],"summary":"ForLoCo billing → workspace tier sync (signed; replay-guarded)","security":[{"eventSignature":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","tier"],"properties":{"email":{"type":"string","format":"email"},"tier":{"type":"string","enum":["free","hourly","monthly"]}}}}}},"responses":{"200":{"description":"Tier updated (previous tier audited)."},"401":{"$ref":"#/components/responses/ErrorUnauthorized"},"404":{"description":"No registry user with that email."}}}},"/api/v1/insights":{"x-service":["blob"],"servers":[{"url":"{blobBaseUrl}","description":"Blob","variables":{"blobBaseUrl":{"default":"https://xr-blob.up.railway.app"}}}],"get":{"operationId":"blobListInsights","tags":["blob"],"summary":"Deterministic schema insights for the acting subject","security":[{"blobApiKey":[],"workspaceToken":[]}],"responses":{"200":{"description":"`{ data: … }` findings (code-keyed, table/field-anchored)."},"401":{"$ref":"#/components/responses/ErrorUnauthorized"}}}},"/api/v1/insights/chat":{"x-service":["blob"],"servers":[{"url":"{blobBaseUrl}","description":"Blob","variables":{"blobBaseUrl":{"default":"https://xr-blob.up.railway.app"}}}],"post":{"operationId":"blobInsightsChat","tags":["blob"],"summary":"Schema-only AI chat about the subject's indexed schemas","security":[{"blobApiKey":[],"workspaceToken":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["message"],"properties":{"message":{"type":"string"},"threadId":{"type":"string"}}}}}},"responses":{"200":{"description":"`{ data: … }` assistant reply (consent-gated)."},"401":{"$ref":"#/components/responses/ErrorUnauthorized"},"501":{"$ref":"#/components/responses/ErrorNotConfigured"}}}},"/api/v1/connectors":{"x-service":["blob"],"servers":[{"url":"{blobBaseUrl}","description":"Blob","variables":{"blobBaseUrl":{"default":"https://xr-blob.up.railway.app"}}}],"get":{"operationId":"blobListConnectors","tags":["blob"],"summary":"List available data-source connectors","security":[{"blobApiKey":[]}],"responses":{"200":{"description":"`{ data: … }` connector registry (13 sources)."}}}},"/api/v1/connectors/{type}/schema":{"x-service":["blob"],"servers":[{"url":"{blobBaseUrl}","description":"Blob","variables":{"blobBaseUrl":{"default":"https://xr-blob.up.railway.app"}}}],"post":{"operationId":"blobConnectorExtractSchema","tags":["blob"],"summary":"Extract a normalized, structure-only schema via one connector","security":[{"blobApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"type","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"Connector-specific credentials/locator (never row data)."}}}},"responses":{"200":{"description":"`{ data: … }` normalized schema."},"400":{"description":"Validation failure (envelope)."},"401":{"$ref":"#/components/responses/ErrorUnauthorized"}}}},"/api/v1/connectors/{type}/resources":{"x-service":["blob"],"servers":[{"url":"{blobBaseUrl}","description":"Blob","variables":{"blobBaseUrl":{"default":"https://xr-blob.up.railway.app"}}}],"post":{"operationId":"blobConnectorListResources","tags":["blob"],"summary":"List the resources (bases/sheets/databases) a credential can see","security":[{"blobApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"type","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"`{ data: … }` resource list."},"401":{"$ref":"#/components/responses/ErrorUnauthorized"}}}},"/api/v1/connectors/{type}/save":{"x-service":["blob"],"servers":[{"url":"{blobBaseUrl}","description":"Blob","variables":{"blobBaseUrl":{"default":"https://xr-blob.up.railway.app"}}}],"post":{"operationId":"blobConnectorSave","tags":["blob"],"summary":"Persist a connector extraction as an indexed schema","security":[{"blobApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"type","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"`{ data: … }` saved schema reference."},"401":{"$ref":"#/components/responses/ErrorUnauthorized"}}}},"/api/v1/connectors/requests":{"x-service":["blob"],"servers":[{"url":"{blobBaseUrl}","description":"Blob","variables":{"blobBaseUrl":{"default":"https://xr-blob.up.railway.app"}}}],"post":{"operationId":"blobRequestConnector","tags":["blob"],"summary":"Request a connector Blob doesn't ship yet","security":[{"blobApiKey":[],"workspaceToken":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["connector"],"properties":{"connector":{"type":"string"},"notes":{"type":"string"}}}}}},"responses":{"201":{"description":"Request recorded."},"401":{"$ref":"#/components/responses/ErrorUnauthorized"}}}},"/api/v1/schemas":{"x-service":["blob"],"servers":[{"url":"{blobBaseUrl}","description":"Blob","variables":{"blobBaseUrl":{"default":"https://xr-blob.up.railway.app"}}}],"get":{"operationId":"blobListSchemas","tags":["blob"],"summary":"The subject's indexed schema library (all connectors)","security":[{"blobApiKey":[],"workspaceToken":[]}],"responses":{"200":{"description":"`{ data: … }` schema index (structure-only)."},"401":{"$ref":"#/components/responses/ErrorUnauthorized"}}}},"/api/v1/schemas/{id}":{"x-service":["blob"],"servers":[{"url":"{blobBaseUrl}","description":"Blob","variables":{"blobBaseUrl":{"default":"https://xr-blob.up.railway.app"}}}],"get":{"operationId":"blobGetSchema","tags":["blob"],"summary":"One indexed schema","security":[{"blobApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"`{ data: … }` schema detail."},"404":{"$ref":"#/components/responses/ErrorNotFound"}}}},"/api/v1/schemas/{id}/versions":{"x-service":["blob"],"servers":[{"url":"{blobBaseUrl}","description":"Blob","variables":{"blobBaseUrl":{"default":"https://xr-blob.up.railway.app"}}}],"get":{"operationId":"blobListSchemaVersions","tags":["blob"],"summary":"Version history for one schema","security":[{"blobApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"`{ data: … }` versions."},"404":{"$ref":"#/components/responses/ErrorNotFound"}}}},"/api/v1/schemas/{id}/versions/{versionId}":{"x-service":["blob"],"servers":[{"url":"{blobBaseUrl}","description":"Blob","variables":{"blobBaseUrl":{"default":"https://xr-blob.up.railway.app"}}}],"get":{"operationId":"blobGetSchemaVersion","tags":["blob"],"summary":"One schema version (diff source)","security":[{"blobApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"versionId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"`{ data: … }` version payload."},"404":{"$ref":"#/components/responses/ErrorNotFound"}}}},"/api/v1/extractions":{"x-service":["blob"],"servers":[{"url":"{blobBaseUrl}","description":"Blob","variables":{"blobBaseUrl":{"default":"https://xr-blob.up.railway.app"}}}],"get":{"operationId":"blobListExtractions","tags":["blob"],"summary":"List extraction jobs","security":[{"blobApiKey":[],"workspaceToken":[]}],"responses":{"200":{"description":"`{ data: … }` extractions."},"401":{"$ref":"#/components/responses/ErrorUnauthorized"}}},"post":{"operationId":"blobCreateExtraction","tags":["blob"],"summary":"Start an extraction job","security":[{"blobApiKey":[],"workspaceToken":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["tokenId"],"properties":{"tokenId":{"type":"string"},"baseId":{"type":"string"}}}}}},"responses":{"201":{"description":"`{ data: … }` extraction started."},"401":{"$ref":"#/components/responses/ErrorUnauthorized"}}}},"/api/v1/extractions/{id}":{"x-service":["blob"],"servers":[{"url":"{blobBaseUrl}","description":"Blob","variables":{"blobBaseUrl":{"default":"https://xr-blob.up.railway.app"}}}],"get":{"operationId":"blobGetExtraction","tags":["blob"],"summary":"One extraction job","security":[{"blobApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"`{ data: … }` extraction detail."},"404":{"$ref":"#/components/responses/ErrorNotFound"}}}},"/api/v1/tokens":{"x-service":["blob"],"servers":[{"url":"{blobBaseUrl}","description":"Blob","variables":{"blobBaseUrl":{"default":"https://xr-blob.up.railway.app"}}}],"get":{"operationId":"blobListTokens","tags":["blob"],"summary":"List the subject's data-source tokens","security":[{"blobApiKey":[],"workspaceToken":[]}],"responses":{"200":{"description":"`{ data: … }` tokens (never plaintext secrets)."},"401":{"$ref":"#/components/responses/ErrorUnauthorized"}}},"post":{"operationId":"blobAddToken","tags":["blob"],"summary":"Add a data-source token (PAT)","security":[{"blobApiKey":[],"workspaceToken":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token"],"properties":{"token":{"type":"string"},"label":{"type":"string"}}}}}},"responses":{"201":{"description":"`{ data: … }` token stored."},"400":{"description":"Validation failure (envelope)."},"401":{"$ref":"#/components/responses/ErrorUnauthorized"}}}},"/api/v1/tokens/{id}":{"x-service":["blob"],"servers":[{"url":"{blobBaseUrl}","description":"Blob","variables":{"blobBaseUrl":{"default":"https://xr-blob.up.railway.app"}}}],"delete":{"operationId":"blobRemoveToken","tags":["blob"],"summary":"Remove a data-source token","security":[{"blobApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Removed."},"404":{"$ref":"#/components/responses/ErrorNotFound"}}}},"/api/v1/tokens/{id}/bases":{"x-service":["blob"],"servers":[{"url":"{blobBaseUrl}","description":"Blob","variables":{"blobBaseUrl":{"default":"https://xr-blob.up.railway.app"}}}],"post":{"operationId":"blobListTokenBases","tags":["blob"],"summary":"Discover the bases/resources visible to one token","security":[{"blobApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"`{ data: … }` base list."},"404":{"$ref":"#/components/responses/ErrorNotFound"}}}},"/api/v1/share-access":{"x-service":["blob"],"servers":[{"url":"{blobBaseUrl}","description":"Blob","variables":{"blobBaseUrl":{"default":"https://xr-blob.up.railway.app"}}}],"get":{"operationId":"blobListShareAccess","tags":["blob"],"summary":"List share-access grants for the subject","security":[{"blobApiKey":[],"workspaceToken":[]}],"responses":{"200":{"description":"`{ data: … }` grants."}}},"post":{"operationId":"blobCreateShareAccess","tags":["blob"],"summary":"Record a shared-base access grant (service-account invite flow)","security":[{"blobApiKey":[],"workspaceToken":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"201":{"description":"Grant recorded."}}}},"/api/v1/share-access/process-pending":{"x-service":["blob"],"servers":[{"url":"{blobBaseUrl}","description":"Blob","variables":{"blobBaseUrl":{"default":"https://xr-blob.up.railway.app"}}}],"post":{"operationId":"blobProcessPendingShareAccess","tags":["blob"],"summary":"Process pending shared-base grants (cron/ops)","security":[{"blobApiKey":[]}],"responses":{"200":{"description":"`{ data: … }` processed count."}}}},"/api/v1/sync-shared-bases":{"x-service":["blob"],"servers":[{"url":"{blobBaseUrl}","description":"Blob","variables":{"blobBaseUrl":{"default":"https://xr-blob.up.railway.app"}}}],"post":{"operationId":"blobSyncSharedBases","tags":["blob","internal-cron"],"summary":"Trigger the shared-base sync sweep (Railway cron)","security":[{"cronSecret":[]},{"blobApiKey":[]}],"responses":{"200":{"description":"`{ data: … }` sync summary."},"401":{"$ref":"#/components/responses/ErrorUnauthorized"}}}},"/api/v1/dashboard":{"x-service":["guardian"],"servers":[{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}}],"get":{"operationId":"guardianDashboard","tags":["guardian"],"summary":"Dashboard PageDocument for the acting subject's org","security":[{"guardianApiKey":[],"workspaceToken":[]}],"responses":{"200":{"description":"`{ data: PageDocument }`."},"401":{"$ref":"#/components/responses/ErrorUnauthorized"}}}},"/api/v1/metrics":{"x-service":["guardian"],"servers":[{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}}],"get":{"operationId":"guardianMetrics","tags":["guardian"],"summary":"Org error metrics","security":[{"guardianApiKey":[],"workspaceToken":[]}],"responses":{"200":{"description":"`{ data: … }` org metrics (org-scoped, never cross-tenant)."},"401":{"$ref":"#/components/responses/ErrorUnauthorized"}}}},"/api/v1/tickets":{"x-service":["guardian"],"servers":[{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}}],"get":{"operationId":"guardianListTickets","tags":["guardian"],"summary":"Error tickets for the subject's org","security":[{"guardianApiKey":[],"workspaceToken":[]}],"responses":{"200":{"description":"Ticket list.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Ticket"}}}}}}},"401":{"$ref":"#/components/responses/ErrorUnauthorized"}}}},"/api/v1/tickets/{id}":{"x-service":["guardian"],"servers":[{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}}],"get":{"operationId":"guardianGetTicket","tags":["guardian"],"summary":"One ticket","security":[{"guardianApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Ticket detail.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Ticket"}}}}}},"404":{"$ref":"#/components/responses/ErrorNotFound"}}}},"/api/v1/tickets/{id}/resolve":{"x-service":["guardian"],"servers":[{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}}],"post":{"operationId":"guardianResolveTicket","tags":["guardian"],"summary":"Resolve a ticket","security":[{"guardianApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"`{ data: Ticket }` resolved."},"404":{"$ref":"#/components/responses/ErrorNotFound"}}}},"/api/v1/tickets/{id}/acknowledge":{"x-service":["guardian"],"servers":[{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}}],"post":{"operationId":"guardianAcknowledgeTicket","tags":["guardian"],"summary":"Acknowledge a ticket","security":[{"guardianApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"`{ data: Ticket }` acknowledged."},"404":{"$ref":"#/components/responses/ErrorNotFound"}}}},"/api/v1/tickets/{id}/reassign":{"x-service":["guardian"],"servers":[{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}}],"post":{"operationId":"guardianReassignTicket","tags":["guardian"],"summary":"Reassign a ticket to an org member","security":[{"guardianApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["assignee"],"properties":{"assignee":{"type":"string","format":"email"}}}}}},"responses":{"200":{"description":"`{ data: Ticket }` reassigned."},"400":{"description":"Unknown member (envelope)."},"404":{"$ref":"#/components/responses/ErrorNotFound"}}}},"/api/v1/tickets/{id}/notes":{"x-service":["guardian"],"servers":[{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}}],"get":{"operationId":"guardianListTicketNotes","tags":["guardian"],"summary":"Notes on a ticket","security":[{"guardianApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"`{ data: … }` notes."}}},"post":{"operationId":"guardianAddTicketNote","tags":["guardian"],"summary":"Add a note to a ticket","security":[{"guardianApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["body"],"properties":{"body":{"type":"string"}}}}}},"responses":{"201":{"description":"Note added."}}}},"/api/v1/groups":{"x-service":["guardian"],"servers":[{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}}],"get":{"operationId":"guardianListGroups","tags":["guardian"],"summary":"Error groups (rollups)","security":[{"guardianApiKey":[],"workspaceToken":[]}],"responses":{"200":{"description":"`{ data: … }` groups."}}},"post":{"operationId":"guardianCreateGroup","tags":["guardian"],"summary":"Create an error group","security":[{"guardianApiKey":[],"workspaceToken":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"}}}}}},"responses":{"201":{"description":"Group created."}}}},"/api/v1/groups/{id}":{"x-service":["guardian"],"servers":[{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}}],"get":{"operationId":"guardianGetGroup","tags":["guardian"],"summary":"One group","security":[{"guardianApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"`{ data: … }` group detail."},"404":{"$ref":"#/components/responses/ErrorNotFound"}}}},"/api/v1/groups/{id}/automations":{"x-service":["guardian"],"servers":[{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}}],"get":{"operationId":"guardianListGroupAutomations","tags":["guardian"],"summary":"Automations in a group","security":[{"guardianApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"`{ data: … }` automations."}}}},"/api/v1/automations":{"x-service":["guardian"],"servers":[{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}}],"get":{"operationId":"guardianListAutomations","tags":["guardian"],"summary":"Indexed automations for the org","security":[{"guardianApiKey":[],"workspaceToken":[]}],"responses":{"200":{"description":"`{ data: … }` automations."}}}},"/api/v1/automations/{id}":{"x-service":["guardian"],"servers":[{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}}],"get":{"operationId":"guardianGetAutomation","tags":["guardian"],"summary":"One automation","security":[{"guardianApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"`{ data: … }` automation detail."},"404":{"$ref":"#/components/responses/ErrorNotFound"}}},"patch":{"operationId":"guardianUpdateAutomation","tags":["guardian"],"summary":"Update an automation (owner/group)","security":[{"guardianApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"owner":{"type":"string"},"groupId":{"type":"string"}}}}}},"responses":{"200":{"description":"`{ data: … }` updated."},"404":{"$ref":"#/components/responses/ErrorNotFound"}}}},"/api/v1/automations/{id}/snooze":{"x-service":["guardian"],"servers":[{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}}],"post":{"operationId":"guardianSnoozeAutomation","tags":["guardian"],"summary":"Snooze an automation's alerts","security":[{"guardianApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"until":{"type":"string","format":"date-time"}}}}}},"responses":{"200":{"description":"Snoozed."}}}},"/api/v1/events":{"x-service":["guardian"],"servers":[{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}}],"get":{"operationId":"guardianListErrorEvents","tags":["guardian"],"summary":"Error event log (org-scoped)","security":[{"guardianApiKey":[],"workspaceToken":[]}],"responses":{"200":{"description":"`{ data: … }` events."}}}},"/api/v1/ingest/error":{"x-service":["guardian"],"servers":[{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}}],"post":{"operationId":"guardianIngestError","tags":["guardian"],"summary":"Route-A error ingestion (off by default — GUARDIAN_INGEST_ENABLED)","security":[{"guardianApiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"Provider error payload (normalized on ingest)."}}}},"responses":{"202":{"description":"Ingested."},"404":{"description":"Ingestion disabled."}}}},"/api/v1/members":{"x-service":["guardian"],"servers":[{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}}],"get":{"operationId":"guardianListMembers","tags":["guardian"],"summary":"Org member directory (assignment targets)","security":[{"guardianApiKey":[],"workspaceToken":[]}],"responses":{"200":{"description":"`{ data: … }` members."}}}},"/api/v1/notifications/routes":{"x-service":["guardian"],"servers":[{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}}],"get":{"operationId":"guardianListNotificationRoutes","tags":["guardian"],"summary":"Notification routes for the org","security":[{"guardianApiKey":[],"workspaceToken":[]}],"responses":{"200":{"description":"`{ data: … }` routes."}}},"post":{"operationId":"guardianCreateNotificationRoute","tags":["guardian"],"summary":"Create a notification route (webhook/Slack/email)","security":[{"guardianApiKey":[],"workspaceToken":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["kind","target"],"properties":{"kind":{"type":"string","enum":["webhook","slack","email","in-app"]},"target":{"type":"string"},"filters":{"type":"object"}}}}}},"responses":{"201":{"description":"Route created."}}}},"/api/v1/notifications/routes/{id}":{"x-service":["guardian"],"servers":[{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}}],"get":{"operationId":"guardianGetNotificationRoute","tags":["guardian"],"summary":"One notification route","security":[{"guardianApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"`{ data: … }` route."},"404":{"$ref":"#/components/responses/ErrorNotFound"}}},"patch":{"operationId":"guardianUpdateNotificationRoute","tags":["guardian"],"summary":"Update a route","security":[{"guardianApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Updated."}}},"delete":{"operationId":"guardianDeleteNotificationRoute","tags":["guardian"],"summary":"Delete a route","security":[{"guardianApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted."}}}},"/api/v1/notifications/routes/{id}/test":{"x-service":["guardian"],"servers":[{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}}],"post":{"operationId":"guardianTestNotificationRoute","tags":["guardian"],"summary":"Send a safe test notification through a route","security":[{"guardianApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Test dispatched."}}}},"/api/v1/notifications/slack/install-url":{"x-service":["guardian"],"servers":[{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}}],"post":{"operationId":"guardianSlackInstallUrl","tags":["guardian"],"summary":"Mint a Slack OAuth install URL (state-signed)","security":[{"guardianApiKey":[],"workspaceToken":[]}],"responses":{"200":{"description":"`{ data: { url } }`."},"501":{"$ref":"#/components/responses/ErrorNotConfigured"}}}},"/api/v1/notifications/slack/callback":{"x-service":["guardian"],"servers":[{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}}],"get":{"operationId":"guardianSlackCallback","tags":["guardian"],"summary":"Slack OAuth callback (browser redirect target)","security":[],"parameters":[{"name":"code","in":"query","required":false,"schema":{"type":"string"}},{"name":"state","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"302":{"description":"Redirect back to the workspace."},"400":{"description":"Invalid state/code."}}}},"/api/admin/v1/keys":{"x-service":["guardian"],"servers":[{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}}],"get":{"operationId":"guardianAdminListKeys","tags":["guardian-admin"],"summary":"List public-API consumer keys","security":[{"guardianAdminEmail":[]}],"responses":{"200":{"description":"`{ data: … }` keys (hashed at rest, prefixes only)."},"403":{"description":"Not on the admin allowlist."}}},"post":{"operationId":"guardianAdminCreateKey","tags":["guardian-admin"],"summary":"Create a consumer key (xrg_live_…)","security":[{"guardianAdminEmail":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["ownerOrg"],"properties":{"ownerOrg":{"type":"string"},"label":{"type":"string"}}}}}},"responses":{"201":{"description":"`{ data: { key } }` — plaintext shown once."}}}},"/api/admin/v1/keys/{id}/revoke":{"x-service":["guardian"],"servers":[{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}}],"post":{"operationId":"guardianAdminRevokeKey","tags":["guardian-admin"],"summary":"Revoke a consumer key","security":[{"guardianAdminEmail":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Revoked."}}}},"/api/admin/v1/keys/{id}/rotate":{"x-service":["guardian"],"servers":[{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}}],"post":{"operationId":"guardianAdminRotateKey","tags":["guardian-admin"],"summary":"Rotate a consumer key","security":[{"guardianAdminEmail":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"`{ data: { key } }` — new plaintext shown once."}}}},"/api/public/v1/tickets":{"x-service":["guardian"],"servers":[{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}}],"get":{"operationId":"guardianPublicListTickets","tags":["guardian-public"],"summary":"Read-only tickets for the key owner's org","security":[{"guardianPublicKey":[]}],"responses":{"200":{"description":"`{ data: Ticket[] }`."},"404":{"description":"Public API disabled (GUARDIAN_PUBLIC_API_ENABLED)."}}}},"/api/public/v1/groups":{"x-service":["guardian"],"servers":[{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}}],"get":{"operationId":"guardianPublicListGroups","tags":["guardian-public"],"summary":"Read-only groups for the key owner's org","security":[{"guardianPublicKey":[]}],"responses":{"200":{"description":"`{ data: … }`."},"404":{"description":"Public API disabled."}}}},"/api/public/v1/automations":{"x-service":["guardian"],"servers":[{"url":"{guardianBaseUrl}","description":"Guardian","variables":{"guardianBaseUrl":{"default":"https://xr-guardian.up.railway.app"}}}],"get":{"operationId":"guardianPublicListAutomations","tags":["guardian-public"],"summary":"Read-only automations for the key owner's org","security":[{"guardianPublicKey":[]}],"responses":{"200":{"description":"`{ data: … }`."},"404":{"description":"Public API disabled."}}}},"/api/health":{"x-service":["dictate"],"servers":[{"url":"{dictateBaseUrl}","description":"Dictate","variables":{"dictateBaseUrl":{"default":"https://xr-dictate-api-production.up.railway.app"}}}],"get":{"operationId":"dictateHealth","tags":["dictate"],"summary":"Liveness (dictate's only health surface — not under /api/v1 yet)","security":[],"responses":{"200":{"description":"OK."}}}},"/api/v1/feed":{"x-service":["dictate"],"servers":[{"url":"{dictateBaseUrl}","description":"Dictate","variables":{"dictateBaseUrl":{"default":"https://xr-dictate-api-production.up.railway.app"}}}],"get":{"operationId":"dictateFeed","tags":["dictate"],"summary":"Recent dictation sessions for the acting user","security":[{"dictateApiKey":[],"dictateUserEmail":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":20}}],"responses":{"200":{"description":"`{ data: … }` sessions feed."},"401":{"$ref":"#/components/responses/ErrorUnauthorized"},"503":{"description":"AUTH-1 key unset in production (fail-closed)."}}}},"/api/v1/sessions":{"x-service":["dictate"],"servers":[{"url":"{dictateBaseUrl}","description":"Dictate","variables":{"dictateBaseUrl":{"default":"https://xr-dictate-api-production.up.railway.app"}}}],"get":{"operationId":"dictateListSessions","tags":["dictate"],"summary":"List the acting user's sessions","security":[{"dictateApiKey":[],"dictateUserEmail":[]}],"responses":{"200":{"description":"`{ data: { sessions } }`."}}},"post":{"operationId":"dictateCreateSession","tags":["dictate"],"summary":"Create a dictation session","security":[{"dictateApiKey":[],"dictateUserEmail":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string","description":"Text brain-dump (audio uploads go to /audio)."}}}}}},"responses":{"201":{"description":"`{ data: { session } }`."}}}},"/api/v1/sessions/{id}":{"x-service":["dictate"],"servers":[{"url":"{dictateBaseUrl}","description":"Dictate","variables":{"dictateBaseUrl":{"default":"https://xr-dictate-api-production.up.railway.app"}}}],"get":{"operationId":"dictateGetSession","tags":["dictate"],"summary":"One session with its extracted actions","security":[{"dictateApiKey":[],"dictateUserEmail":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"`{ data: … }` session detail."},"404":{"$ref":"#/components/responses/ErrorNotFound"}}}},"/api/v1/sessions/{id}/audio":{"x-service":["dictate"],"servers":[{"url":"{dictateBaseUrl}","description":"Dictate","variables":{"dictateBaseUrl":{"default":"https://xr-dictate-api-production.up.railway.app"}}}],"post":{"operationId":"dictateUploadAudio","tags":["dictate"],"summary":"Upload session audio (multipart; transcribed when OPENAI_API_KEY set)","security":[{"dictateApiKey":[],"dictateUserEmail":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"audio":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"`{ data: … }` transcription (or text-fallback notice)."}}}},"/api/v1/sessions/{id}/extract":{"x-service":["dictate"],"servers":[{"url":"{dictateBaseUrl}","description":"Dictate","variables":{"dictateBaseUrl":{"default":"https://xr-dictate-api-production.up.railway.app"}}}],"post":{"operationId":"dictateExtractActions","tags":["dictate"],"summary":"Extract structured actions from a session","security":[{"dictateApiKey":[],"dictateUserEmail":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"`{ data: { actions } }`."},"404":{"$ref":"#/components/responses/ErrorNotFound"}}}},"/api/v1/actions/{id}/approve":{"x-service":["dictate"],"servers":[{"url":"{dictateBaseUrl}","description":"Dictate","variables":{"dictateBaseUrl":{"default":"https://xr-dictate-api-production.up.railway.app"}}}],"post":{"operationId":"dictateApproveAction","tags":["dictate"],"summary":"Approve an extracted action","security":[{"dictateApiKey":[],"dictateUserEmail":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Approved."}}}},"/api/v1/actions/{id}/execute":{"x-service":["dictate"],"servers":[{"url":"{dictateBaseUrl}","description":"Dictate","variables":{"dictateBaseUrl":{"default":"https://xr-dictate-api-production.up.railway.app"}}}],"post":{"operationId":"dictateExecuteAction","tags":["dictate"],"summary":"Execute an approved action (via Zapier MCP when connected)","security":[{"dictateApiKey":[],"dictateUserEmail":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"`{ data: … }` execution result."},"501":{"$ref":"#/components/responses/ErrorNotConfigured"}}}},"/api/v1/actions/{id}/assign":{"x-service":["dictate"],"servers":[{"url":"{dictateBaseUrl}","description":"Dictate","variables":{"dictateBaseUrl":{"default":"https://xr-dictate-api-production.up.railway.app"}}}],"post":{"operationId":"dictateAssignAction","tags":["dictate"],"summary":"Assign an action to the tasks sink","security":[{"dictateApiKey":[],"dictateUserEmail":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Assigned."}}}},"/api/v1/integrations/zapier":{"x-service":["dictate"],"servers":[{"url":"{dictateBaseUrl}","description":"Dictate","variables":{"dictateBaseUrl":{"default":"https://xr-dictate-api-production.up.railway.app"}}}],"get":{"operationId":"dictateGetZapierIntegration","tags":["dictate"],"summary":"The acting user's Zapier MCP connection state","security":[{"dictateApiKey":[],"dictateUserEmail":[]}],"responses":{"200":{"description":"`{ data: … }` connection state (never token material)."}}},"post":{"operationId":"dictateConnectZapier","tags":["dictate"],"summary":"Start a Zapier MCP OAuth connection","security":[{"dictateApiKey":[],"dictateUserEmail":[]}],"responses":{"200":{"description":"`{ data: { url } }` OAuth start."}}},"delete":{"operationId":"dictateDisconnectZapier","tags":["dictate"],"summary":"Disconnect Zapier (tokens destroyed)","security":[{"dictateApiKey":[],"dictateUserEmail":[]}],"responses":{"200":{"description":"Disconnected."}}}},"/api/v1/integrations/zapier/callback":{"x-service":["dictate"],"servers":[{"url":"{dictateBaseUrl}","description":"Dictate","variables":{"dictateBaseUrl":{"default":"https://xr-dictate-api-production.up.railway.app"}}}],"post":{"operationId":"dictateZapierCallback","tags":["dictate"],"summary":"Zapier OAuth callback (token stored encrypted at rest)","security":[{"dictateApiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Connected."}}}},"/api/internal/auth/sso":{"x-service":["forloco"],"servers":[{"url":"{forlocoBaseUrl}","description":"ForLoCo (Hourly)","variables":{"forlocoBaseUrl":{"default":"https://for-lo-co-production.up.railway.app"}}}],"post":{"operationId":"forlocoMintEmbedSso","tags":["forloco"],"summary":"Mint a single-use (≤60s) embed SSO token for the workspace iframe","security":[{"forlocoInternalAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"}}}}}},"responses":{"200":{"description":"Token minted.","content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"},"embedUrl":{"type":"string"},"role":{"type":"string"}}}}}},"404":{"description":"Feature off (FEATURE_WORKSPACE_EMBED)."},"503":{"description":"Internal key unset."}}}},"/api/internal/roster":{"x-service":["forloco"],"servers":[{"url":"{forlocoBaseUrl}","description":"ForLoCo (Hourly)","variables":{"forlocoBaseUrl":{"default":"https://for-lo-co-production.up.railway.app"}}}],"get":{"operationId":"forlocoRoster","tags":["forloco"],"summary":"Engineer + client roster for workspace bubble-up","security":[{"forlocoInternalAuth":[]}],"responses":{"200":{"description":"Roster.","content":{"application/json":{"schema":{"type":"object","properties":{"roster":{"type":"array","items":{"type":"object","required":["email","kind"],"properties":{"email":{"type":"string","format":"email"},"name":{"type":"string"},"kind":{"type":"string","enum":["engineer","client"]}}}}}}}}}}}},"/api/webhooks/stripe":{"x-service":["forloco"],"servers":[{"url":"{forlocoBaseUrl}","description":"ForLoCo (Hourly)","variables":{"forlocoBaseUrl":{"default":"https://for-lo-co-production.up.railway.app"}}}],"post":{"operationId":"forlocoStripeWebhook","tags":["forloco"],"summary":"Stripe events (signature-verified, idempotent)","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"Stripe event envelope (verified via Stripe-Signature header)."}}}},"responses":{"200":{"description":"Processed."},"400":{"description":"Bad signature."}}}},"/api/webhooks/docusign":{"x-service":["forloco"],"servers":[{"url":"{forlocoBaseUrl}","description":"ForLoCo (Hourly)","variables":{"forlocoBaseUrl":{"default":"https://for-lo-co-production.up.railway.app"}}}],"post":{"operationId":"forlocoDocusignWebhook","tags":["forloco"],"summary":"DocuSign envelope events","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Processed."}}}},"/api/webhooks/resend":{"x-service":["forloco"],"servers":[{"url":"{forlocoBaseUrl}","description":"ForLoCo (Hourly)","variables":{"forlocoBaseUrl":{"default":"https://for-lo-co-production.up.railway.app"}}}],"post":{"operationId":"forlocoResendWebhook","tags":["forloco"],"summary":"Resend email delivery events","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Processed."}}}},"/api/webhooks/zoom/events":{"x-service":["forloco"],"servers":[{"url":"{forlocoBaseUrl}","description":"ForLoCo (Hourly)","variables":{"forlocoBaseUrl":{"default":"https://for-lo-co-production.up.railway.app"}}}],"post":{"operationId":"forlocoZoomWebhook","tags":["forloco"],"summary":"Zoom meeting/recording events (webhook secret verified)","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Processed."}}}},"/api/webhooks/airtable/booking-overage":{"x-service":["forloco"],"servers":[{"url":"{forlocoBaseUrl}","description":"ForLoCo (Hourly)","variables":{"forlocoBaseUrl":{"default":"https://for-lo-co-production.up.railway.app"}}}],"post":{"operationId":"forlocoAirtableOverageWebhook","tags":["forloco"],"summary":"Airtable booking-overage hook (signed)","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Processed."}}}},"/api/v1/decisions":{"x-service":["decide"],"servers":[{"url":"{decideBaseUrl}","description":"Decide","variables":{"decideBaseUrl":{"default":"https://xr-decide-production.up.railway.app"}}}],"post":{"tags":["decide-caller"],"summary":"Create a decision","description":"`Idempotency-Key` is REQUIRED. Replaying the same key with an identical\npayload returns the original 201; a different payload returns\n409 `idempotency_conflict`. An unknown `roleSlug` returns 400\n`unknown_role` with `error.details.validRoles`.\n","security":[{"decideCallerKey":[]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecisionCreate"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecisionEnvelope"}}}},"400":{"$ref":"#/components/responses/ValidationOrUnknownRole"},"401":{"$ref":"#/components/responses/Unauthorized"},"409":{"$ref":"#/components/responses/Conflict"},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"429":{"$ref":"#/components/responses/RateLimited"}},"operationId":"decidePostDecisions"},"get":{"tags":["decide-caller"],"summary":"List the caller's decisions","security":[{"decideCallerKey":[]}],"parameters":[{"name":"status","in":"query","schema":{"$ref":"#/components/schemas/DecisionStatus"}},{"name":"roleSlug","in":"query","schema":{"type":"string"}},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/Limit"}],"responses":{"200":{"description":"Page of decisions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecisionListEnvelope"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}},"operationId":"decideGetDecisions"}},"/api/v1/decisions/{id}":{"x-service":["decide"],"servers":[{"url":"{decideBaseUrl}","description":"Decide","variables":{"decideBaseUrl":{"default":"https://xr-decide-production.up.railway.app"}}}],"get":{"tags":["decide-caller"],"summary":"Get a decision (optionally long-polling)","description":"With `?wait=1..60` the request is held until the decision's status\nchanges or the wait elapses; either way the response is 200 with the\ncurrent state and `X-Decide-Long-Poll: changed|timeout`.\nLong-poll is caller-plane only — the Workspace BFF never proxies `wait`.\n","security":[{"decideCallerKey":[]}],"parameters":[{"$ref":"#/components/parameters/DecisionId"},{"name":"wait","in":"query","schema":{"type":"integer","minimum":1,"maximum":60}}],"responses":{"200":{"description":"Current decision state","headers":{"X-Decide-Long-Poll":{"schema":{"type":"string","enum":["changed","timeout"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecisionEnvelope"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}},"operationId":"decideGetDecisionsId"},"delete":{"tags":["decide-caller"],"summary":"Cancel a decision (pending/needs_info only)","security":[{"decideCallerKey":[]}],"parameters":[{"$ref":"#/components/parameters/DecisionId"}],"responses":{"200":{"description":"Cancelled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecisionEnvelope"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}},"operationId":"decideDeleteDecisionsId"}},"/api/v1/decisions/{id}/info-response":{"x-service":["decide"],"servers":[{"url":"{decideBaseUrl}","description":"Decide","variables":{"decideBaseUrl":{"default":"https://xr-decide-production.up.railway.app"}}}],"post":{"tags":["decide-caller"],"summary":"Answer a decider's request for more information","description":"Returns the decision to `pending` and re-notifies assignees. 409 unless the decision is `needs_info`.","security":[{"decideCallerKey":[]}],"parameters":[{"$ref":"#/components/parameters/DecisionId"},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["infoRequestId","answer"],"properties":{"infoRequestId":{"type":"string"},"answer":{"type":"string","maxLength":8192,"description":"Markdown"}}}}}},"responses":{"200":{"description":"Back to pending","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecisionEnvelope"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}},"operationId":"decidePostDecisionsIdInfoResponse"}},"/api/v1/webhooks":{"x-service":["decide"],"servers":[{"url":"{decideBaseUrl}","description":"Decide","variables":{"decideBaseUrl":{"default":"https://xr-decide-production.up.railway.app"}}}],"post":{"tags":["decide-caller"],"summary":"Register a webhook endpoint","description":"The signing `secret` is returned ONCE in this response.","security":[{"decideCallerKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri","description":"https only"}}}}}},"responses":{"201":{"description":"Registered (secret included once)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookCreatedEnvelope"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}},"operationId":"decidePostWebhooks"},"get":{"tags":["decide-caller"],"summary":"List webhook endpoints (secrets omitted)","security":[{"decideCallerKey":[]}],"responses":{"200":{"description":"Endpoints","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookListEnvelope"}}}}},"operationId":"decideGetWebhooks"}},"/api/v1/webhooks/{id}":{"x-service":["decide"],"servers":[{"url":"{decideBaseUrl}","description":"Decide","variables":{"decideBaseUrl":{"default":"https://xr-decide-production.up.railway.app"}}}],"delete":{"tags":["decide-caller"],"summary":"Disable a webhook endpoint","security":[{"decideCallerKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Disabled"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}},"operationId":"decideDeleteWebhooksId"}},"/api/v1/workspace/inbox":{"x-service":["decide"],"servers":[{"url":"{decideBaseUrl}","description":"Decide","variables":{"decideBaseUrl":{"default":"https://xr-decide-production.up.railway.app"}}}],"get":{"tags":["decide-workspace"],"summary":"Decisions routed to the identified decider","description":"Decisions whose roleSlug the AUTH-4 `sub` is assigned to, plus direct assignments.","security":[{"decideApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"status","in":"query","schema":{"$ref":"#/components/schemas/DecisionStatus"}},{"name":"roleSlug","in":"query","schema":{"type":"string"}},{"name":"urgency","in":"query","schema":{"$ref":"#/components/schemas/Urgency"}},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/Limit"}],"responses":{"200":{"description":"Page of decisions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecisionListEnvelope"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}},"operationId":"decideGetWorkspaceInbox"}},"/api/v1/workspace/decisions/{id}":{"x-service":["decide"],"servers":[{"url":"{decideBaseUrl}","description":"Decide","variables":{"decideBaseUrl":{"default":"https://xr-decide-production.up.railway.app"}}}],"get":{"tags":["decide-workspace"],"summary":"Decision detail (info thread + assignment history)","security":[{"decideApiKey":[],"workspaceToken":[]}],"parameters":[{"$ref":"#/components/parameters/DecisionId"}],"responses":{"200":{"description":"Detail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecisionEnvelope"}}}},"404":{"$ref":"#/components/responses/NotFound"}},"operationId":"decideGetWorkspaceDecisionsId"}},"/api/v1/workspace/decisions/{id}/choose":{"x-service":["decide"],"servers":[{"url":"{decideBaseUrl}","description":"Decide","variables":{"decideBaseUrl":{"default":"https://xr-decide-production.up.railway.app"}}}],"post":{"tags":["decide-workspace"],"summary":"Choose an option","security":[{"decideApiKey":[],"workspaceToken":[]}],"parameters":[{"$ref":"#/components/parameters/DecisionId"},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["optionId"],"properties":{"optionId":{"type":"string"},"rationale":{"type":"string","maxLength":2000}}}}}},"responses":{"200":{"description":"Resolved (chosen)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecisionEnvelope"}}}},"409":{"$ref":"#/components/responses/Conflict"}},"operationId":"decidePostWorkspaceDecisionsIdChoose"}},"/api/v1/workspace/decisions/{id}/request-info":{"x-service":["decide"],"servers":[{"url":"{decideBaseUrl}","description":"Decide","variables":{"decideBaseUrl":{"default":"https://xr-decide-production.up.railway.app"}}}],"post":{"tags":["decide-workspace"],"summary":"Ask the caller for more information","security":[{"decideApiKey":[],"workspaceToken":[]}],"parameters":[{"$ref":"#/components/parameters/DecisionId"},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["question"],"properties":{"question":{"type":"string","minLength":1,"maxLength":2000}}}}}},"responses":{"200":{"description":"Now needs_info","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecisionEnvelope"}}}},"409":{"$ref":"#/components/responses/Conflict"}},"operationId":"decidePostWorkspaceDecisionsIdRequestInfo"}},"/api/v1/workspace/decisions/{id}/reassign":{"x-service":["decide"],"servers":[{"url":"{decideBaseUrl}","description":"Decide","variables":{"decideBaseUrl":{"default":"https://xr-decide-production.up.railway.app"}}}],"post":{"tags":["decide-workspace"],"summary":"Reassign to another role or member (exactly one of toRoleSlug/toEmail)","security":[{"decideApiKey":[],"workspaceToken":[]}],"parameters":[{"$ref":"#/components/parameters/DecisionId"},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"toRoleSlug":{"type":"string"},"toEmail":{"type":"string","format":"email"},"note":{"type":"string","maxLength":500}}}}}},"responses":{"200":{"description":"Reassigned (status unchanged)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecisionEnvelope"}}}},"400":{"$ref":"#/components/responses/ValidationOrUnknownRole"},"409":{"$ref":"#/components/responses/Conflict"}},"operationId":"decidePostWorkspaceDecisionsIdReassign"}},"/api/v1/workspace/decisions/{id}/decline":{"x-service":["decide"],"servers":[{"url":"{decideBaseUrl}","description":"Decide","variables":{"decideBaseUrl":{"default":"https://xr-decide-production.up.railway.app"}}}],"post":{"tags":["decide-workspace"],"summary":"Decline / abstain","security":[{"decideApiKey":[],"workspaceToken":[]}],"parameters":[{"$ref":"#/components/parameters/DecisionId"},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"rationale":{"type":"string","maxLength":2000}}}}}},"responses":{"200":{"description":"Resolved (declined)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecisionEnvelope"}}}},"409":{"$ref":"#/components/responses/Conflict"}},"operationId":"decidePostWorkspaceDecisionsIdDecline"}},"/api/v1/workspace/stats":{"x-service":["decide"],"servers":[{"url":"{decideBaseUrl}","description":"Decide","variables":{"decideBaseUrl":{"default":"https://xr-decide-production.up.railway.app"}}}],"get":{"tags":["decide-workspace"],"summary":"Pending/urgent counts for the identity","security":[{"decideApiKey":[],"workspaceToken":[]}],"responses":{"200":{"description":"Counts","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"pendingCount":{"type":"integer"},"urgentCount":{"type":"integer"}}}}}}}}},"operationId":"decideGetWorkspaceStats"}},"/api/v1/workspace/roles":{"x-service":["decide"],"servers":[{"url":"{decideBaseUrl}","description":"Decide","variables":{"decideBaseUrl":{"default":"https://xr-decide-production.up.railway.app"}}}],"get":{"tags":["decide-workspace"],"summary":"List decision roles for the org","security":[{"decideApiKey":[],"workspaceToken":[]}],"responses":{"200":{"description":"Roles","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleListEnvelope"}}}}},"operationId":"decideGetWorkspaceRoles"},"post":{"tags":["decide-workspace"],"summary":"Create a decision role","security":[{"decideApiKey":[],"workspaceToken":[]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleCreate"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleEnvelope"}}}}},"operationId":"decidePostWorkspaceRoles"}},"/api/v1/workspace/roles/{id}":{"x-service":["decide"],"servers":[{"url":"{decideBaseUrl}","description":"Decide","variables":{"decideBaseUrl":{"default":"https://xr-decide-production.up.railway.app"}}}],"patch":{"tags":["decide-workspace"],"summary":"Update a role (name/description; slug immutable)","security":[{"decideApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":80},"description":{"type":"string","maxLength":400}}}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleEnvelope"}}}}},"operationId":"decidePatchWorkspaceRolesId"},"delete":{"tags":["decide-workspace"],"summary":"Archive a role (pending decisions keep their history)","security":[{"decideApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Archived"},"409":{"$ref":"#/components/responses/Conflict"}},"operationId":"decideDeleteWorkspaceRolesId"}},"/api/v1/workspace/roles/{id}/assignments":{"x-service":["decide"],"servers":[{"url":"{decideBaseUrl}","description":"Decide","variables":{"decideBaseUrl":{"default":"https://xr-decide-production.up.railway.app"}}}],"get":{"tags":["decide-workspace"],"summary":"List member assignments for a role","security":[{"decideApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Assignments","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignmentListEnvelope"}}}}},"operationId":"decideGetWorkspaceRolesIdAssignments"},"put":{"tags":["decide-workspace"],"summary":"Replace the full member-email list (self-healing on every save)","security":[{"decideApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["emails"],"properties":{"emails":{"type":"array","maxItems":100,"items":{"type":"string","format":"email"}}}}}}},"responses":{"200":{"description":"Replaced","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignmentListEnvelope"}}}}},"operationId":"decidePutWorkspaceRolesIdAssignments"}},"/api/v1/workspace/keys":{"x-service":["decide"],"servers":[{"url":"{decideBaseUrl}","description":"Decide","variables":{"decideBaseUrl":{"default":"https://xr-decide-production.up.railway.app"}}}],"get":{"tags":["decide-workspace"],"summary":"List caller API keys (prefix + metadata only)","security":[{"decideApiKey":[],"workspaceToken":[]}],"responses":{"200":{"description":"Keys","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeyListEnvelope"}}}}},"operationId":"decideGetWorkspaceKeys"},"post":{"tags":["decide-workspace"],"summary":"Create a caller API key (plaintext returned once)","security":[{"decideApiKey":[],"workspaceToken":[]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","minLength":1,"maxLength":80}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeyCreatedEnvelope"}}}}},"operationId":"decidePostWorkspaceKeys"}},"/api/v1/workspace/keys/{id}/rotate":{"x-service":["decide"],"servers":[{"url":"{decideBaseUrl}","description":"Decide","variables":{"decideBaseUrl":{"default":"https://xr-decide-production.up.railway.app"}}}],"post":{"tags":["decide-workspace"],"summary":"Rotate a key (new plaintext returned once; old key revoked)","security":[{"decideApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Rotated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeyCreatedEnvelope"}}}}},"operationId":"decidePostWorkspaceKeysIdRotate"}},"/api/v1/workspace/keys/{id}/revoke":{"x-service":["decide"],"servers":[{"url":"{decideBaseUrl}","description":"Decide","variables":{"decideBaseUrl":{"default":"https://xr-decide-production.up.railway.app"}}}],"post":{"tags":["decide-workspace"],"summary":"Revoke a key","security":[{"decideApiKey":[],"workspaceToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Revoked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeyEnvelope"}}}}},"operationId":"decidePostWorkspaceKeysIdRevoke"}},"/api/v1/internal/expire":{"x-service":["decide"],"servers":[{"url":"{decideBaseUrl}","description":"Decide","variables":{"decideBaseUrl":{"default":"https://xr-decide-production.up.railway.app"}}}],"post":{"operationId":"decideInternalExpire","tags":["internal-cron"],"summary":"Expire overdue decisions (scheduled job)","security":[{"decideApiKey":[]}],"responses":{"200":{"description":"`{ data: … }` expired count."}}}},"/api/v1/internal/drain":{"x-service":["decide"],"servers":[{"url":"{decideBaseUrl}","description":"Decide","variables":{"decideBaseUrl":{"default":"https://xr-decide-production.up.railway.app"}}}],"post":{"operationId":"decideInternalDrain","tags":["internal-cron"],"summary":"Drain the outbound event outbox (scheduled job)","security":[{"decideApiKey":[]}],"responses":{"200":{"description":"`{ data: … }` drained count."}}}},"/api/v1/mcp":{"x-service":["decide"],"servers":[{"url":"{decideBaseUrl}","description":"Decide","variables":{"decideBaseUrl":{"default":"https://xr-decide-production.up.railway.app"}}}],"post":{"operationId":"decideMcp","tags":["decide-caller"],"summary":"MCP endpoint — request decisions from agent frameworks","security":[{"decideCallerKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"JSON-RPC 2.0 `tools/call` envelope."}}}},"responses":{"200":{"description":"JSON-RPC response."}}}}},"webhooks":{"decisionUpdate":{"post":{"summary":"Delivered to each registered caller endpoint on needs_info/resolved/expired/cancelled","description":"Signed like the workspace inbound event bus:\n`X-Decide-Signature: v1=<hex HMAC-SHA256 over \"<X-Decide-Timestamp>.<rawBody>\">`,\n±300s skew. 5 attempts with exponential backoff, then dead-letter.\n","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["event","decision"],"properties":{"event":{"type":"string","enum":["needs_info","resolved","expired","cancelled"]},"decision":{"$ref":"#/components/schemas/Decision"}}}}}},"responses":{"200":{"description":"Acknowledged (any 2xx)"}}}}}}