Everything the website does on a contract, available to your own software — and to an AI assistant, as tools it can call. Create a deal, compute every deadline the contract creates, and produce the sealed signature packet.
Nothing here is computed by a language model. Deadlines come from the promulgated form's own paragraphs and contracts are filled by the same code the website runs, so the same input always produces the same output. An assistant may call this engine; it never becomes it. That property is why the answer is the same every time, and it is not negotiable.
API keys belong to a paid plan. Reading a deal, listing the address book and computing deadlines cost nothing and are limited only by the per-key rate ceiling. One call spends money: producing a signature packet spends one deal from your plan, exactly as downloading one on the website does — and re-rendering a deal you have already paid for is free, forever. Pass its dealId and nothing is charged.
A free or lapsed account cannot issue a key and an existing key stops calling, but you can always list and revoke your keys. Losing the ability to revoke a live credential because a card expired would be a security problem, not a paywall.
Profile → API keys → Issue a key. Choose read only or read and write; write implies read, read never implies write. The key is shown once. We keep only its hash, so nobody — including us — can print it back afterwards. Keys carry an expiry (90 days by default, a year at most) and can be revoked at any moment; revocation takes effect on the very next call.
curl https://recontract.ai/api/v1/deals \ -H "Authorization: Bearer rc_live_…"
A session cookie is never accepted here, so there is no ambient credential for another site to ride, and cross-origin requests are answered without credentials. GET https://recontract.ai/api/v1 is public and describes everything below, generated from the same table the router uses.
| Call | Scope | What it does |
|---|---|---|
GET /api/v1/account | read | The plan, what is left of it, and what this key may do. |
GET /api/v1/usage | read | This key's calls and deals spent over 30 days, by route. |
GET /api/v1/license | read | The licence bound to the account, as the Commission's public record has it. |
GET /api/v1/deals | read | The deals on the account, most recently touched first. |
POST /api/v1/deals | write | Create or replace a deal. Send deal, or speak for one plain-English line. |
GET /api/v1/deals/{id} | read | One deal, exactly as it is stored. |
DELETE /api/v1/deals/{id} | write | Delete a deal and everything stored with it. |
GET /api/v1/deals/{id}/deadlines | read | Every deadline a stored deal creates, and why each lands where it does. |
POST /api/v1/deadlines | read | Deadlines for a deal sent in the body. Stores nothing. |
POST /api/v1/render | write | Spends one deal. The signature packet: cover sheet, filled contract, addendum, seal. |
GET /api/v1/entities | read | The address book: saved title companies, brokerages and agents. |
POST /api/v1/entities | write | Save a title company, brokerage or agent to the address book. |
DELETE /api/v1/entities/{id} | write | Delete one address-book entry by its id. |
Three ways, and they compose in this order: a stored deal (dealId), then one plain-English line (speak), then an explicit patch (deal and financing), which wins because it is the most specific thing you said.
curl -X POST https://recontract.ai/api/v1/deadlines \
-H "Authorization: Bearer rc_live_…" -H "Content-Type: application/json" \
-d '{
"speak": "Torres selling to Whitfield, 8214 Silent Cedar Lane Houston 77040, 385 thousand, conventional 308 thousand, four grand earnest, 400 option 10 days, close October 30 2026, Lone Star Title",
"deal": { "closing": { "executedMonth": "9", "executedDay": "17", "executedYear2": "26" } }
}'
The patch is merged one section deep, so {"closing":{"executedDay":"17"}} sets that one blank without erasing the rest of the paragraph.
The Effective Date is the one field nobody says out loud. It is the date of final acceptance written on the execution page, and every clock in the contract counts from it. Without it the engine can compute exactly one row — the Effective Date's own — instead of seven. Supply it as deal.closing.executedMonth, executedDay and executedYear2.
From the call above, counting from Thursday 17 September 2026, the two Paragraph 5 clocks land three days apart and follow opposite rules — which is the whole reason this product exists:
2026-09-21 Earnest money and option fee — ¶5A(2) (moved past Sunday) 2026-09-27 Option period ends, 5:00 PM — ¶5B (does not move)
Every row carries the paragraph it comes from, whether it was extended, whether it is estimated, and — when it cannot be computed — which blank was empty. It never guesses.
curl -X POST https://recontract.ai/api/v1/render \
-H "Authorization: Bearer rc_live_…" -H "Content-Type: application/json" \
-d '{ "dealId": "…" }' -o signature-packet.pdf
You get the same file the website produces: a cover sheet, the filled TREC contract, the 40-11 when there is financing, a title intake sheet when you ask for one, and a seal anyone can check at recontract.ai/verify from the file's own bytes. The packet refuses to build if the finished contract does not read back as the deal says — a self-check that has to pass before any bytes are handed over.
The response headers say what happened: X-Recontract-Deal-Id, X-Recontract-Seal-Id, X-Recontract-Contract, and X-Recontract-Deal-Spent, which is 0 when the deal was already paid for. Add ?format=json for the same thing base64-encoded.
The New Home contracts (24-20 and 23-20) are written in the browser, not here. Their self-check reads the finished pages back through a text layer that cannot run at the edge, and a packet nobody has read back is not one we hand over. The API says so with a 501 rather than producing an unchecked contract.
The same API as tools an AI assistant can call — Claude, Cursor, or anything that speaks the Model Context Protocol. The server is one file with no dependencies. There is nothing to install:
curl -O https://recontract.ai/mcp/recontract-mcp.mjs
Claude Code:
claude mcp add recontract --env RECONTRACT_API_KEY=rc_live_… -- node "$PWD/recontract-mcp.mjs"
Anything that reads an mcpServers block:
{
"mcpServers": {
"recontract": {
"command": "node",
"args": ["/path/to/recontract-mcp.mjs"],
"env": { "RECONTRACT_API_KEY": "rc_live_…" }
}
}
}
Twelve tools: account, usage, licence, list_deals, get_deal, save_deal, delete_deal, deal_deadlines, compute_deadlines, list_entities, save_entity, and render_packet — which announces in its own name and twice in its description that it spends a deal. The reading tools are marked read-only so a host can approve them without asking each time.
X-Recontract-Rate-Remaining comes back on every call.GET /api/v1/usage; it is kept six months and goes with your account if you delete it.Every failure is JSON with a sentence and a stable code: missing_key, bad_key, revoked, expired, plan_required, rate_limited, scope, not_found, bad_body, no_deals_left, form_not_written, browser_only, self_check_failed, bad_contract_form, bad_kind, too_large, too_many, unreadable, server_error. A render that fails its own self-check hands the deal back rather than charging for a packet that does not exist.