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

# Introduction

> The contracts.io public API: the same verbs the UI has, and it can never send or sign on its own authority.

<Warning>
  **Draft — ahead of the backend; nothing here is live yet.** This surface is
  written against the design, not against a running server. There is no
  `api.contracts.io` to call, no key to issue, and every response below is an
  illustration rather than a recording. It is published so the shape can be argued
  with before it is built.

  It also predates **CONTRACT-SCHEMA v0** and still uses the older nouns — *ask* for
  Proposal, *receipt* for Version, *relationship* for Room. The
  [glossary](/glossary) maps them.
</Warning>

contracts.io is infrastructure for contracts. You wire contract flows into your ATS, your CRM, or your
own product, and an outside AI negotiates through **the same verbs the UI has**.

That sentence is the whole design. It is also a constraint we accept in both directions, and everything
on this page follows from it.

## The parity principle

<Note>
  **One verb set, two hands.** Every button in the app is an endpoint here, and every endpoint here is
  a button somewhere in the app.
</Note>

The rule runs both ways, and both directions cost us something:

* **If a verb has no button anywhere in the UI, it is not public.** There are no integration-only
  conveniences: no bulk-decide, no "auto-accept anything above 0.9 confidence", no filter DSL for
  search. An API-only verb is a second product with the same logo on it.
* **If a button exists and the API cannot do it, parity is broken and an endpoint is missing.** That is
  a bug report, not a feature request.

<Note>
  **Parity binds the verbs that *act*** (refined 2026-08-24). Anything that stages, changes state, moves
  a word, sends or signs must exist on both surfaces, or one of them is broken.

  A **reading** is not an acting verb. When the in-app agent explains a clause, summarizes a letter, or
  scans for risk, it is composing prose over public reads it already holds: `GET /contracts/{id}`,
  `GET /contracts/{id}/state`, `GET /contracts/{id}/letters/{id}`. There is no `POST /contracts/{id}/explain`,
  and its absence is not a gap: freezing one phrasing of an explanation into an API contract would give
  the product a second place to disagree with itself. You get **equal access to the data, not equal
  access to the sentences**. Every reading the agent performs, you can compose from the same reads.
</Note>

The practical consequence: this API has no integration-specific vocabulary. `POST /contracts/{id}/decisions`
writes to the same private reply draft the **Accept** button writes to. `POST /ask` is the same call the
in-app agent makes. The integration and the person are two hands on one store.

## Three laws the API inherits from the product

<Steps>
  <Step title="The contract is the atom">
    There is no create-a-container call. No envelope, no recipients list to configure, no routing order.
    You draft a contract and a person sends it. A **room** is a *derived* relationship record, born on that
    first Send. `POST /contracts` then `POST /contracts/{id}/send` is the whole origination story.
  </Step>

  <Step title="Words move on unanimity, never on Send">
    No caller can write clause text. Not a human, not a key, not an agent. The API stages *decisions*
    and commits *letters*; it never applies a diff. You **propose**; the words change when every
    required negotiator has accepted, and not before. `PUT /contracts/{id}/blocks/{id}` does not exist and will not.
  </Step>

  <Step title="No key sends or signs on its own authority">
    Send and sign carry a human-confirmation requirement. An API key is an agent with better latency,
    and the standing lock applies to both.
  </Step>
</Steps>

## The never-sends 409

Send-class calls do not fail open and they do not fail soft. Omit `confirmed_by` on a send, a reply, or
a signature and you get one status code back:

```json 409 confirmation_required theme={null}
{
  "error": {
    "type": "conflict_error",
    "code": "confirmation_required",
    "message": "A person must confirm this. Re-send with confirmed_by set to the person_id of the human who pressed the button.",
    "param": "confirmed_by",
    "doc_url": "https://docs.contracts.io/errors#confirmation-required"
  }
}
```

That is the whole agent story in one status code. There is no flag, key, scope, rung, or org setting
that removes it. `send` and `sign` are grantable **scopes**, and a key holding both still gets the 409
without `confirmed_by`.

<Warning>
  **A harness that retries a `confirmation_required` result is a bug, not a fallback.** It is not a rate
  limit and not a transient failure. It is the end of the road. The next actor is a person.
</Warning>

## Guests act through signed links

A guest is a person with no org: the counterparty's freelancer, the founder on the other side of the
table. Guests are first-class negotiators and signers, and **they never hold keys**.

