Developer API ยท v1.1

Quickstart

Make your first verification request in under five minutes.

Before you begin, you’ll need a GhostCite API token. Generate one from your account’s Developer Tools, and send it as a bearer token on every request. See Authentication to get your key.

The endpoint

Send a POST to https://app.rule26ai.com/api/v1/verify with a JSON body of items. Each item has an id (a client-supplied string echoed back on the matching result), a type, and the text to verify. You can mix item types in a single request.

Supported item types

The type field is a fixed v1 value set:

Most types carry their text in rawText. The exceptions are quote, which uses quoteText and links to its citation via parentCaseId, and link, which uses url. The API Reference is the authoritative schema for each type’s fields and constraints. The examples below cover the two most common types, case and quote.

1. Make a request

curl

curl https://app.rule26ai.com/api/v1/verify \
  -H "Authorization: Bearer $GHOSTCITE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      { "id": "r_1", "type": "case", "rawText": "Smith v. Jones, 200 F.3d 1 (2001)" }
    ]
  }'

JavaScript (fetch)

const res = await fetch("https://app.rule26ai.com/api/v1/verify", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.GHOSTCITE_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    items: [
      { id: "r_1", type: "case", rawText: "Smith v. Jones, 200 F.3d 1 (2001)" },
    ],
  }),
});
const data = await res.json();
console.log(data.results[0].verdict.status); // "warning"

Python (requests)

import os, requests

res = requests.post(
    "https://app.rule26ai.com/api/v1/verify",
    headers={"Authorization": f"Bearer {os.environ['GHOSTCITE_API_KEY']}"},
    json={"items": [
        {"id": "r_1", "type": "case", "rawText": "Smith v. Jones, 200 F.3d 1 (2001)"},
    ]},
)
data = res.json()
print(data["results"][0]["verdict"]["status"])  # "warning"

2. Read the response

{
  "results": [
    {
      "id": "r_1",
      "type": "case",
      "citation": { "raw": "Smith v. Jones, 200 F.3d 1 (2001)" },
      "verdict": {
        "status": "warning",
        "outcome": "mismatch",
        "message": "Decision year does not match the resolved authority."
      },
      "opinion": {
        "caseName": "Smith v. Jones",
        "court": { "name": "9th Circuit" },
        "year": 1999,
        "documents": [
          { "provider": "courtlistener", "url": "https://www.courtlistener.com/opinion/..." }
        ]
      },
      "evidence": {
        "comparisons": [
          { "attribute": "year", "cited": "2001", "found": "1999", "match": false }
        ]
      }
    }
  ],
  "summary": {
    "verified": 0, "warning": 1, "critical": 0, "total": 1,
    "unique_citations": 1, "billed_citations": 1,
    "is_fully_verified": false, "is_fully_accounted": true,
    "overallStatus": "warning"
  },
  "usage": { "used": 1, "remaining": 99, "limit": 100 }
}

verdict: the answer

Every result carries a verdict. status is a closed set: verified, warning, or critical. outcome is a finer, open category (e.g. verified, mismatch, not_found), and message is human-readable prose you can surface to users. Above, the case resolved but the cited year is off, a warning.

evidence: the “why”

When the engine performed a deterministic comparison, evidence.comparisons lists each one as { attribute, cited, found, match }. Here, the year the user cited (2001) differs from the authority’s (1999), so match: false. Iterate the comparisons to show an “expected vs. found” view. Read Structured Evidence before you rely on this, because a missing comparison means “not compared,” never “mismatch.”

opinion: the authority

When an authority resolves, opinion gives you the resolved case name, court, year, and inspectable documents (links to the court record). Use it to let reviewers open the source.

usage: your quota

Every response includes usage with used, remaining, and limit for the current window. Watch usage.remaining to pace your calls; see Errors & Rate Limits for what happens when it hits zero.

Verify a quotation

A quote item checks whether a passage actually appears in a resolved authority. It attaches to the citation it came from through parentCaseId, so submit the parent case and the quote together:

curl https://app.rule26ai.com/api/v1/verify \
  -H "Authorization: Bearer $GHOSTCITE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      { "id": "r_1", "type": "case",
        "rawText": "Brown v. Board of Education, 347 U.S. 483 (1954)" },
      { "id": "q_1", "type": "quote",
        "quoteText": "separate educational facilities are inherently unequal",
        "parentCaseId": "r_1" }
    ]
  }'

The response carries one result per item. The quotation result adds a quote object:

{
  "results": [
    {
      "id": "r_1",
      "type": "case",
      "citation": { "raw": "Brown v. Board of Education, 347 U.S. 483 (1954)", "normalized": "347 U.S. 483" },
      "verdict": { "status": "verified", "outcome": "verified", "message": "Citation verified." },
      "opinion": {
        "caseName": "Brown v. Board of Education",
        "court": { "name": "Supreme Court of the United States" },
        "year": 1954
      }
    },
    {
      "id": "q_1",
      "type": "quote",
      "citation": { "raw": "347 U.S. 483" },
      "verdict": { "status": "verified", "outcome": "verified", "message": "Quotation located in the authority." },
      "quote": {
        "matched": true,
        "snippet": "separate educational facilities are inherently unequal"
      }
    }
  ],
  "summary": {
    "verified": 2, "warning": 0, "critical": 0, "total": 2,
    "unique_citations": 1, "billed_citations": 1,
    "is_fully_verified": true, "is_fully_accounted": true,
    "overallStatus": "verified"
  },
  "usage": { "used": 1, "remaining": 99, "limit": 100 }
}

Reading the quotation result:

Reserved fields: the matched passage as it appears in the authority (quote.passage), its location (quote.location), the response link back to the parent (citationId), and document position are reserved for a future version and are not emitted in v1.1. Treat their absence as “not yet available,” not as failure. The API Reference marks each reserved field.

Reading a verification result

You know JSON; these are the GhostCite semantics to build on:

Next

Structured Evidence Full API Reference Errors & Rate Limits