---
title: "Allocate or reclaim affiliate credits"
method: POST
path: "/organizations/sub-orgs/credits"
tags: ["Organizations"]
---

# Allocate or reclaim affiliate credits

`POST /organizations/sub-orgs/credits`

## Request

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

Move credits between the calling key's organization and one of its approved affiliates. A positive amount allocates, a negative amount reclaims. Requires the orgs:manage scope. The transfer is a single database transaction that re-verifies the affiliation under a row lock. 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.
  - `amount` integer, required: Whole credits. Positive allocates to the affiliate, negative reclaims to the parent. Never zero.
  - `note` string

## Response `200`

Transfer applied

- object
  - `parent_balance` integer, required
  - `child_balance` integer, required
  - `amount` integer, required

## 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`: insufficient_parent_balance or insufficient_child_balance. A conflict with the current balance, not a payment prompt — nothing here is purchasable in the moment. Also `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)
