The contract
MASTER SERVICES AGREEMENT
→
What comes back
contract_type96%
auto_renewal96%
notice_days97%
liability_cap95%
key_clauses94%
NodesCredits60 per pageYou get
The workflow
Upload now, run later, poll
Contracts often arrive in batches and get reviewed later. Upload each one as a document packet as it arrives, and start the run when you are ready. Then pollGET /v3/runs/{run_id}/ until status is processed. error and cancelled are terminal too, so stop on those.
Response
Theresults envelope of a processed run, trimmed. Every value is a string on the wire: a multi_select is one comma-separated string of option names, with one evidence snippet per clause, and a boolean is "True" or "False".
Response
verification_status and value_override. Runs and results has the full envelope, section by section.
Rule outcomes (pass, fail, inconclusive) appear in the Validation tab of the run in Studio, next to the extracted values. On this contract notice-at-least-90-days fails, because the notice period is 60 days. To act on a failure automatically, route the run with an If/Else node and send a Slack alert or an email alert.
When it goes wrong
A clause you care about never appears inkey_clauses. A multi_select returns only the option names you declared, so an assignment clause or a most-favoured-nation term has nothing to match among the seven listed here. Add the option. Remember the field tells you a clause is present, not what it says: add a string field for each clause whose wording you need to read.
key_clauses is one string, not a list. Every value is a string on the wire, and a multi_select arrives as its option names joined with ", ". Split on that before you test for membership. A boolean behaves the same way: auto_renewal comes back as "True", not as JSON true.
A range rule has nothing to compare. A range check needs the number you declared. Declare termination_notice_days as integer, so { "type": "range", "min": 90 } compares numbers and your calendar math works on the value directly. Declare effective_date and expiration_date as date for the same reason: term-is-ordered compares them.
A failed rule did not stop anything. severity is a label. A failed error rule never blocks the run; it tells the reviewer where to look first. Read the outcomes in the Validation tab of the run in Studio. To act on a failure automatically, route the run with an If/Else node and end that branch in a Slack alert.
Validation costs more than you expected. An AI rule costs 5 credits, billed once per rule per extraction, not per page. A deterministic rule, including an expression, costs nothing. Use a deterministic rule for anything a calculator can check: it is instant, free and never flakes. A required check on liability_cap is the cheapest way to flag an uncapped contract. Keep AI rules for judgement calls, like whether the indemnification clause protects the Client.
Next steps
Validate node
Every check type, expressions and severities
Run document packet
Run or re-run a packet you uploaded earlier

