# Profiles (/en/api/profile)

Profiles keep accounts, posts, media, comments, and statistics separate per client. In the dashboard, profiles are called **workspaces**; see [Workspaces](/en/profile).

## Managing profiles [#managing-profiles]

| Request                       | What it does                                                                             |
| ----------------------------- | ---------------------------------------------------------------------------------------- |
| `GET /v1/profiles`            | The profiles, oldest first (the default profile first). Filter `external_id`             |
| `POST /v1/profiles`           | `{ "name", "external_id"? }`. An existing `external_id` returns that profile             |
| `GET /v1/profiles/{id}`       |                                                                                          |
| `PATCH /v1/profiles/{id}`     | `{ "name"?, "external_id"? }`                                                            |
| `DELETE /v1/profiles/{id}`    | `202`. The profile's access is revoked right away, its data is deleted in the background |
| `POST /v1/accounts/{id}/move` | `{ "profile_id" }`. Move an account to another profile                                   |

`POST /v1/profiles` is safe to repeat: store your system's client ID as `external_id`, and the same request always returns the same profile.

```bash
curl -X POST https://api.tebar.app/v1/profiles \
  -H "Authorization: Bearer tb_live_xxx" -H "Content-Type: application/json" \
  -d '{ "name": "Sunset Coffee", "external_id": "client-42" }'
```

The endpoints above only work with an **owner key** (a key not locked to a profile). Profile keys get `403 owner_key_required`.

## Working in one profile [#working-in-one-profile]

With an owner key, send the `Tebar-Profile` header with the profile's ID or its `external_id`. Every request then only sees and changes that profile's content:

```bash
curl https://api.tebar.app/v1/accounts \
  -H "Authorization: Bearer tb_live_xxx" \
  -H "Tebar-Profile: client-42"
```

- Without the header, an owner key sees every profile, and new data (posts, media) goes to the default profile.
- An unknown profile gives `404 profile_not_found`.
- A post belongs to one profile: accounts from two profiles in one post are refused with `400 mixed_profiles`, and media from another profile with `400 media_profile_mismatch`.

## Profile keys [#profile-keys]

A key locked to one profile is created in the dashboard (the **⋯** menu on the profile → **Create an API key**). It needs no header, cannot leave its profile, and a header pointing at another profile is refused. Good for apps that serve one client only.

## Moving accounts and deleting profiles [#moving-accounts-and-deleting-profiles]

- **Moving an account:** comments and statistics follow the account, while posts already created stay in the old profile. An account with posts waiting to publish is refused with `409 account_has_scheduled_posts`.
- **Deleting a profile:** the default profile cannot be deleted (`409 default_profile`). If you use [webhooks](/en/api/webhook), endpoints for all profiles receive a `profile.deleted` event once its data is gone.
