# info.description
Generated reference for the schema-backed integration surface and the release-domain-bound Process Twin demo-session service. Do not hand-edit; run `pnpm -C apps/web openapi:emit`.

# paths./api/integration/v1/messages.post.summary
Push an inbound integration message (effectively-once via Idempotency-Key).

# paths./api/integration/v1/messages.post.responses.200.description
The inbound receipt (idempotent replay of an already-recorded message).

# paths./api/integration/v1/messages.post.responses.201.description
The recorded inbound receipt (newly appended).

# paths./api/integration/v1/messages.post.responses.403.description
The key lacks the integration:write scope.

# paths./api/integration/v1/messages.post.responses.409.description
The Idempotency-Key was already used with a different body (record-inbound-message.idempotency-conflict) or by a different key (…idempotency-actor-conflict).

# paths./api/integration/v1/messages.post.responses.422.description
The body does not match the integration-inbound-message schema, or the message content is invalid (record-inbound-message.invalid-input).

# paths./api/integration/v1/messages.post.responses.429.description
Per-key rate limit exceeded (fail-closed GCRA).

# paths./api/integration/v1/messages/{id}.get.parameters[].description
Inbound-message id (`iim_` + 24 lowercase hex). A value not matching the pattern returns the uniform 404 (not-found), NOT a 4xx validation error.

# paths./api/integration/v1/messages/{id}.get.responses.403.description
The key lacks the integration:read scope.

# paths./api/integration/v1/messages/{id}.get.responses.404.description
No such message — the UNIFORM answer for a malformed id AND a genuinely absent one (no existence oracle).

# paths./api/integration/v1/gl/export.get.summary
Pull the vendor-neutral GL export batch.

# paths./api/integration/v1/gl/export.get.responses.403.description
The key lacks the integration:gl:read scope.

# paths./api/integration/v1/gl/export.get.responses.503.description
The named Tier-1 connector is not wired for live egress yet (integration-connector.config-missing) — pull system=in-house meanwhile.

# paths./api/process-twin/v1/demo-sessions.post.summary
Create or idempotently replay a Process Twin demo session.

# paths./api/process-twin/v1/demo-sessions.post.parameters[].description
Caller-chosen operation key, 1–255 characters. Reuse with identical input replays; divergent reuse returns 409.

# paths./api/process-twin/v1/demo-sessions.post.responses.200.description
Existing session returned by idempotent replay.

# paths./api/process-twin/v1/demo-sessions.post.responses.400.description
process-twin-demo.idempotency-key-required — Idempotency-Key is missing or outside the 1–255 character bound. process-twin-demo.invalid-json — The request body is not valid JSON.

# paths./api/process-twin/v1/demo-sessions.post.responses.401.description
process-twin-demo.unauthorized — The Process Twin service API key is missing or invalid.

# paths./api/process-twin/v1/demo-sessions.post.responses.403.description
process-twin-demo.forbidden — The service API key lacks the operation-specific scope.

# paths./api/process-twin/v1/demo-sessions.post.responses.409.description
process-twin-demo.idempotency-conflict — The Idempotency-Key was already used with different request content. process-twin-demo.idempotency-actor-conflict — The Idempotency-Key was already used by a different service principal. process-twin-demo.session-terminal — The requested transition conflicts with a terminal session.

# paths./api/process-twin/v1/demo-sessions.post.responses.413.description
process-twin-demo.too-large — The request body exceeds the bounded service limit.

# paths./api/process-twin/v1/demo-sessions.post.responses.422.description
process-twin-demo.invalid-body — The request body does not match the current operation schema.

# paths./api/process-twin/v1/demo-sessions.post.responses.429.description
process-twin-demo.rate-limited — The per-key request limit was exceeded. process-twin-demo.active-session-capacity — The Process Twin active-session capacity is full.

# paths./api/process-twin/v1/demo-sessions.post.responses.429.headers.Retry-After.description
Seconds to wait before retrying, when the response supplies a value.

# paths./api/process-twin/v1/demo-sessions.post.responses.500.description
process-twin-demo.maintenance-fence-invalid — The Process Twin maintenance/release configuration is invalid. process-twin-demo.error — The request failed unexpectedly.

# paths./api/process-twin/v1/demo-sessions.post.responses.503.description
process-twin-demo.maintenance-fence-held — A protected maintenance operation temporarily blocks session creation. process-twin-demo.maintenance-fence-unmet — The maintenance admission record is unavailable or its preconditions are unmet. process-twin-demo.unavailable — A required Process Twin dependency is unavailable or timed out.

