# Add an agent with its rule and key

Source: https://immiscible.fly.dev/docs/api/post-v1-cli-agents

`POST /v1/cli/agents`

Creates the agent, its first rule from `purpose` (and the workspace's rule templates), and an agent key, shown once. When the agent acts for you and another owner exists, the rule is a proposal they confirm: `pending` says so, and payments start once they do. With `reuse: true`, an agent you can manage with the same name gets a fresh key instead of a twin.

| Field | Description |
|---|---|
| `name` | how people will recognise it |
| `purpose` | `pays_invoices`, `books_travel`, `handles_refunds`, `buys_software`, `answers_customers` or `other` |
| `vendor` | optional: `anthropic`, `openai`, `google`, `meta` or `custom` |
| `reuse` | optional: `true` to reuse an agent of the same name |

## Authentication

CLI token. A token (`imc_...`) the developer CLI gets by signing in through the browser (`immiscible login`, the OAuth device grant), sent as `Authorization: Bearer`. It acts for one person in one workspace: it reads agents and status, and registers an agent with a rule from the same purposes as the console's "Add an agent". It never approves anything or changes an existing rule. Every use re-checks the person's membership and the workspace's sign-in rules; it lasts 90 days and ends from the console's sessions.

## Request

curl:

```bash
curl -X POST "https://immiscible.fly.dev/v1/cli/agents" \
  -H "authorization: Bearer $IMMISCIBLE_TOKEN" \
  -H "content-type: application/json" \
  -d '{
    "name": "Invoice agent",
    "purpose": "pays_invoices",
    "vendor": "openai",
    "reuse": true
  }'
```

Node:

```ts
const res = await fetch('https://immiscible.fly.dev/v1/cli/agents', {
  method: 'POST',
  headers: {
    authorization: `Bearer ${process.env.IMMISCIBLE_TOKEN}`,
    'content-type': 'application/json',
  },
  body: JSON.stringify({
    name: 'Invoice agent',
    purpose: 'pays_invoices',
    vendor: 'openai',
    reuse: true,
  }),
});
const data = await res.json();
console.log(res.status, data);
```

Python:

```python
import os
import requests

res = requests.post(
    "https://immiscible.fly.dev/v1/cli/agents",
    headers={
        "authorization": f"Bearer {os.environ['IMMISCIBLE_TOKEN']}",
        "content-type": "application/json",
    },
    json={
        "name": "Invoice agent",
        "purpose": "pays_invoices",
        "vendor": "openai",
        "reuse": True,
    },
)
print(res.status_code, res.json())
```

## Response

```json
{
  "reused": false,
  "agent": {
    "id": "agt_cd450fd54a34e55e8a8d08d3",
    "name": "Travel desk",
    "vendor": "openai",
    "status": "active",
    "tier": "intern",
    "lastActionAt": null,
    "canManage": true,
    "url": "https://immiscible.fly.dev/app/agents/agt_cd450fd54a34e55e8a8d08d3?w=ws_fa833074ebeb45e8"
  },
  "workspace": {
    "id": "ws_fa833074ebeb45e8",
    "name": "Quayside",
    "role": "owner",
    "currency": "GBP"
  },
  "key": "ask_...",
  "keyId": "key_128433ca90d2",
  "rules": [
    {
      "id": "mdt_08dc6567eac6b6c1aed35fe4",
      "title": "Books travel",
      "kind": "payment",
      "actions": null,
      "description": "Pays up to £1,500 at a time and £10,000 a month. A supplier it has not paid before needs a person."
    }
  ],
  "pending": null,
  "binding": {
    "id": "key_128433ca90d2",
    "prefix": "ask_...",
    "label": "agent: Travel desk",
    "scope": "agent",
    "principalId": "p_548c20992826",
    "teamId": "team_default",
    "taskClassId": "agent.orchestration",
    "policyProfile": null,
    "createdAt": "2026-10-06T12:48:18.383Z",
    "createdBy": "sam@quayside.example",
    "lastUsedAt": null,
    "revokedAt": null,
    "calls": 0
  }
}
```
