Organization Transfers

Transfer a sub-organization from one registered GitHub account to another using a two-party handshake: the current owner initiates, and the recipient accepts. Root organizations cannot be transferred.

Financial data keeps the same organization_id. On accept, ownership and hierarchy are updated under the recipient's root organization. Existing API keys for the transferred organization are revoked.

Note: These endpoints use /organization-transfers (ownership moves). Account-to-account money movements use /transfers — see Transfers.

Transfer Object

{
  "id": "TRF_xxxxxxxx",
  "organization_id": "ORG_xxxxxxxx",
  "organization_name": "Client Books LLC",
  "from_user_id": "USR_xxxxxxxx",
  "from_github_username": "seller",
  "to_user_id": "USR_yyyyyyyy",
  "to_github_username": "buyer",
  "status": "pending",
  "relationship_on_accept": null,
  "initiated_at": "2026-06-01T12:00:00Z",
  "responded_at": null,
  "expires_at": "2026-07-01T12:00:00Z"
}

Status Values

StatusDescription
pendingAwaiting recipient action
acceptedTransfer completed
rejectedRecipient declined
cancelledSender cancelled
expiredPending transfer past expires_at

Initiate Transfer

POST/organizations/:organization_id/organization-transfers
Auth required

Requires a Bearer API key scoped to the sub-organization being transferred (or an ancestor org).

Request Body

ParameterTypeRequiredDescription
to_github_usernamestringYesGitHub username of a registered Crane Ledger recipient

Response

Returns the transfer object with status: pending.


List Outgoing Transfers

GET/organizations/:organization_id/organization-transfers
Auth required

List Incoming Transfers

GET/organizations/:organization_id/organization-transfers/incoming
Auth required

Use your root organization API key. Returns transfers where you are the designated recipient.


Get Transfer Stats

GET/organizations/:organization_id/organization-transfers/:transfer_id/stats
Auth required

Returns counts for accounts, transactions, invoices, bills, contacts, categories, items, and API keys.


Accept Transfer

POST/organizations/:organization_id/organization-transfers/:transfer_id/accept
Auth required

Use your root organization API key. Only the designated recipient can accept.

Request Body

ParameterTypeRequiredDescription
relationshipstringYesowned (consolidated) or linked (stand-alone)

On success, the sub-organization is re-parented under your root org with the chosen relationship. All existing API keys for that organization are revoked.


Reject Transfer

POST/organizations/:organization_id/organization-transfers/:transfer_id/reject
Auth required

Cancel Transfer

POST/organizations/:organization_id/organization-transfers/:transfer_id/cancel
Auth required

Only the sender (organization owner) can cancel while status is pending.


Dashboard BFF Endpoints

The web dashboard uses authenticated Next.js routes that proxy to admin API endpoints:

Dashboard routeAction
GET /api/users/search?github_username=Search registered users (autocomplete)
POST /api/transfersInitiate transfer
GET /api/transfers/incomingList incoming transfers
GET /api/transfers/:id/statsTransfer stats
POST /api/transfers/:id/acceptAccept with relationship
POST /api/transfers/:id/rejectReject
POST /api/transfers/:id/cancelCancel (requires organizationId in body)