> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gtm-api.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Lend an account to another workspace

> 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.



## OpenAPI

````yaml /api-reference/id/openapi.yaml post /api/account-shares
openapi: 3.0.3
info:
  title: 'GTM API public contract: gtm.service.id'
  description: >-
    Identity, access and money: users, teams and members, API keys, OAuth
    clients and authorizations, billing products, subscriptions, transactions
    and payment methods, the credit ledger, notifications, TLS certificates,
    observability and support requests.


    GENERATED. This document is projected from the Zod MCP tool registry in
    `product/mcp/gtm.mcp` (one tool per public endpoint, 1:1). Do not edit it by
    hand; edit the tool definition and regenerate with `pnpm openapi:public`.


    Surface: the public `/api` contract of `gtm.service.id`, 77 operations.
    Internal (`/internal`) and health endpoints are deliberately absent; the
    code-faithful spec that documents those lives in
    `product/openapi/gtm.openapi.tech`.


    Conventions:

    - Auth is a bearer JWT, optionally narrowed by the `Team-SID` header.

    - Every success body is an MCP envelope: `success: true` plus one typed
    `operation` shape (`search`, `get`, `create`, `update`, `delete`, `metrics`,
    `group_by`, `action`), and a `meta` block with `trace_id` for support.

    - Every failure is the same `McpError` envelope with a code from a fixed
    16-code taxonomy, so a client maps errors once.

    - Lists page with `page_size` (0 to 500, default 50) plus an opaque forward
    `cursor`; `page_size: 0` returns counts only.

    - On `GET` and `DELETE`, object-valued query parameters (`filter`, `sort`)
    travel as JSON text and array-valued ones repeat as `name[]=value`.

    - The MCP-only `_meta` field (usage analytics) never reaches the backend and
    is not part of this contract.
  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
  - url: http://localhost:8021
    description: Local Docker (gtm_id_nginx_dev)
security:
  - BearerJwt: []
    TeamSid: []
tags:
  - name: account_shares
    description: Registry package `mcp.id/account_shares`, served on MCP mount `id.access`.
  - name: api_keys
    description: Registry package `mcp.id/api_keys`, served on MCP mount `id.access`.
  - name: billing_payment_methods
    description: >-
      Registry package `mcp.id/billing_payment_methods`, served on MCP mount
      `id.billing`.
  - name: billing_products
    description: >-
      Registry package `mcp.id/billing_products`, served on MCP mount
      `id.billing`.
  - name: billing_subscriptions
    description: >-
      Registry package `mcp.id/billing_subscriptions`, served on MCP mount
      `id.billing`.
  - name: billing_transactions
    description: >-
      Registry package `mcp.id/billing_transactions`, served on MCP mount
      `id.billing`.
  - name: credit_transactions
    description: >-
      Registry package `mcp.id/credit_transactions`, served on MCP mount
      `id.credits`.
  - name: notifications
    description: >-
      Registry package `mcp.id/notifications`, served on MCP mount
      `id.platform`.
  - name: oauth_authorizations
    description: >-
      Registry package `mcp.id/oauth_authorizations`, served on MCP mount
      `id.access`.
  - name: oauth_clients
    description: Registry package `mcp.id/oauth_clients`, served on MCP mount `id.access`.
  - name: observability_requests
    description: >-
      Registry package `mcp.id/observability_requests`, served on MCP mount
      `id.platform`.
  - name: sessions
    description: Registry package `mcp.id/sessions`, served on MCP mount `id.identity`.
  - name: ssl_certificates
    description: >-
      Registry package `mcp.id/ssl_certificates`, served on MCP mount
      `id.platform`.
  - name: support_requests
    description: >-
      Registry package `mcp.id/support_requests`, served on MCP mount
      `id.platform`.
  - name: team_members
    description: Registry package `mcp.id/team_members`, served on MCP mount `id.identity`.
  - name: teams
    description: Registry package `mcp.id/teams`, served on MCP mount `id.identity`.
  - name: users
    description: Registry package `mcp.id/users`, served on MCP mount `id.identity`.
paths:
  /api/account-shares:
    post:
      tags:
        - account_shares
      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.
      operationId: create_account_share
      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'
components:
  schemas:
    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
          nullable: true
          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
    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
              nullable: true
              description: >-
                Resolved user when the share was targeted by email; null when
                targeted by team sid.
            to_email:
              type: string
              nullable: true
              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
              nullable: true
              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
              nullable: true
              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
              nullable: true
            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
              nullable: true
              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
              nullable: true
              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
              nullable: true
              description: >-
                Informational only. When it passes the owner is emailed a recall
                link once; there is NO auto return.
            expiry_notified_at:
              type: string
              nullable: true
            phase_claimed_at:
              type: string
              nullable: true
            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
              nullable: true
            ended_by:
              type: object
              nullable: true
              properties:
                actor_type:
                  type: string
                  enum:
                    - user
                    - support
                    - api_key
                    - system
                actor_sid:
                  type: string
                  nullable: true
                team_sid:
                  type: string
                permissions:
                  type: object
                  additionalProperties: {}
                request_sid:
                  type: string
                  nullable: true
                reason:
                  type: string
                  nullable: true
              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
              nullable: true
              properties:
                actor_type:
                  type: string
                  enum:
                    - user
                    - support
                    - api_key
                    - system
                actor_sid:
                  type: string
                  nullable: true
                team_sid:
                  type: string
                permissions:
                  type: object
                  additionalProperties: {}
                request_sid:
                  type: string
                  nullable: true
                reason:
                  type: string
                  nullable: true
              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
            - 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.
            debug_url:
              type: string
              description: Deep link to the post-call analysis UI.
          required:
            - trace_id
            - span_id
            - timestamp
            - duration_ms
            - debug_url
      required:
        - success
        - operation
        - item
        - already_exists
        - meta
    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:
                  anyOf:
                    - type: string
                    - 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
                    nullable: true
                  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.
            debug_url:
              type: string
              description: Deep link to the post-call analysis UI.
          required:
            - trace_id
            - span_id
            - timestamp
            - duration_ms
            - debug_url
      required:
        - success
        - error
  responses:
    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'
    McpServerError:
      description: >-
        MCP error envelope with `error.code` internal_error or
        service_unavailable.
      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.

````