# Agreebase Docs

> A practical guide to creating, signing, notarising, verifying, and integrating Agreebase records.

Audiences: users, developers, agents
Kind: guide
Updated: 2026-07-12

Agreebase creates durable records of agreements, declarations, witnessed records, and notarised content. These docs are organised around the job you are trying to do:

- Create or respond to a record in the [user guides](/docs/users/record-types).
- Understand record state, signatures, privacy, and permanence in the [concepts](/docs/concepts/permanent-records).
- Build an integration with the [developer documentation](/docs/developers/api-and-mcp).
- Orchestrate Agreebase safely with the [agent guide](/docs/agents/using-agreebase-with-agents).

## Choose a path

- New to Agreebase: [Start here](/docs/start-here).
- Creating an agreement, declaration, or witnessed record: [Record types](/docs/users/record-types), then [Create and seal](/docs/users/create-and-seal).
- Signing or responding to an invitation: [Sign and respond](/docs/users/sign-and-respond).
- Managing an existing record: [Manage a record](/docs/users/manage-record).
- Notarising a file, text, or hash: [Notarise content](/docs/users/notarize-content).
- Checking a record: [Verify a record](/docs/users/verify-record).
- Integrating by HTTP: [REST API reference](/docs/developers/rest-api).
- Integrating an agent: [MCP reference](/docs/developers/mcp-reference).

## Documentation principles

Each important product capability has a user explanation, a developer explanation, and an agent explanation where those audiences need different guidance. The developer pages describe the public contract; internal design notes are not part of that contract.

## Important boundary

Agreebase is not a law firm and these docs are not legal advice. They explain what the product records, what its proof steps mean, what becomes public, and how to verify the resulting artifacts.

---

# Start here

> A short orientation to Agreebase record types, signatures, sealing, permanence, and verification.

Audiences: users, developers, agents
Kind: guide
Updated: 2026-07-12

Agreebase turns an agreement, declaration, witnessed record, or content hash into a record that can be checked later. It combines a defined record state, proof-of-control signing methods, privacy choices, and cryptographic commitments.

## Core ideas

An Agreebase record is built around five ideas:

- The text should be understandable by the people signing it.
- Each signing party proves control of an approved contact point or account; "proof-of-control" of an existing digital identity is core to Agreebase's signature.
- The record keeps its lifecycle and version history explicit.
- Once everyone required has signed, the record seals.
- A sealed record can be verified later either via Agreebase or directly on the Base blockchain record.

## Main record types

An agreement is shared text confirmed by two or more signing parties. A declaration is a single-party statement. A witnessed agreement adds witnesses who sign after the main parties. A notarization records a client-supplied SHA-256 hash for a file, text, or existing digest; Agreebase does not receive the source file bytes.

## What gets produced

When an agreement, declaration, or witnessed agreement seals, Agreebase queues confirmation emails, a signed PDF, evidence metadata, and a blockchain write. Notarizations use their notarization payload and private card instead of a signed PDF. Blockchain confirmation generally happens very quickly, but in some cases may follow receipt of the confirmation email by a few seconds or minutes.

## Good first paths

Use the web app for the guided creation and signing experience. Use REST when another system needs a direct HTTP contract. Use MCP when an agent is working with a human in the loop. Use the public verifier when you only need to check an existing record.

---

# Why there's no account to create

> Agreebase doesn't use usernames or passwords. Here's what replaces an account, and why.

Audiences: users, developers, agents
Kind: concept
Updated: 2026-07-22

If you've used Agreebase before and looked for a sign-up page, a password reset, or a settings screen with an account name on it, you won't find one. This is deliberate, not an unfinished part of the product.

## What Agreebase uses instead

Every action you take proves control of something you already have: an email address, a GitHub or X or Reddit account, a Telegram chat, or a device passkey. Agreebase calls this proof-of-control. There's no separate Agreebase password to create, forget, or have leaked in an unrelated breach, because there's no Agreebase-specific credential in the first place.

When you need to see your records; at `/my-records`, for instance; you verify a one-time code sent to your email, the same way you'd complete an email signature method. That verified email is linked to what Agreebase calls your identity graph: the set of contact points that have been confirmed as belonging to you. Records you've signed, declared, witnessed, or notarized under any of those linked contact points show up together.

## Why not just have accounts

An ordinary account model asks you to create and remember a new credential purely to prove who you are to one service. Agreebase's records already need proof of identity for a different, stronger reason; signing something requires proving control of a real external identity at the moment of signing, not just logging in once. Reusing that same proof-of-control mechanism for everyday access means there's no separate login system to secure, no separate password to leak, and no account that can exist without ever having done anything: every identity in Agreebase's system has actually proven control of something at least once.

## What this means day to day

- You don't need to "sign up" before creating or signing a record; the first time you prove control of an email (or other identity) is effectively your first interaction with Agreebase.
- Losing access to an email account has the same consequence it would for any service that emails you a password reset: you lose the ability to prove that identity until you regain access to it.
- Developers integrating over the API or MCP authenticate the same way underneath; see [Authentication and API keys](/docs/developers/authentication-and-api-keys) for how that maps onto bearer tokens, OAuth, and API keys for machine-to-machine use.

---

# Record types

> Choose between agreements, declarations, witnessed agreements, and notarizations.

Audiences: users, developers, agents
Kind: guide
Updated: 2026-07-12

Choose the record type by asking what you need to preserve: shared terms, one person's statement, an independent witness, or the identity of existing content.

## Agreement

An agreement contains shared terms accepted by an initiator and at least one other signing party. The parties sign the same current version. A participant can propose a change instead of accepting the current text.

Use an agreement for loans, payment arrangements, delivery promises, work terms, authorisations between people, and other shared commitments.

Contracts written via Agreebase have a 350-word limit; we believe that most day-to-day intent that needs to be captured without complex contracts can be captured adequately, and in a legally-binding way, within 350 words.

## Declaration

A declaration is a single-party statement. The declarant writes and signs the record; other people can be added as witnesses. An unwitnessed declaration has one signing participant and uses one required signature method as a minimum, though [additional signing methods](/docs/concepts/signing-methods) can be completed for extra proof of identity.

Use a declaration for an attestation, statement of fact, approval, receipt, or other assertion that one person wants to preserve. For example, a declaration is useful to record that on this date, you approved something in a way whose authenticity cannot be challenged at a later date.

Unless you opt to publish the full text on-chain, Agreebase blockchain records only contain hashes, so a declaration is a way to capture intellectual property of ideas, or other "secret" information privately while still being verifiable in future by [re-creating the hash yourself](/docs/concepts/verification-hashes) and comparing it to the hash on the Agreebase record.

## Witnessed agreement

A witnessed agreement is an agreement with one or more additional witnesses. Witnesses sign after the main signing parties have completed their current version. A record can have at most five active witnesses.

A witness to an Agreebase agreement is attesting that they believe the parties to that agreement did in fact intend to sign it. It is up to the invited witness to confirm such intent independently. If you are invited to be a witness to an Agreebase agreement or declaration, you should contact the parties to confirm that they did indeed sign.

A witness provides an additional signed attestation. A witness is not automatically a party to the underlying obligations. If a witness declines or becomes unavailable, the initiator may be able to replace or waive that witness, depending on the current state and signing progress.

## Notarization

A notarization generates and preserves a SHA-256 has for any existing content:

- `file`: the web app hashes the file without uploading it; Agreebase receives metadata and the hash from the browser, not the file itself.
- `text`: Agreebase normalizes the supplied text, generates its SHA-256 hash, and can retain normalized text for authenticated verification. By default the text being notarized is not published on the blockchain record, but optionally can be.
- `hash`: the client supplies an existing SHA-256 digest and a label or filename. This option is only available via API or MCP.

Notarizations can have co-notarizers who sign the same content hash. They do not generate signed PDFs. Sealed notarizations expose notarization metadata and can generate a private PNG card instead. If a co-notarizer declines, the creator can complete without that person; any other invited co-notarizers must still respond. The creator can rescind the notarization while it remains pending.

## Shared record properties

All record types have an AGR reference, a lifecycle status, a current version, participants, an expiry window where applicable, and privacy/publication settings. Agreements and declarations use the shared body-word limit. A notarization uses content-type-specific size and hash rules.

Choose [Create and seal](/docs/users/create-and-seal) for agreements, declarations, and witnessed records. Choose [Notarise content](/docs/users/notarize-content) for an existing file, text value, or digest.

---

# Create and seal a record

> How the web flow moves from record selection and drafting to signing, sealing, and retained artifacts.

Audiences: users, developers, agents
Kind: guide
Updated: 2026-07-12

The web app is the simplest way to create an agreement, declaration, or witnessed agreement. The flow helps you define the text, review it, choose participants and publication settings, complete the initiator signature, and invite the remaining people.

## 1. Choose the record and draft the text

Start by choosing an agreement, declaration, or witnessed agreement document type. Write the substance in plain language. For an agreement, include the parties, obligations, dates, amounts, conditions, delivery details, and consequences the user actually intends to record.

An agreement is a contract; Agreebase brings the power of the contract into simple, everyday agreements between parties, so when writing your agreement it's useful to think of exactly what is being agreed and any important details that need to be captured.

If you are unsure how to write the agreement or declaration, click the "Draft it for me" button to open the smart-template assistant, which asks structured questions and produces a draft for you to check and edit. See [Drafting with the smart-template assistant](/docs/users/agreement-wizard) for what it asks and what to check before continuing.

Agreements and declarations are limited to 350 normalized words or approximately 7,000 characters. The limit applies across the browser, REST, and MCP creation paths.

## 2. Review the text and legally-binding signals

Agreebase can optionally analyze the draft for missing or unclear material elements that might undermine its legal intent; not legal advice, but a strong signal on whether your draft looks complete for the jurisdiction you selected. See [Reviewing legal completeness](/docs/users/legal-completeness-check) for what it checks, what a recheck does, and how to act on (or skip) what it surfaces.

## 3. Add participants and witnesses

Add the parties who need to sign and provide their display names and contact details they should see in invitations. Agreements can have at most 15 signing participants in total, including the initiator. Declarations have one declarant. Either type can have up to five active witnesses.

Any witnesses that were added are invited after the main signing participants complete their signatures. See [Sign and respond](/docs/users/sign-and-respond) for the recipient experience.

## 4. Set signature and publication rules

An Agreebase signature can comprise one or more methods, with at least one method (email account confirmation via OTP) required. Users (or agents) complete a signature by proving control of an existing digital identity.

The initiator of an agreement chooses how many methods must be completed at a minimum, and the initiator is also required to complete the same minimum. The more signature methods that go into an agreement signature, the more robust that signature is. The maximum number of signature methods permissible is three.

For publication options, hash-only blockchain publication is the default. This means that the blockchain record does not include the full-text but instead a cryptographically generated, secure hash of that text. To learn more about hashes and why they are both private and reliable as confirmation of the text they represent, see [What is a hash?](/docs/concepts/what-is-a-hash).

Full-text publication and verified party details are separate, explicit choices, and result in irreversible publication on the Base public blockchain. Full text is permanently public once written to Base. Verified party publication can include entered names and verified signing email addresses if that option is selected by the initiator, and affected signers must acknowledge that their details, and the fact they signed/witnessed the agreement or declaration being signed, are going to be on a blockchain record that cannot be deleted, before finalization can occur.

Choose an expiry window from one to thirty days when the record should stop accepting outstanding signatures. Settings are locked before the initiator signs; material changes can reset completed signature work.

## 5. Authenticate and sign as the initiator

The initiator verifies control of their own digital identity, completes the required signature methods for the current version of the agreement or declaration being signed, reviews the final text, and explicitly finalizes the signature. Authentication proves control of a digital identity via email one-time passcode (OTP); signing proves that the person controlling that digital identity confirmed intent to sign the record being created - these are two separate and explicit steps.

After the initiator finalizes, the record moves to pending confirmation and Agreebase sends invitations to the other participants. A participant can sign, decline, or submit a counter-proposal. A counter-proposal pauses the record until the initiator resolves it.

## 6. Complete the record

When all required party signatures and required witness signatures (if applicable) are complete, the record seals. If an eligible declined or removed participant is not required to complete, the initiator may explicitly proceed without them.

The sealed version is permanent and unchangeable. If it is an agreement, then modifying its obligations must be done the same way a paper contract would be, which is typically be creating a new agreement, referencing the agreement being modified, and explicitly agreeing with the same parties that you agree to change the terms of the original agreement.

To learn more about the different lifecycle stages of an Agreebase record, see [Lifecycle and versions](/docs/concepts/lifecycle-and-versions).

## 7. Retain the resulting artifacts

For agreements and declarations, Agreebase creates a signed PDF, evidence metadata, confirmation emails, and a blockchain commitment. On rare occasions if the blockchain is congested, parties may receive the confirmation email and PDF before the blockchain record completes, in which case they will receive a follow-on email confirming the blockchain record.

It is important that parties and witnesses retain the confirmation emails sent by Agreebase at the time of sealing or completing a notarization process, as these contain the details required to perform future verification against the record if required.

Use [Manage a record](/docs/users/manage-record) to retrieve sealed artifacts and [Verify a record](/docs/users/verify-record) to check them later.

---

# Drafting with the smart-template assistant

> How the 'Draft it for me' wizard turns a plain description into agreement or declaration text.

Audiences: users, agents
Kind: guide
Updated: 2026-07-22

If you're not sure how to put an agreement or declaration into words, the "Draft it for me" button on the creation screen opens a smart-template assistant instead of leaving you with a blank text box.

## What it asks

The assistant asks structured questions rather than a single open prompt: who the parties are, what's being exchanged or promised, relevant dates and amounts, and any conditions or consequences you want captured. The exact questions depend on the record type; an agreement's questions focus on mutual obligations between parties, a declaration's focus on the single statement being made.

## What it produces, and what it doesn't

The assistant produces a draft body in Agreebase's plain-language style, already shaped to fit within the 350-word / 7,000-character limit shared by agreements and declarations. It is a draft, not a finished, checked document. Before continuing, read it in full and confirm every fact, amount, date, name, and jurisdiction it contains; the assistant works from what you told it, and can't know if a number or a name was mistyped, or if you left out a condition that matters to you.

You can edit the generated text freely once it's in the draft editor; there's no requirement to use it as-is, and no penalty for discarding it and writing the body yourself instead.

## What comes next

Once you have body text, whether drafted by the assistant or written by hand, the next step is reviewing it for legal completeness. See [Reviewing legal completeness](/docs/users/legal-completeness-check) for what that check looks for, and [Create and seal a record](/docs/users/create-and-seal) for the rest of the creation flow.

---

# Reviewing legal completeness

> How the optional binding-signal review works, what it flags, and what it doesn't decide.

Audiences: users, agents
Kind: guide
Updated: 2026-07-22

Before you send an agreement or declaration out for signature, Agreebase can optionally analyze the draft text and tell you whether it looks like it's missing something a court would typically expect to see.

## What it looks for

The review checks the draft against the basic tenets contract law generally looks for in the jurisdiction you selected: whether the parties are clearly identified, whether the obligations are stated specifically enough to be enforced, whether consideration (something of value exchanged) is present, and whether key details like dates, amounts, or conditions are actually in the text rather than implied. It surfaces what it finds as a list of issues, not a pass/fail grade.

## What "binding recheck" means

After you resolve one or more flagged issues, by editing the body text, you can run a limited recheck rather than a full fresh analysis. It re-examines the specific issues that were previously raised, so you can confirm they're resolved without waiting for the whole draft to be re-analyzed from scratch.

## What it doesn't do

This is not legal advice, and it does not decide whether a court would actually enforce your agreement; no automated check can do that, because enforceability also depends on facts outside the text, and on the law of the specific jurisdiction and situation involved. It's a signal to help you notice gaps before you send something out, not a guarantee.

