# Agentic agreements · Integra

> An agentic agreement as Integra implements it, step by step: what it is, how it is created, what the buyer and the seller do with it during a purchase, and how anyone confirms it afterwards.

URL: https://integraledger.com/agentic-agreements

Agentic agreements

## How an agentic agreement is made and proved.

How Integra implements an agentic agreement, step by step: what it is, how it is created, what the buyer and the seller do with it during a purchase, and how anyone confirms it afterwards.

What it is

### One record of what was agreed, and a payment bound to it.

An agentic agreement is what a buyer’s agent and a seller’s agent commit to in one transaction. Integra implements it in three parts.

1. #### The Agentic Transaction Record (ATR)

   One document of exactly what was agreed, assembled for this transaction: the seller’s terms, the offer, and each party’s content as it was received. [Source: LCP §2.3⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#23-legal-terms-are-a-document) · [Source: lcp docs: the ATR⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/concepts/atr.md)
2. #### The ATR hash

   The SHA-256 of the ATR’s exact bytes: its unique fingerprint. Change one byte of the ATR and the hash no longer matches. [Source: LCP §2.5⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#25-optional-fields) · [Source: LCP §12.3⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#123-terms-versioning)
3. #### The payment

   The payment carries the ATR hash in a field it already has, so paying is agreeing to that exact ATR. [Source: lcp docs: binding⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/concepts/binding.md) · [Source: @integraledger/lcp README⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/lcp/README.md)

#### Agreements whose payment comes later, or never

A hotel is agreed at booking and paid at checkout; an order is agreed today and paid on net-30. The ATR exists before any payment does, and until one is made it stands as a proposal. A story told only about payments is a story about the smaller half of commerce. [Source: LCP §6.1⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#61-the-ephemeral-link-pattern)

**Sources (7)**

[LCP §2.3⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#23-legal-terms-are-a-document) · [lcp docs: the ATR⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/concepts/atr.md) · [LCP §2.5⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#25-optional-fields) · [LCP §12.3⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#123-terms-versioning) · [lcp docs: binding⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/concepts/binding.md) · [@integraledger/lcp README⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/lcp/README.md) · [LCP §6.1⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#61-the-ephemeral-link-pattern)

#### The standard

In the standard, the ATR is the terms document itself: a standalone, downloadable document whose SHA-256 is the discovery document’s `atrHash`. The packages assemble one for each sale, so each sale can carry its own terms. [Source: LCP §2.3⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#23-legal-terms-are-a-document) · [Source: LCP §2.5⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#25-optional-fields) · [Source: lcp docs: the ATR⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/concepts/atr.md)

An agreement paid later: the ATR exists, stored and linked, before any payment does. [Source: LCP §6.1⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#61-the-ephemeral-link-pattern) · [Source: lcp docs: the ATR⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/concepts/atr.md)

#### The data

Read from the published packages when the site was built; nothing here is typed by hand.

The example ATR’s exact bytes, as `@integraledger/lcp` assembled them when the site was built

872 bytes

```
{"atrVersion":"1","id":"3b4c7a2e-9f1d-4e6b-8a5c-2d7e1f0b9c34","x402":{"accepts":[{"scheme":"exact","network":"eip155:84532","amount":"40000000","asset":"0x036CbD53842c5426634e7929541eC2318f3dCF7e","payTo":"0x209693Bc6afc0C5328bA36FaF03C514EF312287C","maxTimeoutSeconds":60,"extra":{"name":"USDC","version":"2"}}],"request":{"method":"GET","path":"/v1/market-data","query":"","bodyDigest":"0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}},"terms":{"sold":"10,000 calls to a market-data API","licenceScope":"For internal use; the data may not be redistributed.","acceptableUse":"No resale and no attempt to identify individuals.","rateAndQuota":"At most 100 calls a minute, 10,000 calls in all.","dataRights":"Queries are kept for 30 days, then deleted.","limitationOfLiability":"Liability is capped at the amount paid.","governingLaw":"New York, USA"}}
```

Its ATR hash, H: the SHA-256 of those bytes

```
0x8448dc1b716a5103287cb8f35e36b614ffd91e630ab8b7911833c54748ad5ca6
```

How it is created

### Discovered, agreed, composed and hashed, for each sale.

1. #### Discover

   The seller publishes a legal front door, `/.well-known/legal-context.json`, and the terms an agent must inspect. [Source: LCP §2.1⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#21-well-known-uri)
2. #### Agree

   The buyer’s and the seller’s agents settle the price, the ways it can be paid and the terms that apply to this sale.
3. #### Compose

   The seller assembles the ATR for this sale: a version, an id, the payment options it can be paid by, and each party’s content exactly as received, never parsed or rewritten. [Source: lcp docs: the ATR⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/concepts/atr.md)
4. #### Hash and store

   The seller hashes the ATR’s exact bytes, which gives the ATR hash, and keeps the ATR at a link the buyer can fetch. Integra’s hosted appliance does this for a seller; the open package does it in the seller’s own code. [Source: LCP §2.5⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#25-optional-fields) · [Source: connectors docs: the seller door⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-agentic-connectors/blob/48500fe/docs/concepts/seller-door.md) · [Source: @integraledger/lcp README⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/lcp/README.md)

Because it is assembled per transaction, each sale can carry its own terms: a custom price, a negotiated clause, a private agreement served at a link that expires. [Source: LCP §6.1⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#61-the-ephemeral-link-pattern)

**Sources (6)**

[LCP §2.1⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#21-well-known-uri) · [lcp docs: the ATR⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/concepts/atr.md) · [LCP §2.5⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#25-optional-fields) · [connectors docs: the seller door⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-agentic-connectors/blob/48500fe/docs/concepts/seller-door.md) · [@integraledger/lcp README⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/lcp/README.md) · [LCP §6.1⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#61-the-ephemeral-link-pattern)

#### The standard

The ATR is one UTF-8 JSON object written in a fixed order: `atrVersion`, `id`, the binding slot, then each party’s content as the exact bytes received, never parsed, re-serialised or canonicalised. Its hash is SHA-256 over those bytes. [Source: lcp docs: the ATR⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/concepts/atr.md) · [Source: LCP §2.5⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#25-optional-fields)

#### The data

Read from the published packages when the site was built; nothing here is typed by hand.

A discovery document, the standard’s own full example

level-4-full.json

```
{
  "terms": "https://example.com/terms/v3.json",
  "termsFormat": "json",
  "atrHash": "0x7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069",
  "acceptanceRequired": true,
  "disputeResolution": {
    "method": "Dispute Resolution Service Rules",
    "jurisdiction": "New York, USA",
    "contact": "disputes@example.com",
    "clauseId": "sha256:0xc2eb26d28ff4e229ff35917bd53339d82c1b30ec69435572a8872a4d7609c1dd",
    "source": "https://adr.example.org/clauses/dispute-resolution-service-rules",
    "catalog": "https://adr.example.org/.well-known/dispute-services.json"
  },
  "returns": "https://example.com/api/returns",
  "contact": {
    "legal": "legal@example.com",
    "technical": "api-support@example.com"
  },
  "api": "https://api.example.com/legal-context/v1"
}
```

#### The code

Compiled against the published packages when the site is built.

The seller assembles the ATR, hashes it, and advertises the ATR hash

src/snippets/seller.ts

```
// The seller, for one sale: write the record, hash its exact bytes, and put the hash and the record's link in the
// x402 challenge it answers the request with.
import { assemble, hash, isRefusal, newAtrId } from '@integraledger/lcp';
import { exactEip3009, requestCommitment, tie, type HttpRequest, type PaymentRequired } from '@integraledger/lcp/x402';

export async function offer(
  challenge: PaymentRequired,
  request: HttpRequest,
  terms: Uint8Array,
  store: (bytes: Uint8Array) => Promise<string>, // your storage: it serves these exact bytes at the link it returns
) {
  const answered = await requestCommitment(request);
  if (isRefusal(answered)) return answered;
  const record = await assemble(newAtrId(), tie(challenge.accepts, answered), [['terms', terms]]);
  if (isRefusal(record)) return record;
  const h = await hash(record.bytes);
  const link = await store(record.bytes);
  return exactEip3009.advertise(challenge, h, link, challenge.accepts[0]!);
}
```

#### Check it yourself

1. Hash the ATR’s exact bytes with SHA-256: the result is the ATR hash, the `atrHash` the payment carries. [Source: LCP §2.5⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#25-optional-fields)

During the purchase

### The seller advertises it, the buyer checks it, the payment carries it.

Six steps, from the seller’s payment request to the settled payment. The buyer and the seller each act on the same ATR hash.

1. Seller

   #### Advertise

   The seller advertises the ATR hash and the ATR’s link beside its payment request, in the field its protocol defines. [Source: lcp docs: binding⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/concepts/binding.md)
2. Buyer

   #### Fetch and compare

   The buyer’s gate fetches the ATR from the link, hashes its exact bytes and compares them with the advertised ATR hash. If they differ, it stops, and nothing is signed. [Source: LCP §5.3⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#53-agent-verification-flow-level-2) · [Source: lcp docs: the buyer gate⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/concepts/buyer-gate.md)
3. Buyer

   #### Decide

   The buyer’s own policy decides whether to accept: the level it requires, the jurisdictions and dispute methods it accepts, what an agent may commit to, and when a person must look. It runs before any signing key is used. [Source: LCP §4.2⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#42-policy-primitives) · [Source: LCP §4.3⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#43-policy-evaluation)
4. Buyer

   #### Keep and pay

   The buyer keeps the ATR, byte for byte, and pays. The payment carries the ATR hash in the field its protocol or rail defines: paying is agreeing to that exact ATR. [Source: LCP §5.3⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#53-agent-verification-flow-level-2) · [Source: @integraledger/lcp README⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/lcp/README.md)
5. Seller

   #### Check

   Before it settles, the seller reads the ATR hash back from what the buyer signed, and refuses a payment that carries another. [Source: lcp docs: seller guide⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/guides/seller.md)
6. Seller

   #### Settle

   The payment settles on its own rail, and the seller reads the ATR hash back from the settlement. [Source: lcp docs: seller guide⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/guides/seller.md) · [Source: lcp docs: reading settlement⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/guides/rails.md#reading-settlement)

#### Where the ATR hash travels

#### On the rail

The ATR hash goes in a field the rail already has: a nonce, a memo, a note, a salt. No pairing in the package adds a contract for LCP, and nothing about the rail changes. [Source: lcp docs: rails⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/guides/rails.md) · [Source: lcp docs: binding⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/concepts/binding.md) [Every rail](https://integraledger.com/rails)

#### Beside the payment

The same reference rides the agentic protocols, payment and otherwise: in the challenge, the checkout, the mandate or the task. [Source: lcp docs: agentic checkouts⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/guides/checkouts.md) · [Source: LCP Appendix C⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#appendix-c-protocol-integration-illustrations) [Every protocol](https://integraledger.com/protocols)

#### In the agent

One buyer gate, published in three forms: TypeScript, Python and MCP. Whatever the buyer builds with, the check before payment is the same check. [Source: @integraledger/terms README⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-agentic-terms/blob/c094847/agentic-terms/README.md) · [Source: @integraledger/terms-mcp README⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-agentic-terms/blob/c094847/agentic-terms-mcp/README.md) · [Source: integraledger-terms (Python) README⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-agentic-terms/blob/c094847/agentic-terms-py/README.md)

**Sources (14)**

[lcp docs: binding⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/concepts/binding.md) · [LCP §5.3⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#53-agent-verification-flow-level-2) · [lcp docs: the buyer gate⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/concepts/buyer-gate.md) · [LCP §4.2⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#42-policy-primitives) · [LCP §4.3⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#43-policy-evaluation) · [@integraledger/lcp README⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/lcp/README.md) · [lcp docs: seller guide⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/guides/seller.md) · [lcp docs: reading settlement⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/guides/rails.md#reading-settlement) · [lcp docs: rails⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/guides/rails.md) · [lcp docs: agentic checkouts⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/guides/checkouts.md) · [LCP Appendix C⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#appendix-c-protocol-integration-illustrations) · [@integraledger/terms README⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-agentic-terms/blob/c094847/agentic-terms/README.md) · [@integraledger/terms-mcp README⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-agentic-terms/blob/c094847/agentic-terms-mcp/README.md) · [integraledger-terms (Python) README⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-agentic-terms/blob/c094847/agentic-terms-py/README.md)

#### The standard

**Bought.** Before the signer is called, the gate fetches the ATR from its link and compares the bytes’ hash with the advertised one. Each decline has a name: `hash-mismatch` when the bytes hash to another value; `atr-unfetchable` when the link answers with an error, a redirect or a content coding other than identity; `link-not-https`; `atr-too-large` above 1,048,576 bytes; `offer-unreadable` or `no-payable-option` when the offer cannot be read or paid. [Source: @integraledger/terms README⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-agentic-terms/blob/c094847/agentic-terms/README.md) · [Source: lcp docs: the buyer gate⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/concepts/buyer-gate.md)

**Sold.** The challenge carries the ATR hash and the ATR’s link in `extensions.legalContext` before the buyer signs. The seller reads the ATR hash back from what the buyer presents before it settles, and from the settlement after. [Source: lcp docs: x402⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/guides/x402.md) · [Source: lcp docs: seller guide⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/guides/seller.md)

#### The data

Read from the published packages when the site was built; nothing here is typed by hand.

The seller’s x402 challenge: the ATR hash and the ATR’s link, in `extensions.legalContext`

```
{
  "x402Version": 2,
  "resource": {
    "url": "https://api.seller.example/v1/market-data"
  },
  "accepts": [
    {
      "scheme": "exact",
      "network": "eip155:84532",
      "amount": "40000000",
      "asset": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
      "payTo": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C",
      "maxTimeoutSeconds": 60,
      "extra": {
        "name": "USDC",
        "version": "2"
      }
    }
  ],
  "extensions": {
    "legalContext": {
      "info": {
        "type": "sha256",
        "value": "0x8448dc1b716a5103287cb8f35e36b614ffd91e630ab8b7911833c54748ad5ca6",
        "legalContextUrl": "https://atr.seller.example/0x8448dc1b716a5103287cb8f35e36b614ffd91e630ab8b7911833c54748ad5ca6"
      },
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "properties": {
          "type": {
            "const": "sha256"
          },
          "value": {
            "type": "string",
            "pattern": "^0x[0-9a-f]{64}$"
          },
          "legalContextUrl": {
            "type": "string",
            "pattern": "^https://"
          }
        },
        "required": [
          "type",
          "value",
          "legalContextUrl"
        ]
      }
    }
  }
}
```

What the payer then signs on an EVM chain: the EIP-3009 authorization, whose nonce is the ATR hash

```
{
  "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
  "to": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C",
  "value": "40000000",
  "validAfter": "0",
  "validBefore": "1792000060",
  "nonce": "0x8448dc1b716a5103287cb8f35e36b614ffd91e630ab8b7911833c54748ad5ca6"
}
```

#### The code

Compiled against the published packages when the site is built.

The buyer’s gate compares the ATR with the ATR hash before the wallet signs

src/snippets/buyer.ts

```
// The buyer's agent, before its wallet signs: the gate fetches the record from its link, hashes the exact bytes,
// compares them with the fingerprint the seller advertised, and only then hands the signer a payment that carries it.
import { BINDINGS } from '@integraledger/lcp';
import { transact, type Signer } from '@integraledger/terms';

export async function pay(challenge: unknown, signer: Signer, keep: (record: Uint8Array) => Promise<void>) {
  const binding = BINDINGS.find((b) => b.id === 'x402/exact/eip155/eip3009')!;
  const result = await transact(challenge, binding, signer, fetch);
  if ('decline' in result) throw new Error(`${result.decline.code}: ${result.decline.detail}`);
  if ('approve' in result) return result; // an agreement payment for the agent to approve first
  await keep(result.bytes); // the record it compared, byte for byte
  return result.signed; // the payment, carrying the fingerprint
}
```

The seller’s check, before it settles

src/snippets/seller-check.ts

```
// The seller, before it settles: the payment the buyer presents carries the fingerprint of the record it issued.
import { hashEquals, isRefusal } from '@integraledger/lcp';
import { exactEip3009 } from '@integraledger/lcp/x402';

export async function carriesRecord(presented: unknown, issued: string): Promise<boolean> {
  const h = await exactEip3009.bound(presented); // the nonce the payer signed
  return !isRefusal(h) && hashEquals(h, issued);
}
```

Confirming it afterwards

### The ATR and the payment carry the same ATR hash.

The seller writes what was agreed into one Agentic Transaction Record (ATR) and hashes its exact bytes. The payment carries that ATR hash, the ATR’s unique fingerprint. Anyone holding the ATR can hash it again and see the two match. [Source: LCP §3, Level 2⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#level-2-provable) · [Source: @integraledger/lcp README⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/lcp/README.md)

#### Agentic Transaction Record

Example

**Sold**

10,000 calls to a market-data API

**Terms**

licence scope · acceptable use · rate and quota · data rights

**ATR hash**

0x8448dc…ad5ca6

same

#### Payment

Example

**Amount**

40.00 USDC, on a test network

**Carried in**

the nonce the payer signs

**ATR hash**

0x8448dc…ad5ca6

The ATR and the payment carry the same ATR hash.

**Sources (3)**

[LCP §3, Level 2⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#level-2-provable) · [@integraledger/lcp README⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/lcp/README.md) · [lcp docs: rails⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/guides/rails.md)

#### The standard

The ATR hash is H: SHA-256 over the ATR’s exact bytes, written `0x` and 64 hex digits and compared as 32 bytes. The seller’s x402 challenge carries H and the ATR’s link in `extensions.legalContext`; on an EVM chain the payer then signs H as the nonce of its EIP-3009 transfer authorization. [Source: LCP §2.5⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#25-optional-fields) · [Source: LCP §C.4⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#c4-x402) · [Source: lcp docs: x402⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/guides/x402.md)

This example was assembled and hashed by `@integraledger/lcp` when the site was built, and the payment below was built by its `x402/exact/eip155/eip3009` pairing; nothing in it is typed by hand. [Source: lcp docs: the ATR⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/concepts/atr.md) · [Source: lcp docs: x402⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/guides/x402.md)

#### The data

Read from the published packages when the site was built; nothing here is typed by hand.

The ATR’s exact bytes

872 bytes

```
{"atrVersion":"1","id":"3b4c7a2e-9f1d-4e6b-8a5c-2d7e1f0b9c34","x402":{"accepts":[{"scheme":"exact","network":"eip155:84532","amount":"40000000","asset":"0x036CbD53842c5426634e7929541eC2318f3dCF7e","payTo":"0x209693Bc6afc0C5328bA36FaF03C514EF312287C","maxTimeoutSeconds":60,"extra":{"name":"USDC","version":"2"}}],"request":{"method":"GET","path":"/v1/market-data","query":"","bodyDigest":"0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}},"terms":{"sold":"10,000 calls to a market-data API","licenceScope":"For internal use; the data may not be redistributed.","acceptableUse":"No resale and no attempt to identify individuals.","rateAndQuota":"At most 100 calls a minute, 10,000 calls in all.","dataRights":"Queries are kept for 30 days, then deleted.","limitationOfLiability":"Liability is capped at the amount paid.","governingLaw":"New York, USA"}}
```

H, the ATR hash: the SHA-256 of the ATR’s bytes

```
0x8448dc1b716a5103287cb8f35e36b614ffd91e630ab8b7911833c54748ad5ca6
```

The seller’s x402 challenge: H and the ATR’s link, in `extensions.legalContext`

```
{
  "x402Version": 2,
  "resource": {
    "url": "https://api.seller.example/v1/market-data"
  },
  "accepts": [
    {
      "scheme": "exact",
      "network": "eip155:84532",
      "amount": "40000000",
      "asset": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
      "payTo": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C",
      "maxTimeoutSeconds": 60,
      "extra": {
        "name": "USDC",
        "version": "2"
      }
    }
  ],
  "extensions": {
    "legalContext": {
      "info": {
        "type": "sha256",
        "value": "0x8448dc1b716a5103287cb8f35e36b614ffd91e630ab8b7911833c54748ad5ca6",
        "legalContextUrl": "https://atr.seller.example/0x8448dc1b716a5103287cb8f35e36b614ffd91e630ab8b7911833c54748ad5ca6"
      },
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "properties": {
          "type": {
            "const": "sha256"
          },
          "value": {
            "type": "string",
            "pattern": "^0x[0-9a-f]{64}$"
          },
          "legalContextUrl": {
            "type": "string",
            "pattern": "^https://"
          }
        },
        "required": [
          "type",
          "value",
          "legalContextUrl"
        ]
      }
    }
  }
}
```

What the payer signs: the EIP-3009 authorization, unsigned. Its nonce is the ATR hash.

```
{
  "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
  "to": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C",
  "value": "40000000",
  "validAfter": "0",
  "validBefore": "1792000060",
  "nonce": "0x8448dc1b716a5103287cb8f35e36b614ffd91e630ab8b7911833c54748ad5ca6"
}
```

The same ATR hash, in the field each rail has

Each rail’s field holds the ATR hash in the form it can: all 32 bytes, its LCP string, its first 8 bytes, its low 250 bits, or a hash of it. Each value below is computed by that rail’s own helper in the package. [Source: lcp docs: rails⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/guides/rails.md)

**EVM nonces and salts, Sui’s unused input, the Casper nonce, the Stacks memo: H itself**

0x8448dc1b716a5103287cb8f35e36b614ffd91e630ab8b7911833c54748ad5ca6

**Memos and notes on Solana, Algorand, Hedera, NEAR, Tron, TON and more: H’s LCP string**

lcp:sha256:0x8448dc1b716a5103287cb8f35e36b614ffd91e630ab8b7911833c54748ad5ca6

**The Stellar muxed id: H’s first 8 bytes**

9532110621754675459

**The Starknet nonce: H’s low 250 bits**

0x48dc1b716a5103287cb8f35e36b614ffd91e630ab8b7911833c54748ad5ca6

**The x402 XRP Ledger InvoiceID: SHA-256 of H’s LCP string**

EDFC016DBC705845777C0A0B18ED760674935F8BDC774DE6161D9016D0BD5672

**The MPP challenge id that carries H**

hEjcG3FqUQMofLjzXja2FP_ZHmMKuLeRGDPFR0itXKY.0

#### Check it yourself

1. Press **Hash the ATR in your browser** above: your browser hashes the ATR’s bytes with the Web Crypto API, and the result is H.
2. Or save the ATR’s bytes exactly as shown, with no trailing newline, and hash the file with any SHA-256 tool (`sha256sum`, `openssl dgst -sha256`): the digest is H, the nonce the payer signs.

### Who can check it

#### The buyer

Keeps the ATR it compared before paying, byte for byte, and the payment that carries its ATR hash. [Source: LCP §5.5⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#55-document-preservation) · [Source: lcp docs: the buyer gate⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/concepts/buyer-gate.md)

#### The seller

Keeps the ATR it issued, and reads the ATR hash back from the payment it received and from the settlement on its rail. [Source: lcp docs: seller guide⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/guides/seller.md)

#### The verifier

An auditor, an arbitrator or a counterparty. Given the ATR by either party, it recomputes the ATR hash and compares it with the payment, without asking us. [Source: LCP §5.5⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#55-document-preservation) · [Source: LCP §12.2⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#122-document-integrity)

> A hash without a document is a proof without evidence. [Source: LCP §5.5⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#55-document-preservation)
>
> The technical check does not decide enforceability or who should prevail.

**Sources (4)**

[LCP §5.5⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#55-document-preservation) · [lcp docs: the buyer gate⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/concepts/buyer-gate.md) · [lcp docs: seller guide⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/guides/seller.md) · [LCP §12.2⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#122-document-integrity)

#### The standard

The buyer keeps the bytes its gate compared and the payment it presented. The seller keeps the ATR it issued, and reads the ATR hash back from the payment and the settlement. The verifier needs nothing from Integra: the ATR, from either party, and the payment or the chain. [Source: LCP §5.5⁠ (opens in a new tab)](https://github.com/legal-context-protocol/legal-context-protocol/blob/c8df26d/spec/legal-context-protocol-v1.md#55-document-preservation) · [Source: lcp docs: the buyer gate⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/concepts/buyer-gate.md) · [Source: lcp docs: seller guide⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/guides/seller.md)

#### The code

Compiled against the published packages when the site is built.

From the chain alone: read the ATR hash back from a settled transfer, through your own node

src/snippets/recover.ts

```
// Anyone, from the chain alone: read the fingerprint back from a settled EIP-3009 transfer, through your own node.
import { isRefusal } from '@integraledger/lcp';
import type { Eip155, EvmReader, Hex } from '@integraledger/lcp/evm';
import { exactEip3009 } from '@integraledger/lcp/x402';

export async function fingerprintOf(network: Eip155, asset: Hex, transaction: Hex, reader: EvmReader) {
  const h = await exactEip3009.recover({ network, asset, transaction }, reader);
  return isRefusal(h) ? null : h; // compare it with the hash of the record you hold
}
```

#### Check it yourself

1. Get the ATR’s exact bytes from either party.
2. Hash them with SHA-256, with any tool: `sha256sum`, OpenSSL or the Web Crypto API.
3. Read the ATR hash from the payment: on x402’s EVM exact scheme, the nonce the payer signed, which the settlement transaction also carries. [Source: lcp docs: recovering H from the chain alone⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/guides/rails.md#recovering-h-from-the-chain-alone)
4. Equal means the payment was made for that ATR. It does not show that the amount, payee, asset or timing match the ATR’s content: each pairing’s record says what it proves. [Source: lcp docs: pairings reference⁠ (opens in a new tab)](https://github.com/IntegraLedger/integra-protocol/blob/66274bf/docs/reference/pairings.md)

Go further

### Where each part is set out in full.

- [The Levels of Trust: what a service publishes at each level](https://integraledger.com/levels)
- [By protocol: where the ATR hash rides in each](https://integraledger.com/protocols)
- [By rail: the field each rail carries it in](https://integraledger.com/rails)
- [Payment types: every one in the package, and what each proves](https://integraledger.com/payment-types)
- [Developers: the open packages that do each step](https://integraledger.com/developers)
- [Questions, answered](https://integraledger.com/faq)

### Ready to see your own agreements proved?

Tell us what you sell, buy or carry, and we will show you where the agreement rides in it.

The hosted appliance is free on test networks, with test-network USDC.

[Talk to us](https://integraledger.com/contact)
