---
title: "Create a service account."
method: POST
path: "/organizations/{organizationId}/service-accounts"
tags: ["service-accounts"]
---

# Create a service account.

`POST /organizations/{organizationId}/service-accounts`

## Request

- Base URL: `https://api.shorebird.dev/api/v1`
- URL: `https://api.shorebird.dev/api/v1/organizations/{organizationId}/service-accounts`
- Auth: one of:
  - HTTP bearer
  - HTTP bearer

Creates a service account in the organization with the given role
(`developer` when omitted). Service accounts may hold any of their
roles on every plan. A new account has no keys or trust rules; issue
it a key with `POST .../keys`, or let a CI workflow sign in as it
with `POST .../trust-rules`.

Requires the `serviceAccounts.create` permission, which only the
`admin` and `owner` roles hold. Personal access tokens and federated
(OIDC-exchanged) tokens are refused whatever their role
(`personal_access_token_forbidden` or
`api_key_insufficient_permissions`): sign in to the console instead.

## Request body

- CreateServiceAccountRequest: The request body for POST /organizations/{organizationId}/service-accounts.
  - `name` string, required: The service account's name. Surrounding whitespace is trimmed; what remains must be 1 to 64 characters.
  - `role` 'viewer' | 'developer' | 'appManager' | 'auditor': A role a service account can hold in its organization: a subset of `Role`. Never `admin` or `owner`, so a leaked key cannot manage the organization's members or its other service accounts.

## Response `201`

The newly-created service account.

- ServiceAccount: A non-human account owned by an organization, for CI and other automation. It authenticates only with API keys issued to it or under OIDC trust rules, and is shown as `label` (`name[bot]`).
  - `id` integer, required: The service account's ID, which is also its user ID.
  - `organization_id` integer, required: The organization that owns the service account.
  - `name` string, required: The service account's name.
  - `label` string, required: The name the service account is shown by, `name[bot]`.
  - `role` 'viewer' | 'developer' | 'appManager' | 'auditor', required: A role a service account can hold in its organization: a subset of `Role`. Never `admin` or `owner`, so a leaked key cannot manage the organization's members or its other service accounts.
  - `created_at` string, date-time, required: When the service account was created.
  - `created_by_user_id` integer, nullable, required: The user who created the service account, or null once that user has been deleted.
  - `created_by_email` string, nullable, required: The email of the user who created the service account, or null once that user has been deleted.
  - `last_auth_at` string, date-time, nullable, required: When the service account last authenticated, or null if it never has. Refreshed at most once a day.

## Other responses

- `400`: The organization id is not an integer (`organization_id_malformed`), or the body is not a JSON object, `name` is missing or invalid, or `role` names a role a service account may not hold (`service_account_bad_request`, with the reason in `details`).
- `403`: The caller lacks the `serviceAccounts.create` permission, or authenticated with a credential that may never manage service accounts.
- `404`: No such organization, or the caller is not a member of it (`organization_membership_guard_error`).
- `424`: A database step failed (`service_account_database_error`).
- `default`: Standard error response. Emitted for any non-2xx status where a body can be decoded into an [ErrorResponse].

---

[API](https://skmtc.dev/shorebird/apis/shorebird-codepush-api.md) - [All operations](https://skmtc.dev/shorebird/apis/shorebird-codepush-api/llms.txt) - [OpenAPI document](https://skmtc.dev/shorebird/apis/shorebird-codepush-api/revisions/941da8871d10?raw)
