> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flexprice.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Creating a Service Account

> Create a service account with specific permissions for your automated services

A service account is a special type of account for automated services, integrations, and scripts. Unlike your regular user account, service accounts are assigned specific roles that control what resources they can access in Flexprice.

## Why Use Service Accounts?

Service accounts let you:

* **Isolate access**: Each service gets its own account with only the permissions it needs
* **Improve security**: If an API key is compromised, the damage is limited to that service's permissions
* **Track usage**: See which service is making which API calls
* **Manage easily**: Revoke access for one service without affecting others

## Creating a Service Account

### Choose the Right Role

Before creating a service account, decide which role fits your use case:

Flexprice currently supports following custom roles:

| Role             | Use When                                                                          |
| ---------------- | --------------------------------------------------------------------------------- |
| `super_admin`    | Your service needs full, unrestricted access (treat the key as a root credential) |
| `event_ingestor` | Your service needs to send events to Flexprice                                    |
| `event_reader`   | Your service needs to read event data                                             |

### Via Dashboard

Navigate to **Developers > Service Accounts** and click **Create** to open the service account creation dialog.

<Frame>
  <img src="https://mintcdn.com/flexprice/vMggtqc64rm5hfnA/public/images/docs/rbac/create-service-acc.png?fit=max&auto=format&n=vMggtqc64rm5hfnA&q=85&s=970af506f3c2887a5251d197909de879" alt="Create Service Account" width="3418" height="1966" data-path="public/images/docs/rbac/create-service-acc.png" />
</Frame>

In the dialog:

1. Select the roles you want to assign (Event Ingestor, Event Reader, or both)
2. Click **Create Service Account**

The service account is created with the selected roles and you can now generate API keys for it.

### Via API

<CodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url https://api.cloud.flexprice.io/v1/users \
    --header 'Content-Type: application/json' \
    --header 'x-api-key: <api-key>' \
    --data '{
    "type": "service_account",
    "name": "Event Ingestion Worker",
    "roles": ["event_ingestor"]
  }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.cloud.flexprice.io/v1/users', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-api-key': '<api-key>'
    },
    body: JSON.stringify({
      type: 'service_account',
      name: 'Event Ingestion Worker',
      roles: ['event_ingestor']
    })
  });
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      'https://api.cloud.flexprice.io/v1/users',
      headers={
          'Content-Type': 'application/json',
          'x-api-key': '<api-key>'
      },
      json={
          'type': 'service_account',
          'name': 'Event Ingestion Worker',
          'roles': ['event_ingestor']
      }
  )
  ```
</CodeGroup>

### Response

```json theme={null}
{
  "id": "usr_abc123",
  "type": "service_account",
  "roles": ["event_ingestor"],
  "created_at": "2025-11-14T10:00:00Z"
}
```

<Tip>
  Save the `id` from the response. You'll need it when creating API keys.
</Tip>

## Request Fields

<ParamField path="type" type="string" required>
  Must be set to `"service_account"`.
</ParamField>

<ParamField path="roles" type="array" required>
  List of roles to assign. Must include at least one role.

  Available roles:

  * `super_admin` - Full access to every resource
  * `event_ingestor` - Can send events
  * `event_reader` - Can read events
</ParamField>

<ParamField path="name" type="string">
  Display name shown in the dashboard and audit logs. Helps you identify the
  service account later when listing or updating it.
</ParamField>

## Validation Rules

<Warning>
  **At Least One Role Required**

  You must assign at least one role when creating a service account. Empty roles will return an error.
</Warning>

### Common Errors

**No Roles Provided**

```json theme={null}
{
  "error": "Service accounts must have at least one role assigned"
}
```

**Invalid Role Name**

```json theme={null}
{
  "error": "Invalid role: custom_role"
}
```

## Real-World Examples

### Example 1: Event Ingestion Service

**Scenario**: You have a service that sends user events to Flexprice.

**Create service account with**:

* Role: `event_ingestor`

**What happens**:

* ✅ Service can send events
* ❌ Service cannot read events (403 Forbidden)
* ❌ Service cannot access other resources (403 Forbidden)

### Example 2: Analytics Dashboard

**Scenario**: You have a dashboard that displays event data.

**Create service account with**:

* Role: `event_reader`

**What happens**:

* ✅ Dashboard can read events
* ❌ Dashboard cannot send events (403 Forbidden)
* ❌ Dashboard cannot modify anything (403 Forbidden)

## Assigning Multiple Roles

You can assign both roles to give combined permissions:

**Service account with both roles**:

* Roles: `event_ingestor` and `event_reader`

**What happens**:

* ✅ Can send events (from `event_ingestor`)
* ✅ Can read events (from `event_reader`)

## Updating a Service Account

Rename a service account at any time. Only the display `name` can be changed; roles and type are immutable.

```bash theme={null}
curl --request PUT \
  --url https://api.cloud.flexprice.io/v1/users/{id} \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: <api-key>' \
  --data '{
  "name": "Event Ingestion Worker (prod)"
}'
```

To rotate which roles a service account has, create a new service account with the new role set and migrate the API key over.

## Deleting a Service Account

Archive a service account when it is no longer in use. Existing API keys for that account stop working immediately.

```bash theme={null}
curl --request DELETE \
  --url https://api.cloud.flexprice.io/v1/users/{id} \
  --header 'x-api-key: <api-key>'
```

The endpoint returns `204 No Content` on success. The account is soft-deleted, so its history remains in audit logs.

## Best Practices

<Check>
  **One Service Account Per Service**

  Create separate service accounts for each automated service or integration.
</Check>

<Check>
  **Assign Minimal Permissions**

  Only assign the roles your service actually needs.
</Check>

## Troubleshooting

### Service Getting 403 Errors

**Symptom**: Your service is getting "Forbidden" errors when making API calls.

**Possible Causes**:

1. The service account doesn't have the required role
2. The API key was created before you assigned roles
3. The role doesn't include permission for that endpoint

**Solution**:

1. Check what roles the service account has: `GET /v1/users/usr_abc123`
2. Verify those roles include the permission you need
3. If you recently added roles, create a new API key

### Cannot Create Service Account

**Symptom**: Getting an error when creating the service account.

**Possible Causes**:

1. Forgot to include `roles` in the request
2. Used an invalid role name
3. Specified `roles` as an empty array

**Solution**: Make sure your request includes at least one valid role:

```json theme={null}
{
  "type": "service_account",
  "roles": ["event_ingestor"]
}
```

## Next Steps

<Card title="Generate API Keys" icon="key" href="/docs/rbac/api">
  Create API keys for your service account →
</Card>