You can act on it in any of these ways:

- Revise the body to address what it flagged, and optionally recheck.
- Continue with unresolved issues, if you've judged them not to matter for your situation.
- Skip the review entirely and move straight to adding participants.

None of these choices change how Agreebase seals or verifies the record later; the review only affects what you see before you send it. See [Limitations and availability](/docs/policy/limitations-and-availability) for the broader legal-effect boundaries that apply regardless of this review's result.

---

# Sign and respond

> How invited parties, declarants, co-notarizers, and witnesses review and respond to a record.

Audiences: users, agents
Kind: guide
Updated: 2026-07-12

An invitation asks you to review the current version of an Agreebase record. Agreebase supports full agreement review and amendment ("red-lining"), but you cannot accidentally sign a non-current version as safeguards prevent that.

## Open and identify yourself

Use the invitation link in the email or the record's confirmation route. This email is like a password, which allows you to review and either accept/reject or propose changes to a proposed agreement, so do not share it with anyone.

## Review the exact text

Read the complete current agreement text, participants, witness role, expiry, and publication settings. Pay particular attention to whether full text or verified party details will be written to the public blockchain - Agreebase's web interface will ask you to acknowledge when any blockchain record would include either the full agreement text and/or the parties' confirmed details in plain text. It's not possible to accidentally consent to publication without confirming this via the acknowledgments. If the text or settings are not acceptable, do not finalize the signature and either decline it or contact the initiator with your concerns.

## Choose and complete signature methods

The record requires one, two, or three distinct methods, set by the initiator when the record was created. Email OTP is always one of them: Agreebase sends a short-lived code to your signing email address, and entering it proves you control that address. See [Signing methods](/docs/concepts/signing-methods) for the full list and what each one captures.

Depending on availability, you may also be offered a public proof-post method: GitHub gist, X post, or Reddit post. These work the same way in each case. Agreebase generates a block of proof text tied to this exact record and version, and asks you to publish it somewhere only you control; a gist under your GitHub account, a post from your X account, a profile post on Reddit. You paste the URL back in once it's live. Agreebase then fetches that URL and checks that the page actually contains the generated text (Reddit strips formatting from post bodies, so for Reddit it checks the post title instead, which is generated to carry the same proof in a shorter form). That's the whole mechanism: nobody but the account holder can make GitHub, X, or Reddit show Agreebase's generated text under their name, so a successful check is evidence you controlled that account at that moment. Because the proof has to be public to be checked, it's also visible to anyone who can view that platform; see [Privacy and publication](/docs/concepts/privacy#public-proof-methods) before choosing one.

Telegram works similarly but privately: opening a link from Agreebase in the Agreebase Telegram bot and completing the challenge there proves control of that chat, without anything being posted publicly. A passkey signs a cryptographic challenge through your browser's WebAuthn prompt, which has to happen in the Agreebase browser origin itself; an agent working on your behalf cannot complete this step for you.

Whichever methods you use, each one is tied to the current record version. If the text changes under you (see counter-proposals below), a method you already completed no longer counts and you'll need to redo it against the new version.

When verified party publication is enabled, Agreebase separately asks you to acknowledge that your entered name and verified signing email may be included in the public blockchain record. That acknowledgement is distinct from completing a signature method; you can complete every method and still decline that specific disclosure by not finalizing until you're comfortable with it.

## Finalize

After the required signing methods are verified, review the final text again and take the explicit sign/finalize action. Depending on the lifecycle, finalization may invite the next participant, invite witnesses, or seal the record.

Do not treat a typed name, an authentication OTP, or an agent's statement as a signature. The record is signed only when Agreebase reports a finalized signature execution for the current version.

## Other responses

If you do not accept the current text, you may be able to:

- Submit a counter-proposal. You can do this by describing the changes you'd like to see and then reviewing the difference ("diff") between the proposed version and your proposed version, or by directly editing the text to demonstrate your proposed changes.
- Decline participation with an optional reason. Only the initiator of the agreement will see your provided reason.

Only one counter-proposal can be under review at a time, so if you submit one while the record is pending, the other parties see the record pause in `counter_under_review` until the initiator responds. The initiator can accept it outright, reject it, or accept part of it with a resolved body of their own. If the resulting body is actually different from what was sealed before, every signature already completed for the earlier text, including the initiator's own, is cleared, the version number goes up, and everyone is invited to sign the new text from scratch. If the initiator rejects the proposal, or accepts it without any real change to the body, nothing is reset and the record simply returns to normal pending signing.

Witnesses cannot submit counter-proposals. A witness can sign the attestation, or decline to witness the current version.

## If a party declines or a witness can't complete

A decline doesn't automatically kill the record. If the initiator declines, that's treated as rescinding the whole record rather than an ordinary decline. If a non-initiator signing party declines and there's no other active recipient left to sign, the record moves to `declined` and cannot continue. If other active participants remain, the initiator can choose to remove the declining party (if they haven't signed yet) and proceed without them, subject to the record's own rules about who must sign.

A declined or unresponsive witness is more flexible: the initiator can waive that witness and complete the record without their attestation, or replace them with a different witness invitation entirely. Waiving records, in the final metadata, that the named witness did not sign; it doesn't pretend they did. See [Manage a record](/docs/users/manage-record) for how these actions look from the initiator's side, and [Lifecycle and versions](/docs/concepts/lifecycle-and-versions) for the full state model.

---

# Manage a record

> Retrieve records, respond to lifecycle events, download artifacts, and understand what changes after sealing.

Audiences: users, developers, agents
Kind: guide
Updated: 2026-07-12

Use `/my-records` to authenticate with an email OTP and see records associated with your verified identity graph. Records can also be retrieved by AGR reference through the participant-facing web, REST, or MCP surfaces.

## Pending records

For a pending record, the initiator may be able to:

- Resend an eligible invitation, subject to delivery waits and cooldowns.
- Remove an unsigned participant.
- Waive or complete without a declined or removed participant.
- Replace a declined or removed witness.
- Rescind the pending agreement.

Participants may sign, decline, or submit a counter-proposal. Witnesses can only witness the current version; they do not accept the underlying party obligations through the witness action.

Pending records expire at their configured expiry time. An expired record cannot continue signing; create a new record if the terms still matter.

### Resending an invitation

If a participant hasn't received or has lost their invitation email, the initiator can resend it from the record page in the web app, or through the equivalent REST (`POST /agreements/{id_or_ref}/participants/{party_id}/resend-invitation`) or MCP (`resend_participant_invitation`) call. A resend reuses the same invitation link rather than issuing a new one, so a participant who already started responding doesn't lose progress. Resends are rate-limited per participant to stop repeated sends from becoming a nuisance or a delivery-abuse vector; if a resend is refused for being too soon, wait for the cooldown shown before trying again.

### Rescinding

Rescinding ends a pending agreement, declaration, or co-notarized notarization before it seals. Only the initiator can do it, and only while the record is still pending. It notifies every invited participant that signing has stopped, but it does not create a sealed record or write anything to the blockchain; there is nothing later to verify, because nothing was ever completed. Use it when the terms have changed enough that continuing to collect signatures on the old text no longer makes sense; a fresh record is the right next step if the underlying arrangement still needs to be recorded.

### Adding parties

Participants are set when the record is created or, for an ordinary draft, while the initiator is still editing it before submitting for confirmation; see [Create and seal a record](/docs/users/create-and-seal). Once the initiator has signed and the record moves to pending, no new signing party can be added; the participant list is fixed at that point (a declined or removed witness can still be replaced, per above). If a record needs an additional signer after it's already pending, the initiator's options are to rescind and recreate it with the full participant list, or to seal it as-is and record the addition as a new, related agreement.

## Draft records

An initiator can update or cancel an ordinary draft before it is submitted for confirmation. A draft cancellation is not a cancellation of a sealed record. Notarizations follow their content-hash signing flow and cannot be cancelled or rescinded in the same way as ordinary agreement drafts.

## Sealed records

A sealed record is fixed. The original is not edited in place.

- An amendment creates a new draft that references and will supersede the original when sealed.
- A cancellation creates a new mutual cancellation draft for the sealed record; it does not unilaterally cancel the original.
- A superseded original remains preserved as historical authority for its own version, while the newer record becomes the current authority.

Witnesses cannot initiate amendments. The amendment and cancellation paths copy or reference the original participants according to the lifecycle rules.

## Artifacts

Participants can retrieve the sealed PDF when it has been generated. The PDF is the human-readable signed artifact and includes verification material. A private PNG share card can also be generated for sealed agreements and notarizations. The card is a convenience artifact, not a replacement for the AGR reference, hashes, or verification result.

Blockchain writing and PDF generation are background operations. A sealed record may briefly show a pending blockchain or document state, followed by separate confirmation email(s) when those artifacts are ready.

---

# Notarize content

> Create a notarization for a file, text value, or existing SHA-256 hash without uploading the source file.

Audiences: users, developers, agents
Kind: guide
Updated: 2026-07-12

Notarization records the identity of existing content and, optionally, the people who attest to that same identity. Agreebase does not need to receive the source file.

## Choose the content mode

### File

Pick a file and Agreebase hashes it with SHA-256 right there in your browser, before anything is sent anywhere. Only the resulting digest, plus a filename or label and optional advisory size and MIME type, is submitted. Agreebase stores that hash and metadata; it never receives the file bytes, its local path, file dates, EXIF data, or the file itself, so there's nothing to notarize a wrong version of by mistake and nothing incidental about your file to leak.

### Text

Paste or type the text directly. Agreebase normalizes it; Unicode NFC, line endings converted to LF, outer whitespace trimmed; the same way every time, so the same words always hash to the same digest regardless of which device or editor produced them. See [Verification hashes](/docs/concepts/verification-hashes) if you want the exact normalization steps for reproducing a hash yourself. Text is limited to 64 KB after normalization.

You can choose whether the normalized text may be published publicly. Public text publication is limited to 300 words and, like any blockchain write, is permanent once it confirms.

### Existing hash

If you already have a SHA-256 digest; computed by another system, or one you want to keep entirely outside Agreebase; submit just the digest with a label or filename. Agreebase never sees or asks for the underlying content in this mode.

## Add co-notarizers

The creator can invite up to fourteen co-notarizers. Each co-notarizer signs the same content hash. The creator cannot add their own verified contact point as a co-notarizer. Co-notarizers do not receive the source file from Agreebase.

If a co-notarizer declines, the notarization remains pending. The creator can complete without that co-notarizer from the record page. Each decline is resolved separately, and all other active co-notarizers must still sign before sealing. The creator can instead rescind the pending notarization, which ends signing for every co-notarizer and notifies all invited participants without creating a sealed or blockchain record.

## Choose signing behavior

`pending_signature` starts a normal signing workflow. `auto_seal` can be used with direct API-key authentication when one signature method is required; it can seal immediately when there are no co-notarizers. With co-notarizers, the record remains pending until they complete their signatures.

Notarization signatures use the same proof-of-control methods as other records. See [Signing methods](/docs/concepts/signing-methods).

## What is produced

A sealed notarization email contains a notarization payload, content hash, evidence metadata, blockchain commitment, and private share card. It does not generate a signed PDF. Verification accepts the content hash, normalized text where text was retained, and the blockchain transaction hash.

See [Verify a record](/docs/users/verify-record) for browser verification. For file notarizations, the browser hashes the selected local file and submits only the digest.

---

# Verify a record

> Check a record certificate, text, content hash, signed PDF, or blockchain transaction against an AGR reference.

Audiences: users, developers, agents
Kind: guide
Updated: 2026-07-12

