version90 DEVELOPERS

REST API / AI

AI review & explanations

The trust model carries over the API unchanged: every finding cites contract text, and evidence_verified tells you the quote was deterministically located in the document. AI actions debit AI credits (review = 10, explain = 2); failed runs are voided automatically.

POST /api/v1/versions/{id}/analyze #

Queue a full AI review of a DOCX version: clause segmentation, metadata extraction, baseline comparison (when a baseline is pinned), risk findings with verified evidence, and a summary. Asynchronous — poll GET /analysis until run.status is 'complete' (or 'partial'/'failed').

Auth · Bearer token · reviewer role or above · 10 AI credits

Parameter In Type Required Description
id path uuid yes Version id (ready DOCX)
mode body enum no full (default) | delta | selected_text | focused
Request
curl -X POST "https://app.version90.com/api/v1/versions/$VID/analyze" \
  -H "Authorization: Bearer $V90_TOKEN" \
  -H "Content-Type: application/json" -d '{"mode": "full"}'
202
{ "run_id": "c5d6e7f8-…", "status": "queued" }

Errors

  • 402 allowance_exhaustedmonthly AI credits used (production)
  • 403 user_ai_limit / user_ai_blockedadmin capped the token creator's AI usage
  • 422version is not a ready DOCX
GET /api/v1/versions/{id}/analysis #

The latest analysis for a version: the run (with per-stage progress), all findings, and extracted metadata suggestions. Returns {run: null, findings: [], metadata: []} when nothing has run yet.

Auth · Bearer token · any member

Parameter In Type Required Description
id path uuid yes Version id
Request
curl "https://app.version90.com/api/v1/versions/$VID/analysis" \
  -H "Authorization: Bearer $V90_TOKEN"
200
{
  "run": {
    "id": "c5d6e7f8-…",
    "mode": "full",
    "status": "complete",          // queued | running | complete | partial | failed
    "provider": "anthropic",
    "model_id": "claude-sonnet-5",
    "analyzer_version": "p6.1",
    "pinned_baseline_version_id": "a1b2c3d4-…",
    "stages": {
      "segment":             { "status": "complete", "count": 42 },
      "metadata":            { "status": "complete" },
      "align_findings":      { "status": "complete", "proposed": 9 },
      "evidence_validation": { "status": "complete", "validated": 7, "suppressed": 2 },
      "dedup":               { "status": "complete", "kept": 6 },
      "summary":             { "status": "complete" }
    },
    "summary": "Six findings; liability and payment terms need attention…",
    "error": null,
    "created_at": "2026-07-11T18:20:03+00:00"
  },
  "findings": [ /* finding objects — below */ ],
  "metadata": [{
    "id": "f0e1d2c3-…",
    "field": "payment_terms",       // contract_type, parties, effective_date, …
    "value": "Net 60",
    "evidence": "Invoices are payable within sixty (60) days…",
    "confidence": 0.95,
    "confirmed": false,
    "confirmed_value": null,
    "status": "suggested"           // suggested | confirmed (by a human)
  }]
}

The finding object

{
  "id": "4b8c1d2e-…",
  "title": "Liability is uncapped",
  "finding_type": "nonstandard",     // deviation | changed_value |
                                     // missing_clause | policy_conflict | nonstandard
  "impact_domains": ["liability"],
  "description": "No aggregate cap and no consequential-damages exclusion.",
  "current_evidence": "…each party shall be liable for all damages…",
  "current_anchor": "6A3F2B1C",      // paragraph anchor the quote was verified at
  "baseline_evidence": "",           // the baseline language it deviates from
  "knowledge_evidence": "",          // conflicting internal-policy passage
  "knowledge_citation": "",
  "why_it_matters": "Your standard caps liability at 12 months of fees…",
  "practical_impact": "A single incident could exceed contract value…",
  "recommended_action": "Insert the standard cap clause.",
  "suggested_language": "Liability under this Agreement shall not exceed…",
  "suggestion_source": "baseline",
  "confidence": 0.92,
  "uncertainty": "",
  "evidence_verified": true,         // quote deterministically located in the doc
  "state": "open",                   // open | unverified | accepted | dismissed |
                                     // suggestion_applied
  "decision_reason": "",
  "applied_version_id": null
}

Treat evidence_verified: false findings as unanchored observations (e.g. a missing clause has no quote to verify). Findings whose claimed citation failed verification are suppressed server-side — you never see them.

POST /api/v1/versions/{id}/changes:explain #

Plain-English implications of ONE unresolved tracked change, reasoned against the whole document (terms interlace — a notice-period edit means something different depending on the renewal clause). Synchronous; typically a few seconds. Requires the AI provider to be configured.

Auth · Bearer token · any member · 2 AI credits

Parameter In Type Required Description
id path uuid yes Version id (ready DOCX)
rid body string yes Revision id from GET /versions/{id}/revisions
Request
curl -X POST "https://app.version90.com/api/v1/versions/$VID/changes:explain" \
  -H "Authorization: Bearer $V90_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"rid": "word/document.xml:0"}'
200
{
  "explanation": "Accepting this extends the non-renewal notice from 30 to 60 days. Combined with the auto-renewal in §7.1, missing the window commits you to another 24-month term…",
  "provider": "anthropic",
  "model_id": "claude-sonnet-5",
  "change": {
    "type": "insert",
    "author": "Dana Ferro [Meridian Robotics]",
    "text": "sixty (60)"
  }
}

Errors

  • 404rid not found in this version
  • 502model call failed — the document is unaffected; retry
  • 503AI provider not configured on this deployment