> ## 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.

# Karten

> Virtuelle Visa-Karten, instant. Mehrere pro Agent, niemals für das Modell sichtbar.

Eine Karte ist eine virtuelle Visa, ausgegeben von Ovras reguliertem EU-Banking-Partner. Card-Data (PAN, CVV) ist mit AES-256-GCM at rest verschlüsselt und wird niemals in den Agent-Kontext zurückgegeben — das Modell interagiert ausschließlich mit einem tokenisierten DPAN, der über den Network Token Service derived wird.

**Multi-Card pro Agent ist ein first-class Konzept.** Du kannst innerhalb eines Agents benannte Karten ausgeben (`subscriptions`, `travel`, `one-off`); der Agent wählt pro Transaktion welche.

## Das Karten-Modell

| Feld                              | Beschreibung                                           |
| --------------------------------- | ------------------------------------------------------ |
| `id`                              | `ca_*`                                                 |
| `agentId`                         | An einen Agent gebunden, immutable                     |
| `name`                            | Eindeutig pro Agent — z.B. `default`, `subs`, `travel` |
| `usage`                           | `single` (schließt nach erster Tx) oder `multi`        |
| `status`                          | `active` · `frozen` · `terminated`                     |
| `last4`                           | Letzte vier Ziffern — sicher zum Anzeigen              |
| `brand`                           | Heute immer `visa`                                     |
| `pan_encrypted` / `cvv_encrypted` | AES-256-GCM Ciphertext, Server-only                    |

## Lebenszyklus

| State        | Bedeutung                                                       |
| ------------ | --------------------------------------------------------------- |
| `active`     | Autorisiert Transaktionen                                       |
| `frozen`     | Reversibler Block — `POST /cards/:id/unfreeze` zum Reaktivieren |
| `terminated` | Irreversibel. Neue Karte ausgeben.                              |

## Operationen

| Endpoint                                              | Zweck                                                                    |
| ----------------------------------------------------- | ------------------------------------------------------------------------ |
| `POST /cards/agent/:agentId`                          | Ausgeben (idempotent) — jede Karte gehört zu genau einem Agent           |
| `GET /cards/:cardId`                                  | Lesen — PAN/CVV nie in Response                                          |
| `GET /cards/agent/:agentId/sensitive`                 | Sensitive Reveal (PAN/CVV) — Rate-limited 3/min, audit-logged            |
| `POST /cards/:cardId/freeze` / `/unfreeze` / `/close` | Lifecycle (per-Card)                                                     |
| `POST /fund`                                          | Org-Wallet aufladen (Karten ziehen vom Wallet — kein Card-Level-Funding) |
| `PUT /cards/:cardId/limits`                           | Limits aktualisieren                                                     |

## Karte ausgeben

<CodeGroup>
  ```bash curl theme={}
  curl -X POST https://api.getovra.com/cards/agent/ag_... \
    -H "Authorization: Bearer $OVRA_API_KEY" \
    -H "Content-Type: application/json" \
    -H "Idempotency-Key: $(uuidgen)" \
    -d '{
      "agentId": "ag_...",
      "name": "subscriptions",
      "usage": "multi",
      "purpose": "Nur Recurring SaaS",
      "maxTransactionEuros": 250,
      "monthlyLimitEuros": 1000
    }'
  ```

  ```ts SDK theme={}
  const card = await ovra.cards.create({
    agentId: "ag_...",
    name: "subscriptions",
    usage: "multi",
    purpose: "Nur Recurring SaaS",
    maxTransactionEuros: 250,
    monthlyLimitEuros: 1000,
  });
  ```

  ```text MCP theme={}
  ovra_card { action: "issue", agentId: "ag_...", usage: "multi", purpose: "Nur Recurring SaaS" }
  ```
</CodeGroup>

## Karten-Selektion zur Transaktionszeit

Pro Intent eine Karte referenzieren. Entweder `cardId` oder `cardName` (innerhalb des Agents). Beide weglassen returnt `E_CARD_REQUIRED` — es gibt by design keine implizite Default-Karte.

```bash theme={}
curl -X POST https://api.getovra.com/intents \
  -H "Authorization: Bearer $OVRA_API_KEY" \
  -d '{
    "agentId": "ag_...",
    "cardName": "subscriptions",
    "purpose": "Hetzner verlängern",
    "expectedAmountEuros": 4.51,
    "expectedMerchant": "hetzner.com"
  }'
```

## DPAN — der einzige Card-Identifier den der Merchant sieht

Der DPAN (Device Primary Account Number) ist ein Network-Token, ausgegeben vom Visa Tokenization Service durch den Banking-Partner. Er ist:

* Deterministisch derived von der FPAN
* Nicht reversibel — nutzlos bei Leak
* Auto-updates über alle Merchants wenn die zugrundeliegende Karte rotiert wird

Jede MPP-Credential und jeder CUA-Autofill-Token resolviert auf einen DPAN, niemals auf die FPAN.

## Fill-Tokens (`ftok_*`)

Internal-only verschlüsselte Wrapper für PAN/CVV/Expiry. Im Credential-Flow verwendet, nie an Agents zurückgegeben. Wenn du `ftok_` in deinen Logs siehst, hat unser Sanitizer etwas verpasst — bitte Bug filen.

## Card-Controls-Sync

Spend-Caps, MCC Allow/Block, Country Allow/Block auf der [Policy](/de/concepts/policies) des Karten-Agents werden auf die card-issuer-native Control-Surface gepusht. Policy ist Source of Truth; der Card-Mirror ist Best-Effort-Projection.

## Webhooks

| Event                           | Trigger                                  |
| ------------------------------- | ---------------------------------------- |
| `card.issued`                   | Neue Karte provisioniert                 |
| `card.activated`                | Status auf `active` geflippt             |
| `card.frozen` / `card.unfrozen` | Status-Change                            |
| `card.closed`                   | Terminal-Lifecycle                       |
| `card.rotated`                  | Neue Card-Credentials, alte geschlossen  |
| `card.funded`                   | Funds auf Karte bewegt                   |
| `card.shipped`                  | Reserviert (heute keine physische Karte) |
| `card.limits_changed`           | Limits aktualisiert                      |
| `card.details_changed`          | Cardholder/Expiry/etc geändert           |

## Plan-Tier-Limits

| Plan       | Karten     |
| ---------- | ---------- |
| Free       | 1          |
| Starter    | 10         |
| Business   | 25         |
| Enterprise | Unbegrenzt |

## Weiter

<CardGroup cols={2}>
  <Card title="Agents" icon="user-robot" href="/de/concepts/agents">
    Der Owner jeder Karte.
  </Card>

  <Card title="Policies" icon="shield-check" href="/de/concepts/policies">
    Was jede Karten-Spending steuert.
  </Card>

  <Card title="Bezahlung" icon="credit-card" href="/de/concepts/pay">
    Wie eine Karte tatsächlich belastet.
  </Card>

  <Card title="Transaktionen" icon="receipt" href="/de/concepts/transactions">
    Der Record den jede erfolgreiche Belastung schreibt.
  </Card>
</CardGroup>