Verification is public and does not require an account (see [Why there's no account to create](/docs/no-accounts) for why Agreebase works this way generally). It answers two related questions: does the submitted artifact match this record, and is this record the current sealed authority?

## What you need

You can verify with:

- The AGR reference for the record.
- The full text of an agreement, declaration, or retained text notarization.
- A body hash or notarization content hash.
- A signed PDF/document hash.
- A blockchain transaction hash.

You can also request a public certificate using only the AGR reference. A certificate confirms the public record status and available sealing information; it is not a positive match for a document you hold.

The web verifier is available at `/verify`. A specific record can be opened at `/verify/{agr_reference}`.

## What verification checks

A verification result answers two separate questions, and it's worth keeping them apart: does what you submitted match the sealed record, and is that record still the current authority (or has it since been superseded by an amendment)? A "match" on an old, superseded version is a real match, but it's not the same as matching the agreement as it stands today; the result tells you which one you have.

For agreements and declarations, Agreebase compares whatever you submit against the exact text and hash it sealed: submit the full text and it's normalized and hashed the same way it was at sealing, or submit the body hash directly if that's what you have. Some newer records can also fall back to a fuzzy fingerprint, which can recognize near-complete or lightly-altered text as a probable match even when it isn't byte-for-byte identical; useful as a recovery signal when you don't have the exact original, but it is never reported as an exact match, and shouldn't be treated as one. See [Verification hashes](/docs/concepts/verification-hashes#fuzzy-fingerprints) for how that works.

For notarizations, the content hash is the primary check: submit the digest, or (for a file) select the file itself so your browser hashes it locally the same way it did at notarization time; the file itself is never uploaded to Agreebase. If the notarization retained normalized text, you can also submit that text directly instead of a hash. A transaction hash can be checked against the stored sealing transaction whenever the blockchain provider is able to read it back.

## Privacy boundaries

Public verification does not reveal private signer names, emails, contact hashes, network evidence, or signature execution payloads. It is meant to answer whether a record matches, not to expose participant data.

The response may report an [identicon](/docs/concepts/identicons) and public blockchain metadata, but an identicon is only a secondary visual fingerprint.

## If verification fails

A failed or non-authoritative result can mean:

- The AGR reference is wrong or does not exist.
- The submitted text is incomplete or changed.
- The submitted hash belongs to another artifact.
- A notarization does not retain text for text comparison.
- The record matched but is not sealed yet.
- The record matched an older version that has been superseded.
- The blockchain provider is unavailable.

Compare the source document carefully, normalize or hash it using the method in [Comparing document hashes](/docs/users/comparing-document-hashes), and retry with the most exact artifact available.

---

# Comparing document hashes

> A practical guide to comparing agreement text, notarized content, evidence metadata, and signed PDF hashes.

Audiences: users, developers, agents
Kind: guide
Updated: 2026-07-12

Use this page when a sealed PDF, email, blockchain transaction, or notarization gives you a hash and you want to compare it with the artifact you hold.

## Agreement or declaration text

Normalize the exact body text in this order:

1. Unicode NFC-normalize the text.
2. Replace CRLF and CR line endings with LF.
3. Strip leading and trailing whitespace.
4. Encode the result as UTF-8.
5. Compute SHA-256 and compare the lowercase hexadecimal result with the body hash.

Do not include the title, PDF layout, signature lines, or evidence appendix in the body hash unless those characters are part of the stored record body.

## Reproducing a hash in code

The normalize-then-hash procedure above is easy to get slightly wrong by hand (a stray trailing space, the wrong newline convention), so here it is as code in three common languages. Each one takes the raw body text and produces the same lowercase hex digest Agreebase would store.

### Python

```python
import hashlib
import unicodedata

def agreebase_body_hash(raw_text: str) -> str:
    text = unicodedata.normalize("NFC", raw_text)
    text = text.replace("\r\n", "\n").replace("\r", "\n")
    text = text.strip()
    return hashlib.sha256(text.encode("utf-8")).hexdigest()
```

### JavaScript

```javascript
async function agreebaseBodyHash(rawText) {
  let text = rawText.normalize("NFC");
  text = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n").trim();
  const bytes = new TextEncoder().encode(text);
  const digest = await crypto.subtle.digest("SHA-256", bytes);
  return Array.from(new Uint8Array(digest))
    .map((b) => b.toString(16).padStart(2, "0"))
    .join("");
}
```

### PHP

```php
function agreebase_body_hash(string $rawText): string
{
    $text = Normalizer::normalize($rawText, Normalizer::FORM_C);
    $text = str_replace(["\r\n", "\r"], "\n", $text);
    $text = trim($text);
    return hash("sha256", $text);
}
```

## Text notarization

Use the same NFC, LF, trim, UTF-8, and SHA-256 process. The result must match the notarization content hash. A text notarization can be checked with the public verifier only when the normalized text was made public or when you have the text and submit it for comparison.

## File notarization

Take the exact file you believe was notarized and hash it yourself with SHA-256; the same tool the browser used (`sha256sum`, a hashing library, or the [Python/JavaScript/PHP examples](#reproducing-a-hash-in-code) below). Don't hash a filename, a PDF rendering of the file, an exported metadata sidecar, or a screenshot; any of those will produce a different digest even if the content looks identical to you. Submit the resulting hash to `/verify` with the notarization's AGR reference. Agreebase never receives or stores the file bytes themselves, so this comparison is the only way to confirm the file matches; there's no server-side copy to fall back on.

## Evidence metadata

Every sealed record comes with an evidence metadata package; a JSON document listing the record facts, the body/content hash, and each participant's signing evidence. That package has its own hash, so you can confirm it hasn't been altered independently of confirming the record body itself. To recompute it: take the metadata JSON, remove the `metadata_hash` field itself (it can't hash itself), re-serialize what's left with keys sorted and no extra whitespace, encode as UTF-8, and SHA-256 it. The result should match the `sha256:`-prefixed value stored in the package.

You won't normally need to do this by hand; it matters mainly if you're building an integration that re-verifies evidence packages programmatically, or if you want to confirm a package you were sent hasn't been tampered with before relying on it. The metadata hash is separate from the signed PDF hash: the PDF is its own artifact with its own document hash, not derived from the evidence package.

## Blockchain transaction

Every sealed record includes a transaction hash in its confirmation email; the receipt for the write to Base. The easiest way to inspect it is [basescan.org](https://basescan.org): paste the transaction hash into the search bar, open the transaction, and look at the "Input Data" field. That field holds exactly what Agreebase wrote: for a hash-only record, the AGR reference, the body or content hash, the evidence metadata hash, and the completion time, all as plain readable text (Basescan can decode it as UTF-8 if it doesn't do so automatically; look for a "Decode as UTF-8" or similar toggle near the Input Data section). If full-text publication was enabled, the agreement or declaration body appears there directly instead of just its hash.

This is the check that doesn't depend on Agreebase at all: the transaction is public and permanent on Base regardless of whether Agreebase's own servers are reachable. Compare the body or content hash shown in the calldata against your own recomputed hash, and the evidence metadata hash shown there against your own recomputed metadata hash, and you've verified the record independently of any single party's word for it. See [Verification hashes](/docs/concepts/verification-hashes) for the exact technical model behind all of these, and [Blockchain and permanence](/docs/concepts/agreebase-permanence) for what else the chain record does and doesn't contain.

## Common mistakes

- Hashing the PDF instead of the canonical text.
- Including the evidence appendix in the body hash.
- Using a different newline or Unicode normalization.
- Hashing a changed file rather than the exact original bytes.
- Treating a fuzzy fingerprint match as an exact match.
- Comparing a superseded record with a newer current authority without checking the verification verdict.

---

# API and MCP overview

> Choose the right Agreebase integration surface and find the canonical REST, MCP, authentication, and agent references.

Audiences: developers, agents
Kind: guide
Updated: 2026-07-17

Agreebase exposes the same record model through several surfaces. Choose the surface by who is operating the workflow and whether the caller needs a direct HTTP contract or an agent-human ceremony.

## Surface map

| Surface | Use it for | Entry point |
|---|---|---|
| Web app | Guided creation, signing, record management, and public verification | `/create`, `/confirm/{agr_reference}`, `/my-records`, `/verify` |
| REST API | Server-to-server and application integrations | `/api/v1` |
| Hosted MCP connector | ChatGPT and Claude agent-human workflows with passwordless OAuth | `/mcp/oauth` |
| Direct/raw MCP | Public verification and explicitly configured credentials | `/mcp` |
| Public verification | Unauthenticated certificate and artifact checks | `/api/v1/public` or `/verify` |
| ChatGPT Action contract | ChatGPT-compatible HTTP integration | `/api/v1/chatgpt-action-spec.yaml` |

Machine-readable documentation is available at [/api/openapi.json](/api/openapi.json), [/docs/catalog.json](/docs/catalog.json), [/docs.md](/docs.md), and [/llms.txt](/llms.txt).

## REST API

REST API base: `/api/v1`

## MCP endpoints

MCP endpoint: `/mcp`

Use `/mcp/oauth` for ChatGPT and Claude hosted custom connectors. Adding the connector starts a standard OAuth flow: enter an email address, enter the six-digit authentication OTP, then choose **Verify and connect**. There are no accounts, passwords, registration forms, or API keys to copy. The host stores the OAuth tokens and refreshes the one-hour access token for up to 90 days from the original consent.

Use `/mcp` for direct or raw MCP clients. It retains unauthenticated public verification and accepts credentials that the operator explicitly configures on the transport. It does not use the hosted connector OAuth ceremony. Raw clients can inspect `get_authentication_status` and, when no transport credential is configured, use `request_authentication_otp` followed by `verify_authentication_otp` for the existing short-lived MCP session flow.

MCP clients should begin with the [MCP quickstart](/docs/developers/mcp-quickstart), then use the [MCP reference](/docs/developers/mcp-reference) for the live tool contract, scope requirements, structured responses, and guarded lifecycle rules. Image-bearing REST and MCP response behavior, visibility, and share-card ticket handling are documented in the [image-handling guide](/docs/developers/image-handling).

## Start with the canonical references

- [REST API reference](/docs/developers/rest-api) covers endpoints, request shapes, responses, authentication, scopes, errors, and limits.
- [MCP quickstart](/docs/developers/mcp-quickstart) shows the streamable HTTP handshake and safe verification, authentication, creation, signing, and lifecycle sequences.
- [MCP reference](/docs/developers/mcp-reference) covers tool names, structured workflow responses, preview/execute safeguards, and human steps.
- [Authentication and API keys](/docs/developers/authentication-and-api-keys) covers OTP ceremonies, bearer tokens, API keys, identity linking, and scope boundaries.
- [Image handling](/docs/developers/image-handling) covers compact metadata, inline-image opt-ins, compatibility modes, [identicon](/docs/concepts/identicons) visibility, and single-use card URLs.
- [Using Agreebase with agents](/docs/agents/using-agreebase-with-agents) covers safe orchestration rules rather than protocol schemas.

## Shared product model

The record types are agreement, declaration, witnessed agreement, and notarization. All have an AGR reference, lifecycle status, participants, and sealing state. Agreements, declarations, and witnessed agreements store short normalized bodies. Notarizations store a client-supplied content identity and may not receive source file bytes.

Signatures are version-specific proof-of-control executions. A body change can invalidate current-version signature work. Sealed records are not edited in place; amendments and mutual cancellations create later records.

## Safety boundary

REST is appropriate for application-controlled integrations. MCP is designed for an agent working with a human, so consequential lifecycle actions expose previews, consequence summaries, short-lived confirmation tokens, and exact retry actions. Do not put long-lived API keys in ordinary MCP tool arguments or chat.

The product contract is the generated OpenAPI schema, MCP `tools/list` output, and the public pages linked above. For MCP, the live `tools/list` response is the final authority for the focused discovery catalogue and its argument schemas, enums, annotations, and output schemas. Advanced lifecycle tools documented in the MCP reference remain callable by exact name even when omitted from initial discovery. Internal engineering documents and source paths are not required to use Agreebase.

MCP tools do not accept `api_key` as a normal tool argument. Protected failures use structured values such as `missing_scope`; see the [MCP reference](/docs/developers/mcp-reference).

On `/mcp/oauth`, authentication is completed by the host before MCP initialization and `get_authentication_status` reports the OAuth principal. The authentication bootstrap tools remain in the shared schema for `/mcp` compatibility but are unnecessary for hosted connectors. Authentication only permits access to signature tools: signing still requires the separate, record/version-specific signature ceremony.

---

# MCP quickstart

> Connect ChatGPT and Claude through passwordless OAuth at /mcp/oauth, or configure a direct MCP client at /mcp, then safely operate Agreebase workflows.

Audiences: developers, agents
Kind: guide
Updated: 2026-07-17

This is the shortest reliable path from an MCP client to an Agreebase result. Use it when your client can connect to a streamable HTTP MCP server. For the complete tool contract, see the [MCP reference](/docs/developers/mcp-reference).

Agreebase is an agent-human system. An agent may prepare a record and carry a workflow forward, but the human remains responsible for the exact text, secret inputs, signatures, and consequential confirmations. Agreebase is not a legal service.

## 1. Connect ChatGPT or Claude

Use this endpoint for a hosted custom connector:

```text
https://agreebase.com/mcp/oauth
```

In ChatGPT, add a custom MCP app and enter that URL. In Claude, add a custom remote connector and enter the same URL. The host discovers Agreebase OAuth, registers its connector, and opens the authorization page. Complete:

```text
Connect → enter email → enter OTP → Verify and connect
```

For ChatGPT, open the workspace's app/connector settings, choose to create a custom MCP app, set the server URL to `https://agreebase.com/mcp/oauth`, save, and choose **Connect**. This hosted custom-MCP facility is available only on supported Business, Enterprise, and Edu workspaces.

For Claude, open **Settings → Connectors**, choose **Add custom connector**, set the remote MCP URL to `https://agreebase.com/mcp/oauth`, add it, and choose **Connect**. Claude registers its HTTPS callback dynamically; do not create or paste an Agreebase client secret.

The page identifies the requesting client and exact registered redirect origin, summarizes the permissions, and states that the connection lasts up to 90 days. There is no Agreebase account registration, password, or API key to create or paste. Do not give an API key or OTP to the agent in chat; the host owns the transport ceremony.

The hosted connection grants `create`, `retrieve`, `verify`, `amend`, `cancel`, and `offline_access`. Access tokens last one hour and refresh automatically with rotation until the fixed 90-day consent boundary. Disconnecting revokes the connection. Refresh never expands scopes or extends that boundary.

ChatGPT's custom MCP facility must be available to the user's workspace. Claude must support remote custom connectors. These are hosted MCP connections, not a ChatGPT Action, Custom GPT Action, marketplace app, plugin, or Apps SDK UI.

## 1.5 Connect a direct or raw client

Direct clients use:

```text
https://agreebase.com/mcp
```

This endpoint retains public verification and credentials explicitly configured by the client operator. A raw client uses the streamable HTTP sequence below:

1. `POST /mcp` an `initialize` request with `Content-Type: application/json` and `Accept: application/json, text/event-stream`.
2. Save the `Mcp-Session-Id` response header.
3. Send `notifications/initialized` with that session ID.
4. Send `tools/list` before relying on a tool name, input schema, enum, or annotation.
5. Send `tools/call` requests with the same session ID.

The server may return each JSON-RPC response as an SSE `message` event whose `data` value is the JSON-RPC envelope. A client should accept either an SSE response or an ordinary JSON response and should read the structured result when the server provides `structuredContent`.

An initialization request looks like this:

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2025-06-18",
    "capabilities": {},
    "clientInfo": {
      "name": "example-agent",
      "version": "1.0.0"
    }
  }
}
```

After initialization, send this notification. Notifications have no `id` and do not require the client to interpret a result:

```json
{
  "jsonrpc": "2.0",
  "method": "notifications/initialized",
  "params": {}
}
```

Then discover the current contract:

```json
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/list",
  "params": {}
}
```

The server's negotiated protocol version is authoritative. If a client does not advertise `text/event-stream`, the endpoint may return `406 Not Acceptable`.

## 2. Make the first safe call

Public verification does not require authentication. This call asks whether a record exists and returns a public certificate when no artifact is supplied:

```json
{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "verify_agreement",
    "arguments": {
      "agr_reference": "AGR-ABCD-EFGH"
    }
  }
}
```

For a real artifact, include the strongest value available. For a notarized file or hash record, `content_hash` is normally the correct field:

```json
{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "tools/call",
  "params": {
    "name": "verify_agreement",
    "arguments": {
      "agr_reference": "AGR-ABCD-EFGH",
      "content_hash": "sha256:969e2d23155e65aa91b0bd6ae2688deb2e0c2f6fbf74ebee2721d5f5983c204d"
    }
  }
}
```

Interpret the result using these fields together:

- `record_found` says whether the reference resolved.
- `record_match` says whether the submitted artifact matched the record.
- `verified` is the final verification result.
- `verdict` distinguishes `verified`, `certificate`, `matched_superseded`, `matched_not_sealed`, `no_match`, and `not_found`.
- `current_authority` says whether the matched record is the current authority.
- `match_method` identifies the successful comparison.
- `status` and `sealed_at` describe sealing independently of artifact matching.

Reference-only verification is a certificate lookup. It is not proof that a particular file or text copy matches.

## 2.5 Choose image and card representations

Agreement reads, lists, and verification calls return compact image metadata by default. The metadata includes the [identicon](/docs/concepts/identicons) kind, digest, short hash, dimensions, accessible alt text, and availability; it does not include image bytes or a data URI. Ask for `visual_representation="inline"` when the MCP host can render native image content:

```json
{
  "name": "verify_agreement",
  "arguments": {
    "agr_reference": "AGR-ABCD-EFGH",
    "visual_representation": "inline"
  }
}
```

Use `visual_representation="compatibility_data_uri"` only for a legacy host that explicitly needs an SVG data URI. Inline image bytes are placed in an MCP image content block, not in `structuredContent` or the first text block. Those two redacted payloads are intentionally identical.

Public verification and agreement listings inline document identicons only. After participant authentication, use `get_agreement` for permitted party signature identicons or the signature-execution tools for the current caller's finalized signature identicon.

Share cards are private artifacts. After the existing participant authentication succeeds, call `get_agreement_card` with no representation to receive a short-lived, single-use URL:

```json
{
  "name": "get_agreement_card",
  "arguments": {
    "agr_reference": "AGR-ABCD-EFGH",
    "representation": "url"
  }
}
```

Use `representation="inline"` for native MCP PNG content, or the deliberate `compatibility_base64` mode for an older client. The URL uses the configured public/base URL, expires after the configured short TTL (five minutes by default), and cannot be redeemed twice. Never log or persist the ticket.

## 3. Authentication is transport-level

On `/mcp/oauth`, ChatGPT or Claude completes authentication before MCP initialization. The agent does not call an authentication tool to create the connection and must never request an API key in chat. `get_authentication_status` reports the OAuth principal and all granted scopes. The authentication bootstrap tools remain visible because `/mcp/oauth` and `/mcp` deliberately share the same 27-tool discovery catalogue, but hosted connectors do not need them.

For a direct `/mcp` session, check the current transport or session first:

Check the current transport or session first:

```json
{
  "jsonrpc": "2.0",
  "id": 5,
  "method": "tools/call",
  "params": {
    "name": "get_authentication_status",
    "arguments": {}
  }
}
```

The response reports `authenticated`, `scopes`, `auth_method`, and whether the credential is `session_bound`.

If direct-client retrieval access is needed and no transport credential is configured:

1. Call `request_authentication_otp` with the user's email.
2. Tell the user that Agreebase sent a short-lived six-digit authentication code and wait for the user to provide it.
3. Call `verify_authentication_otp` with the returned `verification_event_id` and the user-provided code.
4. Keep using the same MCP session. A session-bound result grants the `retrieve` scope for up to 600 seconds.
5. Call the tool named by `next_action`, normally `list_agreements` or `get_agreement`.

That direct-client OTP bootstrap is intentionally limited to retrieval. Creating records, executing signatures, and lifecycle changes require a transport credential with the exact returned scope. A transport `Authorization: Bearer` credential may be an Agreebase API key or a short-lived MCP transport token. Never put a long-lived API key in a tool argument or chat message.

An OAuth authentication OTP and every direct-client authentication OTP have purpose `authenticate`. They authorize access only. They can never seed a signature method, satisfy `can_finalize`, create signature evidence, or finalize a record. Every signature still requires the separate record/version-specific ceremony returned by the signature tools.

## 4. Create, sign, and seal a record

Creation tools are consequential. Show the exact final text to the human before calling one, and make publication choices explicit. A minimal agreement call has these required arguments:

```json
{
  "jsonrpc": "2.0",
  "id": 6,
  "method": "tools/call",
  "params": {
    "name": "create_agreement",
    "arguments": {
      "body": "The complete final agreement text, including the obligations and dates the parties approved.",
      "other_party_email": "counterparty@example.com",
      "other_party_name": "Counterparty",
      "on_chain_full_text": false,
      "on_chain_include_verified_parties": false,
      "required_signature_method_count": 1
    }
  }
}
```

A successful creation response contains the AGR reference, an initiator signature state, and usually `next_action` and `human_step`. Follow the exact tool and arguments returned there. Do not infer a signature method from prose.

The signature loop is:

1. Call `start_or_resume_signature_execution` if the returned next action asks for it.
2. Call `start_signature_method` for the selected method.
3. Give the human the exact `human_step.prompt`, proof text, proof title, URL, or challenge instructions returned by Agreebase.
4. Submit only the short-lived user-provided value through `submit_signature_method_input`.
5. Refresh asynchronous methods with `refresh_signature_method` when the next action requests it.
6. Repeat until `signature_execution.can_finalize` is true.
7. Show the exact final text again and obtain affirmative human confirmation.
8. Call `finalize_signature_execution` only after that confirmation.

Email signature OTPs, authentication OTPs, public proof URLs, Telegram challenges, and passkey payloads are different inputs. Never substitute one for another. Other participants may still need to complete their own current version signatures after the initiator finalizes.

## 5. Use previews before consequential lifecycle actions

Amendments, draft updates, participant changes, invitation resends, witness actions, rescissions, cancellations, declines, and counter-proposal resolution are all guarded. The safe sequence is:

1. Call the matching `preview_*` tool.
2. Read the actor, target, current status, agreement version, consequences, notifications, and sealing or blockchain effect.
3. Summarize those consequences to the human and obtain explicit confirmation.
4. Call the matching execute tool with the preview's `confirmation_token`, the same target arguments, and the preview's `agreement_version`.
5. If the token expires or the version changes, call the preview again. Do not retry the old execute call blindly.

The execute tool's `confirmation_token` is short-lived and bound to the principal, scope, record, target, and version that produced the preview.

## 6. Treat every response as a workflow instruction

On a successful response, inspect `next_action` and `human_step` before writing your own next step. On a recoverable failure, inspect `error_code`, `required_scopes`, `retry_after_seconds`, and `retry_action`.

The most useful agent rules are:

- `auth_required`: obtain the required authentication or ask the user to connect a permitted transport credential.
- `missing_scope`: report the exact missing scope; do not guess or request a broader scope silently.
- `confirmation_required`: call the named preview tool.
- `stale_confirmation_token`, `expired`, or `conflict`: refresh the preview or restart the current workflow from the returned retry action.
- `rate_limited`: wait for `retry_after_seconds`; do not loop aggressively.
- `validation_error`: correct the arguments using the live `tools/list` schema.

The complete response and tool catalog are in the [MCP reference](/docs/developers/mcp-reference).

---

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

---

# MCP reference

> The canonical Agreebase MCP contract for transport, authentication, structured workflows, verification, signing, and guarded lifecycle actions.

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

This is the canonical public reference for Agreebase's Model Context Protocol (MCP) server. It describes the operating contract an agent should follow, not just a list of function names.

For a first connection, start with the [MCP quickstart](/docs/developers/mcp-quickstart). For the current exact schemas, enums, annotations, and output models of discoverable tools, call `tools/list` on the connected server. The live discovery response is authoritative for that focused catalogue. Advanced lifecycle tools documented below remain directly callable by exact name even when omitted from discovery.

Agreebase creates permanent, tamper-evident records. It is not a legal service. An agent must preserve user-provided facts, avoid inventing signatures or approvals, show exact text before recording it, and stop for human inputs and consequential confirmations.

## Operating model

An MCP client normally performs this sequence:

```text
initialize → notifications/initialized → tools/list → tools/call
```

The server returns structured workflow state so the agent can continue without guessing. A response may contain:

- `next_action`: the exact next tool and arguments suggested by Agreebase.
- `human_step`: a user-facing prompt, proof text, URL, title, challenge, or expiry that must be handled outside the tool call.
- `requires_confirmation`: whether the agent must obtain explicit approval.
- `error_code`: a machine-readable failure category.
- `required_scopes`: the exact permission needed for a protected action.
- `retry_action`: a safe, structured recovery operation.

Treat these fields as the workflow protocol. Do not derive a tool name from a free-form message when `next_action.tool` is available.

## Transport contract

The hosted connector endpoint is:

```text
/mcp/oauth
```

It is the endpoint for ChatGPT and Claude custom remote MCP connectors. It requires an OAuth access token before MCP initialization and exposes protected resource metadata at `/.well-known/oauth-protected-resource/mcp/oauth`. Authorization-server metadata is at `/.well-known/oauth-authorization-server`; dynamic registration, authorization, token, and revocation are at `/register`, `/authorize`, `/token`, and `/revoke`.

The direct/raw endpoint is:

```text
/mcp
```

Both endpoints delegate to the same FastMCP application, tool registry, schemas, annotations, and domain handlers. `/mcp` retains public verification, API-key bearer transport, and short-lived MCP session authentication. It uses streamable HTTP. A raw client must:

1. `POST` JSON-RPC to `/mcp` with `Content-Type: application/json`.
2. Advertise `Accept: application/json, text/event-stream`.
3. Save the `Mcp-Session-Id` response header from `initialize`.
4. Send subsequent requests with that session header.
5. Accept either an SSE `message` event or a JSON response body.

The initialization request must identify the client and offer a supported MCP protocol version. The server's negotiated `protocolVersion` is authoritative:

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2025-06-18",
    "capabilities": {},
    "clientInfo": {
      "name": "example-agent",
      "version": "1.0.0"
    }
  }
}
```

After receiving the initialization result, send:

```json
{
  "jsonrpc": "2.0",
  "method": "notifications/initialized",
  "params": {}
}
```

Then discover the live contract:

```json
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/list",
  "params": {}
}
```

The discovery response includes each tool's `inputSchema`, `outputSchema`, description, and `annotations`. The `annotations` are safety metadata, not a replacement for authorization. In particular, a `readOnlyHint` does not grant access, and a `destructiveHint` does not by itself mean that the tool is forbidden.

## Tool catalog

### Public and authentication tools

| Tools | Access | Purpose |
|---|---|---|
| `verify_agreement` | Public on `/mcp`; OAuth transport required on `/mcp/oauth` | Return a certificate or compare supplied text, hashes, or a transaction. |
| `get_authentication_status` | Public | Report current transport/session authentication and scopes. |
| `request_authentication_otp` | Public | Email a short-lived authentication code. This has an external side effect. |
| `verify_authentication_otp` | Public | Bind the user-provided authentication code to the current MCP session. |

Authentication OTP access is limited to the `retrieve` scope. It is not a signature OTP and does not grant `create`, `verify`, `amend`, or `cancel`.

### Creation tools

| Tool | Scope | Purpose |
|---|---|---|
| `create_agreement` | `create` | Create a multi-party agreement draft and start the initiator workflow. |
| `create_declaration` | `create` | Create a personal declaration or attestation draft. |
| `create_notarization` | `create` | Record a file, text, or supplied SHA-256 content identity. |

Creation records the supplied content. The agent must obtain human review of the exact final text and publication settings before calling a creation tool.

### Signature execution tools

| Tool | Scope | Purpose |
|---|---|---|
| `start_or_resume_signature_execution` | `verify` | Start or resume the current participant's session. |
| `get_signature_execution` | `verify` | Read the current participant's signature state. |
| `start_signature_method` | `verify` | Start one method for the current record version. |
| `submit_signature_method_input` | `verify` | Submit an OTP, public URL, or passkey payload. |
| `refresh_signature_method` | `verify` | Refresh an asynchronous proof or challenge. |
| `cancel_signature_method` | `verify` | Cancel a pending method. |
| `finalize_signature_execution` | `verify` | Finalize after the required methods are satisfied and the human confirms. |

Supported signature methods are `email_otp`, `github_gist`, `x_post`, `reddit_post`, `webauthn_passkey`, `telegram`, and `api_key` where the live schema makes that method available. The response identifies which methods are available for the current participant and record.

### Retrieval and verification tools

| Tool | Scope | Purpose |
|---|---|---|
| `get_agreement` | `retrieve` | Read an authenticated record and permitted participant evidence. |
| `list_agreements` | `retrieve` | List records in the authenticated identity graph. |
| `get_agreement_card` | `retrieve` | Retrieve a sealed record card as a single-use URL, native MCP image, or explicit compatibility base64. |
| `verify_agreement` | Public | Verify a reference or compare a supplied artifact without private signer evidence. |

`get_agreement` and `list_agreements` are identity-graph operations. Public verification deliberately does not disclose private signer evidence.

### Image and share-card representations

Image-bearing reads default to compact metadata. [Identicon](/docs/concepts/identicons) metadata contains `kind`, `digest`, `short_hash`, `width`, `height`, `alt_text`, and `available`; it does not contain `algorithm`, `version`, SVG bytes, or a data URI. Share-card metadata contains artifact metadata only and never an internal storage path.

`get_agreement`, `list_agreements`, and `verify_agreement` expose `visual_representation` with `metadata`, `inline`, and `compatibility_data_uri` values. `metadata` is the safe default. `inline` adds MCP-native `ImageContent` while keeping image bytes out of structured content. `compatibility_data_uri` is an intentional legacy mode. MCP `structuredContent` and `content[0].text` are the same redacted JSON payload; native inline bytes are separate content blocks.

`list_agreements` and public `verify_agreement` return or inline document identicons only. Authenticated `get_agreement` can additionally return current party signature-identicon metadata and images, while authenticated signature execution tools expose the current caller's finalized signature identicon.

`get_agreement_card` exposes `representation`:

- `url` (default) issues a five-minute, scoped, single-use ticket URL;
- `inline` returns native MCP PNG content without structured image bytes;
- `compatibility_base64` returns legacy base64 bytes in structured content.

Card issuance requires the existing authenticated participant authorization for the declarant, signer, co-signer, or witness. An already-authenticated MCP session is reused; no second authentication step is required. A ticket URL contains no agreement reference, uses `APP_BASE_URL`, and is redeemed atomically exactly once after successful artifact retrieval. Redeemed and expired ticket rows are removed by an hourly maintenance job. See the dedicated [image-handling guide](/docs/developers/image-handling) for visibility and local-versus-hosted URL behavior.

### Guarded lifecycle tools

Every pair below has a read-only preview followed by a separate execute call. The execute call requires the matching short-lived confirmation token and the expected agreement version.

| Preview / execute pair | Scope | Effect |
|---|---|---|
| `preview_amend_agreement` / `amend_agreement` | `amend` | Create a new version from an existing agreement. |
| `preview_update_agreement_draft` / `update_agreement_draft` | `amend` | Change a draft before it is sealed. |
| `preview_resend_participant_invitation` / `resend_participant_invitation` | `amend` | Queue an invitation resend. |
| `preview_replace_declined_witness` / `replace_declined_witness` | `amend` | Replace a declined witness. |
| `preview_resolve_counter_proposal` / `resolve_counter_proposal` | `amend` | Accept, partially accept, or reject a counter-proposal. |
| `preview_withdraw_counter_proposal` / `withdraw_counter_proposal` | `amend` | Withdraw the proposer's pending counter-proposal. |
| `preview_remove_party` / `remove_party` | `cancel` | Remove a participant and affect pending work. |
| `preview_submit_counter_proposal` / `submit_counter_proposal` | `amend` | Submit a counter-proposal and move the record into counter review. |
| `preview_waive_declined_witness` / `waive_declined_witness` | `cancel` | Waive a declined witness when the state permits it. |
| `preview_waive_declined_co_notarizer` / `waive_declined_co_notarizer` | `cancel` | Complete without one declined co-notarizer; other invitations remain active. |
| `preview_rescind_agreement` / `rescind_agreement` | `cancel` | Rescind a pending agreement, declaration, or notarization. |
| `preview_cancel_draft` / `cancel_draft` | `cancel` | Cancel an unsealed draft. |
| `preview_decline_agreement` / `decline_agreement` | `cancel` | Decline participation in the current version. |

The advanced amendment, decline, witness/co-notarizer exception, and
counter-proposal pairs are omitted from `tools/list` to keep initial discovery
focused. They remain registered and directly callable by the exact names shown
above, with the same authentication, scope, role/state, preview, and confirmation
requirements.

## Authentication and scopes

ChatGPT and Claude hosted connectors authenticate at `/mcp/oauth` with the standard authorization-code flow, PKCE S256, Dynamic Client Registration, and resource binding. The authorization ceremony is passwordless:

```text
Connect → enter email → enter OTP → Verify and connect
```

The authorization page displays the requesting client, exact registered redirect origin, permissions, and 90-day connection duration. The user always submits the OTP through **Verify and connect**; an existing browser session is not silently reused. The OAuth grant contains `create`, `retrieve`, `verify`, `amend`, `cancel`, and `offline_access`. Access tokens last one hour. Refresh tokens rotate and remain bounded by the original 90-day grant expiry. Rotation replay revokes the token family. Revocation invalidates the family and its active access tokens.

The direct `/mcp` endpoint resolves authentication from the request transport. A request may carry:

```http
Authorization: Bearer <Agreebase API key or short-lived MCP transport token>
```

The direct endpoint also binds a successful MCP authentication OTP to the current session. The short-lived manual transport token returned when a client cannot preserve session state is valid for at most 600 seconds and is transport-only. Do not store it in long-term memory, prompts, notes, or logs.

Use `get_authentication_status` before protected work. If the response is not authenticated, a protected tool returns a structured `auth_required` error with the exact `required_scopes`. If the credential is valid but too narrow, the tool returns `missing_scope` with both `required_scopes` and `available_scopes`.

| Scope | MCP operations |
|---|---|
| `create` | Creation tools. |
| `retrieve` | `get_agreement`, `list_agreements`, and `get_agreement_card`. |
| `verify` | Signature execution and the authenticated participant actions around it. |
| `amend` | Amendments, draft updates, invitation resends, witness replacement, and counter actions. |
| `cancel` | Participant removal, witness waiver, rescission, draft cancellation, and decline. |

The direct MCP authentication OTP bootstrap grants `retrieve` only. It is suitable for listing and reading records, not for creating or signing them. Use a permitted transport API key or token with the exact required scope for those workflows. MCP never accepts an API key as a normal tool argument.

On `/mcp/oauth`, `get_authentication_status` reports `auth_method="oauth"` and the OAuth principal. The three bootstrap tools remain in the shared schema for direct-client compatibility and are unnecessary for hosted connectors. An OAuth token is accepted only at `/mcp/oauth`; an API key is accepted only by the direct transport. Agents must never ask a user to provide an API key through a prompt or tool call.

Authentication and signing remain strictly separate. An `authenticate` OTP can never become signature evidence, satisfy a required signature method, enable `can_finalize`, or finalize a record. Signature intent always requires the separate record/version-specific `signature_email_otp` or another configured signature method. OAuth authentication does not activate the API-key signature method and cannot use notarization `auto_seal`.

## Creation contract

### Agreements and declarations

`create_agreement` and `create_declaration` require the agent to supply the complete final `body`, participant identity fields, and explicit blockchain publication booleans. The live schema defines all optional fields, but the important creation rules are:

- Bodies are limited to 350 normalized words and 7,000 characters.
- Agreements have at most 15 total signing participants, including the initiator.
- There may be at most five active witnesses.
- `witness_names` must have exactly one name for every `witnesses` address.
- `required_signature_method_count` is `1`, `2`, or `3`.
- `on_chain_full_text` publishes the final sealed text rather than only hashes and metadata.
- `on_chain_include_verified_parties` makes verified signer or witness details public in on-chain metadata and may require an additional human acknowledgement.

Creation returns an agreement summary, signature state, and usually a `next_action`. The creation response is not proof that the record is sealed.

### Notarizations

`create_notarization` accepts `content_type` of `file`, `text`, or `hash` and a SHA-256 `content_hash` in the form `sha256:<64 lowercase hexadecimal digits>`.

- Hash a file's exact bytes on the client; do not send file bytes or local file paths as ordinary notarization content.
- For text notarizations, provide the text and ensure its normalized hash is the supplied `content_hash`.
- File and hash notarizations require a `label` or `filename`.
- `text_public` controls whether normalized text may appear in public reads.
- At most fourteen co-notarizers may be supplied.
- `signature_mode="auto_seal"` is an explicit API-key flow and requires the conditions advertised by the live schema, including one required signature method.

Notarization metadata records what Agreebase intentionally did not ingest. It does not turn an uploaded file into a signed PDF.

## Signature execution contract

Signature execution is scoped to a participant and an agreement version. A successful signature response contains `signature_execution`, whose important fields are:

- `agreement_version`: the version being signed.
- `required_count` and `completed_count`: method progress.
- `minimum_satisfied`: whether the required method count is met.
- `can_finalize`: whether finalization is currently permitted.
- `finalization_blocker`: why finalization is not yet possible.
- `methods`: method-specific status and human instructions.
- `public_party_details_acknowledgement_required`: whether finalization needs explicit acknowledgement of public participant details.

Method-specific inputs are deliberately not interchangeable:

| Method | Start or submit input |
|---|---|
| `email_otp` | Agreebase's six-digit signature code, not an authentication code. |
| `github_gist`, `x_post`, `reddit_post` | The exact generated proof text and then the resulting public URL. |
| `telegram` | The generated challenge or Telegram flow returned by Agreebase. |
| `webauthn_passkey` | A browser-native passkey ceremony and returned payload. |
| `api_key` | Only when the live schema and current workflow make it available. |

Do not paraphrase proof text or Reddit titles. Do not ask a user to paste a private key. When `human_step` is present, stop and give the user the requested instruction rather than attempting to complete it autonomously.

## Verification contract

`verify_agreement` is public and takes:

| Argument | Use |
|---|---|
| `agr_reference` | Required record reference. |
| `body` | Exact candidate agreement or declaration text. |
| `body_hash` | Hash of the candidate agreement body. |
| `content_hash` | Hash of notarized content. |
| `document_hash` | Hash of a signed or rendered document. |
| `tx_hash` | Blockchain transaction hash; requests a live chain check. |

Supply the strongest artifact available. A reference-only call returns a certificate. It does not compare a document.

| `verdict` | Meaning |
|---|---|
| `verified` | A submitted artifact matched and the record is sealed/current as required. |
| `certificate` | The current record was found, but no artifact was submitted. |
| `matched_superseded` | An artifact matched an older record that is no longer current authority. |
| `matched_not_sealed` | An artifact matched, but the record is not sealed. |
| `no_match` | The record exists but the submitted artifact did not match. |
| `not_found` | No record matched the supplied reference. |

The response also reports per-check fields under `checks`, the selected `match_method`, blockchain status, `on_chain_check`, and compact document identicon metadata when a sealed record exists. A visual identicon is a secondary cryptographic fingerprint; it never replaces hashes, sealed status, signature state, or `verify_agreement`.

## Guarded lifecycle contract

A lifecycle preview is read-only but may expose the consequences of an action:

- `actor_identity_summary` identifies the authenticated actor.
- `target_summary` identifies the affected record, participant, witness, or counter-proposal.
- `current_status` and `agreement_version` identify the state being previewed.
- `consequences` describes state and participant effects.
- `notifications_queued` describes expected notifications.
- `sealing_or_blockchain_effect` describes permanence or chain effects.
- `confirmation_token` and `expires_at` authorize the matching execute call.

The execute call must use the same authenticated principal, scope, AGR reference, target identifiers, and expected agreement version. A missing, expired, stale, wrong-principal, wrong-scope, wrong-target, or wrong-version request is not permission to proceed. Follow `retry_action` back to the correct preview tool.

## Response and error handling

When a tool executes, prefer the MCP `structuredContent` object. It follows the tool's `outputSchema`. The text content block is a human-readable JSON copy and is useful as a fallback for clients that do not expose structured content.

There are two error layers:

1. The MCP dispatcher may reject an unknown tool or invalid arguments. The JSON-RPC result may have `isError: true`; re-read `tools/list` and correct the call.
2. A tool may execute and return `success: false`, `error_code`, `error`, and recovery fields. Handle this as a workflow result, not as a transport retry.

Common structured errors:

| Error | Agent response |
|---|---|
| `auth_required` | Obtain the required transport/session authentication. |
| `invalid_credentials` | Stop and reconnect with a valid credential. |
| `missing_scope` | Tell the user the exact missing scope and request an appropriately permitted connection. |
| `validation_error` | Correct the arguments against the current input schema. |
| `confirmation_required` | Call the matching preview tool before executing. |
| `stale_confirmation_token` | Refresh the preview; do not reuse the old token. |
| `expired` | Restart the expired human or lifecycle step. |
| `forbidden` | Stop; do not probe alternate principals or targets. |
| `conflict` | Read the current state and follow the returned retry action. |
| `rate_limited` | Wait for `retry_after_seconds` and avoid a tight retry loop. |
| `not_found` | Report that the record or target was not found without inventing a result. |

Do not log bearer tokens, refresh tokens, authorization codes, client secrets, OAuth transaction identifiers, API keys, OTP codes, confirmation tokens, proof payloads, or private participant evidence.

## Privacy, permanence, and limits

Agreebase records durable evidence. Before creation or finalization, explain:

- Hash-only chain publication exposes a digest and metadata rather than full text.
- Full-text chain publication is more public and permanent.
- Verified party details may publish names and signing contact details when explicitly enabled and acknowledged.
- Public verification does not reveal private signer evidence.
- Notarization stores the supplied content identity and whitelisted metadata; it does not need source file bytes.

The principal limits are:

- Agreement and declaration body: 350 normalized words and 7,000 characters.
- Agreement participants: 15 total signing participants.
- Active witnesses: five.
- Notarization co-notarizers: fourteen.
- OAuth access token: one hour.
- OAuth connection: fixed 90 days from consent.
- Manual MCP authentication transport token: at most 600 seconds.

When a limit or enum is important to a call, trust the current `tools/list` schema over copied documentation.

---

# Authentication and API keys

> Authenticate REST and MCP calls safely with OTP ceremonies, bearer tokens, identity graphs, and scoped API keys.

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

Agreebase distinguishes authentication from signing. Authentication proves control of an Agreebase identity for access. Signing proves control for a specific record version and completes that participant's signature execution.

## REST bearer authentication

Request an authentication OTP through:

```http
POST /api/v1/verification/request-otp
Content-Type: application/json

{"email":"person@example.com","purpose":"authenticate"}
```

Verify the returned event with:

```http
POST /api/v1/verification/verify-otp
Content-Type: application/json

{"verification_event_id":"<event-id>","code":"123456"}
```

The response returns a short-lived bearer token. Send it as:

```http
Authorization: Bearer <token>
```

Authentication OTP, signature OTP, agreement-confirmation OTP, and contact-point linking OTP are separate purposes and cannot be substituted for one another.

## Hosted MCP connector OAuth

ChatGPT and Claude hosted custom connectors use `https://agreebase.com/mcp/oauth`. OAuth is the host-facing transport protocol; Agreebase identity remains an email contact point verified by OTP. The complete connection ceremony is:

```text
Connect → enter email → enter OTP → Verify and connect
```

The authorization page shows the requesting client, its exact registered redirect origin, the permissions, and the 90-day duration before the OTP is sent. Submitting the OTP through **Verify and connect** is explicit consent. Agreebase does not silently reuse a browser login.

The grant includes `create`, `retrieve`, `verify`, `amend`, `cancel`, and `offline_access`. Access tokens last one hour. Every refresh rotates the refresh token and remains bounded by the original 90-day grant expiry; refresh cannot extend the grant or add scopes. Disconnecting through the host invokes token revocation. Reusing a rotated refresh token revokes the whole connection.

OAuth authentication proves permission to operate tools as the verified contact-point identity. It never proves signature intent. An authentication OTP cannot satisfy a signature method, create signature evidence, enable `can_finalize`, or finalize a record. The user must complete a separate record/version-specific `signature_email_otp` or another configured signature method. OAuth also cannot activate API-key notarization `auto_seal`.

## API keys

API keys are long-lived integration credentials. Create them with a bearer-authenticated request to `POST /api/v1/api-keys`. The full key is returned once and cannot be retrieved later. Store it in a secret manager and send it as:

```http
X-API-Key: <agreebase-api-key>
```

List keys with `GET /api/v1/api-keys` and revoke one with `DELETE /api/v1/api-keys/{key_id}`. Revocation immediately prevents future authentication with that key.

## Exact scopes

Scopes are independent and must be granted explicitly:

| Scope | Main operations |
|---|---|
| `create` | Create agreements, declarations, and notarizations. |
| `retrieve` | Retrieve records, list records, and download PDFs/cards. |
| `verify` | Signature execution and verification-related participant actions. |
| `amend` | Amendments, participant invitation resends, witness replacement, and counters where applicable. |
| `cancel` | Declines, removals, rescission, draft cancellation, witness waiver, and cancellation records. |
| `offline_access` | Grants a refresh token so an OAuth connector can renew its access token without a fresh consent. OAuth-only; not issuable to API keys. |

Bearer sessions are live human sessions and are not API-key scope substitutes. The route's required scope is returned in the generated OpenAPI contract and in MCP errors such as `missing_scope`.

## Identity graph

An authenticated identity can have linked verified contact points. Use `GET /api/v1/identity/contact-points` to inspect them and `POST /api/v1/identity/link` to link a new verified email through a dedicated linking OTP ceremony.

The identity graph determines which records a person can retrieve and which participant identity an authenticated action represents. It does not make a person a signer: the participant still needs a finalized signature execution for the target record version.

## Direct/raw MCP authentication

For direct `/mcp`, begin with `get_authentication_status`. A transport `Authorization: Bearer` credential may be an API key or short-lived MCP authentication token. Without one, use `request_authentication_otp` and `verify_authentication_otp`.

The MCP OTP bootstrap grants only the `retrieve` scope and is intended for listing and reading records. Creation, signature execution, and lifecycle actions require a transport credential with the exact scope named by the MCP tool's `required_scopes` response. See the [MCP quickstart](/docs/developers/mcp-quickstart) for the complete session sequence and the [MCP reference](/docs/developers/mcp-reference) for the scope map.

When the client preserves MCP session state, the authenticated principal is bound to that session. When it cannot, verification can return a manual transport token valid for at most 600 seconds. Use it only in the immediate MCP `Authorization` header; do not store it in memory, prompts, logs, or notes.

## Security rules

- Never put an API key in a normal MCP tool argument.
- Never ask a user to paste a long-lived key into a chat transcript.
- For hosted connectors, let ChatGPT or Claude perform OAuth; do not request an API key or OTP inside the agent conversation.
- Do not log bearer tokens, refresh tokens, authorization codes, client secrets, API keys, transaction identifiers, or OTP codes.
- Treat OTPs as one-time, short-lived ceremony inputs.
- Check the exact returned scope instead of guessing a broader permission.

---

# Image handling and share cards

> External image representations, identicon visibility, and scoped share-card downloads in Agreebase.

Audiences: developers, agents
Kind: guide
Updated: 2026-07-13

Agreebase has two image-bearing artifact types:

- Document and signature identicons; deterministic visual fingerprints of a sealed record and of a finalized signer or witness, respectively. See [Identicons](/docs/concepts/identicons) for what they represent, how they're generated, and what they're safe to rely on; this page covers only their wire representation.
- A share card is a rendered PNG artifact intended for an authorized participant to share or download. It is not an identicon and is never exposed as ordinary public metadata.

## Default response shape

REST and MCP agreement listing, retrieval, and verification responses use compact metadata by default. An identicon contains:

```json
{
  "kind": "document",
  "digest": "sha256:...",
  "short_hash": "abid:12ab-34cd-56ef",
  "width": 266,
  "height": 154,
  "alt_text": "Document identicon AGR-... (abid:12ab-34cd-56ef)",
  "available": true
}
```

The default response contains no SVG bytes, data URI, storage path, or card download URL. Share-card metadata contains the filename, content type, dimensions, artifact hash, generation time, and `available`; it does not contain an internal storage path.

## Requesting a visual representation

MCP tools that return image-bearing data expose `visual_representation`:

- `metadata` is the default and is appropriate when an agent needs to compare fingerprints, display accessible metadata, or keep context small.
- `inline` keeps the structured payload compact and adds MCP-native `ImageContent`. Use it when the host can display MCP images immediately.
- `compatibility_data_uri` deliberately places the legacy SVG data URI in the structured response. Use it only for a client that cannot consume native MCP image content.

The same compact payload is used for MCP `structuredContent` and the first text content block. Inline image bytes are carried only by a separate native image block, so an agent should not copy image data from the text block.

Share cards use a separate `representation` choice on `get_agreement_card`:

- `url` is the default and returns a short-lived, single-use download ticket.
- `inline` returns the PNG as native MCP `ImageContent`, without putting bytes in structured content.
- `compatibility_base64` deliberately returns legacy base64 bytes in the structured payload.

Examples:

```json
{"agr_reference":"AGR-...","visual_representation":"metadata"}
```

Use this for listing or checking a record. For a visual MCP-capable client:

```json
{"agr_reference":"AGR-...","visual_representation":"inline"}
```

To retrieve a private card after participant authentication:

```json
{"agr_reference":"AGR-...","representation":"url"}
```

Use `representation="inline"` only when the agent's MCP host is prepared to render an image block. Use compatibility modes only when an older client requires the legacy wire format.

## Visibility

Public known-reference verification and public agreement responses may expose document-identicon metadata only when the record is sealed. They never expose signature identicons, card artifacts, storage paths, agreement bodies, or private participant metadata. Agreebase does not provide an identicon listing or enumeration endpoint.

MCP `verify_agreement`, including its `inline` representation, returns only the document identicon. MCP `list_agreements` likewise returns or inlines only the document identicon represented by each list item. It does not add party or signature images that are absent from the list contract.

Authenticated participant `get_agreement` views may expose the document identicon and permitted current signature-identicon metadata for its parties. Authenticated signature-execution reads expose the current caller's finalized signature identicon. Participant authorization uses the existing identity graph, so declarants, signers, co-signers, and witnesses retain the same access behavior as the corresponding agreement and signature APIs.

The visual fingerprint itself is not treated as a private agreement lookup. However, unauthenticated access is restricted to a caller-supplied known reference and sealed public metadata; it cannot be used to enumerate records or infer private participant data.

Share cards are stricter: only an authenticated, authorized participant may request one. Existing authenticated binary card routes retain their existing authorization. MCP card retrieval uses the already-authenticated MCP session and does not ask the user to authenticate again.

## Share-card URLs

The URL returned by REST card-ticket issuance or MCP `get_agreement_card`:

- identifies only an opaque ticket, never an agreement reference or metadata;
- expires after five minutes by default, within the configured bounded TTL;
- succeeds only once after a successful artifact read;
- is redeemed atomically, so concurrent requests cannot both consume it;
- is removed from the ticket store after redemption or expiry by an hourly maintenance job;
- is returned with `Cache-Control: no-store`, `Referrer-Policy: no-referrer`, and content-sniffing protections.

Treat a ticket URL as a secret. Do not log it, put it in a prompt transcript, or persist it beyond the immediate download. A failed or expired redemption returns a generic not-found response and does not reveal whether a ticket was ever valid.

---

# AGREEBASE.md

> A drop-in project file that teaches an AI agent how to create, sign, verify, and manage Agreebase records safely.

Audiences: developers, agents
Kind: guide
Updated: 2026-07-24

`AGREEBASE.md` is a self-contained project file that tells AI agents how to use Agreebase correctly and safely. It covers creation, signing, verification, consequential actions, and a small durable record log without duplicating the full API reference.

## How to use it

1. Copy the block below into `AGREEBASE.md` in the root of your project.
2. Reference `AGREEBASE.md` from the project instruction file your agents load automatically.
3. Keep the record log at the bottom of the file. It gives agents enough non-sensitive context to remember Agreebase records they created.

For more information on the Agreebase MCP interface, see [MCP quickstart](/docs/developers/mcp-quickstart).

````markdown
# AGREEBASE.md

Guidance for AI agents using Agreebase in this project. Read this before creating, signing, verifying, or changing any Agreebase record.

Agreebase creates permanent, tamper-proof, blockchain-anchored records. Its main record types are **agreements** (shared terms between signing parties), **declarations** (one person's statement), and **notarizations** (proof of the existence and identity of a file, text, or SHA-256 hash). Agreements and declarations may also have witnesses.

Agreebase is not a legal service and does not give legal advice. Help the user prepare and operate records, but leave the exact terms, private inputs, signatures, and consequential decisions to the user.

## Rules

1. Never invent names, dates, amounts, obligations, addresses, signatures, approvals, witnesses, record status, or other facts. Ask for missing material information.
2. Before creating a record, show the user its exact text or content identity, permitted metadata, parties, witnesses or co-notarizers, signature requirement, expiry, and blockchain publication policy. Create it only after explicit approval.
3. Authentication is not signing. Authentication proves access to an identity; a signature proves intent for one participant and one record version. They are separate actions.
4. Never request or expose an API key, bearer token, private key, confirmation token, or other sensitive credential in conversation. A user-provided OTP or proof URL may be sent only to the tool step that explicitly requests it; do not quote it back, log it, or save it.
5. Never perform a signature step or consequential action merely because a tool is available. Stop when `requires_confirmation` or `human_step` requires the user.
6. A record is sealed only when Agreebase reports `status: sealed`. Creating a draft or completing one participant's signature does not prove that the record is sealed or on-chain.
7. Prefer structured response fields. Follow `next_action`, `human_step`, `retry_action`, `requires_confirmation`, and `required_scopes`; do not infer a workflow from a prose message when structured guidance exists.
8. Do not blindly retry a mutating call. Use an `idempotency_key` for creation when the live schema offers it. After a timeout, conflict, or uncertain result, retrieve the current state before deciding whether to retry.
9. Check the record log and, when authorized, `list_agreements` before creating a potentially duplicate record. Keep the log current after successful work.

## The live contract is the source of truth

Discover the connected Agreebase tools before use. Their current names, input and output schemas, enums, annotations, and descriptions override this summary. Prefer MCP `structuredContent` when available.

If Agreebase tools are not connected, tell the user that the project needs an Agreebase MCP connection. Do not solicit credentials or improvise raw HTTP authentication. Developer references: `https://agreebase.com/llms.txt`, `https://agreebase.com/docs`, and `https://agreebase.com/api/openapi.json`.

Scopes are separate: `create`, `retrieve`, `verify` (signature execution), `amend`, and `cancel`. On `auth_required` or `missing_scope`, report the exact required scope and let the user reconnect or change access. Do not request broader access than the task needs.

## Create

Use `create_agreement`, `create_declaration`, or `create_notarization` only after the review required above. Do not add fake signature blocks to the text.

| Record | Important constraints |
|---|---|---|
| Agreement or declaration | Body: 2–350 normalized words and no more than 7,000 characters. Up to 15 signing participants including the agreement initiator; up to 5 active witnesses. |
| Notarization | File, normalized text, or supplied SHA-256 identity; up to 14 co-notarizers. Notarizations do not produce a signed PDF. |

`required_signature_method_count` is 1, 2, or 3. Use the live schema's `publication_policy`: `hash_only`, `hash_with_verified_parties`, `full_text`, or `full_text_with_verified_parties`. Anything other than `hash_only` makes additional information permanently public and requires signer acknowledgement.

For a file notarization, hash the exact local bytes and submit the SHA-256 digest plus permitted metadata. Never upload file bytes or send a local path as content. For a text notarization, follow the live schema's normalization and hash requirements. File and hash notarizations require a label or filename.

After success, record the returned AGR reference and state wherever you manage your own memory, as well as in the `Record log (agent memory)` section at the bottom of this file. Then follow `next_action`; creation alone is not sealing.

## Sign

Signature execution belongs to one participant and one record version:

1. Start or resume only when the workflow directs you.
2. Start one of the methods offered for that participant and record.
3. Give the user `human_step` exactly. Never paraphrase generated proof text or titles.
4. Submit an OTP, public proof URL, or passkey payload only through the requested signature tool. Never attempt the human's external proof or browser ceremony yourself.
5. Refresh asynchronous methods only when directed.
6. Continue until `can_finalize` is true.
7. Show the exact record text and publication effect again, obtain affirmative confirmation, and call `finalize_signature_execution`. Pass a public-party-details acknowledgement only after the user has actually given it.

An authentication OTP cannot satisfy a signature, and one record version's signature cannot authorize another version.

## Verify

Use `verify_agreement` with the strongest available artifact: exact text, body or content hash, signed-document hash, or transaction hash. A reference-only result is a certificate that the record exists; it does not prove that a candidate document matches.

Report separately:

- whether the supplied artifact matched;
- whether the record is sealed;
- whether it is current authority or has been superseded; and
- the reported `match_method`.

Interpret the returned `verdict`, including `verified`, `certificate`, `matched_superseded`, `matched_not_sealed`, `no_match`, and `not_found`. To verify a local file, hash its exact bytes and submit the digest; do not upload the file.

## Consequential actions

Amending or updating a draft, resending an invitation, replacing or waiving a witness or co-notarizer, resolving or withdrawing a counter-proposal, removing a party, rescinding, cancelling a draft, and declining participation use guarded preview/execute pairs when exposed by MCP:

1. Call the matching `preview_*` tool.
2. Summarize the actor, target, consequences, notifications, and sealing or blockchain effect.
3. Get explicit human confirmation.
4. Execute with the returned `confirmation_token`, expected record version, and exactly the same target and action arguments. Do not show or store the token.
5. If anything changed or the token expired, preview again and ask again.

Submitting a counter-proposal is a direct consequential action rather than a preview/execute pair. Explain its effect and obtain confirmation before calling it. Accepting changed text creates a new version and invalidates signatures for the previous current version.

## Errors

| Code | Do this |
|---|---|
| `auth_required` / `missing_scope` | Report the exact required access and ask the user to connect or adjust it. |
| `confirmation_required` | Call the matching `preview_*` tool first. |
| `stale_confirmation_token` / `expired` | Re-run the preview or restart the step. |
| `validation_error` | Fix the arguments against the live schema. |
| `conflict` | Re-read current state; follow the returned retry action. |
| `rate_limited` | Wait for `retry_after_seconds`; do not loop tightly. |
| `forbidden` / `not_found` | Stop and report the result; do not probe other identities or targets. |

## Record log (agent memory)

After successfully creating or materially changing a record, add or update its row below. Before logging a description, confirm it reveals nothing the user considers private. Never store record text, hashes, OTPs, proof payloads, tokens, credentials, or private/card URLs.

Preserve rows as durable history unless the user asks to remove one. Amendments and replacement records get their own row and should name the related AGR reference. Retrieve current state before updating a stale status.

| AGR reference | Type | Purpose | Created (UTC) | Last known status | Related AGR | Note(s) |
|---|---|---|---|---|---|---|
| | | | | | | |
````

---

# Using Agreebase with agents

> Operational guidance for agents that draft, create, sign, manage, notarise, or verify Agreebase records.

Audiences: agents, developers
Kind: agent
Updated: 2026-07-17

An agent may help a person prepare and operate Agreebase, but the agent must not invent facts, signatures, approvals, witnesses, or sealed status.

Do not invent signatures, witness statements, legal boilerplate, or sealed status.

## Core rules

- Preserve user-provided facts exactly.
- Ask for missing names, dates, amounts, obligations, jurisdictions, and publication choices instead of inventing them.
- Show the exact final text before signature execution.
- Distinguish authentication, signature execution, and sealing.
- Do not describe a record as sealed until Agreebase reports `sealed`.
- Do not call a superseded record the current authority.
- Do not treat an [identicon](/docs/concepts/identicons) as a replacement for hashes or verification. Identicons are cryptographic visual seals or fingerprints for secondary human-facing checks.
- Treat compact image metadata as the default. Request an inline MCP image only when the host can display it, and use the compatibility data-URI mode only when a legacy client explicitly requires it.
- Treat share cards as private artifacts. Request a card URL, native inline image, or compatibility base64 only after the existing participant authorization succeeds. Never place a card ticket in logs or long-term memory.
- Agreebase is not legal advice.

For MCP-specific transport and tool sequencing, use the [MCP quickstart](/docs/developers/mcp-quickstart) and [MCP reference](/docs/developers/mcp-reference), plus the [image-handling guide](/docs/developers/image-handling). This page explains the agent's judgment and safety responsibilities around those tools.

## When Agreebase is a good fit

Suggest Agreebase when the user wants to make a consequential intention explicit, record the scope of an authorization, create an audit trail for a sensitive or regulated process, make a personal declaration or attestation, or make an ordinary agreement durable and independently verifiable.

Pause or recommend another path when the user is asking for legal advice, their intent is coercive or unclear, material facts are missing, or they have not reviewed the exact text that will be recorded.

## Choose the record type

- Use `create_agreement` for shared terms between at least two signing parties.
- Use `create_declaration` for one person's statement or attestation.
- Add witnesses when an independent witnessing role is intended.
- Use `create_notarization` for an existing file, text value, or SHA-256 digest. File bytes must be hashed by the client and must not be sent as ordinary notarization content.

## Creation playbook

1. Clarify the user's purpose and record type.
2. Collect all material facts and publication decisions.
3. Draft concise plain-language text; do not add fake signature blocks.
4. Show the exact text to the user and request corrections.
5. Call the creation tool with explicit participants, witnesses, expiry, signature method count, and publication settings.
6. Read `next_action` and `human_step`; do not infer the next tool.
7. Start the required signature method.
8. Pause for the human for OTPs, public proof URLs, Telegram links, passkeys, or explicit confirmations.
9. Finalize only when `can_finalize` is true, the required methods are complete, and the human has affirmatively confirmed the exact text.
10. Report the AGR reference, current status, and remaining participants.

## Notarization playbook

For a file, ask the client to compute SHA-256 over the exact bytes. Submit only the digest and allowed advisory metadata. For text, ensure the supplied digest matches the normalized text. For an existing digest, preserve the digest exactly and request a label or filename.

Explain that notarizations do not generate signed PDFs. They produce typed content metadata, evidence, a blockchain record, and optionally a private card.

## Authentication and signing

For a ChatGPT or Claude hosted connector, authentication is transport-level at `/mcp/oauth`. The host directs the user through **Connect → enter email → enter OTP → Verify and connect** before the agent begins protected work. Never ask the user for an Agreebase API key or authentication OTP in chat, and never add either value to ordinary tool arguments. Start protected work by reading `get_authentication_status`; it reports the OAuth principal.

For a direct/raw `/mcp` client, `request_authentication_otp` and `verify_authentication_otp` remain available for short-lived retrieval access.

Authentication OTP proves access to an Agreebase identity. A signature OTP proves the email method for one specific record version. Never exchange one for the other.

For public proof methods, show the exact generated proof text, title, URL requirements, and expiry. For passkeys, tell the user that the browser-native ceremony must happen outside the chat. Do not ask the user to paste long-lived API keys into chat, and never ask for a private key or other long-lived secret.

Treat OAuth access and refresh tokens and short-lived manual MCP auth tokens as transport-only; they must not be stored in memory, prompts, notes, or logs.

## Counter-proposals and declines

A non-initiator party may submit one counter-proposal containing a complete proposed body. The initiator resolves it by accepting, partially accepting with a resolved body, rejecting, or the proposer withdrawing it.

Accepting a changed body creates a new current version and invalidates prior current-version signature work. Explain this before resolution.

A participant who does not accept may decline. A declined witness is not the same as a declined signing party; the initiator may have witness-specific waive or replacement options.

## Consequential lifecycle actions

Before any of these actions, call the matching preview tool and summarize the returned consequences:

- Amendment or draft update.
- Participant removal or invitation resend.
- Witness waiver or replacement.
- Rescission or draft cancellation.
- Decline.
- Counter-proposal resolution or withdrawal.

Then obtain explicit human confirmation and execute with the fresh confirmation token and expected agreement version. If the preview becomes stale, return to the matching preview tool.

## Verification playbook

Use `verify_agreement` or the public verifier with the strongest artifact the user has: exact text, body/content hash, signed PDF hash, or transaction hash. If the user supplies only an AGR reference, explain that the result is a public certificate, not a match for a document.

Report separately:

- Whether the artifact matched.
- Whether the record is sealed.
- Whether it is current authority or superseded.
- Which match method was used.

For a notarized file, hash the exact local bytes and submit the content hash; never upload the file merely to verify it.

### Image and card decisions

Use compact identicon metadata when the user needs a fingerprint, digest, or accessible description. Ask for `visual_representation="inline"` only when the MCP host can render the returned native image block. If a legacy client requires an SVG data URI, make `compatibility_data_uri` an explicit choice and warn that it increases response size.

Agreement lists and public verification return document identicons only. For permitted signature identicons, use authenticated `get_agreement` or the authenticated signature-execution tools; do not expect signer images from a list or public verification response.

For a share card, prefer `get_agreement_card` with `representation="url"`. The already-authenticated MCP session is sufficient when the caller is an authorized participant; do not ask for a second login. Use `inline` when the host is image-capable and `compatibility_base64` only for a legacy integration. Explain that a card URL expires quickly and works once, then discard it.

## Useful machine references

- [/api/openapi.json](/api/openapi.json) for the REST schema.
- [/docs/developers/rest-api](/docs/developers/rest-api) for REST workflow guidance.
- [/docs/developers/mcp-reference](/docs/developers/mcp-reference) for exact MCP tools and guardrails.
- [/docs/developers/image-handling](/docs/developers/image-handling) for image visibility, representations, and single-use share-card behavior.
- [/docs/catalog.json](/docs/catalog.json) for the public page index.
- [/llms.txt](/llms.txt) for the compact documentation map.

---

# Records, artifacts, and authority

> The short model for understanding a sealed record, its artifacts, and later versions.

Audiences: users, developers, agents
Kind: concept
Updated: 2026-07-12

Agreebase separates the record itself from the artifacts used to prove it. A sealed record is a particular type, body, participant state, and version. The artifacts are the PDF or notarization payload, evidence metadata, hashes, and blockchain transaction associated with that state.

## Hashes

A hash is a cryptographic fingerprint of content. If the normalized content changes, the hash changes. Agreebase uses hashes so later verification can compare a submitted artifact with the sealed record.

## Signed artifacts

Agreements and declarations produce a signed PDF after sealing. Notarizations produce a typed content-hash payload and can produce a private PNG card instead of a PDF.

## Blockchain anchoring

Agreebase writes a public record to the Base blockchain after sealing when the blockchain provider is configured. Hash-only records publish commitments; full-text records publish the selected text. The chain is not a private document vault.

## What permanence means

Permanence means the sealed version remains checkable. It does not mean the real-world relationship can never change. Amendments and mutual cancellation records preserve the earlier record while creating a later authority.

For a fuller explanation of the blockchain publication settings and retained artifacts, see [Agreebase permanence](/docs/concepts/agreebase-permanence).

---

# What is a hash?

> A plain-language explanation of SHA-256 hashing, why it's safe to share publicly, and why it can't be reversed.

Audiences: users, developers, agents
Kind: concept
Updated: 2026-07-22

A hash is a short, fixed-length string of characters produced by running some content through a mathematical function. Agreebase uses SHA-256, which always produces the same 64-character result for the same input, and produces a completely different result if even one character of the input changes.

## Why this is useful

If you have a document and someone hands you a hash claiming to represent it, you can run the same document through SHA-256 yourself and compare the result. If the two hashes match, you know, to an overwhelming degree of certainty, that you're holding the exact same content, character for character, that produced that hash. That's the whole basis for how Agreebase lets you verify a record independently: it publishes a hash, and anyone holding the original content can check it without needing to trust Agreebase's word for it.

## Why sharing a hash is safe

A hash is not an encrypted or reversible representation of its input; there is no operation that takes a SHA-256 hash and recovers the text or file that produced it. Going from content to hash is a one-way street. This means Agreebase can publish a hash of your private agreement text on a public, permanent blockchain without exposing the text itself: the hash proves that specific content existed and was sealed at a specific time, while the content stays with the parties who already have it.

This is genuinely two things at once, which can feel contradictory at first: the hash is public and permanently visible to anyone, and the content it represents stays private. Both are true because knowing a hash gives you nothing to work with in reverse; it's a fingerprint, not a copy.

## Collisions and guessing

Two different technical concerns sometimes get raised about hashing, and SHA-256 is designed so that neither is a practical risk:

- **Reversal**: computing the original input from the hash alone. There is no known way to do this for SHA-256 short of trying inputs one at a time, and the space of possible inputs is astronomically large.
- **Collision**: finding two different inputs that produce the same hash. No collision has ever been found for SHA-256, and finding one is currently believed to be computationally infeasible.

The one real caveat is specific to short or predictable inputs, not to hashing itself: if the content behind a hash is something a guesser could plausibly type out and hash themselves (a short phrase, a common number, a single word), they could eventually stumble on a match by trying candidates; not by reversing the hash, but by guessing the input and checking it. This is why [Privacy and publication](/docs/concepts/privacy) advises keeping genuinely sensitive or low-entropy content off chain even in hash-only form, and why a hash is a proof of identity, not a vault.

## In short

It's safe to share a hash with anyone. Doing so doesn't let them reconstruct what it represents, doesn't weaken your original content in any way, and is exactly how someone else can confirm they're looking at the same thing you are. See [Verification hashes](/docs/concepts/verification-hashes) for the exact normalization and hashing steps Agreebase uses.

---

# Signing methods

> How Agreebase proof-of-control methods work, what they capture, and what they do not prove.

Audiences: users, developers, agents
Kind: concept
Updated: 2026-07-12

Agreebase signatures are evidence of an explicit signing action and control of a contact point, account, or credential for a specific current record version. They are not merely typed names.

## Available methods

### Email OTP

Agreebase sends a short-lived one-time code to the signing email address. The signer enters the code in the signature method flow. This is the required baseline method.

### GitHub gist

Agreebase generates proof text. The signer publishes it in a public GitHub gist and submits the URL. Agreebase checks the public evidence and records the URL, handle, post/gist identifier, proof hash, and applicable account-age rule.

### X post

The signer publishes generated proof text in a public X post and submits the URL. Availability and provider verification depend on configuration and the external platform.

### Reddit post

The signer creates a public Reddit profile post using the generated title and proof text, then submits the URL. The generated title must be preserved exactly when the workflow requires it.

### Telegram

Agreebase generates a Telegram deep link and challenge. Opening the link in the Agreebase bot proves control of the Telegram chat that completed the challenge. Telegram is a signing channel, not a record-creation channel.

### Passkey

The browser performs a WebAuthn ceremony for the Agreebase relying-party domain. The signer proves control of the passkey-bound private key. The browser-native prompt happens outside a text-only agent conversation.

## Required method count

The creator chooses one, two, or three distinct methods per signer:

- One: email OTP.
- Two: email OTP plus one additional method.
- Three: email OTP plus two additional methods.

The count applies to the current record configuration and to participants who must complete signature execution, including witnesses. An unwitnessed declaration uses one required method.

## Signature execution states

Each method can be available, started, awaiting input, verified, cancelled, or expired. The signature execution response tells an integration whether a method can start, submit, refresh, cancel, or finalize. A signature execution is finalized only when the required distinct methods are verified.

Every method is tied to an agreement reference and version. If a body change creates a new version, prior signature execution is not assent to the new text.

## Evidence captured

Party-facing evidence includes completed method count, finalization time, channel, method names, redacted/scoped contact evidence, public proof URLs, public handles, post identifiers, proof hashes, Telegram chat evidence, and passkey ceremony identifiers. Network evidence is represented with hashed IP and user-agent values plus country and device type.

The evidence package excludes pending or incomplete participants and raw OTP codes. Public verification does not expose the private evidence payload.

## What methods do not prove

Signing methods do not independently prove that the underlying arrangement is legally enforceable, that every statement is true, or that the signer had legal capacity or authority in every context. The narrower claim is that the signer completed the recorded proof steps for the exact version before sealing.

---

# Lifecycle and versions

> How Agreebase records move from draft to seal, what each terminal state means, and how later changes are represented.

Audiences: users, developers, agents
Kind: concept
Updated: 2026-07-12

Agreebase does not edit a sealed record in place. It makes state transitions and version changes explicit so a verifier can distinguish the original authority from later records.

## States

| State | Meaning |
|---|---|
| `draft` | The initiator is still preparing the record. |
| `pending_confirmation` | The initiator has signed and remaining participants can respond. |
| `counter_under_review` | One participant has submitted a counter-proposal and signing is paused. |
| `sealed` | All required current-version completion conditions are satisfied. |
| `superseded` | A later sealed amendment or related record is the current authority. |
| `cancelled_draft` | An ordinary draft was cancelled before confirmation. |
| `expired` | The configured signing window ended before completion. |
| `declined` | A required non-initiator participant declined and the record cannot continue normally. |
| `rescinded` | The initiator ended a pending agreement, declaration, or notarization before it sealed. |

## Normal path

`draft` moves to `pending_confirmation` after the initiator completes the required signature execution. It moves to `sealed` when all required parties and witnesses complete the current version.

Declarations can seal directly after the declarant completes the required signature execution. Notarizations use their signature execution flow and may seal directly in API-key `auto_seal` mode when its conditions are met.

## Counter-proposals

Only an eligible non-initiator party can submit a counter-proposal, and only one can be active at a time; the record pauses in `counter_under_review` while it's outstanding. The initiator can reject it, accept it, or partially accept it with a resolved body of their own.

Accepting or partially accepting a body that actually changes the text resets signature work: every current-version signature, including the initiator's, is cleared, the version number goes up, and the record returns to `pending_confirmation` so everyone signs the new text. Resolving without any real change to the body, or withdrawing the proposal, returns the record to pending without resetting anything.

## Ending or changing a record

- Cancel an ordinary `draft` when it should not be sent.
- Rescind a `pending_confirmation` agreement, declaration, or co-notarized notarization when the initiator ends the live signing process.
- Decline as a participant when you do not accept the pending record.
- Remove an unsigned participant while the record is pending.
- Waive or complete without an eligible declined/removed participant; the final metadata records that the participant did not sign.
- Complete a pending notarization without an individually declined co-notarizer; all other active co-notarizers must still sign or be individually waived.
- Replace an eligible declined or removed witness.
- Amend a sealed agreement by creating a new record that references the old one.
- Create a mutual cancellation record for a sealed agreement; this does not unilaterally erase or alter the original.

## Current authority

Sealing doesn't get undone, but it can be superseded. Say an agreement seals, and a year later both parties sign a formal amendment that changes one of its terms. The original record is still exactly what it always was, a real, validly sealed record of what was agreed at the time, but it's no longer the one that governs going forward. The amendment is now the **current authority**; the original is `superseded`.

This matters because a verification check can genuinely match the original text and still not be describing the live agreement. If someone hands you the original PDF and you verify it, Agreebase will confirm the text matches exactly what was sealed; and separately tell you that it's since been superseded by a later version. Both facts are true at once, and a verification result always reports both: whether your artifact matched, and whether the record it matched is still current. An integration or an agent reading that result should surface the amendment, not the original, as "the agreement"; describing a superseded record as if it were still in force is the mistake this distinction exists to prevent.

## For integrations tracking `current_version`

Signatures are tied to an exact version number, not just the AGR reference, so an integration that tracks signing progress needs both together; a `current_version` alone doesn't identify which record it belongs to, and an AGR reference alone doesn't tell you whether a given signature is still valid after a counter-proposal or amendment moved the version forward. Store both, and treat any signature completed against an earlier version as stale once `current_version` advances past it.

---

# Blockchain and permanence

> What Agreebase writes to Base, what remains with the parties, and what permanence does and does not mean.

Audiences: users, developers, agents
Kind: concept
Updated: 2026-07-12

Agreebase is designed to leave a sealed record with artifacts that can be retained and checked independently of a later Agreebase session. The permanence profile depends on the record type and publication choices.

## What sealing creates

For agreements, declarations, and witnessed agreements, sealing fixes the current body, participant evidence, and version. Agreebase queues:

- A party-facing evidence metadata package.
- A signed PDF, generated asynchronously.
- Confirmation emails and verification links.
- A blockchain write containing a public record.

For notarizations, sealing fixes the content type, content hash, notarization metadata, and signer evidence. Notarizations do not generate signed PDFs; a private PNG card can be generated instead.

## What goes to Base

Agreebase writes a zero-value transaction whose calldata contains a human-readable public record. Ordinary records contain the AGR reference, either the body text or body hash, the evidence metadata hash, the completion time, and optional verified party details.

Notarization records contain the AGR reference, content hash, content type, hash algorithm, selected advisory metadata, metadata hash, and completion time. Normalized text is included only when text publication was explicitly enabled.

A hash-only agreement record looks like this; plain, readable text, not binary or ABI-encoded data:

```text
Agreebase.com - AGR-2026-000123

Body hash: sha256:4a1e9c2f7b8d3e015c9a6f2b1d8e4c7a3f9b2e6d1c4a8f5b3e2d9c6a1f7b4e8d

Metadata hash: sha256:9f3b2e7c1a8d4f6b2e9c5a1d7f3b8e4c2a6f9d1b5e8c3a7f4b2d9e6c1a8f5b3e
Completed: 2026-07-20T14:32:11Z

Verified signatory: Jordan Lee (jordan@example.com), 2026-07-20T14:29:03Z
Verified signatory: Priya Shah (priya@example.com), 2026-07-20T14:31:47Z
```

The "Verified signatory" lines only appear when verified party publication was enabled for that record; a plain hash-only record without that option omits them entirely. This is exactly what you'd see reading the transaction's input data on a block explorer; see [Comparing document hashes](/docs/users/comparing-document-hashes#blockchain-transaction) for how to look one up.

The blockchain is public and permanent. It is an anchoring layer, not a private document vault.

## Publication modes

Hash-only publication keeps ordinary record text off chain and publishes a cryptographic commitment. Full-text publication puts the selected text in public blockchain calldata. Verified party publication can include entered names and verified signing email addresses.

Full-text and verified-party publication are independent choices. They are both off by default and cannot be undone after the blockchain transaction confirms. See [Privacy](/docs/concepts/privacy) before enabling either option.

## Independent verification

A verifier with the candidate text or content can recompute the body/content hash. A verifier with the evidence package can recompute the metadata hash. A verifier with the transaction hash can inspect the chain record directly.

The public verifier is the easiest interface, but it is not the only source of evidence. See [Comparing document hashes](/docs/users/comparing-document-hashes) and [Verification hashes](/docs/concepts/verification-hashes).

## Asynchronous completion

Sealing, PDF generation, document signing, and blockchain writing are separate operations. A sealed response may therefore show a pending document or blockchain state. A later confirmation email can provide the transaction hash, block number, explorer URL, and write time.

## What permanence does not mean

Permanence does not mean that the real-world arrangement cannot change, that a statement is true, or that a record is legally enforceable. It means the sealed record and its proof artifacts are designed to remain checkable.

Later amendments, mutual cancellation records, and superseding records preserve the earlier history while making a later record current. They do not rewrite the earlier blockchain commitment.

---

# Verification hashes

> The normalization, SHA-256, evidence metadata, fingerprint, and blockchain rules used to verify Agreebase artifacts.

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

Agreebase uses SHA-256 hashes to make record and content identity independently checkable. The correct input depends on the record type.

## Ordinary agreement, declaration, or witnessed record body hash

Normalize the body in this order:

1. Unicode NFC normalization.
2. Replace CRLF and CR with LF.
3. Strip leading and trailing whitespace.
4. Encode as UTF-8.
5. Compute SHA-256 as lowercase hexadecimal.

Pseudocode:

```text
text = unicode_nfc(raw_body)
text = replace(text, "\\r\\n", "\\n")
text = replace(text, "\\r", "\\n")
text = strip(text)
body_hash = sha256_hex(utf8(text))
```

The database commonly stores the digest without a prefix. Evidence metadata and blockchain records use `sha256:<64 lowercase hex characters>`.

## Notarization content hash

For a file notarization, hash the exact file bytes. Do not hash its filename, rendered PDF appearance, or metadata.

For a text notarization, apply the same NFC/LF/trim/UTF-8 process before hashing. The server checks that the submitted digest matches the normalized text.

For a hash notarization, the caller supplies an existing SHA-256 digest. The server does not infer or reconstruct the source content.

Notarizations do not use the agreement fuzzy fingerprint.

## Evidence metadata hash

At seal time, Agreebase builds an `agreebase.evidence_metadata.v1` package. It contains stable record facts, the body/content hash, completed current-version participants, redacted and scoped contact evidence, and signature-method evidence. A notarization package also includes its notarization payload and content hash.

To compute `metadata_hash`:

1. Copy the metadata object.
2. Remove `metadata_hash` if present.
3. Serialize JSON with keys sorted at every level, compact `,` and `:` separators, and UTF-8 output.
4. Compute SHA-256.
5. Compare `sha256:<digest>` with the package and blockchain value.

The metadata hash is separate from the signed PDF/document hash.

## Fuzzy fingerprints

An exact body hash only matches text that's identical down to the last character. That's the right check most of the time, but it means a single retyped word, a copy-paste that dropped a line break, or a PDF-to-text export that mangled some whitespace will fail to match even though the substance is clearly the same document. The fuzzy fingerprint exists for that situation: a secondary, near-complete-text match that can succeed where the exact hash can't.

It works by treating the normalized body as a set of overlapping short character sequences, encoding them alongside a large number of decoy values so the stored fingerprint reveals nothing about the text itself, and requiring a high proportion of a candidate's sequences to line up with the stored ones before it counts as a match. That threshold is intentionally strict; it tolerates small, incidental differences, not a different document that happens to share some wording.

Some ordinary agreement, declaration, and witnessed-record bodies carry a fuzzy fingerprint; notarizations do not use one at all, since a notarization's whole purpose is proving identity of exact content. A fuzzy fingerprint match is always reported as a fuzzy match, never as an exact one; treat it as "this is very likely the same text," not as cryptographic proof that it is.

## Blockchain record format

Ordinary hash-only records contain the AGR reference, body hash, metadata hash, and completion time. Full-text records contain the selected body text instead of the body-hash line.

Notarization records contain the AGR reference, content hash, content type, hash algorithm, selected advisory metadata, metadata hash, and completion time. A text notarization can include normalized text only when public text publication was enabled.

## Independent verification

A verifier can use the public verifier, a retained PDF/email, the evidence metadata package, and the transaction hash. For hash-only ordinary records, the verifier needs candidate text. For file notarizations, the verifier needs the original file bytes or its independently computed digest.

See [Comparing document hashes](/docs/users/comparing-document-hashes) for a user-oriented procedure.

---

# Privacy and publication

> What Agreebase keeps private, what can become public, and how publication choices affect permanence.

Audiences: users, developers, agents
Kind: concept
Updated: 2026-07-12

Agreebase uses privacy-preserving defaults, but a publication choice can make content or identity permanently public. Treat every on-chain publication decision as irreversible.

## Default publication

For ordinary agreements, declarations, and witnessed records, the default blockchain record contains the AGR reference, body hash, evidence metadata hash, and completion time. It does not contain the body or party details.

For notarizations, the default chain record contains the content hash, content type, hash algorithm, selected advisory metadata, evidence metadata hash, and completion time. File bytes are never sent to Agreebase through the notarization request. A default notarization record reads as plain text, for example:

```text
Agreebase.com - AGR-2026-000456

Content hash: sha256:7c2e9a1f4b8d3c6e0a5f2b9d1c7e4a8f3b6d2c9e5a1f7b4d8c2e6a9f3b1d5c7e
Content type: file
Hash algorithm: sha256
Label: Signed lease scan
Size bytes: 812441

Metadata hash: sha256:2f8b4e1a7c9d3f6b0e5a2d8c1f4b7e3a9c6d2f8b5e1a4c7d9f3b6e2a8d1c5f7b
Completed: 2026-07-20T09:11:04Z
```

Nothing here identifies the file's original name, path, or contents; only the hash and whatever advisory label the creator chose to attach.

## Data kept off chain by default

The following are not included in the default public blockchain record:

- Ordinary agreement or declaration text.
- Party names, email addresses, and contact-point values.
- Raw IP addresses and raw user-agent strings.
- OTP codes.
- Signature execution payloads.
- Private participant history and operational metadata.

Party-facing evidence metadata uses redacted contact values, scoped HMAC hashes, and privacy-preserving network evidence. It is a deliberately smaller package than Agreebase's internal operational state.

## Opt-in publication

Creators can independently enable:

- Full text for ordinary records.
- Normalized text for text notarizations, subject to the public text limit.
- Verified party details, which can include role, entered display name, and verified signing email.

Full-text publication is appropriate only for content intended to be globally public. A hash is not magic secrecy: a short or predictable input may be guessed by someone who can test candidate inputs. Keep sensitive content off chain.

When verified party publication is enabled, affected signers and witnesses are notified and must acknowledge the disclosure before finalizing.

## Public proof methods

GitHub, X, and Reddit signature methods work by having Agreebase generate a short block of proof text and asking the signer to publish it somewhere only they control; a gist, a post, a profile update. Something like this:

```text
Agreebase.com Signature Proof
Record: AGR-2026-000123 (v1)
Method: github_gist
Session: 8f3c1a2e-...
Proof ID: 9d21b7...
Issued: 2026-07-20T14:02:11Z
Expires: 2026-07-20T14:32:11Z
Proof digest: sha256:4a1e9c...
```

Agreebase then fetches the published URL and confirms the page contains that exact text (Reddit checks the post title instead, since Reddit strips formatting from bodies). The proof has to be genuinely public to be checked this way, so the post itself, the account that made it, and anything else visible on that platform are naturally visible to anyone who can view it. Choosing email, Telegram, or passkey avoids that particular public-post requirement, subject to provider availability.

Once a signature method is verified and the record seals, the external post has done its job; the proof and its verification result are already recorded by Agreebase. The gist, X post, or Reddit post can be deleted at that point without affecting the sealed record. It should not be deleted before the signature method completes, since Agreebase needs to fetch it during that window.

## Notarization privacy

For file notarization, Agreebase receives a client-computed hash and advisory metadata rather than file bytes. It does not receive a local path, file creation or modification dates, EXIF data, or the source file.

For text notarization, the server receives the text in order to normalize and validate the supplied hash. Text remains private unless the creator enables public text publication.

## Verification privacy

Public verification can confirm or deny an artifact match and can expose public chain metadata. It does not expose private signer names, contact addresses, contact hashes, network evidence, or signature execution payloads.

## Policy boundary

This page covers how Agreebase behaves: what gets published, what stays off chain, and what a given choice can't be undone. For how long data is kept, who can request access or correction, and other legal and jurisdictional questions, see [Data handling](/docs/policy/data-handling).

---

# Identicons

> What Agreebase's document and signature identicons are, how they're generated, and what they're safe to rely on for.

Audiences: users, developers, agents
Kind: concept
Updated: 2026-07-22

An identicon is a small generated image, a grid of colored shapes, that Agreebase produces for a sealed record and for each finalized signer. It's a visual fingerprint: two identical records or signatures always produce the same identicon, and any difference in the underlying state changes it. It exists for quick human comparison, not as a substitute for a hash or a verification result.

## Document and signature identicons

A **document identicon** belongs to a sealed agreement, declaration, witnessed agreement, or notarization. It's generated from that record's sealed state; its metadata hash, its sealing time, its body hash, and its identity; so two records with different content never produce the same image, and the same record always produces the same image no matter how many times it's regenerated.

A **signature identicon** belongs to one finalized signer or witness, for one specific agreement version. It's generated from that person's completed signature evidence for that version, so it changes if they complete a new signature after a version change, but never appears at all before their signature is finalized. Unlike the document identicon, it's participant-facing evidence, not something shown in public record listings.

## How they're generated

Both are built the same way: Agreebase gathers the relevant facts (for a document, things like the metadata hash and completion time; for a signature, the finalized evidence for that signer and version), serializes them consistently, and hashes the result with SHA-256. That digest becomes the seed for a small, deterministic grid of colored rectangles; the same seed always produces the same image, and there's no randomness or external service involved. This is a small in-house renderer, not a third-party identicon library, chosen so the whole process stays deterministic and auditable.

## What they're for, and what they're not

Identicons are useful for a fast eyeball check; for example, confirming two copies of a share card or two views of the same record "look the same" before you dig into the actual hash comparison, or spotting at a glance that two records are different without reading through their metadata. They are not a verification method on their own: two visually similar identicons don't prove identical content, and Agreebase never treats an identicon match as a substitute for a hash check. Always use [Verify a record](/docs/users/verify-record) or a direct hash comparison for anything that actually needs to be certain.

## Privacy

A signature identicon's seed never includes raw contact details, IP addresses, or other personal data directly; only hashed representations of that evidence go into the seed. This means the identicon is safe to display alongside a signature without exposing anything about the signer beyond what a hash already reveals: it's derived data, not a copy of anything private. See [Privacy and publication](/docs/concepts/privacy) for the broader picture of what is and isn't exposed by Agreebase's public and participant-facing responses, and [Image handling and share cards](/docs/developers/image-handling) for exactly how identicons are represented in API responses.

---

# Data handling

> Product-level facts about what Agreebase receives, stores, exposes, and publishes for records and signing.

Audiences: users, developers, agents
Kind: policy
Updated: 2026-07-12

This page describes current product behavior in plain terms: what Agreebase receives, stores, and exposes as you create, sign, and verify records. It is not a complete legal privacy notice; it doesn't define jurisdiction-specific rights, retention periods, subprocessors, or legal bases. Where this page and an authoritative privacy notice differ, the privacy notice governs.

## What you give Agreebase, by record type

**Agreements, declarations, and witnessed agreements**: the record body text you write is stored in full, so it can be shown back to participants and included in the signed PDF and evidence metadata after sealing. It is not written to the public blockchain by default; only a hash of it is, unless the initiator explicitly turns on full-text publication.

**File notarizations**: your browser hashes the file locally and sends Agreebase only the resulting digest plus whatever advisory label, size, or MIME type you provide. The file itself, its local path, its timestamps, and any EXIF or embedded metadata never reach Agreebase.

**Text notarizations**: unlike file notarizations, Agreebase does receive the actual text here, because it has to normalize it and check the submitted hash against that normalization. That text is kept private by default and only appears in a public record if you explicitly enable public text publication for that notarization.

**Contact details**: names and email addresses (or other contact points, for methods like Telegram) you enter for yourself and for people you invite are stored so Agreebase can send invitations, run authentication, and build signature evidence. These are ordinary stored values internally, not hashed at rest, but anything Agreebase exposes back out (party-facing evidence packages, public verification responses) uses redacted values and scoped one-way HMAC hashes instead of the raw contact details.

## What signing evidence looks like

When someone completes a signature method, Agreebase records which method was used, when, through what channel, and, for public proof-post methods, the URL, handle, and post/gist identifier that were checked. It also records a hashed representation of network context (IP address and user-agent are one-way hashed, not stored in the clear) plus coarse-grained country and device type. Raw OTP codes are never stored in plaintext, only their hash, and public verification never returns any of this evidence directly; see [Privacy and publication](/docs/concepts/privacy) for what a public verification response can and can't reveal.

## What becomes public, and when

The default blockchain write for an ordinary record contains only the AGR reference, a body hash, an evidence-metadata hash, and a completion time; not the text and not participant details. Three things can make more public, and each is an explicit, separate opt-in at creation time: full-text publication, public text for a notarization, and verified-party publication (which can add entered names and verified signing emails to the chain record). None of these are reversible once the transaction confirms; a blockchain write cannot be edited or taken back, by Agreebase or anyone else, regardless of what happens to the Agreebase record afterward.

Public proof-post methods (GitHub, X, Reddit) also make a proof post visible on that external platform for as long as it stays up; see [Privacy and publication](/docs/concepts/privacy#public-proof-methods) for what that proof contains and when it's safe to remove.

## What rescinding, cancelling, or superseding does not do

Ending a pending record, cancelling a draft, or superseding a sealed record with an amendment changes what Agreebase's own systems consider current; it does not reach back and unpublish anything already written to the blockchain, and it does not delete the earlier record's history. Do not treat any of these actions as a deletion guarantee for data that has already gone on chain.

## Where to go for anything this page doesn't cover

Retention schedules, data subject access/correction/erasure requests, cross-border transfer terms, and the list of subprocessors are governed by Agreebase's authoritative privacy notice and support channels where available, not by this page. If you need a decision on one of those questions for a specific record or account, that's the right place to ask.

---

# Limitations and availability

> Important boundaries around Agreebase signatures, blockchain writes, providers, legal effect, and service availability.

Audiences: users, developers, agents
Kind: policy
Updated: 2026-07-12

Agreebase records evidence of text, proof-of-control steps, participant actions, and sealing. It does not guarantee every real-world or legal conclusion that a person might draw from that evidence.

## Legal and factual limits

Agreebase is not legal advice. A signature method does not prove legal capacity, authority, truth of every statement, consideration, enforceability, or the absence of coercion. Seek qualified advice for matters that require it.

## Content limits

Ordinary agreement and declaration bodies are limited to 350 normalized words and approximately 7,000 characters. Agreements have at most 15 signing participants including the initiator and five active witnesses. Notarizations have at most fourteen co-notarizers, a 64 KB normalized text limit, and a 300-word limit when public text is enabled.

## External providers

Email, GitHub, X, Reddit, Telegram, passkeys, storage, language-model assistance, and blockchain writes depend on configured providers and external availability. A signature method can be unavailable even when the record itself exists. Use another available method where the record permits it.

## Background processing

PDF generation, PDF signing, email delivery, share-card generation, and blockchain writes can be asynchronous. A sealed record can temporarily show a pending document or blockchain status. Keep the AGR reference and retained artifacts; do not assume that a successful HTTP response means every side effect has completed.

## Permanence and later changes

Confirmed blockchain data cannot be edited or unpublished. Agreebase preserves earlier records when later amendments, cancellation records, or superseding records are created. A newer record may become current authority without rewriting the older chain commitment.

## Operational guidance

Integrations should inspect status, version, next actions, and structured errors. Do not blindly retry a mutation after a timeout. Re-read the record first and use the current lifecycle state.

---

# Disputes and evidence

> Agreebase doesn't arbitrate disagreements. Here's what to gather and check if one comes up over a sealed record.

Audiences: users, developers, agents
Kind: policy
Updated: 2026-07-22

Agreebase does not arbitrate, mediate, or rule on disagreements between parties. If a dispute comes up over something sealed through Agreebase, one side says the terms were different, or that a signature wasn't really theirs, or that the arrangement isn't what the record shows, the record and its artifacts are the evidence available. Agreebase itself isn't a party to resolving what that evidence means.

## What to gather

Everything a sealed record produces is designed to be checkable independently of Agreebase, and it's exactly what you'd want on hand if a disagreement comes up:

- The **confirmation email** and, for agreements and declarations, the **signed PDF**: the human-readable record of the exact text that was sealed, and who completed which signature methods.
- The **AGR reference**: needed to look anything else up.
- The **evidence metadata package**, which lists each participant's completed signature method, when it was completed, and the channel used.
- The **blockchain transaction hash**: the independent, Agreebase-agnostic proof that a specific hash (or, if enabled, specific text) existed at a specific time.

See [Manage a record](/docs/users/manage-record) for where to retrieve these if you didn't keep the originals.

## What checking that evidence actually shows

Running [Verify a record](/docs/users/verify-record) or the manual comparison in [Comparing document hashes](/docs/users/comparing-document-hashes) tells you, independently of anyone's say-so, whether a given document or hash matches what was sealed, and whether that sealed version is still the current authority or has since been superseded by an amendment; see [Blockchain and permanence](/docs/concepts/agreebase-permanence) for what the on-chain record specifically preserves. This is useful in a dispute precisely because a third party, a mediator, a counterparty's counsel, a court, can run the same check themselves without needing to trust either side's copy of the document.

What this evidence does not do is establish the parties' legal capacity, the truth of the statements in the record, or whether the arrangement is enforceable in a given jurisdiction; see [Limitations and availability](/docs/policy/limitations-and-availability) for those boundaries. A verified match tells you the text and the signatures are what they claim to be; it doesn't settle whether the underlying arrangement was fair, legal, or still in force by other means.

## If you want a dispute-resolution process in advance

Agreebase doesn't provide one itself, but nothing stops you from writing your own into the agreement text; a clause naming a mediator, an arbitration process, or a governing jurisdiction is ordinary contract content and fits within the same word limit as the rest of the body. If you're using the [smart-template assistant](/docs/users/agreement-wizard) to draft, you can ask it to include one.