# paths./api/process-twin/v1/demo-sessions.post.responses.503.headers.Retry-After.description
Seconds to wait before retrying, when the response supplies a value.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}.get.summary
Read bounded Process Twin demo session metadata.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}.get.parameters[].description
Main-owned CRM source-link id. A malformed id returns the same 404 as an absent or foreign session.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}.get.responses.401.description
process-twin-demo.unauthorized — The Process Twin service API key is missing or invalid.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}.get.responses.403.description
process-twin-demo.forbidden — The service API key lacks the operation-specific scope.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}.get.responses.404.description
process-twin-demo.not-found — The source-link id is malformed, absent, or outside the key release domain.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}.get.responses.429.description
process-twin-demo.rate-limited — The per-key request limit was exceeded. process-twin-demo.active-session-capacity — The Process Twin active-session capacity is full.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}.get.responses.429.headers.Retry-After.description
Seconds to wait before retrying, when the response supplies a value.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}.get.responses.500.description
process-twin-demo.maintenance-fence-invalid — The Process Twin maintenance/release configuration is invalid. process-twin-demo.error — The request failed unexpectedly.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}.get.responses.503.description
process-twin-demo.maintenance-fence-held — A protected maintenance operation temporarily blocks session creation. process-twin-demo.maintenance-fence-unmet — The maintenance admission record is unavailable or its preconditions are unmet. process-twin-demo.unavailable — A required Process Twin dependency is unavailable or timed out.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}.get.responses.503.headers.Retry-After.description
Seconds to wait before retrying, when the response supplies a value.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}/state.get.summary
Read bounded operational state for one Process Twin demo session.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}/state.get.parameters[].description
Main-owned CRM source-link id. A malformed id returns the same 404 as an absent or foreign session.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}/state.get.responses.401.description
process-twin-demo.unauthorized — The Process Twin service API key is missing or invalid.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}/state.get.responses.403.description
process-twin-demo.forbidden — The service API key lacks the operation-specific scope.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}/state.get.responses.404.description
process-twin-demo.not-found — The source-link id is malformed, absent, or outside the key release domain.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}/state.get.responses.429.description
process-twin-demo.rate-limited — The per-key request limit was exceeded. process-twin-demo.active-session-capacity — The Process Twin active-session capacity is full.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}/state.get.responses.429.headers.Retry-After.description
Seconds to wait before retrying, when the response supplies a value.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}/state.get.responses.500.description
process-twin-demo.maintenance-fence-invalid — The Process Twin maintenance/release configuration is invalid. process-twin-demo.error — The request failed unexpectedly.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}/state.get.responses.503.description
process-twin-demo.maintenance-fence-held — A protected maintenance operation temporarily blocks session creation. process-twin-demo.maintenance-fence-unmet — The maintenance admission record is unavailable or its preconditions are unmet. process-twin-demo.unavailable — A required Process Twin dependency is unavailable or timed out.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}/state.get.responses.503.headers.Retry-After.description
Seconds to wait before retrying, when the response supplies a value.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}/revoke.post.summary
Revoke a Process Twin demo session. The request body must be empty.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}/revoke.post.parameters[].description
Main-owned CRM source-link id. A malformed id returns the same 404 as an absent or foreign session.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}/revoke.post.parameters[].description
Caller-chosen operation key, 1–255 characters. Reuse with identical input replays; divergent reuse returns 409.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}/revoke.post.responses.200.description
Revoked Process Twin demo session metadata.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}/revoke.post.responses.400.description
process-twin-demo.idempotency-key-required — Idempotency-Key is missing or outside the 1–255 character bound. process-twin-demo.invalid-json — The request body is not valid JSON.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}/revoke.post.responses.401.description
process-twin-demo.unauthorized — The Process Twin service API key is missing or invalid.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}/revoke.post.responses.403.description
process-twin-demo.forbidden — The service API key lacks the operation-specific scope.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}/revoke.post.responses.404.description
process-twin-demo.not-found — The source-link id is malformed, absent, or outside the key release domain.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}/revoke.post.responses.409.description
process-twin-demo.idempotency-conflict — The Idempotency-Key was already used with different request content. process-twin-demo.idempotency-actor-conflict — The Idempotency-Key was already used by a different service principal. process-twin-demo.session-terminal — The requested transition conflicts with a terminal session.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}/revoke.post.responses.413.description
process-twin-demo.too-large — The request body exceeds the bounded service limit.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}/revoke.post.responses.422.description
process-twin-demo.invalid-body — The request body does not match the current operation schema.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}/revoke.post.responses.429.description
process-twin-demo.rate-limited — The per-key request limit was exceeded. process-twin-demo.active-session-capacity — The Process Twin active-session capacity is full.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}/revoke.post.responses.429.headers.Retry-After.description
Seconds to wait before retrying, when the response supplies a value.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}/revoke.post.responses.500.description
process-twin-demo.maintenance-fence-invalid — The Process Twin maintenance/release configuration is invalid. process-twin-demo.error — The request failed unexpectedly.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}/revoke.post.responses.503.description
process-twin-demo.maintenance-fence-held — A protected maintenance operation temporarily blocks session creation. process-twin-demo.maintenance-fence-unmet — The maintenance admission record is unavailable or its preconditions are unmet. process-twin-demo.unavailable — A required Process Twin dependency is unavailable or timed out.

