Skip to main content
Sharing lends a connected LinkedIn account to another workspace and is revocable at any moment; a transfer moves ownership for good. Both keep the same LinkedIn session and the same antidetect browser profile, so nobody re-logs in. Prefer sharing even when the move sounds permanent: only a share can be rolled back.
Give this to your AI agent to lend an account without touching the app:“Lend a LinkedIn account to another gtm-api workspace. POST to https://app.gtm-api.com/id/v4/api/account-shares with {"channel":"linkedin","account_sid":"ln_ac_...","to_email":"..."} using my API key. It answers 201 with status pending, which means nothing has started yet. Poll POST /api/account-shares/search with filter {"sid":{"eq":"ac_sh_..."}} every 15 seconds until status is active or failed, then report the status, holder_over_slot and failure_reason. Do not call recall or return unless I ask. Never touch account-transfers, it is permanent.”

Share or transfer

Lend an account

The account must be one your workspace owns, past its LinkedIn login, and not already a side of another share or transfer. A billing hold does not block a loan. LinkedIn only, so passing "channel": "email" is not supported. The receiving workspace must exist and be neither suspended nor deleted; target it by to_email (resolved to that user’s working team) or by to_team_sid, exactly one of the two. One call lends one account, so lending five accounts is five calls.
The 201 answers with item.sid (ac_sh_...) and item.status: "pending": the row was written, the loan has not started. Poll POST /api/account-shares/search (the loans you issued) until the status is active. The receiving side polls POST /api/account-shares/list-received, scoped to loans made to them.
There is no error response for a loan that fails after the 201: the outcome lands on the row as status plus failure_reason, so poll it. A background reconciler re-drives any share that stalls, every 5 minutes, until it advances or a human intervenes.

Statuses

Nothing leaves a terminal status, and there is no expired status. failure_reason is one of park_failed, export_failed, copy_refused, probe_stale or team_purged on a share, and park_failed, copy_refused or probe_stale on a transfer.
A row on owner_parked whose phase_attempts passes 10 with no failure_reason is stuck in the copy retry, which never terminates on its own. An export failure is different: it gives up after 5 attempts and lands failed with export_failed. Send support the share sid plus the exact status and phase_attempts.

What happens on your side

Account status and browser status both become shared_out (the Senders list shows the browser as shared out, hold reason “Lent to another workspace”), the browser session is stopped and its automation server is released. The account leaves every scheduler, dispatcher and stale-heartbeat sweep, so silence from a parked account is expected, not a fault.
Parking stops in-flight work: running sync runs are cancelled with the reason account_shared_out, auto-scrapes and mass-action runs are paused with the reason account_unavailable. On recall only what the park paused is resumed, so a manual pause or a limit hold you set survives the round trip. Cancelled sync runs are never recreated: the scheduler mints fresh ones once the account is back.
You keep two things while the account is away: a cloud-browser session on the parked original, and its proxy. That session is how you fix a LinkedIn logout mid-loan, and nobody is notified when one happens, so the borrower has to tell you. You cannot delete the parked account or re-connect the same LinkedIn member to work around the share: both answer 409 conflict, account_shared_out.

What the receiving side gets

One exception: if the receiving workspace held this account before and its old copy is still soft-deleted, that row is restored rather than created fresh: same sid, old conversation and connection history back, sync clocks preserved, no full backfill. Use reset-sync to force one. The receiving side also cannot:
  • See the browser profile id. vendor_profile_id reads back as *** on every borrowed browser, during the loan and after it ends, so an ex-holder cannot re-bind the profile later.
  • Re-share it (an account can be in at most one live share), manage the proxy (no proxy field crosses), or inherit your roles: permissions are never granted across workspaces, and the copy is governed entirely by their own roles.
Lending an account out does not free your slot. Your claim is held for the whole loan, and the receiving workspace claims a slot of its own. If they have no free slot, the share still reaches active with holder_over_slot: true and their copy lands in the subscription_required hold, so they cannot run it until they upgrade. A share never fails because of slots. Plan slot caps are in Billing and plans.
A lent-out account is skipped by the downgrade sweep, so it cannot slip into subscription_required while away; the check re-runs when it comes back. Lending out an already-downgraded account is allowed.

End a share

Teardown soft-deletes the borrowed copy, stops its browser, revokes every cloud-browser key it minted, and fails its pending activity rows with browser_deleted. The borrower keeps the conversations and connections that copy synced. Your original is un-parked: browser back to stopped, account status recomputed from its own signals.
Instead of sid you may pass a filter plus a confirmation_count. Filter mode pins status to active server-side (your filter can only narrow the set), drains at most 100 shares per call, and requires confirmation_count to equal the count that same filter returns with status: {"eq": "active"} pinned and page_size: 0. Anything else answers 409 confirmation_count_mismatch. It is not atomic: on a mid-batch error the response carries no counters and the shares already stamped keep closing, so re-query rather than retrying the same body, and take a fresh count before each call. closing_count counts shares that started closing, never ones already recalled.
planned_return_at does not auto-return anything. When it passes, an hourly job emails the owner once that the date passed, and stamps expiry_notified_at. The loan runs until somebody ends it. A soft-deleted workspace changes nothing: the 30-day recovery window has to elapse and the purge has to run before the loan is driven to a terminal status.

Refusals

An active share blocks a transfer of the same account (409 account_currently_shared, recall first), and an in-flight transfer blocks a share.

Transfer permanently

Transfers use the same machinery and the same body as a share, minus planned_return_at. Create with POST /api/account-transfers, then poll GET /api/account-transfers/{sid} or POST /api/account-transfers/search. Transferring out of a billing hold is allowed, and is the intended exit for an account you no longer want to pay for.
There is no MCP tool for any transfer route, including the read ones, and that is on purpose: an AI agent must not be able to give an account away. There is also no view-only permission tier, so can_manage_account_transfers gates reads as well as writes. Point agents at sharing instead.

Who gets told

Emails go to the counterparty, not to whoever made the call. The receiving workspace owner gets account_share_received, account_share_recalled and account_transfer_received; you get account_share_returned, account_share_expired and account_share_failed. Webhooks are owner-side only and fan out to the workspace that owns the row: account-shares.created, account-shares.returned, .recalled and .failed, plus account-transfers.completed and .failed. The borrowing side has no webhook, so its arrival signal is the email plus polling list-received.