For AI agents and developers

LitigationWatch for AI agents

Everything an AI agent needs to watch Australian companies for litigation on someone's behalf. It's plain HTTPS and JSON on this website: no SDK, plug-in or MCP server.

How it works

  1. Get access. Ask the account owner to approve you (OAuth device flow). If they have no account yet, approving creates one.
  2. Check the account. GET /api/v1/account returns the plan, usage and next_steps.
  3. Make sure a plan is active. If not, create a payment link and give it to the owner. The owner always pays; agents never pay or change what is charged.
  4. Add companies by full legal name or ACN. Look names up in our directory of 15,340 companies first.
  5. Get alerts: poll GET /api/v1/alerts?since=<last id>, or create an alert rule that POSTs matching alerts to your URL. The owner keeps getting alert emails either way.

Base URL: https://litigationwatch.dev. All API responses are JSON. Every page on this site is also available as Markdown: add .md to the path (/pricing.md, /index.md) or send Accept: text/markdown. Machine-readable: /llms.txt, /openapi.json, OAuth metadata, resource metadata, API catalog.

1. Get access (device flow)

Standard OAuth 2.0 device authorization grant (RFC 8628). No client registration: choose a short client_id for your agent and a client_name the owner will recognise. Add login_hint (the owner's email) and we email them a link to approve; otherwise show them verification_uri_complete.

curl -s https://litigationwatch.dev/oauth/device_authorization \
  -d client_id=my-agent \
  -d client_name="My Agent" \
  -d login_hint=owner@example.com
{
  "device_code": "kV3...",
  "user_code": "BCDF-GHJK",
  "verification_uri": "https://litigationwatch.dev/activate",
  "verification_uri_complete": "https://litigationwatch.dev/activate?code=BCDF-GHJK",
  "expires_in": 900,
  "interval": 5,
  "email_sent": true,
  "instructions": "We emailed owner@example.com a link to approve this request. ..."
}

The owner signs in, checks the code matches and approves. Poll every interval seconds until you get tokens:

curl -s https://litigationwatch.dev/oauth/token \
  -d grant_type=urn:ietf:params:oauth:grant-type:device_code \
  -d device_code=kV3... \
  -d client_id=my-agent

While waiting you get {"error": "authorization_pending"} (keep polling), slow_down (add 5 seconds to your interval), access_denied or expired_token (stop). On approval:

{
  "access_token": "lwat_...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "lwrt_...",
  "scope": "account:read companies:read companies:write ..."
}

Send Authorization: Bearer <access_token> on API calls. Access tokens last an hour. Refresh them before or after they expire; each refresh token works once and returns a new one. Reusing an old refresh token revokes your access, so always store the newest.

curl -s https://litigationwatch.dev/oauth/token \
  -d grant_type=refresh_token \
  -d refresh_token=lwrt_...

Optional parameters: scope (space-separated; omit it to ask for everything below). API keys: owners can also create a key at /app/agents and give it to an agent; send it the same way. It doesn't expire until they remove it.

ScopeLets the agent
account:readSee your account email, plan and usage
companies:readSee your watchlist
companies:writeAdd, edit and remove companies on your watchlist
alerts:readRead your litigation alerts
alerts:writeMark alerts as read or unread
rules:readSee alert rules (where alerts are sent)
rules:writeCreate, change and delete alert rules that send your alerts to web addresses
billing:readSee your plan and billing status
billing:writeCreate payment links for you to open (you always confirm and pay yourself)

2. Check the account

curl -s https://litigationwatch.dev/api/v1/account \
  -H "Authorization: Bearer lwat_..."

Returns account, plan (plan, monitoring_active, company_limit, renews_on, ends_on, payment_overdue), usage, alert counts and next_steps: plain sentences telling you what to do next.

3. Make sure a plan is active

Plans: Standard, US$9 a month for 20 companies; Pro, US$29 a month for 100. Larger watchlists: Corporate. Create a Stripe Checkout link for the owner (it expires in 24 hours). With "email_owner": true we also email it to them.

curl -s https://litigationwatch.dev/api/v1/billing/checkout \
  -H "Authorization: Bearer lwat_..." \
  -H "Content-Type: application/json" \
  -d '{"plan": "standard", "email_owner": true}'

Then poll GET /api/v1/account until plan.monitoring_active is true. Plan changes and cancellations are confirmed by the owner in the app; GET /api/v1/billing gives you the links to send them.

4. Add companies

Courts record parties by their full legal name, so get it exactly. Search our directory (no token needed):

curl -s "https://litigationwatch.dev/api/v1/directory?q=woolworths"

Then add companies: by acn alone if it's in the directory, otherwise by legal_name (with acn or abn if you know it).

curl -s https://litigationwatch.dev/api/v1/companies \
  -H "Authorization: Bearer lwat_..." \
  -H "Content-Type: application/json" \
  -d '{"companies": [
        {"acn": "000014675"},
        {"legal_name": "Example Holdings Pty Ltd", "note": "Parent company"}
      ]}'
{
  "added": 2,
  "results": [
    { "index": 0, "status": "added", "legal_name": "WOOLWORTHS GROUP LIMITED", "company": { "id": "ent_...", ... } },
    { "index": 1, "status": "added", "legal_name": "Example Holdings Pty Ltd", "company": { ... } }
  ],
  "companies_count": 2,
  "company_limit": 20
}

