Actors And Access Control

This group covers the actor model and the authorization model. Read it in scope-building order: create principals first, define reusable permission bundles second, bind those bundles into tenant scope third, and then add execution-control surfaces like policies or approval queues.

Principals, Scope, And Control

Create user

Human operator principal. Create a user when a person needs to review, approve, or operate inside enterprise scope through a canonical human actor resource.

Request URL

POST
POST https://business-api.youhodler.com/users

Request Body

application/json
{
  "display_name": "Jane Doe",
  "email": "jane.doe@acme.example",
  "scope_ref": "enterprises/b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b"
}

Response

application/json
{
  "created_at": "2026-05-01T10:00:00Z",
  "display_name": "Jane Doe",
  "email": "jane.doe@acme.example",
  "etag": "W/\"a1b2c3d4\"",
  "federation": null,
  "id": "b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b",
  "identity_source": "platform-managed",
  "resource": "human_actor",
  "scope_ref": "enterprises/b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b",
  "status": "active",
  "updated_at": "2026-05-01T10:00:00Z"
}

Create service account

Backend principal. Create a service account when execution should happen from server-side infrastructure instead of a human session.

Request URL

POST
POST https://business-api.youhodler.com/service-accounts

Request Body

application/json
{
  "description": "Withdrawal automation account",
  "parent_ref": "enterprises/b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b",
  "roles": [
    {
      "role_ref": "roles/b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b",
      "scope_ref": "enterprises/b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b"
    }
  ]
}

Response

application/json
{
  "client_id": "b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b",
  "client_secret": "cs_live_abc123placeholder",
  "client_secret_expires_at": "2026-05-01T10:00:00Z",
  "principal_ref": "service-accounts/b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b",
  "role_assignment_errors": [],
  "role_assignments": [],
  "service_account": {
    "description": "Withdrawal automation account",
    "created_at": "2026-05-01T10:00:00Z",
    "current_secret_expires_at": "2026-05-01T10:00:00Z",
    "etag": "W/\"sa-etag-0001\"",
    "external_id": "sa-ext-001",
    "id": "b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b",
    "parent_ref": "enterprises/b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b",
    "previous_secret_expires_at": null,
    "principal_ref": "service-accounts/b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b",
    "resource": "service_account",
    "status": "active",
    "updated_at": "2026-05-01T10:00:00Z"
  }
}

Create role

Reusable access bundle. Create a role before granting scope so principals can inherit a named capability set instead of accumulating one-off permission logic.

Request URL

POST
POST https://business-api.youhodler.com/roles

Request Body

application/json
{
  "name": "Enterprise Admin",
  "description": "Full administrative access within an enterprise",
  "permissions": [
    "withdrawals.create",
    "deposits.read",
    "clients.read"
  ],
  "scope_ref": "enterprises/b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b"
}

Response

application/json
{
  "name": "Enterprise Admin",
  "description": "Full administrative access within an enterprise",
  "created_at": "2026-05-01T10:00:00Z",
  "etag": "W/\"a1b2c3d4\"",
  "id": "b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b",
  "permissions": [
    "withdrawals.create",
    "deposits.read",
    "clients.read"
  ],
  "platform_managed": false,
  "resource": "role",
  "scope_ref": "enterprises/b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b",
  "status": "active",
  "updated_at": "2026-05-01T10:00:00Z"
}

Grant role assignment

Principal-to-scope binding. Grant a role assignment when a user or service account needs that role inside a specific enterprise or client boundary.

Request URL

POST
POST https://business-api.youhodler.com/role-assignments

Request Body

application/json
{
  "principal_ref": "users/b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b",
  "role_ref": "roles/b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b",
  "scope_anchor_kind": "explicit",
  "scope_propagation": "subtree",
  "scope_ref": "enterprises/b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b"
}

Response

application/json
{
  "created_at": "2026-05-01T10:00:00Z",
  "etag": "W/\"a1b2c3d4\"",
  "id": "b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b",
  "principal_ref": "users/b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b",
  "resource": "role_assignment",
  "role_ref": "roles/b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b",
  "scope_anchor_kind": "explicit",
  "scope_propagation": "subtree",
  "scope_ref": "enterprises/b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b",
  "status": "active",
  "updated_at": "2026-05-01T10:00:00Z"
}

List capabilities

Product feature flags. Read capabilities to inspect which product-level features (e.g. conversion, deposit,withdrawal) are enabled or disabled for a given tenant scope. Note: this endpoint returns feature toggles, not the API permission names used in POST /roles (e.g. clients.read,internal_transfers.create).

Request URL

GET
GET https://business-api.youhodler.com/capabilities?scope_ref=enterprises/11111111-1111-4111-8111-111111111111&page_size=50

Response

application/json
{
  "items": [
    {
      "name": "withdrawals.create",
      "enabled": true
    },
    {
      "name": "deposits.read",
      "enabled": true
    },
    {
      "name": "clients.read",
      "enabled": false
    }
  ],
  "next_page_token": null
}

Create policy

Execution control surface. Create a policy once access is already in place and you need canonical governance around later mutating operations.

Request URL

POST
POST https://business-api.youhodler.com/policies

Request Body

application/json
[object Object]

Response

application/json
[object Object]

List approvals

Governed work queue. List approvals when execution has already created decision cases and operators need to inspect pending review work.

Request URL

GET
GET https://business-api.youhodler.com/approvals?scope_ref=enterprises/11111111-1111-4111-8111-111111111111&status=pending

Response

application/json
{
  "items": [
    {
      "action_family": "withdrawal",
      "created_at": "2026-05-01T10:00:00Z",
      "decision": null,
      "expires_at": "2026-05-01T10:00:00Z",
      "governed_ref": "clients/b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b",
      "id": "b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b",
      "initiated_by": {
        "actor": null,
        "approved_by": null,
        "authenticated_principal": {
          "id": "b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b",
          "kind": "user",
          "tenant_ref": "enterprises/b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b"
        },
        "enterprise_binding": {
          "tenant_type": "enterprise",
          "topology_ref": "enterprises/b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b"
        },
        "federation": null,
        "identity_source": "platform-managed",
        "initiated_by": null,
        "subject": {
          "id": "b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b",
          "kind": "user",
          "tenant_ref": "enterprises/b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b"
        }
      },
      "operation_id": "b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b",
      "requirement_snapshot": {
        "authority_ref": "enterprises/b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b",
        "expires_at": "2026-05-01T10:00:00Z",
        "governed_ref": "clients/b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b",
        "initiator_cannot_approve": true,
        "reason_code": "high_value",
        "required_human_approvals": 1,
        "requirement_key": "withdrawal_approval",
        "source": "policy"
      },
      "resource": "approval",
      "status": "pending",
      "updated_at": "2026-05-01T10:00:00Z"
    }
  ],
  "next_page_token": null
}