# paths./api/process-twin/v1/demo-sessions/{sourceLinkId}/revoke.post.responses.503.headers.Retry-After.description
Seconds to wait before retrying, when the response supplies a value.

# components.schemas.integration-inbound-message.description
The INBOUND integration-message envelope a corporate ERP / iPaaS PUSHES to `POST /api/integration/v1/messages` (R10b Interop / Lane 4 — ADR-0221), so the enterprise SYNCS rather than bypasses the native module. This is the request-body contract: the route validates EVERY pushed body against this schema (the `live-frame-envelope.ts` / claim-public-wire `defineEnvelope` discipline) and fails closed on a malformed body (422) BEFORE any write. FROZEN append-only: extend by ADDING optional properties or `messageType` values, never by renaming/removing. The `payload` is OPAQUE to the spine (the integrator's vendor-domain data) — recorded durably on the ledger event, folded by the deferred downstream consumer (BET), bounded by the route's 16 KiB body cap. The request also carries an `Idempotency-Key` HTTP header (NOT a body field) — the dedup identity a re-push replays on. APPS/WEB-OWNED.

# components.schemas.integration-inbound-message.properties.schemaVersion.description
Envelope version. Bumps only on a breaking shape change (append-only additions do NOT bump it).

# components.schemas.integration-inbound-message.properties.messageType.description
The CLOSED inbound message-type vocabulary. `gl.posting-ack` (the ERP confirms it posted a GL batch we exported), `master-data.upsert` (a master-data record — cost center / GL-account mapping / vendor), `hr.worker-event` (an HRIS worker lifecycle event). A new type is an APPEND-ONLY enum extension.

# components.schemas.integration-inbound-message.properties.source.description
The integrator's own system label (e.g. `sap-prod`, `workato`) — for operator attribution + the desk filter.

# components.schemas.integration-inbound-message.properties.occurredAt.description
The integrator-ASSERTED external event time (a canonical UTC instant `YYYY-MM-DDTHH:MM:SS.sssZ`). Distinct from when WE recorded it (the receipt's `receivedAt`).

# components.schemas.integration-inbound-message.properties.externalRef.description
OPTIONAL — the integrator's own reference for this message (their reconciliation handle).

# components.schemas.integration-inbound-message.properties.payloadVersion.description
The integrator's per-`messageType` PAYLOAD version (versions the opaque `payload` shape, independently of this envelope `schemaVersion`).

# components.schemas.integration-inbound-message.properties.payload.description
The OPAQUE vendor-domain payload (a JSON object). The spine never inspects it — recorded on the ledger event, folded by the deferred downstream consumer (BET `integration-inbound-domain-apply`). Bounded by the route's 16 KiB request-body cap.

# components.schemas.integration-inbound-receipt.description
The receipt resource the inbound surface returns for a pushed message (R10b Interop / Lane 4 — ADR-0221): the body of `POST /api/integration/v1/messages` (201 created / 200 replayed) and `GET /api/integration/v1/messages/:id` (round-trippable read-back). Stripe-resource shaped — `object` / `id` / `livemode`-free here, `receivedAt` is our UNIX-epoch-seconds timestamp (the `created` convention). FROZEN append-only: extend by ADDING optional properties or `status` values, never by renaming/removing. The opaque pushed PAYLOAD is NOT echoed (the integrator already holds it; the spine indexes only the receipt axes). APPS/WEB-OWNED.

# components.schemas.integration-inbound-receipt.properties.schemaVersion.description
Resource-envelope version. Bumps only on a breaking shape change (append-only additions do NOT bump it).

# components.schemas.integration-inbound-receipt.properties.object.description
The resource type discriminator (the Stripe `object` convention).

# components.schemas.integration-inbound-receipt.properties.id.description
The inbound-message id (the per-message ledger stream id; round-trippable via GET).

# components.schemas.integration-inbound-receipt.properties.messageType.description
The message type (the closed inbound vocabulary). A SHAPE freeze (non-empty string), not a value freeze — append-only new types are allowed.

# components.schemas.integration-inbound-receipt.properties.source.description
The integrator's own system label, echoed back.

# components.schemas.integration-inbound-receipt.properties.status.description
The run-state (the inbound apply ladder, widened by migration 0070 — R17 Governed Integration Layer Phase 1a / ADR-0269). `received` = the durable, idempotent CAPTURE (the only value the /v1 capture route writes); `applying` = an active/stale apply lease; `processed` / `failed` / `deferred` = terminal states the apply worker (later phases) advances the row to. APPEND-ONLY enum extension (the frozen-receipt rule allows adding `status` values) so the integrator can poll for the new states without a wire change.

# components.schemas.integration-inbound-receipt.properties.occurredAt.description
The integrator-asserted external event time, echoed back faithfully (a canonical UTC instant).

# components.schemas.integration-inbound-receipt.properties.receivedAt.description
When WE durably recorded the message, as UNIX EPOCH SECONDS (the store-clock instant; the Stripe `created` convention).

# components.schemas.integration-inbound-receipt.properties.externalRef.description
The integrator's own reference, echoed back, or null when none was supplied.

# components.schemas.integration-inbound-receipt.properties.payloadVersion.description
The per-messageType payload version the integrator declared.

# components.schemas.integration-gl-export.description
The vendor-NEUTRAL general-ledger export batch the native Tier-1 interoperability surface emits (R10b Interop / Lane 4 — ADR-0221). A corporate ERP / iPaaS PULLS it from `GET /api/integration/v1/gl/export` (integration:gl:read scope), and the Tier-1 connector adapters (SAP / Oracle, behind the integration-adapters seam) map THIS shape onto their proprietary egress (IDoc/BAPI/OData, Oracle GL interface). FROZEN append-only: extend by ADDING optional properties or `format` values, never by renaming/removing. The numbers are single-sourced from the SAME `readGlExport` fold the accountant-facing CSV/IIF download (`/api/accounting/export`) and the `/accounting` console render, so the machine batch can never drift from them. `schemaVersion` versions this batch envelope. v1 carries the trial balance (one line per account+currency); the per-posting tie-out is an append-only `format` extension. APPS/WEB-OWNED (the root schemas/ directory is the chassis emit pipeline; product wire shapes live here).

# components.schemas.integration-gl-export.properties.schemaVersion.description
Batch-envelope version. Bumps only on a breaking shape change wire consumers must adapt to (append-only additions do NOT bump it).

# components.schemas.integration-gl-export.properties.object.description
The resource type discriminator (the Stripe `object` convention).

# components.schemas.integration-gl-export.properties.format.description
The GL read shape this batch carries. v1 is `trial-balance` (one line per account+currency) — the universally-ingestable GL export every ERP accepts. A future per-posting tie-out is an APPEND-ONLY new `format` value, never a change to this one.

# components.schemas.integration-gl-export.properties.generatedAt.description
When this batch was produced, as UNIX EPOCH SECONDS (the Stripe `created` convention — derived from the request boundary instant, never an ambient fold read).

# components.schemas.integration-gl-export.properties.tenant.description
The branded lowercase tenant id the batch belongs to.

# components.schemas.integration-gl-export.properties.lastSeq.description
The GL stream position this batch was read at (the `X-GL-Last-Seq` provenance watermark) — the integrator pins reconciliation to it; null when the stream is empty.

# components.schemas.integration-gl-export.properties.asOf.description
The knowledge-time cut the books were read as of (a canonical UTC instant), or null for the live tip. A reproduce-the-books pull pins this so two pulls return byte-identical lines.

# components.schemas.integration-gl-export.properties.lines.description
One classified line per account+currency, sorted by account code (deterministic across ICU builds). An off-chart / tenant-override code carries `unclassified` for type + section — NEVER dropped (the GL-egress honesty rule).

# components.schemas.integration-gl-export.properties.lines.items.properties.accountType.description
The classified account type, or `unclassified` for an off-chart / tenant-override code (never dropped).

# components.schemas.integration-gl-export.properties.lines.items.properties.statementSection.description
The statement section, or `unclassified` for an off-chart code.

# components.schemas.integration-gl-export.properties.lines.items.properties.balanceMinor.description
The signed account balance in MINOR units (debit +, credit −) — the machine-precise authoritative value (BigInt-exact upstream, never float math).

# components.schemas.integration-gl-export.properties.lines.items.properties.balanceMajor.description
The signed balance rendered in major units (a convenience display string; `balanceMinor` is authoritative).

# components.schemas.error-envelope.description
The uniform error body every non-2xx integration response carries. Dispatch on `error.code` (stable, dot-namespaced); the HTTP status is the coarse class. `request_id` is the support-correlation handle.

# components.schemas.error-envelope.properties.error.properties.param.description
The offending field / header, when the error is parameter-scoped.

# components.schemas.process-twin-demo-create.description
Current v2 create request. Historical v1 is accepted only by the explicit compatibility decoder and is not the published write shape.

# components.schemas.process-twin-demo-error-envelope.description
Uniform Process Twin service error. Dispatch on error.code; request_id and the request-id response header are support-correlation handles.

# components.securitySchemes.processTwinDemoApiKey.description
Process Twin service API token. Keys are release-domain-bound and scope each operation.