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

# Authentication

> API authentication methods

# Authentication

Orbit authenticates **API requests** two ways: an API key for server-to-server
calls, and a session Bearer token for dashboard users. Enterprise organizations
can additionally sign users in through [SAML single sign-on](#single-sign-on-saml)
and provision them through [SCIM](#directory-provisioning-scim). Pick the method
that matches how the request is made.

## API Key (Server-to-Server)

Include your API key in the `X-API-Key` header:

```bash theme={null}
curl https://api.orbit.devotel.io/api/v1/messages \
  -H "X-API-Key: dv_live_sk_your_key_here"
```

## Bearer Token (Dashboard Users)

For dashboard users, use JWT Bearer tokens:

```bash theme={null}
curl https://api.orbit.devotel.io/api/v1/messages \
  -H "Authorization: Bearer eyJhbG..."
```

<Note>
  You may also pass an API key via `Authorization: Bearer dv_live_pk_...` (any
  `dv_` key — `dv_live_sk_`, `dv_test_sk_`, `dv_live_pk_`, `dv_test_pk_`) for
  environments where the `X-API-Key` custom header is blocked by CORS. The server
  accepts either form: it reads `X-API-Key` first, then falls back to a `Bearer`
  token that carries a `dv_` prefix. A JWT (which starts with `eyJ`) is still
  treated as a dashboard session token, so the two never collide.
</Note>

## API Key Format

| Type        | Prefix        | Usage                             |
| ----------- | ------------- | --------------------------------- |
| Live Secret | `dv_live_sk_` | Server-side API calls             |
| Test Secret | `dv_test_sk_` | Server-side API calls (test mode) |
| Live Public | `dv_live_pk_` | Client-side (browser SDKs)        |
| Test Public | `dv_test_pk_` | Client-side (test mode)           |

<Warning>
  A public key (`dv_live_pk_` / `dv_test_pk_`) is meant to be embedded in
  client-side code, so it is **restricted to read-only scopes** at creation.
  Write and administrative scopes — `messages:write`, `contacts:write`, `admin`,
  the `*` wildcard, and the sensitive account reads `billing:read` /
  `settings:read` — are rejected for a public key with a `422`. Use a **secret
  key** (`dv_live_sk_`) for any operation that sends or modifies data.

  Still treat any key you ship to a browser or mobile bundle as publicly visible
  and scope it to the minimum reads it needs.
</Warning>

## Single sign-on (SAML)

Enterprise organizations can log dashboard users in through a SAML 2.0 identity
provider — Okta, Microsoft Entra ID (formerly Azure AD), OneLogin, Google
Workspace, or PingFederate. SSO
authenticates people into the dashboard; it does not mint API keys, so
server-to-server calls still use the methods above.

An owner configures the connection under **Settings → Single sign-on** in the
dashboard (or via `PATCH /api/v1/settings/saml`): set your IdP's SSO URL, entity
ID, and signing certificate, then use **Test connection** before enabling it.

Each organization gets its own set of endpoints, keyed by your organization slug
(`orgSlug`). They live at the API root, **not** under `/api/v1`:

| Method | Endpoint                        | Purpose                                                                    |
| ------ | ------------------------------- | -------------------------------------------------------------------------- |
| GET    | `/auth/saml/{orgSlug}/metadata` | Service-provider metadata XML to import into your IdP                      |
| GET    | `/auth/saml/{orgSlug}/login`    | Start the SSO flow (redirects to your IdP)                                 |
| POST   | `/auth/saml/{orgSlug}/callback` | Assertion Consumer Service (ACS) — your IdP posts the signed response here |
| GET    | `/auth/saml/{orgSlug}/logout`   | Start single logout                                                        |

Point your IdP at the metadata endpoint, for example
`https://api.orbit.devotel.io/auth/saml/acme/metadata` for the `acme`
organization.

## Directory provisioning (SCIM)

Provision and deprovision dashboard users automatically from your identity
provider over SCIM 2.0. Generate a provisioning token under **Settings → SCIM**
(or via `POST /api/v1/settings/scim/generate-token`) — the token is shown once,
so copy it into your IdP immediately.

Your IdP sends the token as a Bearer credential on every request:

```bash theme={null}
curl https://api.orbit.devotel.io/scim/v2/acme/Users \
  -H "Authorization: Bearer <your-scim-token>"
```

Endpoints follow the SCIM 2.0 spec and return `application/scim+json`. They are
keyed by your organization slug and live at the API root, **not** under
`/api/v1`:

| Resource  | Endpoints                                                                                                |
| --------- | -------------------------------------------------------------------------------------------------------- |
| Users     | `/scim/v2/{orgSlug}/Users` (list, create), `/scim/v2/{orgSlug}/Users/{id}` (get, replace, patch, delete) |
| Groups    | `/scim/v2/{orgSlug}/Groups` (list, create/update), `/scim/v2/{orgSlug}/Groups/{id}` (get)                |
| Discovery | `/scim/v2/{orgSlug}/ServiceProviderConfig`, `/ResourceTypes`, `/Schemas`                                 |

<Note>
  SAML and SCIM are independent: SSO controls how users sign in, SCIM controls
  which users exist. You can enable either on its own, though most IdPs configure
  both together.
</Note>