Each result has a status: added, duplicate, invalid, limit_reached (with a hint to upgrade), or needs_confirmation when the name doesn't end like a company name (for example no "Pty Ltd"); resend with "allow_unusual_names": true if it's right. Litigation is often against a parent, subsidiary or trustee company, so add related entities too. New companies are included in the next daily check.

Each company's status is monitored, paused (over the plan limit after a downgrade) or not_monitored (no active plan).

5. Get alerts

Poll

Alert ids only increase. Keep the highest id you've seen and ask for newer ones:

curl -s "https://litigationwatch.dev/api/v1/alerts?since=0&limit=100" \
  -H "Authorization: Bearer lwat_..."

Filters: company_id, jurisdiction (comma-separated: CTH, NSW, VIC, QLD, WA, SA, TAS, ACT, NT), min_confidence (low, medium, high, exact), unread (true/false). Paging: since (ascending) or before with order=desc; limit up to 200; follow next while has_more is true. Mark alerts read with POST /api/v1/alerts/read {"ids": [1042]} or {"all": true}.

{
  "id": 1042,
  "company_id": "ent_...",
  "company_name": "Example Holdings Pty Ltd",
  "court": "Federal Court of Australia",
  "jurisdiction": "CTH",
  "case_number": "NSD 1482/2026",
  "case_title": "Northbridge Capital Pty Ltd v Example Holdings Pty Ltd",
  "party_name": "EXAMPLE HOLDINGS PTY LTD",
  "party_role": "Respondent",
  "event_type": "Originating application filed",
  "event_date": "2026-11-04",
  "summary": "Claim for breach of a supply agreement.",
  "source_url": "https://www.fedcourt.gov.au/...",
  "confidence": "exact",
  "detected_at": "2026-11-05T21:14:03.000Z",
  "read": false,
  "app_url": "https://litigationwatch.dev/app/alerts/1042"
}

confidence says how sure the match is: exact (the legal name as recorded), high, medium (possible match) or low.

Alert rules (push)

A rule sends matching alerts to your HTTPS endpoint, as they happen (checked every 5 minutes) or once a day as a digest. Only alerts found after the rule is created are sent. Up to 20 rules per account.

curl -s https://litigationwatch.dev/api/v1/alert-rules \
  -H "Authorization: Bearer lwat_..." \
  -H "Content-Type: application/json" \
  -d '{
        "name": "Federal and NSW, high confidence",
        "url": "https://agent.example.com/hooks/litigation",
        "filter": { "jurisdictions": ["CTH", "NSW"], "min_confidence": "high" },
        "schedule": "instant"
      }'
  • filter (all optional, combined with AND): company_ids (from GET /api/v1/companies), jurisdictions, min_confidence, keywords (any of them, matched in the court, case title, parties, event or summary).
  • schedule: instant (default) or daily, with daily_hour_utc 0–23 (default 22, which is morning on the Australian east coast).
  • url: a public https:// address on the default port. Redirects are not followed.

The response includes a secret, shown once. Test the endpoint with POST /api/v1/alert-rules/{id}/test. Each delivery looks like this:

POST https://agent.example.com/hooks/litigation
Content-Type: application/json
LitigationWatch-Signature: t=1794022334,v1=5f2c...
LitigationWatch-Rule: rule_...
LitigationWatch-Delivery: rule_...-881-2

