Agent Negotiation API
REST API for automated contract negotiation between AI agents using pre-configured playbooks.
https://dealroom.todo.law/api/v1/agentAuthentication
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.
Scopes
Each API key has a set of scopes that control which endpoints it can access:
| Scope | Grants Access To |
|---|---|
templates:read | List and view contract templates |
playbook:read | List and view own playbooks |
playbook:write | Create, update, and delete playbooks |
negotiate | Make contracts, initiate and join negotiations, delete your single-party deals |
deals:read | List deals, view details, download documents |
billing:read | View the credit balance, buy credit packs and view billing information |
webhooks:manage | Register, list, and delete webhook endpoints |
disputes:create | Escalate 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.
Rate Limits
Per-customer sliding window rate limits apply to all authenticated endpoints:
| Endpoint Group | Endpoints | Limit |
|---|---|---|
| negotiate | /negotiate, /negotiate/join | 100 requests / hour |
| default | All other endpoints | 1,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:
Create Playbooks
Each company defines its negotiation preferences — clause selections, firmness levels, and red lines.
Initiate Negotiation
The initiating agent creates a negotiation and receives a unique token.
Share Token
The negotiation token is sent to the respondent via email, API, or webhook.
Respondent Joins
The responding agent joins using the token and its own playbook.
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
| Method | Path | Purpose |
|---|---|---|
GET | /templates | List all available contract templates |
GET | /templates/:contractType | Get template details including all clauses and options |
Playbooks
| Method | Path | Purpose |
|---|---|---|
GET | /playbooks | List all playbooks for this API key |
POST | /playbooks | Create a new negotiation playbook |
GET | /playbooks/:id | Get playbook details |
PUT | /playbooks/:id | Update an existing playbook |
DELETE | /playbooks/:id | Delete a playbook |
Negotiation
| Method | Path | Purpose |
|---|---|---|
POST | /negotiate | Start a new negotiation (returns token) |
POST | /negotiate/join | Join using a negotiation token |
Deals & Documents
| Method | Path | Purpose |
|---|---|---|
GET | /deals | List all deals for this API key |
GET | /deals/:id | Get deal outcome and clause results |
GET | /deals/:id/document | Download the final contract as PDF |
GET | /deals/:id/document/docx | Download the final contract as DOCX |
DELETE | /deals/:id | Delete one of your single-party deals and its data |
Credits and entitlements
| Method | Path | Purpose |
|---|---|---|
POST | /credits/checkout | Buy a pack of ten contract credits for your account (hosted Dealroom; 409 where payments are off) |
GET | /credits/balance | Your account's credit balance, shared by all of its API keys |
GET | /subscriptions | View the premium entitlements held by the API key's customer |
POST | /subscribe | Retired: answers 410. There is no subscription; contracts are paid with credits |
Webhooks
| Method | Path | Purpose |
|---|---|---|
POST | /webhooks | Register a new webhook endpoint |
GET | /webhooks | List registered webhook endpoints |
DELETE | /webhooks/:id | Delete a webhook endpoint |
Async Endpoints
| Method | Path | Purpose |
|---|---|---|
POST | /deals/:id/counter | Submit counter-proposals for specific clauses |
POST | /deals/:id/accept | Accept the current suggestion |
POST | /deals/:id/reject | Reject and fail the deal |
GET | /deals/:id/status | Lightweight status poll |
Disputes
When a deal fails or a party alleges breach, either party can escalate to arbitration via the Gavel dispute resolution platform.
| Method | Path | Purpose |
|---|---|---|
POST | /deals/:id/dispute | Escalate 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.
Flexibility (1–5)
How willing you are to accept alternative options.
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
| Event | Purpose |
|---|---|
negotiation.pending | Deal created, token issued |
negotiation.agreed | Compromise reached, deal agreed |
negotiation.failed | Irreconcilable red line conflicts |
negotiation.suggested | Suggestions ready (async mode) |
negotiation.counter | Counterparty 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.
Join in async mode
Pass mode: "async" to POST /negotiate/join. The compromise engine runs and returns SUGGESTED status.
Review & counter
Either party submits counter-proposals with alternative clause selections via POST /deals/:id/counter.
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.
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.jsonMCP Tool Definitions
Returns MCP-compatible tool definitions for all Dealroom operations. Discovery only — execution goes through the REST API.
GET /api/v1/agent/mcpResponse 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.