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

# Agents

> First-class entities that own cards, tokens, transactions, and a policy.

An agent is a Stripe-shaped resource: it owns cards, tokens, transactions, and exactly one policy at a time. Agents are typed for AI use — they carry a `purpose`, optional `framework` (`openai-assistants`, `anthropic-sdk`, `langgraph`, `crewai`), and optional capabilities so the dashboard and audit trail can describe what they're for.

## The agent model

| Field                  | Description                                             |
| ---------------------- | ------------------------------------------------------- |
| `id`                   | `ag_*`                                                  |
| `name`                 | Display name                                            |
| `policyId`             | Exactly one policy, mutable but always present          |
| `profile.purpose`      | **Required.** Free text — describe what the agent does. |
| `profile.framework`    | Optional — e.g. `langgraph`                             |
| `profile.capabilities` | Optional `string[]` — what the agent can do             |
| `profile.description`  | Optional longer description                             |
| `profile.department`   | Optional cost-center tag                                |
| `profile.ownerContact` | Optional escalation contact                             |
| `status`               | `active` · `suspended` · `archived`                     |

## Minimal create

The dashboard create drawer (and the documented happy path) is `name + purpose + policyId`. Other profile fields are optional, hidden behind an "Advanced" toggle.

<CodeGroup>
  ```bash curl theme={}
  curl -X POST https://api.getovra.com/agents \
    -H "Authorization: Bearer $OVRA_API_KEY" \
    -H "Content-Type: application/json" \
    -H "Idempotency-Key: $(uuidgen)" \
    -d '{
      "name": "procurement-bot",
      "policyId": "po_default_...",
      "profile": { "purpose": "Buy office supplies under EUR 100" }
    }'
  ```

  ```ts SDK theme={}
  const agent = await ovra.agents.create({
    name: "procurement-bot",
    policyId: "po_default_...",
    profile: { purpose: "Buy office supplies under EUR 100" },
  });
  ```

  ```text MCP theme={}
  ovra_agent { action: "provision", name: "procurement-bot", policyId: "po_default_...", profile: { purpose: "..." } }
  ```
</CodeGroup>

## Lifecycle

| Endpoint                                | Purpose                                |
| --------------------------------------- | -------------------------------------- |
| `POST /agents`                          | Create (idempotent)                    |
| `GET /agents/:id`                       | Read                                   |
| `PATCH /agents/:id`                     | Update name / profile / status         |
| `DELETE /agents/:id`                    | Archive (cascades over cards + tokens) |
| `POST /agents/:id/freeze` / `/unfreeze` | Pause / resume authorization           |
| `POST /agents/:id/tokens`               | Issue an agent-scoped token (`at_*`)   |

## Agent tokens

Agents can hold their own scoped tokens (`at_*`). A token is bound to one agent, carries typed permissions, and may have an optional spend cap (via [delegation](/concepts/delegations)).

```bash theme={}
curl -X POST https://api.getovra.com/agents/ag_.../tokens \
  -H "Authorization: Bearer $OVRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "label": "production-runtime",
    "scopes": ["intents.write", "checkout.write"],
    "expiresInDays": 90
  }'
```

Use `at_*` tokens in your runtime instead of sharing your org-level `sk_*` key. Cross-agent reads with an `at_*` token return `403 E_AGENT_ISOLATION` — strict isolation is one of the [sacred invariants](/introduction#sacred-invariants).

## Signing keys (Phase 8 prep)

For each agent, an Ed25519 keypair is provisioned async. The public JWK is exposed at:

```http theme={}
GET /.well-known/agent-jwks/{agent_id}
```

This is wiring for **Visa Trusted Agent Protocol** (RFC 9421 HTTP Message Signatures). No outbound signing is enabled in v1.2 — code lands when the first TAP-aware merchant requires it.

## Webhooks

* `agent.created`
* `agent.frozen`
* `agent.unfrozen`

## Plan-tier limits

| Plan       | Agents    |
| ---------- | --------- |
| Free       | 1         |
| Starter    | 5         |
| Business   | 10        |
| Enterprise | Unlimited |

## Surfaces

| Surface   | Capability                      |
| --------- | ------------------------------- |
| REST      | `/agents`, `/agents/:id/tokens` |
| SDK       | `ovra.agents.*`                 |
| MCP       | `ovra_agent` (admin-side)       |
| Dashboard | `/dashboard/agents`             |

## Next

<CardGroup cols={2}>
  <Card title="Cards" icon="rectangle" href="/concepts/cards">
    Issue cards bound to an agent.
  </Card>

  <Card title="Policies" icon="shield-check" href="/concepts/policies">
    Define what an agent can spend.
  </Card>

  <Card title="Intents" icon="file-signature" href="/concepts/intents">
    The approval primitive every charge starts with.
  </Card>

  <Card title="Pay" icon="credit-card" href="/concepts/pay">
    How an agent actually pays.
  </Card>
</CardGroup>
