# REST API reference

> The public Agreebase REST contract for creating, signing, retrieving, changing, notarising, and verifying records.

Audiences: developers, agents
Kind: reference
Updated: 2026-07-12

The REST base path is `/api/v1`.

> The full generated contract, with exact request/response JSON schemas and security declarations for every route, is always available at [`/api/openapi.json`](/api/openapi.json). Treat it as the source of truth ahead of this page for field-level shapes.

## Authentication

Public routes require no credentials. Protected routes accept a short-lived bearer token or an API key where the route supports that scope:

```http
Authorization: Bearer <short-lived-token>
```

```http
X-API-Key: <long-lived-key>
```

See [Authentication and API keys](/docs/developers/authentication-and-api-keys).

## Public verification routes

| Method | Route | Purpose |
|---|---|---|
| `GET` | `/public/verify/{agr_reference}` | Return a public certificate and current-authority result. |
| `POST` | `/public/verify/{agr_reference}` | Verify text, body/content hash, document hash, or transaction hash. |
| `GET` | `/public/agreements/{agr_reference}` | Return redacted public record metadata. |

Verification is also available through the browser at `/verify`.

## Authentication and identity routes

| Method | Route | Purpose |
|---|---|---|
| `POST` | `/verification/request-otp` | Request an OTP for authentication, confirmation, or linking. |
| `POST` | `/verification/verify-otp` | Verify an OTP and issue a bearer token where applicable. |
| `GET` | `/identity/contact-points` | List verified identity contact points. |
| `POST` | `/identity/link` | Link a verified email through a linking OTP. |
| `GET` | `/identity/agreements` | List records associated with the identity graph. |
| `GET` | `/api-keys` | List non-revoked API keys. |
| `POST` | `/api-keys` | Create an API key; the secret is returned once. |
| `DELETE` | `/api-keys/{key_id}` | Revoke an API key. |

## Creation routes

| Method | Route | Required scope | Purpose |
|---|---|---|---|
| `POST` | `/agreements` | `create` | Create an agreement draft and initiator participant. |
| `POST` | `/declarations` | `create` | Create a single-declarant draft. |
| `POST` | `/notarizations` | `create` | Create a file, text, or hash notarization. |

Agreement and declaration bodies contain 2–350 normalized words and at most 7,000 characters. Agreements support up to 15 signing participants including the initiator and up to 5 active witnesses. Notarizations support up to 14 co-notarizers and do not accept source file bytes.

Notarization requests accept `content_type` values `file`, `text`, or `hash`. Text requests include normalized-text validation; file and hash requests require a label or filename.

## Agreement and declaration routes

| Method | Route | Purpose |
|---|---|---|
| `GET` | `/agreements/{id_or_ref}` | Retrieve an authenticated participant view. |
| `PATCH` | `/agreements/{id_or_ref}` | Update an eligible draft. |
| `POST` | `/agreements/{id_or_ref}/submit` | Submit a signed ordinary draft for confirmation. |
| `POST` | `/agreements/{id_or_ref}/signature-execution` | Start or resume the caller's signature execution. |
| `GET` | `/agreements/{id_or_ref}/signature-execution` | Read signature execution state. |
| `POST` | `/agreements/{id_or_ref}/signature-execution/methods/{method}/start` | Start a method. |
| `POST` | `/agreements/{id_or_ref}/signature-execution/methods/{method}/submit` | Submit OTP, URL, or WebAuthn evidence. |
| `POST` | `/agreements/{id_or_ref}/signature-execution/methods/{method}/refresh` | Refresh an expiring method. |
| `POST` | `/agreements/{id_or_ref}/signature-execution/methods/{method}/cancel` | Cancel a pending method. |
| `POST` | `/agreements/{id_or_ref}/signature-execution/finalize` | Finalize the current participant signature. |
| `GET` | `/agreements/{id_or_ref}/document` | Download the sealed signed PDF. |
| `GET` | `/agreements/{id_or_ref}/card.png` | Download or lazily generate the private card. |
| `POST` | `/agreements/{id_or_ref}/card-ticket` | Issue a short-lived, single-use private card URL. |

The returned ticket is redeemed by `GET /artifacts/share-card/{token}`. The token is opaque, scoped to one card, short-lived, and single-use; clients must not log or persist it.

The signature method values are `email_otp`, `github_gist`, `x_post`, `reddit_post`, `telegram`, and `webauthn_passkey`.

