---
title: "Offboard an affiliate"
method: POST
path: "/organizations/sub-orgs/offboard"
tags: ["Organizations"]
---

# Offboard an affiliate

`POST /organizations/sub-orgs/offboard`

## Request

- Base URL: `https://app.arkova.ai/api/v1`
- URL: `https://app.arkova.ai/api/v1/organizations/sub-orgs/offboard`
- Auth: one of:
  - HTTP bearer
  - API key in header `X-API-Key`

Reclaim an affiliate's remaining credits to the parent and then suspend it. Requires the orgs:manage scope. Reclaim, suspension and their audit records commit together in one transaction. A failed transaction rolls back the reclaim; a transport failure does not establish whether it committed. Retrying is safe and never moves the same credits twice. The affiliate's anchored records are NOT touched — they stay verifiable after the relationship ends. Lifecycle: a child requests affiliation (dashboard) and becomes PENDING; approve moves PENDING to APPROVED; credits move only while the affiliate is APPROVED and not suspended; offboard reclaims the remaining credits and suspends the affiliate, in any status; revoke ends the relationship from APPROVED or PENDING. offboard then revoke and revoke then offboard are both supported - offboard never requires APPROVED and revoke never refuses a suspended affiliate. Counts against the API key monthly usage quota (no exemption exists for administration routes) and requires the organization payment state to be current.

## Request body

- object
  - `org_public_id` string, required: Public identifier of the affiliated organization. NOT the internal uuid — sending one returns 400 use_public_id.
  - `reason` string

## Response `200`

Offboarded

- object
  - `reclaimed` integer, required: Credits returned to the parent by this call. Zero on a retry that already reclaimed.
  - `suspended` boolean, required
  - `already_suspended` boolean: True when the affiliate was already suspended before this call.

## Other responses

- `400`: Invalid request
- `401`: Authentication required
- `403`: Refused, named by a machine code in `error`: `insufficient_scope` (the key lacks orgs:manage), `acting_org_not_found` (the key's own organization no longer exists), or `sub_org_cannot_manage_sub_orgs` (the key belongs to an affiliated organization, which cannot administer affiliates of its own).
- `404`: No affiliated organization the caller may address answers to this public id. Deliberately indistinguishable from "belongs to another parent", "not approved yet" and "suspended" — this endpoint is not an existence oracle.
- `409`: `409 ambiguous_caller`: the request presented both a verified session and an API key, and neither credential may be allowed to pick which organization is acting. Send exactly one.
- `422`: Request body failed validation
- `429`: Rate limit exceeded
- `502`: The underlying database function refused the call with a code this API version does not name. `error` carries that code verbatim. Not a 500: the request was answered, not dropped.
- `503`: A required lookup or RPC was unavailable, named by a machine code in `error`: `org_lookup_unavailable` (the acting-organization read failed), `sub_org_lookup_unavailable`, `sub_org_list_unavailable`, `rollup_projection_unavailable`, `credit_allocation_unavailable`, `credit_rollup_unavailable`, `balance_lookup_unavailable`, `suspend_unavailable`, `offboard_unavailable`, `cap_check_unavailable`, or `api_key_principal_unresolved` (the key is authorized but the principal it must stamp on the row could not be resolved). Never returned in place of a definitive answer.

---

[API](https://skmtc.dev/arkova/apis/arkova-verification-api.md) · [All operations](https://skmtc.dev/arkova/apis/arkova-verification-api/llms.txt) · [OpenAPI document](https://skmtc.dev/arkova/apis/arkova-verification-api/revisions/a14858d1efd4?raw)
