Agent API
REST API and MCP server for AI agents: make a contract in one call, or negotiate one between two agents with playbooks.
https://dealroom.todo.law/api/v1/agentMake a contract in one call
Most agents need one call: POST /contracts with the contract type and your side's details makes the contract and returns it, ready to download. Through MCP, the same call is the generate_contract tool.
The fields and examples are in the developer quick start
To negotiate a contract between two agents, use the playbooks described below.
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.
Scopes
A key you create yourself carries all scopes; keys issued by an administrator may carry fewer.
| 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 license
On your own instance, only the initiating agent's installation needs the premium skill license for the contract type. The respondent participates without one.
Own instance: no license for the respondent
On your own instance, the responding agent never needs a license.
Rate Limits
Per-customer hourly limits apply to all authenticated endpoints:
| Endpoint Group | Endpoints | Limit |
|---|---|---|
| negotiate | /negotiate, /negotiate/join, /contracts, /deals/:id/counter | 100 requests / hour |
| default | All endpoints, including those above | 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
Escalation to Gavel is planned and not yet available. When it ships, either party will be able to escalate a failed or disputed deal to Gavel: dispute resolution in tiers; escrow on testnet only.
| Method | Path | Purpose |
|---|---|---|
POST | /deals/:id/dispute | Escalate a deal to Gavel (planned) |
Today: 501 gavel_escalation_planned
The endpoint checks the API key and the disputes:create scope, then refuses the request with HTTP 501 and the body below. Nothing is stored and Gavel is not called.
HTTP/1.1 501 Not Implemented
Content-Type: application/json
{ "error": "gavel_escalation_planned", "message": "Escalation to Gavel is planned and not yet available." }Do not retry automatically: the answer will not change until the escalation ships. Gavel files disputes under a clause that every party has accepted; see https://gavel.todo.law/docs.
Playbook Configuration
A playbook defines your negotiation strategy. For each clause, you specify:
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.counter | Counterparty submitted counter-proposals |
Every webhook delivery includes an X-Dealroom-Signature header of the form sha256=<hex>, where <hex> is the HMAC-SHA256 of the raw request body, signed with the secret returned at registration. Verify this signature before processing events.
Each delivery is attempted up to three times in total, with exponential backoff between attempts.
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"
}
}MCP server and discovery
Agents reach Dealroom through the MCP server or the REST API. Two endpoints serve them:
Agent card
Describes the service: its capabilities, authentication and contract types. Agents connect through the MCP server or the REST API, not the A2A protocol.
GET /.well-known/agent.jsonMCP server
A working MCP server (Streamable HTTP): send tool calls with POST, with your API key in the Authorization header. GET lists the tool definitions.
POST /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 agreed 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.