---
title: "Create"
method: POST
path: "/service-accounts"
tags: ["service-accounts"]
---

# Create

`POST /service-accounts`

## Request

- Base URL: `https://api.instruxi.dev/api/v1/enforcer`
- URL: `https://api.instruxi.dev/api/v1/enforcer/service-accounts`
- Auth: one of:
  - API key in header `Authorization`
  - API key in header `X-API-Key`

Mints a service account in the caller's own tenant — there is no tenant override. The mint fence applies: the role may never exceed the caller's own Permissions (403 role_exceeds_caller), and a portal-link or agent credential may never mint one (403 agent_cannot_mint). slug is tenant-unique, case-insensitive (409 slug_taken otherwise) and immutable after creation.

## Request body

- InternalDeliveryHttpHandlerCreateServiceAccountRequest
  - `description` string
  - `name` string
  - `role_id` string, uuid
  - `slug` string

## Response `201`

Created

- InternalDeliveryHttpHandlerServiceAccountResponse
  - `data` InternalDeliveryHttpHandlerServiceAccountView
    - `active` boolean
    - `agent_id` string: AgentID is nil on this branch (see serviceaccounts.AgentBinding) — agents.service_account_id lands with v3-agents-schema.
    - `created_at` string
    - `created_by` string
    - `description` string
    - `email` string
    - `groups` InternalDeliveryHttpHandlerServiceAccountGroupRef[]: Groups is populated on GET /service-accounts/{id} only — a list page decorating every row with its group memberships is an N+1 this type does not force; use GET /service-accounts/{id}/groups for the full list on any one account.
      - `id` string
      - `name` string
      - `slug` string
    - `id` string
    - `key_count` integer
    - `kind` string
    - `last_used_at` string
    - `name` string
    - `role` InternalDeliveryHttpHandlerServiceAccountRoleView
      - `id` string
      - `permissions` InternalDeliveryHttpHandlerServiceAccountPermsView
        - `admin_managed` boolean
        - `cross_tenant` boolean
        - `tenant_manage` boolean
        - `tenant_read` boolean
        - `tenant_write` boolean
      - `slug` string
    - `slug` string
    - `tenant_id` string
    - `updated_at` string
  - `success` boolean

## Other responses

- `400`: invalid_input | unknown_role
- `401`: Unauthorized
- `403`: role_exceeds_caller | role_not_allowed | agent_cannot_mint
- `409`: slug_taken

---

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