A guest acts through the signed link they were sent, and they act in both directions. **Reading uses the
link**, so the address somebody was emailed just works:

```bash theme={null}
GET https://api.contracts.io/contracts/con_1?t=<signed-token>
```

**Writing uses a header**, because web addresses end up in server logs and support tickets:

```bash theme={null}
curl -X POST https://api.contracts.io/contracts/con_1/decisions \
  -H "Authorization: Token <signed-token>" \
  -H "If-Match: sha256:9f2c..." \
  -d '{ "block_id": "blk_9", "type": "counter", "text": "nine (9) months", "why": "..." }'
```

That is a guest countering a clause, and the same credential signs. The link grants exactly what the
contract's required-party list grants that person, and nothing else: no other contract, no corpus question, no
webhooks. The token names one contract and one person, so a guest call sends no `Contracts-Acting-Person`
and no `confirmed_by`. The token already supplies both. See
[Guests](/api/authentication#guests-reading-and-writing-through-a-link).

There is no guest key issuance endpoint, and there will not be one. That would be an ACL for a person
who must never see one. Guests also never get MCP, for the same reason.

## What you can do

The public surface is everything a negotiator or a signer can do to a contract, plus the reads that make a
contract legible to somebody who was not in the room.

| Group               | What it covers                                                                                                                                                                                                                                                                                      |
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Find your feet**  | Learn who you are and what you are holding, with [`GET /me`](/api/authentication#step-zero-find-out-who-you-are). Read the rows waiting on you, grouped by who you are dealing with, with [`GET /attention`](/api/attention).                                                                       |
| **Make a contract** | Draft one from a sentence or from a template, or import a document you already have. Set facts, and confirm the ones a parse guessed at.                                                                                                                                                            |
| **Negotiate**       | Read the letters and the live questions. Stage decisions, take them back, write the covering note, and commit the round. Pull a proposal you already sent.                                                                                                                                          |
| **Sign**            | Sign against an exact hash, withdraw a signature, [read every signature back](/api/signing#read-the-signatures) with the words it actually bound, and fetch [the certificate](/api/signing#the-certificate) once the contract completes.                                                            |
| **Keep up**         | Walk one contract's [event log](/api/contracts#walk-a-contracts-events), find every contract that moved since a timestamp with `GET /contracts?updated_since=`, and [manage your own webhook endpoints](/api/webhooks#managing-endpoints): register one, rotate its secret, replay what you missed. |
| **The rest**        | Invite people and remove them, cancel, amend, read a clause conversation, upload and read files, [ask a question](/api/ask) across everything you can open, and accept or reject a mail thread somebody forwarded in.                                                                               |

## What is not here

Stated plainly so you do not go looking:

<CardGroup cols={2}>
  <Card title="No envelope API" icon="ban">
    No create envelope → add recipients → set routing order → send. Capacity does that work.
  </Card>

  <Card title="No rooms-first API" icon="ban">
    No `POST /rooms`, no membership call, no name you set. Relationships are derived.
  </Card>

  <Card title="No direct text writes" icon="ban">
    Words move on unanimity or they do not move.
  </Card>

  <Card title="No live collaboration" icon="ban">
    No presence, cursors, or realtime document stream. Webhooks and polling are the whole story.
  </Card>
</CardGroup>

Also out of scope at v1: workflows and connectors, internal comments as an API surface, playbook
*authoring*, approval routing, seats, billing, SSO, branding, and per-clause or per-asset permissions.

## Start here

<CardGroup cols={2}>
  <Card title="Quickstart" icon="rocket" href="/api/quickstart">
    Draft, send, run a reply cycle, and sign. All as curl.
  </Card>

  <Card title="Core concepts" icon="book-open" href="/anatomy">
    Contracts, letters, asks, facts, capacity, receipts.
  </Card>

  <Card title="Authentication" icon="key" href="/api/authentication">
    Org keys, per-person tokens, acting persons, scopes.
  </Card>

  <Card title="MCP" icon="plug" href="/api/mcp">
    The same verbs for an outside agent, one seat down.
  </Card>
</CardGroup>

<Info>
  **Status: draft.** This documentation is written against the API design drafts, ahead of the
  endpoints existing. Shapes here are the contract we intend to ship; see the
  [Changelog](/api/changelog) for what is stable and what is still moving.
</Info>
