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

# Collect

> Collect payments for work your agents deliver.

Collect closes the loop on agent-native economies — your agent doesn't only spend, it can also earn. Issue a payment request and the counterparty pays from another Ovra wallet (instant, free) or via SEPA with reference matching (external).

<Note>
  **Internal Ovra-to-Ovra works today.** External SEPA inbound matching is on the roadmap and is currently rejected by the `/settle` endpoint. See the status table below.
</Note>

## Why this matters

If your agent does work that someone else paid for — services, goods, microtransactions, API calls — you need a way to collect. Without Collect, "agent payments" is a one-way street. With it, agents can run businesses.

## The payment-request model

| Field                      | Description                                                                        |
| -------------------------- | ---------------------------------------------------------------------------------- |
| `id`                       | `pr_*`                                                                             |
| `destinationWalletId`      | Where settled funds land                                                           |
| `amountEuros`              | EUR amount, ≤ 1,000,000                                                            |
| `description`              | Free text; surfaces in the payer view                                              |
| `counterpartyOwnerId`      | Set for **internal** requests (other Ovra customer)                                |
| `sepaInstructions`         | `{ iban, bic, reference }` for **external** requests; reference is `OVRA-PR-<hex>` |
| `payerName` / `payerEmail` | Optional — surfaces on the payer page                                              |
| `agentId`                  | Optional — bind the request to a specific agent                                    |
| `expiresAt`                | Optional TTL (max 30 days)                                                         |
| `status`                   | `pending → paid · expired · cancelled`                                             |

## Operations

| Endpoint                          | Purpose                                                                       |
| --------------------------------- | ----------------------------------------------------------------------------- |
| `POST /claim/requests`            | Create a request. Pass `counterpartyOwnerId` for internal, omit for external. |
| `GET /claim/requests`             | List your requests. Filter `status`, use `inbound=true` for the payer view.   |
| `GET /claim/requests/:id`         | Detail — owner or counterparty allowed.                                       |
| `POST /claim/requests/:id/settle` | **Internal only.** Atomic wallet→wallet debit/credit + ledger + transfer row. |
| `POST /claim/requests/:id/cancel` | Cancel an unpaid request.                                                     |
| `GET /claim/requests/:id/pay`     | Public payer page — no auth required.                                         |

<Note>
  The pillar is named **Collect** but the routes still mount under `/claim/*`. The route rename is upcoming tech-debt; the URL contract is stable.
</Note>

## Create a request

<CodeGroup>
  ```bash curl theme={}
  curl -X POST https://api.getovra.com/claim/requests \
    -H "Authorization: Bearer $OVRA_API_KEY" \
    -H "Content-Type: application/json" \
    -H "Idempotency-Key: $(uuidgen)" \
    -d '{
      "destinationWalletId": "wal_...",
      "amountEuros": 49.00,
      "description": "Research report — 3 sources",
      "payerEmail": "ops@acme.example"
    }'
  ```

  ```ts SDK theme={}
  const req = await ovra.collect.create({
    destinationWalletId: "wal_...",
    amountEuros: 49,
    description: "Research report — 3 sources",
    payerEmail: "ops@acme.example",
  });
  ```
</CodeGroup>

Response:

```json theme={}
{
  "id": "pr_...",
  "amountEuros": 49,
  "status": "pending",
  "settlementType": "external",
  "sepaInstructions": {
    "iban": "DE89370400440000001234",
    "bic": "PLINDE21",
    "reference": "OVRA-PR-a3f9b1c2"
  },
  "expiresAt": "2026-05-20T10:00:00Z"
}
```

## Settle path matrix

<Tabs>
  <Tab title="Internal (Ovra → Ovra)">
    Counterparty has an Ovra wallet. Pass `counterpartyOwnerId` in the create call. The counterparty calls `POST /claim/requests/:id/settle` with `sourceWalletId`. We run the debit and credit in a single transaction:

    * SQL `BEGIN`
    * `UPDATE wallets SET balance_euros = balance_euros - amount WHERE id = :src AND balance_euros >= amount`
    * `UPDATE wallets SET balance_euros = balance_euros + amount WHERE id = :dst`
    * INSERT `ledger_entries` (debit + credit), `transfers` row, mark request `paid`
    * `COMMIT`
    * Fire `claim.request.paid` webhook

    Result: instant, free, fully auditable. ✅ Production-ready.
  </Tab>

  <Tab title="External (SEPA inbound)">
    Counterparty is outside Ovra. The request returns `sepaInstructions` with a `OVRA-PR-<hex>` reference. The payer initiates SEPA with that reference.

    ⚠️ **Currently TODO.** `/settle` rejects external requests today (no SEPA-In reconciliation pipeline yet). Choices on the table:

    1. Integrate a dedicated SEPA-In provider for reference matching.
    2. Use the banking partner's SEPA-Inbound feed (v1.3+ live mode).
    3. Manual operator match in dashboard for the demo phase.
  </Tab>
</Tabs>

## Surfaces

| Surface           | Status                                                                                              |
| ----------------- | --------------------------------------------------------------------------------------------------- |
| REST API          | Full                                                                                                |
| SDK (`@ovra/sdk`) | `ovra.collect.*`                                                                                    |
| MCP               | `ovra_claim` (action-multiplexed) — tool name will rename to `ovra_collect` in a future MCP release |
| Dashboard         | `/dashboard/collect` — create drawer, filter list, detail drawer                                    |

## Webhooks

Subscribe to these events to react in real time:

* `claim.request.created`
* `claim.request.paid`
* `claim.request.expired`
* `claim.request.cancelled`

See [Webhooks](/concepts/webhooks) for delivery, retries, and signature verification.

## Next

<CardGroup cols={2}>
  <Card title="Accounts" icon="wallet" href="/concepts/accounts">
    Wallets, IBANs, transfers — where the funds live.
  </Card>

  <Card title="Webhooks" icon="bell" href="/concepts/webhooks">
    Fire-and-forget delivery for `claim.request.*` events.
  </Card>
</CardGroup>
