Agent Legal Context
Specification

API Specification

All HTTP endpoints for terms retrieval, verification, acceptance, and dispute resolution.

The ALC API provides HTTP/JSON access to all legal context operations. It bridges the agent world (HTTP/JSON) to the on-chain world (smart contracts, resolvers) without requiring agents to have web3 libraries, RPC providers, or blockchain knowledge.

All endpoints MUST be served over HTTPS. All request and response bodies MUST use application/json content type unless otherwise specified. All timestamps in response body fields use ISO 8601 format. Exception: The timestamp and expiry fields in POST /v1/records/{recordId}/accept are Unix epoch integers (uint256) to match EIP-712 signed data exactly.


Create Record

Creates a new on-chain record (IntegraRecord in the reference implementation). Used by vendors to register their terms (Tier 1/2) and by parties to register negotiated agreements (Tier 3).

POST /v1/records

Request:

{
  "terms": {
    "url": "https://example.com/terms/v1.html"
  },
  "resolvers": {
    "documentLocation": true,
    "contact": {
      "legal": "[email protected]",
      "technical": "[email protected]"
    },
    "disputeResolution": {
      "method": "AAA Commercial Rules",
      "jurisdiction": "New York, USA"
    }
  },
  "chain": "tempo",
  "acceptanceRequired": false
}
FieldTypeRequiredDescription
terms.urlstringOne of url/documentURL of the terms document. The API will fetch and snapshot it.
terms.documentstringOne of url/documentBase64-encoded terms document bytes for direct upload.
resolversobjectREQUIREDResolver configuration. At minimum documentLocation MUST be true.
chainstringOPTIONALTarget chain for the on-chain record.
acceptanceRequiredbooleanOPTIONALWhether counterparties must explicitly accept (Tier 2). Default: false.

Response (201 Created):

{
  "recordId": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890",
  "contentHash": "0x7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069",
  "chain": "tempo",
  "chainId": 42431,
  "transactionHash": "0x...",
  "api": "https://api.integraledger.net/v1/records/0xabcdef1234567890...",
  "status": "active"
}

The response includes the api URL that the vendor SHOULD place in their legal-context.json discovery document.


Get Record

Retrieves record metadata for a given on-chain record.

GET /v1/records/{recordId}

Response (200 OK):

{
  "recordId": "0xabcdef...",
  "contentHash": "0x7f83b165...",
  "chain": "tempo",
  "chainId": 42431,
  "contractAddress": "0x1234...5678",
  "effectiveDate": "2026-03-01T00:00:00Z",
  "state": "active",
  "resolvers": {
    "documentLocation": "https://api.integraledger.net/v1/records/0xabcdef.../terms",
    "contact": "https://api.integraledger.net/v1/records/0xabcdef.../contact",
    "disputeResolution": "https://api.integraledger.net/v1/records/0xabcdef.../dispute"
  },
  "versions": [
    {
      "contentHash": "0x7f83b165...",
      "effectiveDate": "2026-03-01T00:00:00Z",
      "status": "current"
    },
    {
      "contentHash": "0x3a4b5c6d...",
      "effectiveDate": "2025-09-15T00:00:00Z",
      "status": "superseded"
    }
  ]
}

Get Terms

Retrieves the actual terms document -- the exact bytes that were hashed to produce the contentHash.

GET /v1/records/{recordId}/terms
ParameterTypeRequiredDescription
versionquery stringOPTIONALA specific contentHash to retrieve a historical version.

The response body IS the terms document. The Content-Type header indicates the format (e.g., text/html, application/pdf, application/json).

Verification: Clients SHOULD verify by computing SHA-256(response body) and comparing to the contentHash.

Required response headers:

HeaderDescription
X-Integra-HashThe contentHash of the returned document
X-Integra-RecordThe recordId on-chain
X-Integra-ChainThe chain identifier

Verify Hash

Verifies whether a given hash corresponds to a valid, on-chain-anchored terms record.

GET /v1/verify/{contentHash}

Response (200 OK):

{
  "verified": true,
  "contentHash": "0x7f83b165...",
  "recordId": "0xabcdef...",
  "chain": "tempo",
  "chainId": 42431,
  "effectiveDate": "2026-03-01T00:00:00Z",
  "status": "current",
  "vendor": {
    "domain": "example.com"
  }
}

Response (404 Not Found):

{
  "verified": false,
  "contentHash": "0x7f83b165...",
  "error": "Hash not found in any registered IntegraRecord"
}

Accept Terms

Records an explicit terms acceptance (Tier 2). The request body contains an EIP-712 signature over the content hash.

POST /v1/records/{recordId}/accept

Request:

{
  "contentHash": "0x7f83b165...",
  "acceptor": "0x742d35Cc...",
  "principal": "0x9f8e7d6c...",
  "authorizationRef": "0xaabbccdd...",
  "signature": "0x...",
  "timestamp": 1710856200,
  "expiry": 1742392200
}
FieldTypeRequiredDescription
contentHashstringREQUIREDHash of the terms being accepted.
acceptorstringREQUIREDEthereum address of the accepting party (agent or human).
principalstringOPTIONALEthereum address of the human principal, if acceptor is an agent.
authorizationRefstringOPTIONALReference to the authorization grant.
signaturestringREQUIREDEIP-712 signature over the TermsAcceptance typed data.
timestampintegerREQUIREDUnix epoch timestamp. MUST match the EIP-712 signed data.
expiryintegerOPTIONALUnix epoch timestamp after which acceptance is no longer valid.

The timestamp and expiry fields are integers (Unix epoch seconds), not ISO 8601 strings. This ensures they match the uint256 values in the EIP-712 typed data exactly.

Response (201 Created):

{
  "acceptanceId": "0x...",
  "contentHash": "0x7f83b165...",
  "acceptor": "0x742d35Cc...",
  "status": "recorded",
  "onChainRef": {
    "chain": "tempo",
    "transactionHash": "0x..."
  }
}

Get Contact Information

Retrieves structured contact information for the vendor.

GET /v1/records/{recordId}/contact

Response (200 OK):

{
  "legal": {
    "email": "[email protected]",
    "name": "Example Corp Legal Department"
  },
  "technical": {
    "email": "[email protected]",
    "endpoint": "https://support.example.com/api"
  },
  "dispute": {
    "email": "[email protected]",
    "endpoint": "https://api.integraledger.net/v1/records/0xabcdef.../disputes",
    "method": "AAA Commercial Arbitration Rules",
    "jurisdiction": "New York, USA"
  }
}

Get Dispute Resolution Process

Retrieves the dispute resolution process for agreements under these terms.

GET /v1/records/{recordId}/dispute

Response (200 OK):

{
  "method": "AAA Commercial Arbitration Rules",
  "jurisdiction": "New York, USA",
  "automated": {
    "enabled": true,
    "threshold": "1000.00",
    "currency": "USD",
    "description": "Disputes under $1,000 resolved automatically via pre-defined rules"
  },
  "escalation": {
    "enabled": true,
    "threshold": "1000.00",
    "institution": "American Arbitration Association",
    "rules": "Commercial Arbitration Rules",
    "filing": "https://api.integraledger.net/v1/records/0xabcdef.../disputes"
  },
  "resolver": {
    "chain": "tempo",
    "address": "0x9876...5432",
    "type": "ADRResolverV3"
  }
}

File Dispute

Initiates a dispute under the terms governing a specific transaction.

POST /v1/records/{recordId}/disputes

Request:

{
  "claimant": "0x742d35Cc...",
  "respondent": "0x9f8e7d6c...",
  "transactionRef": {
    "chain": "tempo",
    "transactionHash": "0x...",
    "contentHash": "0x7f83b165..."
  },
  "category": "non-delivery",
  "description": "Service was not delivered within the SLA specified in the terms",
  "evidenceHashes": ["0xaaaa...", "0xbbbb..."],
  "requestedRelief": "refund"
}

Response (201 Created):

{
  "disputeId": "0x...",
  "status": "filed",
  "resolverAddress": "0x9876...5432",
  "nextSteps": "Evidence submission period: 14 days",
  "onChainRef": {
    "chain": "tempo",
    "transactionHash": "0x..."
  }
}

Error Responses

All error responses conform to RFC 9457 Problem Details format:

{
  "type": "https://integraledger.net/problems/record-not-found",
  "title": "Record Not Found",
  "status": 404,
  "detail": "No IntegraRecord found for the specified recordId",
  "instance": "/v1/records/0xabcdef..."
}
HTTP StatusTypeDescription
400invalid-requestRequest body fails schema validation
401unauthorizedMissing or invalid authentication
404record-not-foundIntegraRecord does not exist
404hash-not-foundcontentHash not recognized
409already-acceptedTerms already accepted by this address
422invalid-signatureEIP-712 signature verification failed
422hash-mismatchProvided contentHash does not match the record
502chain-unavailableOn-chain verification temporarily unavailable

Authentication

Endpoints that modify state (POST methods) MUST require authentication. Implementations SHOULD support:

  • API key authentication via Authorization: Bearer {key} header
  • EIP-712 signed request bodies (self-authenticating)

Endpoints that only read state (GET methods) SHOULD be publicly accessible to enable open verification.


Deployment Models

The API MAY be hosted in three configurations. All three MUST implement the same interface. Clients MUST NOT need to know which model is in use.

ModelDescriptionVendor EffortControl
Hosted (e.g., Integra)Vendor creates a record. A hosted ALC API fronts it.Zero infrastructureProvider operates the API
Self-hostedVendor runs the API, pointing at their own on-chain records.Full infrastructureFull vendor control
Third-party hostedConsortium or platform runs the API for its members.Depends on providerThird-party operates the API