Notarizations have equivalent signature execution routes under `/notarizations/{id_or_ref}/signature-execution`, plus `GET /notarizations/{id_or_ref}` and `GET /notarizations/{id_or_ref}/card.png` and `POST /notarizations/{id_or_ref}/card-ticket`. Notarizations do not expose a PDF route.

## Lifecycle routes

| Method | Route | Effect |
|---|---|---|
| `POST` | `/agreements/{id_or_ref}/decline` | Decline as a non-initiator participant or witness. |
| `POST` | `/agreements/{id_or_ref}/participants/{party_id}/resend-invitation` | Resend an eligible invitation. |
| `POST` | `/agreements/{id_or_ref}/witnesses/{party_id}/waive` | Proceed without an eligible declined/removed witness. |
| `POST` | `/agreements/{id_or_ref}/co-notarizers/{party_id}/waive` | Complete a notarization without one declined co-notarizer. |
| `POST` | `/agreements/{id_or_ref}/participants/{party_id}/complete-without` | Proceed without an eligible declined/removed participant. |
| `POST` | `/agreements/{id_or_ref}/witnesses/{party_id}/replace` | Replace an eligible declined/removed witness. |
| `POST` | `/agreements/{id_or_ref}/rescind` | Initiator ends a pending agreement, declaration, or notarization. |
| `POST` | `/agreements/{id_or_ref}/amend` | Create a new amendment draft for a sealed agreement. |
| `POST` | `/agreements/{id_or_ref}/cancel` | Create a mutual cancellation draft for a sealed agreement. |

These operations are state- and role-dependent. See [Lifecycle and versions](/docs/concepts/lifecycle-and-versions).

## Counter-proposal routes

Counter-proposals are submitted by eligible non-initiator parties while an agreement is pending. Only one can be active.

| Method | Route | Purpose |
|---|---|---|
| `POST` | `/agreements/{id_or_ref}/counter` | Submit a full proposed body. |
| `GET` | `/agreements/{id_or_ref}/counter/{counter_id}` | Retrieve a counter-proposal. |
| `POST` | `/agreements/{id_or_ref}/counter/{counter_id}/resolve` | Initiator accepts, partially accepts, or rejects. |
| `POST` | `/agreements/{id_or_ref}/counter/{counter_id}/withdraw` | Proposer withdraws a pending counter. |

Partial acceptance requires a resolved body. An accepted body change increments the current version and resets affected signature work.

## Response and error behavior

Successful record responses include the AGR reference, type, status, version, participants, witness summary, blockchain state where applicable, party-facing metadata when sealed, and compact optional image metadata. [Identicons](/docs/concepts/identicons) contain `kind`, `digest`, `short_hash`, `width`, `height`, `alt_text`, and `available`. They do not contain SVG bytes, data URIs, or internal algorithm/version fields by default. Share-card metadata never contains a storage path or ordinary download URL.

For authenticated agreement and signature retrieval, add `image_representation=compatibility_data_uri` only when an older client requires an inline SVG data URI. The default `metadata` representation is safe for ordinary clients and leaves internal identicon serializers and rendering APIs unchanged. Public verification and known-reference agreement responses expose document-identicon metadata only for sealed records; they do not expose signature identicons, cards, bodies, or private participant data. Authenticated full agreement responses may include permitted current party signature-identicon metadata, and authenticated signature-execution reads may include the current caller's finalized signature identicon. REST public routes never serialize those signature identicons.

The card-ticket endpoints require the same authenticated participant authorization as the existing binary card routes. A successful response uses the configured `APP_BASE_URL`, identifies no agreement data in its opaque URL, expires after five minutes by default, and can be redeemed once. Redemption uses `Cache-Control: no-store`, `Referrer-Policy: no-referrer`, and atomic single-use enforcement. The URL is intentionally not a presigned storage URL. An hourly maintenance job removes redeemed and expired ticket records.

Common HTTP outcomes include:

- `400` for malformed requests.
- `401` for missing or invalid authentication.
- `403` for role or scope failure.
- `404` for missing records or artifacts.
- `409` for lifecycle conflicts or stale state.
- `422` for validation errors.
- `429` for OTP, provider, invitation, or route rate limits.

Do not retry a mutating request blindly after a timeout. Re-read the record and signature state, then follow the returned lifecycle state or next action.