{
  "type": "alerts",
  "rule": { "id": "rule_...", "name": "Federal and NSW, high confidence" },
  "sent_at": "2026-11-05T21:15:00.000Z",
  "alerts": [ { "id": 1042, "court": "Federal Court of Australia", ... } ]
}

Verify the signature: HMAC-SHA256 with the secret over <t>.<raw body>, compared with v1. Reject requests more than 5 minutes old.

import crypto from "node:crypto";

function verify(rawBody, header, secret) {
  const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
  if (Math.abs(Date.now() / 1000 - Number(parts.t)) > 300) return false;
  const expected = crypto.createHmac("sha256", secret).update(parts.t + "." + rawBody).digest("hex");
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}
import hashlib, hmac, time

def verify(raw_body: bytes, header: str, secret: str) -> bool:
    parts = dict(p.split("=", 1) for p in header.split(","))
    if abs(time.time() - int(parts["t"])) > 300:
        return False
    expected = hmac.new(secret.encode(), parts["t"].encode() + b"." + raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, parts["v1"])

Answer with any 2xx status within 10 seconds. Failed deliveries are retried after 1 minute, 5 minutes, 30 minutes, 2, 6 and 12 hours. After 20 failed deliveries in a row the rule is paused; resume it with POST /api/v1/alert-rules/{id} {"enabled": true}. The owner can see and delete every rule.

All endpoints

MethodPathScopePurpose
POST/oauth/device_authorization—Ask the owner for access (device flow)
POST/oauth/token—Poll for tokens; refresh tokens
POST/oauth/revoke—Revoke a token or API key
GET/api/v1/accountaccount:readPlan, usage, alert counts and next steps
GET/api/v1/directory?q=—Find a company's exact legal name and ACN
GET/api/v1/companiescompanies:readList the watchlist
POST/api/v1/companiescompanies:writeAdd up to 200 companies
GET/api/v1/companies/{id}companies:readOne company
POST/api/v1/companies/{id}companies:writeChange legal name, ACN/ABN or note
POST/api/v1/companies/{id}/deletecompanies:writeRemove from the watchlist
GET/api/v1/alertsalerts:readAlerts, filtered and paged by id
GET/api/v1/alerts/{id}alerts:readOne alert
POST/api/v1/alerts/readalerts:writeMark alerts read or unread
GET/api/v1/alert-rulesrules:readList alert rules
POST/api/v1/alert-rulesrules:writeCreate a rule (webhook)
GET/api/v1/alert-rules/{id}rules:readA rule and its recent deliveries
POST/api/v1/alert-rules/{id}rules:writeChange a rule (any field, or enabled)
POST/api/v1/alert-rules/{id}/testrules:writeSend a sample alert to the URL now
POST/api/v1/alert-rules/{id}/rotate-secretrules:writeNew signing secret
POST/api/v1/alert-rules/{id}/deleterules:writeDelete a rule
GET/api/v1/billingbilling:readPlan, prices and links for the owner
POST/api/v1/billing/checkoutbilling:writePayment link for the owner to open

Only GET and POST are used. The full schema is at /openapi.json.

Errors and limits

Errors use RFC 9457 problem details with a hint saying what to do next. OAuth endpoints use the standard {"error", "error_description"} form.

HTTP/1.1 402 Payment Required
Content-Type: application/problem+json

{
  "type": "https://litigationwatch.dev/agents#errors",
  "title": "plan_required",
  "status": 402,
  "detail": "This account has no active plan, so companies can't be added yet.",
  "hint": "Create a payment link with POST /api/v1/billing/checkout {\"plan\":\"standard\"} and give it to owner@example.com. Once they pay, retry."
}

Common title values: invalid_token, token_expired (refresh it), insufficient_scope, plan_required, invalid_field (with field), not_found, rate_limited (with retry_after and a Retry-After header). Limits: 120 API requests a minute per agent; 60 directory searches a minute per IP; 10 access requests per 10 minutes per IP.

Acting for the owner

  • Act only on the owner's instructions. They approve your access, see everything you set up at /app/agents, and can remove it at any time.
  • Never pay or try to get around payment. Send the owner a link; they decide.
  • Company pages in our directory don't list court cases and don't suggest a company is involved in any. Don't present them as evidence of litigation.
  • We can only see what courts and tribunals publish. Suppressed or confidential matters aren't visible to anyone outside the court. Alerts aren't legal advice.

Questions: contact support.

Are you sure?