# Authentication and API keys

> How to create a key, send it, keep it safe, and tell the two kinds of credential apart.

Source: https://docs.xplantpro.com/docs/authentication

Every request carries a credential as a bearer token:

```http
Authorization: Bearer xpk_live_…
```

There are two kinds of credential, and they are not interchangeable.

| | Workspace API key | Device token |
| --- | --- | --- |
| Prefix | `xpk_live_` or `xpk_dev_` | `xpd_live_` or `xpd_dev_` |
| Can do | Whatever its [scopes](https://docs.xplantpro.com/docs/scopes.md) allow, across the workspace | Post readings, events and heartbeats for **one** device, nothing else |
| Lives on | A server, a script, an integration you run | The device itself: a Raspberry Pi, a gateway, a microcontroller |
| Created in | Settings → Integrations → API Keys | With the API, using a workspace key (see [Device tokens](https://docs.xplantpro.com/docs/device-tokens.md)) |

## Plans and access

Three things bound what a key can do: **its scopes**, **its owner's role**, and **the workspace's plan**. A key never does more than its owner can in xPlant.

### By plan

| Plan | What API keys can do |
| --- | --- |
| xPlant+ Teams, Enterprise | The whole API: every scope. |
| Hobby, Pro Lab | Connect devices only: `read:devices`, `write:devices`, `write:sensor_readings` and `write:device_events`. Keys can register devices, manage their tokens, and post their readings and events. They can't read sensor readings back; that data is visible in xPlant. |
| Free | No API access. Every request answers `402 PAID_PLAN_REQUIRED`. |

A call outside what the plan includes answers `402 PAID_PLAN_REQUIRED`. See [plans](https://www.xplantpro.com/en/subscriptions) to upgrade. Your plan's allowances still apply too: registering devices beyond the plan's allowance answers `402 DEVICE_LIMIT_REACHED`.

### By role

A key acts with its owner's role in the workspace, as it is at the time of each request. If the owner's role changes, the key follows.

| Scopes | Minimum role of the key's owner |
| --- | --- |
| `read:` scopes, except the two below | Any active member |
| `write:` scopes, except the one below | `member` |
| `read:pricing`, `read:commerce`, `write:demand` | `manager` |

Roles rank `owner` > `admin` > `manager` > `member` > `viewer` > `guest`. A call that needs more than the owner's role answers `403 FORBIDDEN`, and the message names the scope and the role it needs, for example:

```json
{
  "ok": false,
  "data": null,
  "error": "This key's owner is a viewer in this workspace, which cannot use write:tasks (needs member or above). A key never does more than its owner can in xPlant.",
  "code": "FORBIDDEN"
}
```

The wording can change; branch on `code`. As a rule of thumb, **`402` is about the plan, and `403` is about the role or a missing scope.**

### When you create a key

You can only grant scopes that your role and your plan allow. A scope above your role is refused with `403`, and one above your plan with `402`, and both messages name the scopes involved.

### Check before you call

[`GET /me`](https://docs.xplantpro.com/docs/api/account/get-me.md) returns the key's `scopes` (what it was created with), `effectiveScopes` (what it can use right now, after the role and plan limits), the owner's `role`, and `apiAccess`: `full` on Teams and Enterprise, `devices` on plans whose keys can connect devices only.

### Devices after a plan lapses

Device tokens keep posting readings, events and heartbeats after a plan lapses, so sensors don't go quiet. New devices and new tokens follow the plan's device allowance.

Enterprise customers can scope organisation-specific integrations and API requirements with us: [support@xplantpro.com](mailto:support@xplantpro.com).

## Creating a key

1. Open **Settings → Integrations → [API Keys](https://app.xplantpro.com/settings/integrations/api-keys)** in xPlant.
2. Name the key after what will use it ("Nightly task sync", "Grow room dashboard"). You'll thank yourself when you need to revoke one.
3. Choose its scopes. A key gets exactly what you tick, and nothing by default. See [Scopes](https://docs.xplantpro.com/docs/scopes.md) for what each one allows and some common setups.
4. Copy the key straight away. **It is shown once.** If you lose it, create a new one and revoke the old.

**Scopes are fixed when a key is created.** To change what an integration can do, create a new key with the scopes it needs, move the integration to it, then revoke the old key. Rotating a key in xPlant issues a new secret with the same name, scopes and environment.

A workspace can have up to 10 active keys at a time.

## Live and dev keys

The `xpk_live_` and `xpk_dev_` prefixes are labels for your own bookkeeping. **Both act on your real workspace, with the same data and the same limits. There is no sandbox.** Use a dev key to keep test traffic separate in your records, not to protect production data.

## What a key can reach

- **One workspace.** A key belongs to the workspace it was created in and can never read or write another workspace's records. If you belong to several labs, each needs its own key.
- **Its scopes, and nothing more.** No scope implies another; `write:tasks` does not grant `read:tasks`.
- **A record in another workspace looks the same as one that doesn't exist.** Both answer `404 NOT_FOUND`, so a key can't be used to probe for ids.

Call [`GET /me`](https://docs.xplantpro.com/docs/api/account/get-me.md) to see which key you're using and every scope it holds. It needs no scope.

## When a key stops working

| You get | Because |
| --- | --- |
| `401 UNAUTHORIZED` | The key is missing, mistyped or revoked, or the person who created it has left the workspace. |
| `402 PAID_PLAN_REQUIRED` | The workspace's plan doesn't include this call. Teams and Enterprise include the whole API; Hobby and Pro Lab keys can connect devices only; Free has no API access. See [Plans and access](#plans-and-access). |
| `403 FORBIDDEN` | The key lacks the scope this endpoint needs, or its owner's role is below what the scope needs. The `error` text says which, e.g. `Missing scope: write:tasks`. |
| `403 DEVICE_TOKEN_NOT_ACCEPTED` | You sent a device token to an endpoint that needs a workspace key. |

A key is tied to the member who created it. When someone leaves the workspace, their keys stop working, so create keys for long-running integrations from an account that will stay.

## Keeping keys safe

- Keep keys in environment variables or a secrets manager, never in source code or a repository.
- **Never put a workspace key on a device.** A box on a shelf, in a room other people walk through, should carry a [device token](https://docs.xplantpro.com/docs/device-tokens.md) that can only post its own readings.
- Never embed a key in a web page or a mobile app. Anyone who opens it can read it. Call the API from your own backend instead.
- Give each integration its own key with only the scopes it needs, so you can revoke one without breaking the others.
- If a key leaks, revoke it in **Settings → Integrations → API Keys** at once, then create a replacement.
