Connections

Transfer connection ownership

Changes owner_user_id and nothing else. The new owner gets implicit edit, plus delete and transfer, which no grant confers; every existing grant on the connection stays as it was, so who else could already reach it is unaffected. To change who can reach a connection, use POST /connection/{id}/share and DELETE /connection/{id}/share/{aclId}. Only the Elaichi record changes: the stored credential is untouched, so toolbox entries pinned to this connection keep resolving and executing across the transfer. This is the non-destructive alternative to delete when a member leaves. Allowed for the current owner only. It costs the outgoing owner their access: their reach came from ownership, not a grant, so unless a grant of their own already covered them they hold nothing afterwards (access: null), and because a toolbox entry runs on its delegator's access to the pinned connection, every entry they pinned stops resolving, for everyone including the new owner. retain_access: true prevents that by granting them use as an ordinary, listed, revocable share in the same operation; only the connection's owner may use it. Call GET /connection/{id}/transfer-preview first to see the same numbers. connected_by_user_id is not rewritten, deliberately: the stored credential still belongs to whoever authorized it, so the response carries the new owner_user_id beside the unchanged connected_by_user_id and connected_by_label. A client that shows "Connected by" from owner_user_id would claim the new owner authenticated an account they never touched. The new owner must be an active member: a suspended one is refused with 400 member_not_active.

post/connection/{id}/transfer

Request

  • Base URL: https://api.elaichi.ai
  • URL: https://api.elaichi.ai/connection/{id}/transfer
  • Auth: HTTP bearer

Path parameters

idstring required

Connection id (conn_…).

Headers

X-Organization-Idstring

Target organization (org_…). Required for cookie/session auth on org-scoped routes; optional for API tokens, which carry their organization, and rejected when it names a different one.

Request body

owner_user_idstring required

New owning member (usr_…).

retain_accessboolean

Keep the OUTGOING owner's access as an ordinary use share, so the toolbox entries they pinned to this connection keep working. Defaults to false. Refused (403) for any caller who is not the connection's own owner — offboarding never passes it, and a departing member keeps nothing.

Response

OK

idstring

Connection id (conn_…).

connector_slugstring

Which connector this account is on.

namestring
owner_user_idstring

Owning member (usr_…); calls run as this identity. The owner has implicit edit, plus delete and transfer, which no share confers. Move it with POST /connection/{id}/transfer. This is who is accountable for the connection now, which after a transfer is not who authenticated it; see connected_by_user_id.

connected_by_user_idstring nullable

Who authenticated this account (usr_…): the member whose third-party credential Elaichi holds. Written once at creation and never rewritten. It differs from owner_user_id on purpose: POST /connection/{id}/transfer moves the owner and does not touch the stored credential, so after a transfer these are two different people and only this one should be shown as "Connected by". Null means not recorded, never "nobody": connections created before this field existed are null. Show nothing for a null.

connected_by_labelstring nullable

Display name for connected_by_user_id (name, else email). Present on every response that returns a connection, commands included. A null label beside a non-null connected_by_user_id means the person has left the organization; show "Former member". Compare the two fields, never one alone: a null id means "not recorded", a null label means "departed".

saffron_account_idstring nullable

Identifier of the stored credential Elaichi holds for this connection. Opaque; null until the connect flow completes.

status'pending' | 'active' | 'needs_reauth' | 'disconnected'

pending = created but not yet authenticated (open connect_url); active = usable; needs_reauth = the credential expired or was revoked upstream, call reconnect; disconnected = no longer usable. Refreshed when connections are read.

last_errorstring nullable
accessstring

The caller's relationship to this connection: owner, or a granted view/use/edit level. A connection the caller neither owns nor holds a grant on is not visible to them at all, whatever organization permission they hold.

created_atstring date-time
updated_atstring date-time
can_shareboolean

Whether the caller may share this connection: the owner, edit access, or a team admin on a team-granted one, and connection:share. Computed by the API, so read it rather than re-deriving it from owner_user_id and permissions.

can_manageboolean

Present on every list and detail row. Whether the caller may edit this connection's own settings: the owner, or edit access.

can_transferboolean

Present on every list and detail row. Whether the caller may transfer or delete this connection: the owner only. Narrower than can_manage, because an edit grant lets someone use and reconfigure a connection, never give it away or destroy it.

can_revoke_shareboolean

Present on every list and detail row. Whether the caller may grant or revoke access to this connection. It matches can_share and is separate from can_manage: an edit grantee whose role omits connection:share can reconfigure or reconnect the connection but cannot change who else has access. Mirrors DELETE /connection/{id}/share/{aclId}.

access_via'owner' | 'direct' | 'team' | 'org'

How the caller reaches this connection, not who else can. owner: they own it. direct: a grant names them personally. team: a grant to a team they belong to (or administer), named in access_via_team. org: an organization-wide grant. When several sources apply, the broadest wins and the access level plays no part: owner, else org, else team, else direct. A caller with edit personally and view org-wide reads org, because this field says how far the connection reaches, not what the caller may do with it. It describes only the caller's own access, so a view or use grantee still gets it while the list of other grantees stays hidden. Absent when nothing reaches the caller (for example, the former owner after a transfer of a resource that was never shared); absent never means org.

affected_toolbox_countinteger

Exact number of toolboxes with an entry pinned to this connection.

broken_delegation_countinteger

Exact number of those that stopped working, because the outgoing owner pinned them and lost the access they run on. Already 0 when any grant saved them — the retain_access one, or an org-wide/team share the outgoing owner already held.

retained_accessboolean

True iff a retained use grant was actually made for the outgoing owner. False when they never asked for one — which is not the same as having lost access, since a grant they already held still counts: read access for that.

Changes

No recorded changes to this operation across all 1 revision of this API.