---
title: "SELF-ENROLLMENT AT EQUAL AUTHORITY. A credential that ALREADY holds business authority in a workspace (today: a legacy key) obtains its own machine identity with EXACTLY the same authority, with no human step: an enrollment that cannot widen authority needs no new approval, because moving a write from 'human owner actor, this authority' to 'machine actor, the same authority' grants nothing — it corrects a misattribution. The caller cannot name identity, workspace, actor, membership, grant, scopes, capabilities or authority; only an optional human-readable label, which names the identity and does not authorize it. This endpoint NEVER returns a Work Token: mint one with POST /identity/token. Idempotent per credential + workspace: a second call returns the SAME ids. A legacy→identity binding a human already made by hand is ADOPTED, never duplicated. After enrolling, business writes made with that same credential are attributed to the machine actor and never to the human owner; if a legacy_blanket grant existed for it, that grant is revoked (never mutated) and the issued grant carries supersedes_grant_id. An owner may revoke the enrollment; the revocation leaves a durable tombstone, after which this endpoint returns 403 self_enrollment_revoked until the owner explicitly re-enables it."
method: POST
path: "/identity/enroll"
---

# SELF-ENROLLMENT AT EQUAL AUTHORITY. A credential that ALREADY holds business authority in a workspace (today: a legacy key) obtains its own machine identity with EXACTLY the same authority, with no human step: an enrollment that cannot widen authority needs no new approval, because moving a write from 'human owner actor, this authority' to 'machine actor, the same authority' grants nothing — it corrects a misattribution. The caller cannot name identity, workspace, actor, membership, grant, scopes, capabilities or authority; only an optional human-readable label, which names the identity and does not authorize it. This endpoint NEVER returns a Work Token: mint one with POST /identity/token. Idempotent per credential + workspace: a second call returns the SAME ids. A legacy→identity binding a human already made by hand is ADOPTED, never duplicated. After enrolling, business writes made with that same credential are attributed to the machine actor and never to the human owner; if a legacy_blanket grant existed for it, that grant is revoked (never mutated) and the issued grant carries supersedes_grant_id. An owner may revoke the enrollment; the revocation leaves a durable tombstone, after which this endpoint returns 403 self_enrollment_revoked until the owner explicitly re-enables it.

`POST /identity/enroll`

## Request

- Base URL: `https://forbiz.io/api/public/agent`
- URL: `https://forbiz.io/api/public/agent/identity/enroll`
- Auth: HTTP bearer

## Request body

- object
  - `label` string: Optional human-readable name for the machine identity when one has to be created. It names the identity; it never authorizes it.

## Response `200`

The canonical ids of the enrollment. binding_preexisted, enrollment_created and already_enrolled are three distinct facts and are never interchangeable: a hand-made binding is infrastructure for enrolling, not a consummated enrollment, so a first call against one returns binding_preexisted=true, enrollment_created=true, already_enrolled=false.

- object
  - `identity_id` string
  - `actor_id` string
  - `membership_id` string
  - `grant_id` string
  - `grant_kind` 'issued'
  - `workspace_id` string
  - `binding_preexisted` boolean: A legacy→identity binding already existed (possibly made by a human, by hand).
  - `enrollment_created` boolean: THIS call materialised actor + membership + issued grant.
  - `already_enrolled` boolean: The enrollment was already consummated before this call.
  - `supersedes_grant_id` string, nullable: The credential's former legacy_blanket grant, now revoked and still readable. Never mutated.

## Other responses

- `400`: caller_selected_authority_rejected — the body tried to supply identityId, workspaceId, actorId, membershipId, grantId, scopes, capabilities, authority or any other unknown field. Only `label` is accepted.
- `403`: identity_token_cannot_enroll — a Work Identity Token attempted to enroll; renewal_only_credential — a dedicated renewal credential (or a legacy credential switched to renewal_only) has no business authority to derive from; credential_class_cannot_enroll — default deny for any other credential class; self_enrollment_revoked — an owner revoked this credential's enrollment and only an explicit owner action may re-enable it.
- `409`: equal_authority_not_derivable — enrollment would WIDEN authority: the adopted identity's canonical authority exceeds the enrolling credential's. Nothing was enrolled. An identity whose stored authority is the same or NARROWER enrolls successfully, and the issued grant carries the identity's (narrower) authority.

---

[API](https://skmtc.dev/forbiz/apis/forbiz-external-agent-api.md) · [All operations](https://skmtc.dev/forbiz/apis/forbiz-external-agent-api/llms.txt) · [OpenAPI document](https://skmtc.dev/forbiz/apis/forbiz-external-agent-api/revisions/e5b10d59dc5f?raw)
