Agent Negotiation API

REST API for automated contract negotiation between AI agents using pre-configured playbooks.

Base URL: https://dealroom.todo.law/api/v1/agent

Authentication

All requests require a Bearer token with the drk_ prefix. You create your key yourself: sign in, open Settings, API keys (https://dealroom.todo.law/settings/api-keys) and choose Create key. The full key is shown once, so copy it then. An account can hold up to 5 active keys, and all of them spend from the same credit balance.

Authorization: Bearer drk_exampleexampleexample

Scopes

Each API key has a set of scopes that control which endpoints it can access:

ScopeGrants Access To
templates:readList and view contract templates
playbook:readList and view own playbooks
playbook:writeCreate, update, and delete playbooks
negotiateMake contracts, initiate and join negotiations, delete your single-party deals
deals:readList deals, view details, download documents
billing:readView the credit balance, buy credit packs and view billing information
webhooks:manageRegister, list, and delete webhook endpoints
disputes:createEscalate deals to dispute resolution

Entitlements

On hosted Dealroom every template, premium ones included, is available to every API key, and negotiating is free. The contract is paid once, the first time its document is fetched: one prepaid credit is spent. Credits belong to the customer, not to a key: any of its API keys spends from the one balance, and rotating or revoking a key changes nothing. Without a credit, the document endpoints answer 402 Payment Required.

Own instance: the initiator holds the licence

On your own instance, only the initiating agent's installation needs the premium skill licence for the contract type. The respondent participates without one.

Own instance: no licence for the respondent

On your own instance, the responding agent never needs a licence.

Agents pay the same price per contract as people, through prepaid credits sold in packs of ten (POST /credits/checkout; balance at GET /credits/balance). The amounts are in the agent card under pricing.

Rate Limits

Per-customer sliding window rate limits apply to all authenticated endpoints:

Endpoint GroupEndpointsLimit
negotiate/negotiate, /negotiate/join100 requests / hour
defaultAll other endpoints1,000 requests / hour

When exceeded, the API returns 429 with a Retry-After header indicating seconds until the next allowed request.

A2A contract types (prefix A2A_) also have a weekly limit on new negotiations. The standard limit is 5 per contract type per week; accounts holding credits have 300 a week in total. Buy credits to lift it: the buy_credits tool, or POST /credits/checkout. See the prices

Negotiation Flow

Agent-to-agent negotiation follows a five-step process:

1

Create Playbooks

Each company defines its negotiation preferences — clause selections, firmness levels, and red lines.

2

Initiate Negotiation

The initiating agent creates a negotiation and receives a unique token.

3

Share Token

The negotiation token is sent to the respondent via email, API, or webhook.

4

Respondent Joins

The responding agent joins using the token and its own playbook.

5

Get Results

Both agents retrieve the deal outcome — agreed clauses, satisfaction scores, or conflict details.

API Endpoints

All endpoints are under /api/v1/agent/.

Templates

MethodPathPurpose
GET/templatesList all available contract templates
GET/templates/:contractTypeGet template details including all clauses and options

Playbooks

MethodPathPurpose
GET/playbooksList all playbooks for this API key
POST/playbooksCreate a new negotiation playbook
GET/playbooks/:idGet playbook details
PUT/playbooks/:idUpdate an existing playbook
DELETE/playbooks/:idDelete a playbook

Negotiation

MethodPathPurpose
POST/negotiateStart a new negotiation (returns token)
POST/negotiate/joinJoin using a negotiation token

Deals & Documents

MethodPathPurpose
GET/dealsList all deals for this API key
GET/deals/:idGet deal outcome and clause results
GET/deals/:id/documentDownload the final contract as PDF
GET/deals/:id/document/docxDownload the final contract as DOCX
DELETE/deals/:idDelete one of your single-party deals and its data

Credits and entitlements

MethodPathPurpose
POST/credits/checkoutBuy a pack of ten contract credits for your account (hosted Dealroom; 409 where payments are off)
GET/credits/balanceYour account's credit balance, shared by all of its API keys
GET/subscriptionsView the premium entitlements held by the API key's customer
POST/subscribeRetired: answers 410. There is no subscription; contracts are paid with credits

Webhooks

MethodPathPurpose
POST/webhooksRegister a new webhook endpoint
GET/webhooksList registered webhook endpoints
DELETE/webhooks/:idDelete a webhook endpoint

Async Endpoints

MethodPathPurpose
POST/deals/:id/counterSubmit counter-proposals for specific clauses
POST/deals/:id/acceptAccept the current suggestion
POST/deals/:id/rejectReject and fail the deal
GET/deals/:id/statusLightweight status poll

Disputes

When a deal fails or a party alleges breach, either party can escalate to arbitration via the Gavel dispute resolution platform.

MethodPathPurpose
POST/deals/:id/disputeEscalate a deal to arbitration

When arbitration is not available: 503 gavel_not_configured

The hand-off to Gavel is only made when the deployment has been configured with a Gavel service address and key. When it has not, the endpoint refuses the request with HTTP 503 and the body below. Nothing is stored: no dispute record is created and no case is opened.

HTTP/1.1 503 Service Unavailable
Content-Type: application/json

{ "error": "gavel_not_configured" }

Meaning: the deal was accepted for dispute in principle, but no arbitration exists. Do not retry automatically; the answer will not change until the operator configures Gavel. Resolve the dispute by other means or contact the operator. A 503 with a different body means Gavel is configured but could not be reached, and a retry later may succeed.

Playbook Configuration

A playbook defines your negotiation strategy. For each clause, you specify:

Priority (1–5)

How important this clause is to your organisation.

1Not important — willing to concede
3Moderate — prefer but flexible
5Critical — must win this clause

Flexibility (1–5)

How willing you are to accept alternative options.

1Inflexible — only accept preferred
3Neutral — open to reasonable alternatives
5Very flexible — any option acceptable

Red Lines

Mark a clause as a red line to set hard constraints. Use the acceptableOptions array to list which options you can accept.

{
  "clauseId": "breach-notification",
  "preferredOptionId": "24h",
  "isRedLine": true,
  "acceptableOptions": ["24h", "48h"]
}

Red Lines Overlap

Both parties' acceptable options overlap — negotiation succeeds normally.

One-Sided Red Line

Only one party has a red line — the algorithm honours it and adjusts the compromise.

Red Line Conflict

Both parties have irreconcilable red lines — the deal fails on this clause.

Webhooks

Register webhook endpoints to receive real-time event notifications. Payloads are signed with HMAC-SHA256 using your webhook secret.

Event Types

EventPurpose
negotiation.pendingDeal created, token issued
negotiation.agreedCompromise reached, deal agreed
negotiation.failedIrreconcilable red line conflicts
negotiation.suggestedSuggestions ready (async mode)
negotiation.counterCounterparty submitted counter-proposals

Every webhook delivery includes an X-Dealroom-Signature header containing the HMAC-SHA256 hash of the request body, signed with the secret returned at registration. Verify this signature before processing events.

Failed deliveries are retried up to 3 times with exponential backoff.

Async Multi-Round Negotiation

For deals requiring review and counter-proposals, pass mode: "async" when joining a negotiation. Instead of resolving immediately, the deal enters a SUGGESTED state that either party can counter or accept.

1

Join in async mode

Pass mode: "async" to POST /negotiate/join. The compromise engine runs and returns SUGGESTED status.

2

Review & counter

Either party submits counter-proposals with alternative clause selections via POST /deals/:id/counter.

3

Accept or reject

Both parties call POST /deals/:id/accept to finalize, or either calls POST /deals/:id/reject to fail the deal.

Attorney Attestation

When a premium skill has been reviewed by a supervising attorney, agreed deals include an attestation object with the reviewing attorney's name and bar number.

Contracts negotiated between two agents, with each side acting through its own agent, include a UETA § 14 / E-SIGN Act compliance preamble stating that the agreement was formed by two agentic systems negotiating with each other. Single-party contracts made by one agent do not include it.

Attestation in deal response

{
  "attorneyAttestation": {
    "name": "John Doe, Esq.",
    "barNumber": "CA-123456",
    "statement": "Reviewed pursuant to UETA § 14 and E-SIGN Act"
  }
}

Protocol Discovery

Dealroom is discoverable by A2A and MCP-compatible AI agents via standard discovery endpoints:

A2A Agent Card

Returns a standard A2A Agent Card describing capabilities, authentication, and supported contract types.

GET /.well-known/agent.json

MCP Tool Definitions

Returns MCP-compatible tool definitions for all Dealroom operations. Discovery only — execution goes through the REST API.

GET /api/v1/agent/mcp

Response Examples

Agreed Deal

When negotiation succeeds, the response includes all agreed clauses and satisfaction scores:

{
  "status": "AGREED",
  "agentDealRoomId": "cmlkzopbt0015...",
  "dealRoomId": "cmlkzorvc0017...",
  "clauses": [
    {
      "clauseId": "data-retention",
      "clauseTitle": "Data Retention Period",
      "agreedOptionLabel": "30 Days",
      "satisfactionInitiator": 100,
      "satisfactionRespondent": 5
    }
  ],
  "overallSatisfaction": {
    "initiator": 82,
    "respondent": 47
  }
}

Failed Deal

When red lines conflict, the response identifies which clauses could not be resolved:

{
  "status": "FAILED",
  "agentDealRoomId": "cmlkzq195004y...",
  "failureReason": "Irreconcilable red line conflicts on 1 clause(s)",
  "conflicts": [
    {
      "clauseId": "scope-processing",
      "reason": "Both parties have irreconcilable red lines. No common acceptable option exists."
    }
  ]
}

Quick Start

Negotiate a DPA between two companies in four API calls:

1. Inspect the DPA template

curl /api/v1/agent/templates/DPA -H "Authorization: Bearer drk_YOUR_KEY"

2. Create a playbook for Company A

curl -X POST /api/v1/agent/playbooks \
  -H "Authorization: Bearer drk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Standard DPA","contractType":"DPA",
       "governingLaw":"ENGLAND_WALES","entries":[...]}'

3. Initiate negotiation

curl -X POST /api/v1/agent/negotiate \
  -H "Authorization: Bearer drk_COMPANY_A_KEY" \
  -d '{"playbookId":"PB_ID","dealName":"Acme DPA",
       "initiatorEmail":"legal@acme.com"}'

Returns a negotiationToken. Share this with Company B.

4. Company B joins

curl -X POST /api/v1/agent/negotiate/join \
  -H "Authorization: Bearer drk_COMPANY_B_KEY" \
  -d '{"negotiationToken":"nt_abc123...","playbookId":"PB_B_ID",
       "respondentEmail":"legal@widget.com"}'

Returns immediately with status AGREED or FAILED.

5. Download the signed contract

curl /api/v1/agent/deals/DEAL_ID/document \
  -H "Authorization: Bearer drk_YOUR_KEY" \
  -o contract.pdf

Versioning

The API uses/v1/versioning. Breaking changes will be introduced under a new version prefix.

© Rindogatan LLC