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
- Get access. Ask the account owner to approve you (OAuth device flow). If they have no account yet, approving creates one.
- Check the account.
GET /api/v1/accountreturns the plan, usage andnext_steps. - 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.
- Add companies by full legal name or ACN. Look names up in our directory of 15,340 companies first.
- 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.
| Scope | Lets the agent |
|---|---|
account:read | See your account email, plan and usage |
companies:read | See your watchlist |
companies:write | Add, edit and remove companies on your watchlist |
alerts:read | Read your litigation alerts |
alerts:write | Mark alerts as read or unread |
rules:read | See alert rules (where alerts are sent) |
rules:write | Create, change and delete alert rules that send your alerts to web addresses |
billing:read | See your plan and billing status |
billing:write | Create 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(fromGET /api/v1/companies),jurisdictions,min_confidence,keywords(any of them, matched in the court, case title, parties, event or summary).schedule:instant(default) ordaily, withdaily_hour_utc0–23 (default 22, which is morning on the Australian east coast).url: a publichttps://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
| Method | Path | Scope | Purpose |
|---|---|---|---|
| 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/account | account:read | Plan, usage, alert counts and next steps |
| GET | /api/v1/directory?q= | — | Find a company's exact legal name and ACN |
| GET | /api/v1/companies | companies:read | List the watchlist |
| POST | /api/v1/companies | companies:write | Add up to 200 companies |
| GET | /api/v1/companies/{id} | companies:read | One company |
| POST | /api/v1/companies/{id} | companies:write | Change legal name, ACN/ABN or note |
| POST | /api/v1/companies/{id}/delete | companies:write | Remove from the watchlist |
| GET | /api/v1/alerts | alerts:read | Alerts, filtered and paged by id |
| GET | /api/v1/alerts/{id} | alerts:read | One alert |
| POST | /api/v1/alerts/read | alerts:write | Mark alerts read or unread |
| GET | /api/v1/alert-rules | rules:read | List alert rules |
| POST | /api/v1/alert-rules | rules:write | Create a rule (webhook) |
| GET | /api/v1/alert-rules/{id} | rules:read | A rule and its recent deliveries |
| POST | /api/v1/alert-rules/{id} | rules:write | Change a rule (any field, or enabled) |
| POST | /api/v1/alert-rules/{id}/test | rules:write | Send a sample alert to the URL now |
| POST | /api/v1/alert-rules/{id}/rotate-secret | rules:write | New signing secret |
| POST | /api/v1/alert-rules/{id}/delete | rules:write | Delete a rule |
| GET | /api/v1/billing | billing:read | Plan, prices and links for the owner |
| POST | /api/v1/billing/checkout | billing:write | Payment 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.