openapi: 3.2.0 info: title: 'GTM API public contract: gtm.service.id Account Shares API' description: 'Identity, access and money: users, teams and members, API keys, OAuth clients and authorizations, billing products, subscriptions, transactions and payment methods, notifications, TLS certificates and support requests.' version: '1.0' contact: name: GTM API url: https://gtm-api.com email: support@gtm-api.com license: name: Proprietary url: https://gtm-api.com/license servers: - url: https://app.gtm-api.com/id/v4 description: Production, through the app.gtm-api.com gateway security: - BearerJwt: [] TeamSid: [] tags: - name: account_shares description: Registry package `mcp.id/account_shares`, served on MCP mount `id.access`. paths: /api/account-shares: post: operationId: create_account_share summary: Lend an account to another workspace description: 'Lend ONE of your connected accounts to another workspace, temporarily and revocably. This is a loan, not a handover: permanent ownership transfer has no MCP tool at all. Target exactly one of to_email (resolved to that user''s working team) or to_team_sid; neither, both, a bad email or a self-target is 422. account_sid is prefix agnostic (ln_ac_, em_ac_); `channel` says which service owns it. ALWAYS ASYNC: returns 201 with status pending, and the loan has NOT started. Poll search_account_shares with filter { sid: { eq } } until status is active (the holder can work) or failed (read failure_reason); rolling_back means it is being undone, so do not re-issue. holder_over_slot true means the copy landed in the holder''s subscription hold and they cannot work until they upgrade; a share never fails on slots. One row is one account with no bulk arm, so N accounts is N calls. planned_return_at only emails the owner a recall link; there is no auto return. Needs can_manage_account_shares. Contract: - MCP tool `create_account_share`, registry package `mcp.id/account_shares`, mount `id.access`. - Operation `create`, response envelope `create`. - Flags: none.' tags: - account_shares requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateAccountShareRequest' responses: '200': description: '`create` success envelope.' content: application/json: schema: $ref: '#/components/schemas/CreateAccountShareResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: create_account_share x-gtm-mcp-mount: id.access x-gtm-entity: account_shares x-gtm-operation: create x-gtm-envelope: create x-gtm-availability: ga x-gtm-dangerous: false x-gtm-mass-action: false x-gtm-step-eligible: false x-gtm-schedule-required: false x-gtm-tool-class: complex /api/account-shares/list-received: post: operationId: list_received_account_shares summary: List received account shares description: 'List the account shares your team RECEIVED: accounts on loan TO you. Reach for this whenever the question is about a BORROWED account (what did we borrow, from whom, until when, is it still active), and for search_account_shares when it is about an account your own team owns and lent out. Registered as an action route but it is a plain read, with the same envelope, filters and sorts as search. It is also the holder''s only programmatic arrival signal, because the domain events fan out to the owner team alone: poll filter { status: { eq: "active" } } sorted by created_at asc. Rows belong to the owner tenant, so created_by and ended_by arrive with permissions emptied and the trace id nulled. include:["counterparty_team"] names the other workspace; no counts block, and page_size 0 returns pagination.total_count alone. Needs can_view_account_shares. Contract: - MCP tool `list_received_account_shares`, registry package `mcp.id/account_shares`, mount `id.access`. - Operation `action`, response envelope `search`. - Flags: read only.' tags: - account_shares requestBody: required: false content: application/json: schema: $ref: '#/components/schemas/ListReceivedAccountSharesRequest' responses: '200': description: '`search` success envelope.' content: application/json: schema: $ref: '#/components/schemas/ListReceivedAccountSharesResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: list_received_account_shares x-gtm-mcp-mount: id.access x-gtm-entity: account_shares x-gtm-operation: action x-gtm-envelope: search x-gtm-availability: ga x-gtm-dangerous: false x-gtm-mass-action: false x-gtm-step-eligible: false x-gtm-schedule-required: false x-gtm-tool-class: typical /api/account-shares/recall: post: operationId: recall_account_share summary: Recall a lent-out account description: 'Take a lent-out account back. Owner side, no holder consent. Target EXACTLY ONE of sid (ac_sh_) or filter; neither or both is 422 on sid_or_filter. FILTER MODE fans out over the loans you ISSUED, the server FORCES status to active so your filter can only narrow the set, and it drains INLINE at most 100 shares per call, minting no mass-action row. It also requires confirmation_count equal to the active-pinned pagination.total_count search_account_shares reports for the same filter; anything else is 409 confirmation_count_mismatch. Single-sid mode ignores it. ASYNC: the call stamps status closing and a driver does the teardown, so closing_count means shares that STARTED closing, never shares recalled; poll status to recalled. NOT atomic: a mid-batch error returns no counters and earlier shares stay closing, so re-query search rather than retrying the same body. closing_count below total_matched leaves a remainder; every next call needs a FRESH count. Needs can_manage_account_shares. Contract: - MCP tool `recall_account_share`, registry package `mcp.id/account_shares`, mount `id.access`. - Operation `action`, response envelope `action`. - Flags: dangerous: the MCP layer gates it behind a preview/commit token, and the effect cannot be undone through this API; mass action: this verb''s own request accepts a filter or targets[] set, which the owning service drains.' tags: - account_shares requestBody: required: false content: application/json: schema: $ref: '#/components/schemas/RecallAccountShareRequest' responses: '200': description: '`action` success envelope.' content: application/json: schema: $ref: '#/components/schemas/RecallAccountShareResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: recall_account_share x-gtm-mcp-mount: id.access x-gtm-entity: account_shares x-gtm-operation: action x-gtm-envelope: action x-gtm-availability: ga x-gtm-dangerous: true x-gtm-mass-action: true x-gtm-step-eligible: false x-gtm-schedule-required: false x-gtm-tool-class: typical /api/account-shares/return: post: operationId: return_account_share summary: Return a borrowed account description: 'Give a borrowed account back early. Holder side. Same shape as recall_account_share: EXACTLY ONE of sid (ac_sh_) or filter, filter mode server-pinned to status active, drained INLINE at most 100 shares per call with no mass-action row minted, and confirmation_count required with filter and matched against the active-pinned pagination.total_count of list_received_account_shares (409 confirmation_count_mismatch otherwise). The difference is the side: the filter resolves over the loans you RECEIVED, and a share you do not hold is 403 not_share_holder. ASYNC: it stamps status closing, then the driver tears the holder copy down and un-parks the owner, so closing_count counts shares that STARTED closing; poll status to returned. Not atomic, and the same remainder and recount rule as recall. Deleting the borrowed copy on the channel has the same effect, ending the loan with end_reason holder_deleted_copy. Needs can_manage_account_shares. Contract: - MCP tool `return_account_share`, registry package `mcp.id/account_shares`, mount `id.access`. - Operation `action`, response envelope `action`. - Flags: dangerous: the MCP layer gates it behind a preview/commit token, and the effect cannot be undone through this API; mass action: this verb''s own request accepts a filter or targets[] set, which the owning service drains.' tags: - account_shares requestBody: required: false content: application/json: schema: $ref: '#/components/schemas/ReturnAccountShareRequest' responses: '200': description: '`action` success envelope.' content: application/json: schema: $ref: '#/components/schemas/ReturnAccountShareResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: return_account_share x-gtm-mcp-mount: id.access x-gtm-entity: account_shares x-gtm-operation: action x-gtm-envelope: action x-gtm-availability: ga x-gtm-dangerous: true x-gtm-mass-action: true x-gtm-step-eligible: false x-gtm-schedule-required: false x-gtm-tool-class: typical /api/account-shares/search: post: operationId: search_account_shares summary: Search issued account shares description: 'List the account shares your team ISSUED: accounts you lent OUT to another workspace. Sharing is TEMPORARY and revocable; permanent ownership transfer is a web-app-only flow with no MCP tool, so never offer this as a way to give an account away. This is also the polling surface, since there is no get tool and no /{sid} route: read one loan with filter { sid: { eq } } and watch status until active (the holder can work), failed (it never started, read failure_reason), or terminal recalled / returned. filter.owner_account_sid answers ''is this account lent out and to whom''; holder_over_slot finds loans that landed with no free slot. The number recall_account_share has to confirm is pagination.total_count here, NOT total_matched; page_size 0 returns it with no rows. No include[], no counts block, no free-text q. Needs can_view_account_shares. Contract: - MCP tool `search_account_shares`, registry package `mcp.id/account_shares`, mount `id.access`. - Operation `search`, response envelope `search`. - Flags: read only.' tags: - account_shares requestBody: required: false content: application/json: schema: $ref: '#/components/schemas/SearchAccountSharesRequest' responses: '200': description: '`search` success envelope.' content: application/json: schema: $ref: '#/components/schemas/SearchAccountSharesResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: search_account_shares x-gtm-mcp-mount: id.access x-gtm-entity: account_shares x-gtm-operation: search x-gtm-envelope: search x-gtm-availability: ga x-gtm-dangerous: false x-gtm-mass-action: false x-gtm-step-eligible: false x-gtm-schedule-required: false x-gtm-tool-class: typical components: schemas: RecallAccountShareRequest: type: object description: Request body of `recall_account_share`. properties: sid: type: string minLength: 18 maxLength: 18 pattern: ^ac_sh_ description: Single-share mode. Mutually exclusive with filter. filter: type: object properties: sid: type: object properties: eq: type: string in: type: array items: type: string additionalProperties: false channel: type: object properties: eq: type: string enum: - linkedin - email in: type: array items: type: string enum: - linkedin - email additionalProperties: false description: '"My LinkedIn loans" vs "my email loans".' status: type: object properties: eq: type: string enum: - pending - owner_parked - active - closing - holder_released - rolling_back - returned - recalled - failed ne: type: string enum: - pending - owner_parked - active - closing - holder_released - rolling_back - returned - recalled - failed in: type: array items: type: string enum: - pending - owner_parked - active - closing - holder_released - rolling_back - returned - recalled - failed nin: type: array items: type: string enum: - pending - owner_parked - active - closing - holder_released - rolling_back - returned - recalled - failed additionalProperties: false description: 'The phase. { eq: "active" } is the live set; { in: ["rolling_back","failed"] } is the loans that gave up.' to_team_sid: type: object properties: eq: type: string in: type: array items: type: string additionalProperties: false description: 'Owner side question: everything lent to team X.' to_user_sid: type: object properties: eq: type: string in: type: array items: type: string additionalProperties: false owner_account_sid: type: object properties: eq: type: string in: type: array items: type: string additionalProperties: false description: 'Share history of an owned account: "is this account lent out, and to whom".' holder_account_sid: type: object properties: eq: type: string in: type: array items: type: string additionalProperties: false description: 'Holder side question: map a borrowed copy back to its loan.' holder_over_slot: type: object properties: eq: type: boolean additionalProperties: false description: Which loans reached active but landed with no free slot on the holder side. end_reason: type: object properties: eq: type: string enum: - returned_by_holder - recalled_by_owner - holder_deleted_copy - holder_team_purged - owner_team_purged in: type: array items: type: string enum: - returned_by_holder - recalled_by_owner - holder_deleted_copy - holder_team_purged - owner_team_purged is_null: type: boolean additionalProperties: false failure_reason: type: object properties: eq: type: string enum: - park_failed - export_failed - copy_refused - probe_stale - team_purged in: type: array items: type: string enum: - park_failed - export_failed - copy_refused - probe_stale - team_purged is_null: type: boolean additionalProperties: false owner_cluster_id: type: object properties: eq: type: integer in: type: array items: type: integer additionalProperties: false holder_cluster_id: type: object properties: eq: type: integer in: type: array items: type: integer additionalProperties: false phase_claimed_at: type: object properties: gte: type: string lte: type: string is_null: type: boolean additionalProperties: false planned_return_at: type: object properties: gte: type: string lte: type: string gt: type: string lt: type: string is_null: type: boolean additionalProperties: false description: '{ is_null: true } is an open ended lend.' created_at: type: object properties: gte: type: string lte: type: string gt: type: string lt: type: string additionalProperties: false description: Mass-target mode, resolved against the loans you ISSUED. status is overwritten with eq active server side, so it cannot be widened. Mutually exclusive with sid. confirmation_count: type: integer minimum: 0 description: Blast-radius confirmation, REQUIRED with filter and ignored with sid. Must equal the active-pinned pagination.total_count of the same filter from search_account_shares; a mismatch is 409, not a partial run. McpError: type: object properties: success: type: boolean enum: - false error: type: object properties: code: type: string enum: - validation_failed - nothing_to_update - not_found - relation_not_found - invalid_transition - limit_exceeded - payment_required - duplicate_rejected - conflict - delete_blocked - unauthorized - forbidden - rate_limited - internal_error - service_unavailable - not_implemented message: type: string recoverable: type: boolean suggestion: type: string field_errors: type: object additionalProperties: type: array items: type: object properties: rule: type: string message: type: string required: - rule - message blockers: type: array items: type: object properties: type: type: string description: Machine-readable blocker type (active_flow, pending_tasks, …). severity: type: string enum: - hard - soft description: hard = external action required; soft = acknowledge is enough. description: type: string entity_sid: type: - string - 'null' count: type: integer resolution: type: string description: 'Hard: tool name to call. Soft: code for acknowledge[].' resolution_hint: type: string required: - type - severity - description - entity_sid - resolution - resolution_hint context: type: object additionalProperties: {} required: - code - message - recoverable meta: type: object properties: trace_id: type: string description: UUID v7; same 128-bit value as the X-Trace-Id header. span_id: type: string pattern: ^[0-9a-f]{16}$ description: 16 hex chars, root span of this request. timestamp: type: string description: ISO 8601 UTC (Y-m-dTH:i:sZ), response time. duration_ms: type: integer minimum: 0 description: Server-side wall clock. team_sid: type: - string - 'null' description: The team this call ran in (the token team, or the team_sid override). Null when unauthenticated; absent from pre-2026-08-20 backends. actor_type: type: - string - 'null' description: user | agent | api_key | system. Null when unauthenticated; absent from pre-2026-08-20 backends. required: - trace_id - span_id - timestamp - duration_ms required: - success - error RecallAccountShareResponse: type: object properties: success: type: boolean enum: - true operation: type: string enum: - action action: type: string description: kebab-case verb; matches the route segment. item: type: - object - 'null' properties: sid: type: string team_sid: type: string description: 'The OWNER team: the row tenant, the side that lent the account out.' channel: type: string enum: - linkedin - email description: Which channel service owns the physical account pair. to_team_sid: type: string description: 'The HOLDER team: the side that borrowed the account.' to_user_sid: type: - string - 'null' description: Resolved user when the share was targeted by email; null when targeted by team sid. to_email: type: - string - 'null' description: The targeting input kept for audit; null when targeted by team sid. owner_cluster_id: type: integer holder_cluster_id: type: integer owner_account_sid: type: string description: 'The owner''s channel account row, parked for the duration of the loan. Prefix agnostic: ln_ac_ on LinkedIn, em_ac_ on email.' owner_channel_ref: type: - string - 'null' description: Opaque second row the channel needs to name (LinkedIn puts its ab_br_ browser sid here); null when the channel needs none. holder_account_sid: type: - string - 'null' description: The holder's copy. NULL until the copy phase lands, so it is null on every pre-active row. holder_channel_ref: type: - string - 'null' owner_account_label: type: - string - 'null' description: 'The channel''s display name for the lent account, e.g. "Jane Roe (jane-roe)". Use it to tell one share from another when reporting to a human. Null when the channel had no name to give. Display only: never filter, match or reason on it.' status: type: string enum: - pending - owner_parked - active - closing - holder_released - rolling_back - returned - recalled - failed description: The durable phase, and the answer to "did the loan start". Only active means the holder can work. holder_over_slot: type: boolean description: True when the holder had no free account slot at create, so the copy landed in the channel's subscription hold. The loan still reaches active; the holder cannot work until it upgrades. end_reason: type: - string - 'null' enum: - returned_by_holder - recalled_by_owner - holder_deleted_copy - holder_team_purged - owner_team_purged description: Stamped when an ending is REQUESTED. Only ever set on a row that reached active. failure_reason: type: - string - 'null' enum: - park_failed - export_failed - copy_refused - probe_stale - team_purged description: Why a pre-active phase gave up. Non null on exactly rolling_back and failed. planned_return_at: type: - string - 'null' description: Informational only. When it passes the owner is emailed a recall link once; there is NO auto return. expiry_notified_at: type: - string - 'null' phase_claimed_at: type: - string - 'null' phase_attempts: type: integer description: Attempts on the CURRENT phase, reset on every advance. A large and growing value is the stuck signal on a phase that may not give up. ended_at: type: - string - 'null' ended_by: type: - object - 'null' properties: actor_type: type: string enum: - user - support - api_key - system - agent actor_sid: type: - string - 'null' team_sid: type: string actor_name: type: - string - 'null' description: The OAuth client that acted ("Claude", "n8n"); null for a user, an API key or a system job. oauth_client_sid: type: - string - 'null' description: The acting OAuth client (id_oc_*); null off the OAuth path. reason: type: - string - 'null' description: Why a system actor wrote the row (snapshot_capture_job, ...); null otherwise. permissions: type: object additionalProperties: {} description: 'Internal audit context: the grant set the actor held at write time. Not a contract.' cluster_id: type: - integer - 'null' description: 'Internal audit context: the cluster that served the write.' trace_id: type: - string - 'null' description: 'Internal audit context: the trace id of the request that wrote the row.' required: - actor_type - actor_sid - team_sid - permissions description: Who ended it. The machine readable why is end_reason (an ending) or failure_reason (a failure), never this blob. created_by: type: - object - 'null' properties: actor_type: type: string enum: - user - support - api_key - system - agent actor_sid: type: - string - 'null' team_sid: type: string actor_name: type: - string - 'null' description: The OAuth client that acted ("Claude", "n8n"); null for a user, an API key or a system job. oauth_client_sid: type: - string - 'null' description: The acting OAuth client (id_oc_*); null off the OAuth path. reason: type: - string - 'null' description: Why a system actor wrote the row (snapshot_capture_job, ...); null otherwise. permissions: type: object additionalProperties: {} description: 'Internal audit context: the grant set the actor held at write time. Not a contract.' cluster_id: type: - integer - 'null' description: 'Internal audit context: the cluster that served the write.' trace_id: type: - string - 'null' description: 'Internal audit context: the trace id of the request that wrote the row.' required: - actor_type - actor_sid - team_sid - permissions created_at: type: string updated_at: type: string required: - sid - team_sid - channel - to_team_sid - to_user_sid - to_email - owner_cluster_id - holder_cluster_id - owner_account_sid - owner_channel_ref - holder_account_sid - holder_channel_ref - owner_account_label - status - holder_over_slot - end_reason - failure_reason - planned_return_at - expiry_notified_at - phase_claimed_at - phase_attempts - ended_at - ended_by - created_by - created_at - updated_at result: type: object properties: closing_count: type: integer minimum: 0 description: Shares this call stamped closing. The teardown is the driver's, so this is never "recalled" or "returned". total_matched: type: integer minimum: 0 description: True count of active shares the target set held. closing_count below this means a remainder is left; re-read the count before the next call. required: - closing_count - total_matched meta: type: object properties: trace_id: type: string description: UUID v7; same 128-bit value as the X-Trace-Id header. span_id: type: string pattern: ^[0-9a-f]{16}$ description: 16 hex chars, root span of this request. timestamp: type: string description: ISO 8601 UTC (Y-m-dTH:i:sZ), response time. duration_ms: type: integer minimum: 0 description: Server-side wall clock. team_sid: type: - string - 'null' description: The team this call ran in (the token team, or the team_sid override). Null when unauthenticated; absent from pre-2026-08-20 backends. actor_type: type: - string - 'null' description: user | agent | api_key | system. Null when unauthenticated; absent from pre-2026-08-20 backends. required: - trace_id - span_id - timestamp - duration_ms required: - success - operation - action - item - result - meta CreateAccountShareResponse: type: object properties: success: type: boolean enum: - true operation: type: string enum: - create item: type: object properties: sid: type: string team_sid: type: string description: 'The OWNER team: the row tenant, the side that lent the account out.' channel: type: string enum: - linkedin - email description: Which channel service owns the physical account pair. to_team_sid: type: string description: 'The HOLDER team: the side that borrowed the account.' to_user_sid: type: - string - 'null' description: Resolved user when the share was targeted by email; null when targeted by team sid. to_email: type: - string - 'null' description: The targeting input kept for audit; null when targeted by team sid. owner_cluster_id: type: integer holder_cluster_id: type: integer owner_account_sid: type: string description: 'The owner''s channel account row, parked for the duration of the loan. Prefix agnostic: ln_ac_ on LinkedIn, em_ac_ on email.' owner_channel_ref: type: - string - 'null' description: Opaque second row the channel needs to name (LinkedIn puts its ab_br_ browser sid here); null when the channel needs none. holder_account_sid: type: - string - 'null' description: The holder's copy. NULL until the copy phase lands, so it is null on every pre-active row. holder_channel_ref: type: - string - 'null' owner_account_label: type: - string - 'null' description: 'The channel''s display name for the lent account, e.g. "Jane Roe (jane-roe)". Use it to tell one share from another when reporting to a human. Null when the channel had no name to give. Display only: never filter, match or reason on it.' status: type: string enum: - pending - owner_parked - active - closing - holder_released - rolling_back - returned - recalled - failed description: The durable phase, and the answer to "did the loan start". Only active means the holder can work. holder_over_slot: type: boolean description: True when the holder had no free account slot at create, so the copy landed in the channel's subscription hold. The loan still reaches active; the holder cannot work until it upgrades. end_reason: type: - string - 'null' enum: - returned_by_holder - recalled_by_owner - holder_deleted_copy - holder_team_purged - owner_team_purged description: Stamped when an ending is REQUESTED. Only ever set on a row that reached active. failure_reason: type: - string - 'null' enum: - park_failed - export_failed - copy_refused - probe_stale - team_purged description: Why a pre-active phase gave up. Non null on exactly rolling_back and failed. planned_return_at: type: - string - 'null' description: Informational only. When it passes the owner is emailed a recall link once; there is NO auto return. expiry_notified_at: type: - string - 'null' phase_claimed_at: type: - string - 'null' phase_attempts: type: integer description: Attempts on the CURRENT phase, reset on every advance. A large and growing value is the stuck signal on a phase that may not give up. ended_at: type: - string - 'null' ended_by: type: - object - 'null' properties: actor_type: type: string enum: - user - support - api_key - system - agent actor_sid: type: - string - 'null' team_sid: type: string actor_name: type: - string - 'null' description: The OAuth client that acted ("Claude", "n8n"); null for a user, an API key or a system job. oauth_client_sid: type: - string - 'null' description: The acting OAuth client (id_oc_*); null off the OAuth path. reason: type: - string - 'null' description: Why a system actor wrote the row (snapshot_capture_job, ...); null otherwise. permissions: type: object additionalProperties: {} description: 'Internal audit context: the grant set the actor held at write time. Not a contract.' cluster_id: type: - integer - 'null' description: 'Internal audit context: the cluster that served the write.' trace_id: type: - string - 'null' description: 'Internal audit context: the trace id of the request that wrote the row.' required: - actor_type - actor_sid - team_sid - permissions description: Who ended it. The machine readable why is end_reason (an ending) or failure_reason (a failure), never this blob. created_by: type: - object - 'null' properties: actor_type: type: string enum: - user - support - api_key - system - agent actor_sid: type: - string - 'null' team_sid: type: string actor_name: type: - string - 'null' description: The OAuth client that acted ("Claude", "n8n"); null for a user, an API key or a system job. oauth_client_sid: type: - string - 'null' description: The acting OAuth client (id_oc_*); null off the OAuth path. reason: type: - string - 'null' description: Why a system actor wrote the row (snapshot_capture_job, ...); null otherwise. permissions: type: object additionalProperties: {} description: 'Internal audit context: the grant set the actor held at write time. Not a contract.' cluster_id: type: - integer - 'null' description: 'Internal audit context: the cluster that served the write.' trace_id: type: - string - 'null' description: 'Internal audit context: the trace id of the request that wrote the row.' required: - actor_type - actor_sid - team_sid - permissions created_at: type: string updated_at: type: string required: - sid - team_sid - channel - to_team_sid - to_user_sid - to_email - owner_cluster_id - holder_cluster_id - owner_account_sid - owner_channel_ref - holder_account_sid - holder_channel_ref - owner_account_label - status - holder_over_slot - end_reason - failure_reason - planned_return_at - expiry_notified_at - phase_claimed_at - phase_attempts - ended_at - ended_by - created_by - created_at - updated_at already_exists: type: boolean meta: type: object properties: trace_id: type: string description: UUID v7; same 128-bit value as the X-Trace-Id header. span_id: type: string pattern: ^[0-9a-f]{16}$ description: 16 hex chars, root span of this request. timestamp: type: string description: ISO 8601 UTC (Y-m-dTH:i:sZ), response time. duration_ms: type: integer minimum: 0 description: Server-side wall clock. team_sid: type: - string - 'null' description: The team this call ran in (the token team, or the team_sid override). Null when unauthenticated; absent from pre-2026-08-20 backends. actor_type: type: - string - 'null' description: user | agent | api_key | system. Null when unauthenticated; absent from pre-2026-08-20 backends. required: - trace_id - span_id - timestamp - duration_ms required: - success - operation - item - already_exists - meta ListReceivedAccountSharesRequest: type: object description: Request body of `list_received_account_shares`. properties: filter: type: object properties: sid: type: object properties: eq: type: string in: type: array items: type: string additionalProperties: false channel: type: object properties: eq: type: string enum: - linkedin - email in: type: array items: type: string enum: - linkedin - email additionalProperties: false description: '"My LinkedIn loans" vs "my email loans".' status: type: object properties: eq: type: string enum: - pending - owner_parked - active - closing - holder_released - rolling_back - returned - recalled - failed ne: type: string enum: - pending - owner_parked - active - closing - holder_released - rolling_back - returned - recalled - failed in: type: array items: type: string enum: - pending - owner_parked - active - closing - holder_released - rolling_back - returned - recalled - failed nin: type: array items: type: string enum: - pending - owner_parked - active - closing - holder_released - rolling_back - returned - recalled - failed additionalProperties: false description: 'The phase. { eq: "active" } is the live set; { in: ["rolling_back","failed"] } is the loans that gave up.' to_team_sid: type: object properties: eq: type: string in: type: array items: type: string additionalProperties: false description: 'Owner side question: everything lent to team X.' to_user_sid: type: object properties: eq: type: string in: type: array items: type: string additionalProperties: false owner_account_sid: type: object properties: eq: type: string in: type: array items: type: string additionalProperties: false description: 'Share history of an owned account: "is this account lent out, and to whom".' holder_account_sid: type: object properties: eq: type: string in: type: array items: type: string additionalProperties: false description: 'Holder side question: map a borrowed copy back to its loan.' holder_over_slot: type: object properties: eq: type: boolean additionalProperties: false description: Which loans reached active but landed with no free slot on the holder side. end_reason: type: object properties: eq: type: string enum: - returned_by_holder - recalled_by_owner - holder_deleted_copy - holder_team_purged - owner_team_purged in: type: array items: type: string enum: - returned_by_holder - recalled_by_owner - holder_deleted_copy - holder_team_purged - owner_team_purged is_null: type: boolean additionalProperties: false failure_reason: type: object properties: eq: type: string enum: - park_failed - export_failed - copy_refused - probe_stale - team_purged in: type: array items: type: string enum: - park_failed - export_failed - copy_refused - probe_stale - team_purged is_null: type: boolean additionalProperties: false owner_cluster_id: type: object properties: eq: type: integer in: type: array items: type: integer additionalProperties: false holder_cluster_id: type: object properties: eq: type: integer in: type: array items: type: integer additionalProperties: false phase_claimed_at: type: object properties: gte: type: string lte: type: string is_null: type: boolean additionalProperties: false planned_return_at: type: object properties: gte: type: string lte: type: string gt: type: string lt: type: string is_null: type: boolean additionalProperties: false description: '{ is_null: true } is an open ended lend.' created_at: type: object properties: gte: type: string lte: type: string gt: type: string lt: type: string additionalProperties: false include: type: array items: type: string enum: - counterparty_team description: Relations to eager-load (see entity Includes). sort: type: object properties: field: type: string enum: - created_at - planned_return_at - updated_at direction: type: string enum: - asc - desc description: Default desc. required: - field page_size: type: integer minimum: 0 maximum: 200 description: 0..200, default 50. page_size=0 = count-only, page_size=1 = getFirst. cursor: type: - string - 'null' description: Opaque forward cursor from a previous response pagination.next_cursor. SearchAccountSharesRequest: type: object description: Request body of `search_account_shares`. properties: filter: type: object properties: sid: type: object properties: eq: type: string in: type: array items: type: string additionalProperties: false channel: type: object properties: eq: type: string enum: - linkedin - email in: type: array items: type: string enum: - linkedin - email additionalProperties: false description: '"My LinkedIn loans" vs "my email loans".' status: type: object properties: eq: type: string enum: - pending - owner_parked - active - closing - holder_released - rolling_back - returned - recalled - failed ne: type: string enum: - pending - owner_parked - active - closing - holder_released - rolling_back - returned - recalled - failed in: type: array items: type: string enum: - pending - owner_parked - active - closing - holder_released - rolling_back - returned - recalled - failed nin: type: array items: type: string enum: - pending - owner_parked - active - closing - holder_released - rolling_back - returned - recalled - failed additionalProperties: false description: 'The phase. { eq: "active" } is the live set; { in: ["rolling_back","failed"] } is the loans that gave up.' to_team_sid: type: object properties: eq: type: string in: type: array items: type: string additionalProperties: false description: 'Owner side question: everything lent to team X.' to_user_sid: type: object properties: eq: type: string in: type: array items: type: string additionalProperties: false owner_account_sid: type: object properties: eq: type: string in: type: array items: type: string additionalProperties: false description: 'Share history of an owned account: "is this account lent out, and to whom".' holder_account_sid: type: object properties: eq: type: string in: type: array items: type: string additionalProperties: false description: 'Holder side question: map a borrowed copy back to its loan.' holder_over_slot: type: object properties: eq: type: boolean additionalProperties: false description: Which loans reached active but landed with no free slot on the holder side. end_reason: type: object properties: eq: type: string enum: - returned_by_holder - recalled_by_owner - holder_deleted_copy - holder_team_purged - owner_team_purged in: type: array items: type: string enum: - returned_by_holder - recalled_by_owner - holder_deleted_copy - holder_team_purged - owner_team_purged is_null: type: boolean additionalProperties: false failure_reason: type: object properties: eq: type: string enum: - park_failed - export_failed - copy_refused - probe_stale - team_purged in: type: array items: type: string enum: - park_failed - export_failed - copy_refused - probe_stale - team_purged is_null: type: boolean additionalProperties: false owner_cluster_id: type: object properties: eq: type: integer in: type: array items: type: integer additionalProperties: false holder_cluster_id: type: object properties: eq: type: integer in: type: array items: type: integer additionalProperties: false phase_claimed_at: type: object properties: gte: type: string lte: type: string is_null: type: boolean additionalProperties: false planned_return_at: type: object properties: gte: type: string lte: type: string gt: type: string lt: type: string is_null: type: boolean additionalProperties: false description: '{ is_null: true } is an open ended lend.' created_at: type: object properties: gte: type: string lte: type: string gt: type: string lt: type: string additionalProperties: false include: type: array items: type: string enum: - counterparty_team description: Relations to eager-load (see entity Includes). sort: type: object properties: field: type: string enum: - created_at - planned_return_at - updated_at direction: type: string enum: - asc - desc description: Default desc. required: - field page_size: type: integer minimum: 0 maximum: 200 description: 0..200, default 50. page_size=0 = count-only, page_size=1 = getFirst. cursor: type: - string - 'null' description: Opaque forward cursor from a previous response pagination.next_cursor. ReturnAccountShareRequest: type: object description: Request body of `return_account_share`. properties: sid: type: string minLength: 18 maxLength: 18 pattern: ^ac_sh_ description: Single-share mode. Mutually exclusive with filter. filter: type: object properties: sid: type: object properties: eq: type: string in: type: array items: type: string additionalProperties: false channel: type: object properties: eq: type: string enum: - linkedin - email in: type: array items: type: string enum: - linkedin - email additionalProperties: false description: '"My LinkedIn loans" vs "my email loans".' status: type: object properties: eq: type: string enum: - pending - owner_parked - active - closing - holder_released - rolling_back - returned - recalled - failed ne: type: string enum: - pending - owner_parked - active - closing - holder_released - rolling_back - returned - recalled - failed in: type: array items: type: string enum: - pending - owner_parked - active - closing - holder_released - rolling_back - returned - recalled - failed nin: type: array items: type: string enum: - pending - owner_parked - active - closing - holder_released - rolling_back - returned - recalled - failed additionalProperties: false description: 'The phase. { eq: "active" } is the live set; { in: ["rolling_back","failed"] } is the loans that gave up.' to_team_sid: type: object properties: eq: type: string in: type: array items: type: string additionalProperties: false description: 'Owner side question: everything lent to team X.' to_user_sid: type: object properties: eq: type: string in: type: array items: type: string additionalProperties: false owner_account_sid: type: object properties: eq: type: string in: type: array items: type: string additionalProperties: false description: 'Share history of an owned account: "is this account lent out, and to whom".' holder_account_sid: type: object properties: eq: type: string in: type: array items: type: string additionalProperties: false description: 'Holder side question: map a borrowed copy back to its loan.' holder_over_slot: type: object properties: eq: type: boolean additionalProperties: false description: Which loans reached active but landed with no free slot on the holder side. end_reason: type: object properties: eq: type: string enum: - returned_by_holder - recalled_by_owner - holder_deleted_copy - holder_team_purged - owner_team_purged in: type: array items: type: string enum: - returned_by_holder - recalled_by_owner - holder_deleted_copy - holder_team_purged - owner_team_purged is_null: type: boolean additionalProperties: false failure_reason: type: object properties: eq: type: string enum: - park_failed - export_failed - copy_refused - probe_stale - team_purged in: type: array items: type: string enum: - park_failed - export_failed - copy_refused - probe_stale - team_purged is_null: type: boolean additionalProperties: false owner_cluster_id: type: object properties: eq: type: integer in: type: array items: type: integer additionalProperties: false holder_cluster_id: type: object properties: eq: type: integer in: type: array items: type: integer additionalProperties: false phase_claimed_at: type: object properties: gte: type: string lte: type: string is_null: type: boolean additionalProperties: false planned_return_at: type: object properties: gte: type: string lte: type: string gt: type: string lt: type: string is_null: type: boolean additionalProperties: false description: '{ is_null: true } is an open ended lend.' created_at: type: object properties: gte: type: string lte: type: string gt: type: string lt: type: string additionalProperties: false description: Mass-target mode, resolved against the loans you RECEIVED. status is overwritten with eq active server side. Mutually exclusive with sid. confirmation_count: type: integer minimum: 0 description: Blast-radius confirmation, REQUIRED with filter and ignored with sid. Must equal the active-pinned pagination.total_count of the same filter from list_received_account_shares. CreateAccountShareRequest: type: object description: Request body of `create_account_share`. properties: channel: type: string enum: - linkedin - email description: Which channel service owns the account you are lending. account_sid: type: string minLength: 18 maxLength: 18 description: 'The owned account to lend. Length checked only, never prefix checked: the same field names a LinkedIn account (ln_ac_), an email account (em_ac_) or a future channel''s sender, and `channel` is what says which.' to_email: type: string maxLength: 255 format: email description: 'Default targeting: the holder team is that user''s working team. Exactly one of to_email or to_team_sid.' to_team_sid: type: string minLength: 18 maxLength: 18 pattern: ^ts_tm_ description: Direct targeting. Exactly one of to_email or to_team_sid; it must not be your own team. planned_return_at: type: - string - 'null' description: 'ISO 8601 UTC. Informational only: it drives one owner reminder email with a recall link. There is NO auto return.' required: - channel - account_sid ReturnAccountShareResponse: type: object properties: success: type: boolean enum: - true operation: type: string enum: - action action: type: string description: kebab-case verb; matches the route segment. item: type: - object - 'null' properties: sid: type: string team_sid: type: string description: 'The OWNER team: the row tenant, the side that lent the account out.' channel: type: string enum: - linkedin - email description: Which channel service owns the physical account pair. to_team_sid: type: string description: 'The HOLDER team: the side that borrowed the account.' to_user_sid: type: - string - 'null' description: Resolved user when the share was targeted by email; null when targeted by team sid. to_email: type: - string - 'null' description: The targeting input kept for audit; null when targeted by team sid. owner_cluster_id: type: integer holder_cluster_id: type: integer owner_account_sid: type: string description: 'The owner''s channel account row, parked for the duration of the loan. Prefix agnostic: ln_ac_ on LinkedIn, em_ac_ on email.' owner_channel_ref: type: - string - 'null' description: Opaque second row the channel needs to name (LinkedIn puts its ab_br_ browser sid here); null when the channel needs none. holder_account_sid: type: - string - 'null' description: The holder's copy. NULL until the copy phase lands, so it is null on every pre-active row. holder_channel_ref: type: - string - 'null' owner_account_label: type: - string - 'null' description: 'The channel''s display name for the lent account, e.g. "Jane Roe (jane-roe)". Use it to tell one share from another when reporting to a human. Null when the channel had no name to give. Display only: never filter, match or reason on it.' status: type: string enum: - pending - owner_parked - active - closing - holder_released - rolling_back - returned - recalled - failed description: The durable phase, and the answer to "did the loan start". Only active means the holder can work. holder_over_slot: type: boolean description: True when the holder had no free account slot at create, so the copy landed in the channel's subscription hold. The loan still reaches active; the holder cannot work until it upgrades. end_reason: type: - string - 'null' enum: - returned_by_holder - recalled_by_owner - holder_deleted_copy - holder_team_purged - owner_team_purged description: Stamped when an ending is REQUESTED. Only ever set on a row that reached active. failure_reason: type: - string - 'null' enum: - park_failed - export_failed - copy_refused - probe_stale - team_purged description: Why a pre-active phase gave up. Non null on exactly rolling_back and failed. planned_return_at: type: - string - 'null' description: Informational only. When it passes the owner is emailed a recall link once; there is NO auto return. expiry_notified_at: type: - string - 'null' phase_claimed_at: type: - string - 'null' phase_attempts: type: integer description: Attempts on the CURRENT phase, reset on every advance. A large and growing value is the stuck signal on a phase that may not give up. ended_at: type: - string - 'null' ended_by: type: - object - 'null' properties: actor_type: type: string enum: - user - support - api_key - system - agent actor_sid: type: - string - 'null' team_sid: type: string actor_name: type: - string - 'null' description: The OAuth client that acted ("Claude", "n8n"); null for a user, an API key or a system job. oauth_client_sid: type: - string - 'null' description: The acting OAuth client (id_oc_*); null off the OAuth path. reason: type: - string - 'null' description: Why a system actor wrote the row (snapshot_capture_job, ...); null otherwise. permissions: type: object additionalProperties: {} description: 'Internal audit context: the grant set the actor held at write time. Not a contract.' cluster_id: type: - integer - 'null' description: 'Internal audit context: the cluster that served the write.' trace_id: type: - string - 'null' description: 'Internal audit context: the trace id of the request that wrote the row.' required: - actor_type - actor_sid - team_sid - permissions description: Who ended it. The machine readable why is end_reason (an ending) or failure_reason (a failure), never this blob. created_by: type: - object - 'null' properties: actor_type: type: string enum: - user - support - api_key - system - agent actor_sid: type: - string - 'null' team_sid: type: string actor_name: type: - string - 'null' description: The OAuth client that acted ("Claude", "n8n"); null for a user, an API key or a system job. oauth_client_sid: type: - string - 'null' description: The acting OAuth client (id_oc_*); null off the OAuth path. reason: type: - string - 'null' description: Why a system actor wrote the row (snapshot_capture_job, ...); null otherwise. permissions: type: object additionalProperties: {} description: 'Internal audit context: the grant set the actor held at write time. Not a contract.' cluster_id: type: - integer - 'null' description: 'Internal audit context: the cluster that served the write.' trace_id: type: - string - 'null' description: 'Internal audit context: the trace id of the request that wrote the row.' required: - actor_type - actor_sid - team_sid - permissions created_at: type: string updated_at: type: string required: - sid - team_sid - channel - to_team_sid - to_user_sid - to_email - owner_cluster_id - holder_cluster_id - owner_account_sid - owner_channel_ref - holder_account_sid - holder_channel_ref - owner_account_label - status - holder_over_slot - end_reason - failure_reason - planned_return_at - expiry_notified_at - phase_claimed_at - phase_attempts - ended_at - ended_by - created_by - created_at - updated_at result: type: object properties: closing_count: type: integer minimum: 0 description: Shares this call stamped closing. The teardown is the driver's, so this is never "recalled" or "returned". total_matched: type: integer minimum: 0 description: True count of active shares the target set held. closing_count below this means a remainder is left; re-read the count before the next call. required: - closing_count - total_matched meta: type: object properties: trace_id: type: string description: UUID v7; same 128-bit value as the X-Trace-Id header. span_id: type: string pattern: ^[0-9a-f]{16}$ description: 16 hex chars, root span of this request. timestamp: type: string description: ISO 8601 UTC (Y-m-dTH:i:sZ), response time. duration_ms: type: integer minimum: 0 description: Server-side wall clock. team_sid: type: - string - 'null' description: The team this call ran in (the token team, or the team_sid override). Null when unauthenticated; absent from pre-2026-08-20 backends. actor_type: type: - string - 'null' description: user | agent | api_key | system. Null when unauthenticated; absent from pre-2026-08-20 backends. required: - trace_id - span_id - timestamp - duration_ms required: - success - operation - action - item - result - meta SearchAccountSharesResponse: type: object properties: success: type: boolean enum: - true operation: type: string enum: - search items: type: array items: type: object properties: item: type: object properties: sid: type: string team_sid: type: string description: 'The OWNER team: the row tenant, the side that lent the account out.' channel: type: string enum: - linkedin - email description: Which channel service owns the physical account pair. to_team_sid: type: string description: 'The HOLDER team: the side that borrowed the account.' to_user_sid: type: - string - 'null' description: Resolved user when the share was targeted by email; null when targeted by team sid. to_email: type: - string - 'null' description: The targeting input kept for audit; null when targeted by team sid. owner_cluster_id: type: integer holder_cluster_id: type: integer owner_account_sid: type: string description: 'The owner''s channel account row, parked for the duration of the loan. Prefix agnostic: ln_ac_ on LinkedIn, em_ac_ on email.' owner_channel_ref: type: - string - 'null' description: Opaque second row the channel needs to name (LinkedIn puts its ab_br_ browser sid here); null when the channel needs none. holder_account_sid: type: - string - 'null' description: The holder's copy. NULL until the copy phase lands, so it is null on every pre-active row. holder_channel_ref: type: - string - 'null' owner_account_label: type: - string - 'null' description: 'The channel''s display name for the lent account, e.g. "Jane Roe (jane-roe)". Use it to tell one share from another when reporting to a human. Null when the channel had no name to give. Display only: never filter, match or reason on it.' status: type: string enum: - pending - owner_parked - active - closing - holder_released - rolling_back - returned - recalled - failed description: The durable phase, and the answer to "did the loan start". Only active means the holder can work. holder_over_slot: type: boolean description: True when the holder had no free account slot at create, so the copy landed in the channel's subscription hold. The loan still reaches active; the holder cannot work until it upgrades. end_reason: type: - string - 'null' enum: - returned_by_holder - recalled_by_owner - holder_deleted_copy - holder_team_purged - owner_team_purged description: Stamped when an ending is REQUESTED. Only ever set on a row that reached active. failure_reason: type: - string - 'null' enum: - park_failed - export_failed - copy_refused - probe_stale - team_purged description: Why a pre-active phase gave up. Non null on exactly rolling_back and failed. planned_return_at: type: - string - 'null' description: Informational only. When it passes the owner is emailed a recall link once; there is NO auto return. expiry_notified_at: type: - string - 'null' phase_claimed_at: type: - string - 'null' phase_attempts: type: integer description: Attempts on the CURRENT phase, reset on every advance. A large and growing value is the stuck signal on a phase that may not give up. ended_at: type: - string - 'null' ended_by: type: - object - 'null' properties: actor_type: type: string enum: - user - support - api_key - system - agent actor_sid: type: - string - 'null' team_sid: type: string actor_name: type: - string - 'null' description: The OAuth client that acted ("Claude", "n8n"); null for a user, an API key or a system job. oauth_client_sid: type: - string - 'null' description: The acting OAuth client (id_oc_*); null off the OAuth path. reason: type: - string - 'null' description: Why a system actor wrote the row (snapshot_capture_job, ...); null otherwise. permissions: type: object additionalProperties: {} description: 'Internal audit context: the grant set the actor held at write time. Not a contract.' cluster_id: type: - integer - 'null' description: 'Internal audit context: the cluster that served the write.' trace_id: type: - string - 'null' description: 'Internal audit context: the trace id of the request that wrote the row.' required: - actor_type - actor_sid - team_sid - permissions description: Who ended it. The machine readable why is end_reason (an ending) or failure_reason (a failure), never this blob. created_by: type: - object - 'null' properties: actor_type: type: string enum: - user - support - api_key - system - agent actor_sid: type: - string - 'null' team_sid: type: string actor_name: type: - string - 'null' description: The OAuth client that acted ("Claude", "n8n"); null for a user, an API key or a system job. oauth_client_sid: type: - string - 'null' description: The acting OAuth client (id_oc_*); null off the OAuth path. reason: type: - string - 'null' description: Why a system actor wrote the row (snapshot_capture_job, ...); null otherwise. permissions: type: object additionalProperties: {} description: 'Internal audit context: the grant set the actor held at write time. Not a contract.' cluster_id: type: - integer - 'null' description: 'Internal audit context: the cluster that served the write.' trace_id: type: - string - 'null' description: 'Internal audit context: the trace id of the request that wrote the row.' required: - actor_type - actor_sid - team_sid - permissions created_at: type: string updated_at: type: string required: - sid - team_sid - channel - to_team_sid - to_user_sid - to_email - owner_cluster_id - holder_cluster_id - owner_account_sid - owner_channel_ref - holder_account_sid - holder_channel_ref - owner_account_label - status - holder_over_slot - end_reason - failure_reason - planned_return_at - expiry_notified_at - phase_claimed_at - phase_attempts - ended_at - ended_by - created_by - created_at - updated_at included: type: object additionalProperties: {} required: - item - included pagination: type: object properties: next_cursor: type: - string - 'null' has_more: type: boolean total_count: type: - integer - 'null' required: - next_cursor - has_more - total_count applied_filters: type: object additionalProperties: {} includes: type: array items: type: string meta: type: object properties: trace_id: type: string description: UUID v7; same 128-bit value as the X-Trace-Id header. span_id: type: string pattern: ^[0-9a-f]{16}$ description: 16 hex chars, root span of this request. timestamp: type: string description: ISO 8601 UTC (Y-m-dTH:i:sZ), response time. duration_ms: type: integer minimum: 0 description: Server-side wall clock. team_sid: type: - string - 'null' description: The team this call ran in (the token team, or the team_sid override). Null when unauthenticated; absent from pre-2026-08-20 backends. actor_type: type: - string - 'null' description: user | agent | api_key | system. Null when unauthenticated; absent from pre-2026-08-20 backends. required: - trace_id - span_id - timestamp - duration_ms counts: type: object additionalProperties: {} required: - success - operation - items - pagination - applied_filters - includes - meta ListReceivedAccountSharesResponse: type: object properties: success: type: boolean enum: - true operation: type: string enum: - search items: type: array items: type: object properties: item: type: object properties: sid: type: string team_sid: type: string description: 'The OWNER team: the row tenant, the side that lent the account out.' channel: type: string enum: - linkedin - email description: Which channel service owns the physical account pair. to_team_sid: type: string description: 'The HOLDER team: the side that borrowed the account.' to_user_sid: type: - string - 'null' description: Resolved user when the share was targeted by email; null when targeted by team sid. to_email: type: - string - 'null' description: The targeting input kept for audit; null when targeted by team sid. owner_cluster_id: type: integer holder_cluster_id: type: integer owner_account_sid: type: string description: 'The owner''s channel account row, parked for the duration of the loan. Prefix agnostic: ln_ac_ on LinkedIn, em_ac_ on email.' owner_channel_ref: type: - string - 'null' description: Opaque second row the channel needs to name (LinkedIn puts its ab_br_ browser sid here); null when the channel needs none. holder_account_sid: type: - string - 'null' description: The holder's copy. NULL until the copy phase lands, so it is null on every pre-active row. holder_channel_ref: type: - string - 'null' owner_account_label: type: - string - 'null' description: 'The channel''s display name for the lent account, e.g. "Jane Roe (jane-roe)". Use it to tell one share from another when reporting to a human. Null when the channel had no name to give. Display only: never filter, match or reason on it.' status: type: string enum: - pending - owner_parked - active - closing - holder_released - rolling_back - returned - recalled - failed description: The durable phase, and the answer to "did the loan start". Only active means the holder can work. holder_over_slot: type: boolean description: True when the holder had no free account slot at create, so the copy landed in the channel's subscription hold. The loan still reaches active; the holder cannot work until it upgrades. end_reason: type: - string - 'null' enum: - returned_by_holder - recalled_by_owner - holder_deleted_copy - holder_team_purged - owner_team_purged description: Stamped when an ending is REQUESTED. Only ever set on a row that reached active. failure_reason: type: - string - 'null' enum: - park_failed - export_failed - copy_refused - probe_stale - team_purged description: Why a pre-active phase gave up. Non null on exactly rolling_back and failed. planned_return_at: type: - string - 'null' description: Informational only. When it passes the owner is emailed a recall link once; there is NO auto return. expiry_notified_at: type: - string - 'null' phase_claimed_at: type: - string - 'null' phase_attempts: type: integer description: Attempts on the CURRENT phase, reset on every advance. A large and growing value is the stuck signal on a phase that may not give up. ended_at: type: - string - 'null' ended_by: type: - object - 'null' properties: actor_type: type: string enum: - user - support - api_key - system - agent actor_sid: type: - string - 'null' team_sid: type: string actor_name: type: - string - 'null' description: The OAuth client that acted ("Claude", "n8n"); null for a user, an API key or a system job. oauth_client_sid: type: - string - 'null' description: The acting OAuth client (id_oc_*); null off the OAuth path. reason: type: - string - 'null' description: Why a system actor wrote the row (snapshot_capture_job, ...); null otherwise. permissions: type: object additionalProperties: {} description: 'Internal audit context: the grant set the actor held at write time. Not a contract.' cluster_id: type: - integer - 'null' description: 'Internal audit context: the cluster that served the write.' trace_id: type: - string - 'null' description: 'Internal audit context: the trace id of the request that wrote the row.' required: - actor_type - actor_sid - team_sid - permissions description: Who ended it. The machine readable why is end_reason (an ending) or failure_reason (a failure), never this blob. created_by: type: - object - 'null' properties: actor_type: type: string enum: - user - support - api_key - system - agent actor_sid: type: - string - 'null' team_sid: type: string actor_name: type: - string - 'null' description: The OAuth client that acted ("Claude", "n8n"); null for a user, an API key or a system job. oauth_client_sid: type: - string - 'null' description: The acting OAuth client (id_oc_*); null off the OAuth path. reason: type: - string - 'null' description: Why a system actor wrote the row (snapshot_capture_job, ...); null otherwise. permissions: type: object additionalProperties: {} description: 'Internal audit context: the grant set the actor held at write time. Not a contract.' cluster_id: type: - integer - 'null' description: 'Internal audit context: the cluster that served the write.' trace_id: type: - string - 'null' description: 'Internal audit context: the trace id of the request that wrote the row.' required: - actor_type - actor_sid - team_sid - permissions created_at: type: string updated_at: type: string required: - sid - team_sid - channel - to_team_sid - to_user_sid - to_email - owner_cluster_id - holder_cluster_id - owner_account_sid - owner_channel_ref - holder_account_sid - holder_channel_ref - owner_account_label - status - holder_over_slot - end_reason - failure_reason - planned_return_at - expiry_notified_at - phase_claimed_at - phase_attempts - ended_at - ended_by - created_by - created_at - updated_at included: type: object additionalProperties: {} required: - item - included pagination: type: object properties: next_cursor: type: - string - 'null' has_more: type: boolean total_count: type: - integer - 'null' required: - next_cursor - has_more - total_count applied_filters: type: object additionalProperties: {} includes: type: array items: type: string meta: type: object properties: trace_id: type: string description: UUID v7; same 128-bit value as the X-Trace-Id header. span_id: type: string pattern: ^[0-9a-f]{16}$ description: 16 hex chars, root span of this request. timestamp: type: string description: ISO 8601 UTC (Y-m-dTH:i:sZ), response time. duration_ms: type: integer minimum: 0 description: Server-side wall clock. team_sid: type: - string - 'null' description: The team this call ran in (the token team, or the team_sid override). Null when unauthenticated; absent from pre-2026-08-20 backends. actor_type: type: - string - 'null' description: user | agent | api_key | system. Null when unauthenticated; absent from pre-2026-08-20 backends. required: - trace_id - span_id - timestamp - duration_ms counts: type: object additionalProperties: {} required: - success - operation - items - pagination - applied_filters - includes - meta responses: McpServerError: description: MCP error envelope with `error.code` internal_error or service_unavailable. content: application/json: schema: $ref: '#/components/schemas/McpError' McpClientError: description: MCP error envelope. `error.code` is one of validation_failed, nothing_to_update, not_found, relation_not_found, invalid_transition, limit_exceeded, payment_required, duplicate_rejected, conflict, delete_blocked, unauthorized, forbidden, rate_limited, not_implemented. content: application/json: schema: $ref: '#/components/schemas/McpError' securitySchemes: BearerJwt: type: http scheme: bearer bearerFormat: JWT description: Access token issued by gtm.service.id. Its `access_identity` claim carries `team_sid`, `actor_sid` and `actor_type`, and that team scope is authoritative. TeamSid: type: apiKey in: header name: Team-SID description: Team scope for tokens that do not carry one. Ignored when the token already names a team.