# Authentication

The Meteor API authenticates with a secret **API key**. Every request carries the key in the `Authorization` header, and the key defines **which workspace** it belongs to and **what it can do** (its scopes).

## Key format

Every key starts with a prefix that tells you its type:

- `met_live_…` — production key. It performs real actions and spends Energy.
- `met_test_…` — **test mode** key: runs cost nothing, which is what you want while you build. External side effects (sending WhatsApp messages, running integrations) are blocked.

> The key is a server-side secret. Never ship it to a browser or a mobile app, and never commit it. If it leaks, revoke it from the dashboard and create a new one.

## Create a key

In your Meteor dashboard: **Settings → Developers → Create API key**. You pick the scopes it needs and the environment (live or test). The key is shown **once** — store it the moment you create it.

If your current plan does not include API access, the dashboard offers you the **Developer Plan**, which has no fixed cost.

## Use the key

Keep it in an environment variable, never hardcoded:

```bash
export MET_API_KEY=met_live_your_key_here
```

With the SDK:

```ts
import Met from '@meteor.ia/sdk';

const met = new Met(process.env.MET_API_KEY, { workspaceId: 7 });
```
```python
import os
from meteor_ia import Met

met = Met(os.environ["MET_API_KEY"], workspace_id=7)
```

With `curl`, the key goes as a Bearer token:

```bash
curl https://api.met.meteor.com.co/api/v1/workspaces/7/runs \
  -H "Authorization: Bearer $MET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"input":"Hello"}'
```

## Scopes

A key can only do what it has a **scope** for. Scopes follow the pattern `domain:action`, where `:write` covers create, update and delete (there is no separate `:update`). Ask for the ones your integration needs and nothing else.

### Running Mets

| Scope | Allows |
|---|---|
| `runs:execute` | Run Mets — **spends Energy** |
| `runs:read` | Read runs and history |
| `agents:read` / `agents:write` | View / create and configure Mets |
| `skills:read` / `skills:manage` | View / manage skills |
| `functions:read` / `functions:write` | AI Functions (code and Met tools) |
| `automations:read` / `automations:write` | View / create triggers |
| `automations:execute` | Fire automations |
| `flows:write` | Create and edit flows |

### Data

| Scope | Allows |
|---|---|
| `collections:read` / `collections:write` | Collections |
| `items:read` / `items:write` | Items |
| `contacts:read` / `contacts:write` | CRM |
| `tasks:read` / `tasks:write` | Agentic tasks (steps a Met runs) |
| `variables:read` / `variables:write` | Workspace variables |
| `files:read` / `files:write` | Files and media library |

### Conversations and channels

| Scope | Allows |
|---|---|
| `conversations:read` | Read WhatsApp and CRM conversations |
| `handoff:manage` | Autopilot, assignment, operator message |
| `channels:read` | Channel status and broadcasts |
| `channels:send` | Send over WhatsApp and broadcasts |

### Integrations and platform

| Scope | Allows |
|---|---|
| `integrations:read` / `integrations:manage` | View / enable MCP integrations and their credentials |
| `integrations:execute` | Run integration tools |
| `mcp:use` | Open a session on the external MCP server |
| `webhooks:manage` | Inbound webhooks and outbound subscriptions |
| `events:read` | Workspace activity feed |
| `reminders:read` / `reminders:write` | Reminders |
| `billing:read` | Plan and usage (there is no `billing:write`) |
| `sites:read` | Websites |
| `snapshots:read` / `snapshots:install` | Template catalog / install templates |

### Partner keys only

These scopes **cannot be issued on a workspace key**: the server re-checks on every request and answers `403`. See the [Partners API](../../partners.html).

| Scope | Allows |
|---|---|
| `partner:clients:read` | Attributed clients |
| `partner:leads:read` / `partner:leads:write` | Leads |
| `partner:projects:read` / `partner:projects:write` | Implementation projects |
| `partner:support:read` / `partner:support:write` | Your own tickets and your clients' |
| `partner:commissions:read` · `partner:payouts:read` | Commissions and payouts (always read-only) |
| `snapshots:publish` | Publish a template to the marketplace |
| `workspaces:provision` | Create client workspaces |

### Restricted in test mode

A `met_test_` key cannot exercise scopes with real external effects: `integrations:execute`, `channels:send`, `snapshots:install` and `workspaces:provision` answer `403` with `test_mode_restricted`. The rest of the surface behaves the same.

If a key tries something outside its scopes, the API answers `403` with the code `missing_scope`, and the `param` field carries the missing scope. Do not retry — ask the key owner to widen the scopes.

## Revoke

A revoked key stops working in **under 60 seconds**. Revoke and rotate keys at the first sign of a leak, and use a different key per environment (one for test, one for production).
