---
title: "Change a service account's role."
method: PATCH
path: "/organizations/{organizationId}/service-accounts/{serviceAccountId}"
tags: ["service-accounts"]
---

# Change a service account's role.

`PATCH /organizations/{organizationId}/service-accounts/{serviceAccountId}`

## Request

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

Sets the service account's role, the one property of it that
changes. Its keys and trust rules then act with the new role. The
change is audited even when the role is unchanged.

Requires the `serviceAccounts.update` permission, which only the
`admin` and `owner` roles hold. Personal access tokens and federated
tokens are refused whatever their role.

## Request body

- UpdateServiceAccountRequest: The request body for PATCH /organizations/{organizationId}/service-accounts/{serviceAccountId}.
  - `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.

## Response `200`

The service account, with its new role.

- 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 service account id is not an integer, the body is not a JSON object, or `role` is missing or names a role a service account may not hold (`service_account_bad_request`).
- `403`: The caller lacks the `serviceAccounts.update` 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`), or the organization has no service account with that id (`service_account_not_found`).
- `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)
