# Which endpoints does the Provely API expose?

> The REST API is the only place verification happens: operations, action results, verify, receipts, events, contracts, skills, and usage under /v1.

Canonical: https://provely.sh/docs/api  
Last reviewed: 2026-09-05  

**The control plane at `https://api.provely.sh` exposes ten endpoints under `/v1`. It is the only place verification happens. Every other surface is a thin client of this API.**

| Method and path | Purpose | Metered |
| --- | --- | --- |
| `POST /v1/operations` | Create an operation against a contract. Returns the idempotency key and the correlation keys. | no |
| `POST /v1/operations/{id}/action-result` | Submit the provider acknowledgement (E1). | no |
| `POST /v1/operations/{id}/verify` | Observe once and evaluate the contract. | yes, one verified action |
| `GET /v1/operations/{id}` | Read the operation state and the last verdict. | no |
| `GET /v1/operations/{id}/receipt` | Read the signed receipt. | no |
| `POST /v1/events/{provider}/{workspace}` | Receive a provider webhook. The signature is validated and the event is deduplicated. | no |
| `GET /v1/contracts/{id}` | Read a contract by id. | no |
| `GET /v1/skills/{service}` | Read the skill manifest of a service. | no |
| `POST /v1/connections` | Store a read-only provider credential, encrypted. | no |
| `GET /v1/usage` | Read the plan bucket, the bought bucket, and the verified actions this period. | no |

## How does authentication work?

- Send `Authorization: Bearer pv_...` with an API key, or an OAuth access token from the pinned issuer.
- The control plane hashes an API key at rest. A key carries scopes, expires, and rotates with a grace time.
- The credential decides the account. There is no account id in the request body.
- Every response carries a request id in `x-request-id`.

## What happens when the agent session ends?

The agent reports the operation id. A later session, the CLI, or the dashboard resumes it by id and fetches the receipt. An agent is ephemeral. An operation is not.

## How does a metered call behave?

1. Rate limit, then request size, then parse, then preflight.
2. Idempotency: a reused `Idempotency-Key` with the same body returns the stored result. A different body returns 422.
3. Reserve one credit, run, then settle. A failed run refunds the credit.
4. With no credit left, the response is 402 with the plans and the packs in `payment`.

*Create and verify an operation with curl*

```text
curl -X POST https://api.provely.sh/v1/operations \
  -H "Authorization: Bearer $PROVELY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"contract":"stripe.refund.succeeded","input":{"charge_id":"ch_3QxT5s2eZvKYlo2C","amount_cents":14200}}'

curl -X POST https://api.provely.sh/v1/operations/op_01J.../verify \
  -H "Authorization: Bearer $PROVELY_API_KEY" \
  -H "Idempotency-Key: verify-op_01J...-1"
```

### Is there an OpenAPI document?

Yes. The control plane serves `/v1/openapi.json`. The SDK clients are generated from it.

### Which events does the billing webhook accept?

The six Stripe events for checkout, invoices, refunds, and disputes, plus `checkout.session.async_payment_succeeded`. The control plane grants credits only from a signed webhook.

## Read next

- [Read the SDK reference](https://provely.sh/docs/sdks)
- [Read the pricing](https://provely.sh/pricing)
- [Read what a receipt proves](https://provely.sh/receipts)
