API documentation

The public, read-only interface to the TOSWO AI risk monitor and incident record. No key, no sign-up, JSON over HTTPS.

Introduction

The TOSWO API publishes the same data that drives the public monitor at toswo.com/monitor and the incident record since 2018: the current AI risk level and why it was set, the status of every monitored system, every public event with its evidence mix, and yearly counts. It is meant for researchers, journalists, newsrooms and anyone who wants to cite or redistribute the data.

Base URLhttps://api.toswo.com

All responses are JSON encoded as UTF-8 unless an endpoint says otherwise. Times are ISO 8601 in UTC, for example 2026-10-09T14:05:40.000Z. Fields without a value are returned as null rather than left out. Response examples on this page show the exact shape of each object; the values in them are illustrative.

The same paths are also served on the main site, so https://toswo.com/v1/level and https://api.toswo.com/v1/level return the same document.

Access and limits

  • No key. Every read endpoint is open. There is nothing to register and no token to send.
  • CORS. All GET responses, errors included, carry access-control-allow-origin: *, so they can be read from a browser on any site.
  • Caching. Each GET sends cache-control: public, max-age=N, s-maxage=N, stale-while-revalidate=4N. N is 15 seconds for the level, status and events, 30 to 60 seconds for systems, single events, the badge, the CSV, the feed and publications, 300 seconds for yearly history and one hour for labels. Polling faster than N returns the same document.
  • Rate limits. 300 requests per minute per IP address across the whole API. POST /v1/reports is limited to 5 per hour per IP address and report tracking to 30 per minute. Every response carries x-ratelimit-limit, x-ratelimit-remaining and x-ratelimit-reset (seconds); a 429 also carries retry-after.

If you need the full record, download the CSV once rather than paging through /v1/events. For sustained or bulk use, contact us.

Versioning

Everything under /v1 changes additively only. We may add endpoints, fields, query parameters and new values for enumerations such as category or source. We do not rename, remove or change the type or meaning of an existing field within /v1. Clients should ignore fields they do not recognise and handle unknown enumeration values gracefully.

A breaking change will be published under /v2, announced in advance on this page, with /v1 kept running alongside it during the transition. The unversioned /feed.xml and /embed/status follow the same rule.

Licence and citation

TOSWO data is free to use, cite and redistribute with attribution. Credit TOSWO and link to the event's url or to toswo.com/data.

Events imported from the AI Incident Database (source is aiid) remain under that project's CC BY-SA 4.0 licence. Credit the AI Incident Database, link the record in sourceUrl, and share adapted datasets that include those records under the same licence.

Please cite as:

TOSWO AI risk monitor, event {slug}, retrieved {date}.

For example: TOSWO AI risk monitor, event 2026-10-09-false-answers-in-the-deception-canary-suite-q7k2, retrieved 9 October 2026.

Status

GET/v1/status

Everything the monitor shows in one document: level, systems, live events, regions, evidence streams and 30 days of level history.

No query parameters · cached 15 s

Request
curl https://api.toswo.com/v1/status
Response 200 (arrays shortened)
{
  "level": 3,
  "levelName": "Elevated",
  "levelText": "Confirmed anomalous behavior in at least one widely used system.",
  "score": 5.3,
  "reason": "Two systems show anomalous behavior and one is offline. Set automatically from probes and public reports.",
  "changedAt": "2026-10-09T08:41:03.000Z",
  "generatedAt": "2026-10-09T14:12:07.000Z",
  "observedAt": "2026-10-09T14:12:03.000Z",
  "counts": {
    "systems": 6,
    "affected": 3,
    "regions": 16,
    "activeEvents": 5,
    "probesPerHour": 1080,
    "reports24h": 120,
    "countries24h": 16
  },
  "systems": [
    {
      "slug": "openai-api",
      "name": "OpenAI API",
      "provider": "OpenAI",
      "kind": "Frontier models",
      "status": "anom",
      "summary": "Deception canary failure rate +3.1σ",
      "latencyMs": 412,
      "history": ["ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "anom", "anom", "anom", "anom", "anom", "anom", "anom", "anom"]
    }
  ],
  "events": [
    {
      "id": "d054d85d-3eb7-403e-99db-8efa36c12a81",
      "slug": "2026-10-09-false-answers-in-the-deception-canary-suite-q7k2",
      "title": "False answers in the deception canary suite",
      "summary": "Canary prompts that check for deliberate misstatements failed at three times the usual rate for six hours.",
      "category": "deception",
      "state": "confirmed",
      "confidence": 74,
      "probeShare": 70,
      "reportCount": 212,
      "systems": ["OpenAI API"],
      "regions": ["US", "GB", "DE"],
      "auto": false,
      "startedAt": "2026-10-09T08:30:12.000Z",
      "updatedAt": "2026-10-09T14:05:40.000Z",
      "resolvedAt": null,
      "url": "https://toswo.com/events/2026-10-09-false-answers-in-the-deception-canary-suite-q7k2",
      "source": "toswo",
      "sourceUrl": null
    }
  ],
  "regions": [
    {
      "country": "DE",
      "lat": 51.2,
      "lon": 10.4,
      "status": "anom",
      "reports": 8,
      "incidents": 1,
      "probeFailures": 0
    }
  ],
  "signals": [
    {
      "key": "http",
      "title": "Availability probes",
      "text": "6 endpoints, checked every minute",
      "value": "360/h"
    },
    {
      "key": "statuspage",
      "title": "Provider status pages",
      "text": "Official incident feeds, read every minute",
      "value": "2 feeds"
    },
    {
      "key": "canary",
      "title": "Behavior canaries",
      "text": "Fixed prompts that test for deception, refusal drift and unsafe actions",
      "value": "720/h"
    },
    {
      "key": "reports",
      "title": "Public reports",
      "text": "Weighted by each reporter's track record",
      "value": "120 / 24h"
    }
  ],
  "history": [
    {
      "day": "2026-10-08",
      "level": 2
    },
    {
      "day": "2026-10-09",
      "level": 3
    }
  ],
  "method": "https://toswo.com/method"
}

Fields

FieldTypeMeaning
levelintegerCurrent level, 1 to 5, as in /v1/level.
levelNamestringName of the level; name in /v1/level.
levelTextstringStandard description of the level; text in /v1/level.
scorenumberWeighted evidence score behind the level. Its scale is described in the method.
reasonstringWhy the level is what it is now.
changedAtdate-timeWhen the level was last set.
generatedAtdate-timeWhen this document was computed.
observedAtdate-time | nullWhen a probe last ran. Use this, not generatedAt, to judge how fresh the data is.
countsobjectsystems, affected, regions, activeEvents, probesPerHour, reports24h, countries24h, all integers.
systemsSystem[]Every monitored system, as in /v1/systems.
eventsEvent[]Up to 20 live-monitor events (source is always toswo), open events first, then by last update.
regionsobject[]Countries with public reports in the last 24 hours or a publicly reported incident in the last 12 months: country (ISO 3166-1 alpha-2), lat, lon, status, reports (last 24 hours), incidents (last 12 months), probeFailures.
signalsobject[]The four evidence streams with a short live figure: key, title, text, value.
historyobject[]The highest level of each of the last 30 days, oldest first: day (YYYY-MM-DD) and level.
methodurlLink to the published method.

Level

GET/v1/level

The current AI risk level, its standard description and the reason it was set. The smallest document to poll.

No query parameters · cached 15 s · fields: Level

Request
curl https://api.toswo.com/v1/level
Response 200
{
  "level": 3,
  "name": "Elevated",
  "text": "Confirmed anomalous behavior in at least one widely used system.",
  "reason": "Two systems show anomalous behavior and one is offline. Set automatically from probes and public reports.",
  "changedAt": "2026-10-09T08:41:03.000Z",
  "generatedAt": "2026-10-09T14:12:07.000Z",
  "affectedSystems": 3
}

Systems

GET/v1/systems

Every monitored system with its current status and the last 24 hours in half-hour steps.

No query parameters · cached 30 s · fields: System

Request
curl https://api.toswo.com/v1/systems
Response 200
{
  "systems": [
    {
      "slug": "openai-api",
      "name": "OpenAI API",
      "provider": "OpenAI",
      "kind": "Frontier models",
      "status": "anom",
      "summary": "Deception canary failure rate +3.1σ",
      "latencyMs": 412,
      "history": ["ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "anom", "anom", "anom", "anom", "anom", "anom", "anom", "anom"]
    },
    {
      "slug": "mistral-api",
      "name": "Mistral API",
      "provider": "Mistral AI",
      "kind": "Frontier models",
      "status": "out",
      "summary": "Unreachable from 4 of 5 probe regions",
      "latencyMs": null,
      "history": ["ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "ok", "deg", "out", "out", "out"]
    }
  ]
}

Events

GET/v1/events

Events from the live monitor and the imported record, filtered and ordered as requested.

Cached 15 s · fields: Event

Query parameters

NameTypeDefaultMeaning
limitinteger25Number of events to return, 1 to 100.
statestringnoneOnly events in this state: watching, developing, confirmed, resolved.
systemstringnoneOnly events that involve this system, by its slug from /v1/systems, for example openai-api.
sourcestringnoneOnly events from this source: toswo for the live monitor, aiid for the imported AI Incident Database record.
categorystringnoneOnly events in this category: deception, unauthorized, replication, manipulation, exfiltration, bypass, shutdown, outage, other.
fromdatenoneOnly events that started on or after this date or date-time (ISO 8601, UTC).
todatenoneOnly events that started before this date or date-time. Exclusive: to=2027-01-01 ends with 31 December 2026.
beforedate-timenoneOnly events whose updatedAt is earlier than this, or whose startedAt is earlier when order=started. Use it to page backwards.
orderstringupdatedupdated: open events first, then by last update, newest first. started: strictly by start time, newest first.

Without source, both live and imported events are returned. To page through results, pass order=started and set before to the startedAt of the last event you received. Imported events are dated to the day, so several can share a start time; to take the whole record without gaps, use the CSV or narrow by from and to.

Request
curl "https://api.toswo.com/v1/events?state=confirmed&system=openai-api&limit=10"

curl "https://api.toswo.com/v1/events?source=aiid&from=2022-01-01&to=2023-01-01&order=started"
Response 200
{
  "events": [
    {
      "id": "d054d85d-3eb7-403e-99db-8efa36c12a81",
      "slug": "2026-10-09-false-answers-in-the-deception-canary-suite-q7k2",
      "title": "False answers in the deception canary suite",
      "summary": "Canary prompts that check for deliberate misstatements failed at three times the usual rate for six hours.",
      "category": "deception",
      "state": "confirmed",
      "confidence": 74,
      "probeShare": 70,
      "reportCount": 212,
      "systems": ["OpenAI API"],
      "regions": ["US", "GB", "DE"],
      "auto": false,
      "startedAt": "2026-10-09T08:30:12.000Z",
      "updatedAt": "2026-10-09T14:05:40.000Z",
      "resolvedAt": null,
      "url": "https://toswo.com/events/2026-10-09-false-answers-in-the-deception-canary-suite-q7k2",
      "source": "toswo",
      "sourceUrl": null
    },
    {
      "id": "5b0e2c4a-91d7-4f3e-8a26-0c7d9e1f4b38",
      "slug": "aiid-999901",
      "title": "Customer service chatbot states a refund policy that does not exist",
      "summary": "A support chatbot told a customer that a discount could be claimed retroactively, contradicting the company's published policy.",
      "category": "deception",
      "state": "resolved",
      "confidence": 70,
      "probeShare": 0,
      "reportCount": 0,
      "systems": [],
      "regions": [],
      "auto": false,
      "startedAt": "2022-11-11T00:00:00.000Z",
      "updatedAt": "2022-11-11T00:00:00.000Z",
      "resolvedAt": "2022-11-11T00:00:00.000Z",
      "url": "https://toswo.com/events/aiid-999901",
      "source": "aiid",
      "sourceUrl": "https://incidentdatabase.ai/cite/999901"
    }
  ]
}

One event

GET/v1/events/{slug}

A single public event with its full description and timeline.

Cached 30 s · 404 not_found for an unknown slug · fields: Event

Request
curl https://api.toswo.com/v1/events/2026-10-09-false-answers-in-the-deception-canary-suite-q7k2
Response 200
{
  "id": "d054d85d-3eb7-403e-99db-8efa36c12a81",
  "slug": "2026-10-09-false-answers-in-the-deception-canary-suite-q7k2",
  "title": "False answers in the deception canary suite",
  "summary": "Canary prompts that check for deliberate misstatements failed at three times the usual rate for six hours.",
  "category": "deception",
  "state": "confirmed",
  "confidence": 74,
  "probeShare": 70,
  "reportCount": 212,
  "systems": ["OpenAI API"],
  "regions": ["US", "GB", "DE"],
  "auto": false,
  "startedAt": "2026-10-09T08:30:12.000Z",
  "updatedAt": "2026-10-09T14:05:40.000Z",
  "resolvedAt": null,
  "url": "https://toswo.com/events/2026-10-09-false-answers-in-the-deception-canary-suite-q7k2",
  "source": "toswo",
  "sourceUrl": null,
  "body": "Between 08:30 and 14:30 UTC the deception canaries returned knowingly false answers in 9% of runs, against a baseline of 3%.",
  "updates": [
    {
      "at": "2026-10-09T14:05:40.000Z",
      "text": "Confirmed by a researcher after review of the canary transcripts.",
      "auto": false
    },
    {
      "at": "2026-10-09T08:30:12.000Z",
      "text": "Opened automatically from probe results.",
      "auto": true
    }
  ]
}

Events as CSV

GET/v1/events.csv

The same events as a CSV file for spreadsheets and statistics packages, up to 10,000 rows per request.

Cached 60 s · content-type: text/csv; charset=utf-8 · downloads as toswo-events.csv

Query parameters

NameTypeDefaultMeaning
statestringnoneOnly events in this state: watching, developing, confirmed, resolved.
systemstringnoneOnly events that involve this system, by its slug from /v1/systems, for example openai-api.
sourcestringnoneOnly events from this source: toswo for the live monitor, aiid for the imported AI Incident Database record.
categorystringnoneOnly events in this category: deception, unauthorized, replication, manipulation, exfiltration, bypass, shutdown, outage, other.
fromdatenoneOnly events that started on or after this date or date-time (ISO 8601, UTC).
todatenoneOnly events that started before this date or date-time. Exclusive: to=2027-01-01 ends with 31 December 2026.
beforedate-timenoneOnly events whose updatedAt is earlier than this, or whose startedAt is earlier when order=started. Use it to page backwards.

Rows are ordered as in /v1/events by default (open events first, then by last update). Every value is quoted; empty and null values are written as "". The systems column joins names with "; ". Columns: id, started_at, updated_at, resolved_at, state, category, confidence, probe_share, report_count, systems, title, url, source, source_url.

Request
curl -o toswo-events.csv "https://api.toswo.com/v1/events.csv?from=2026-01-01"
Response 200
id,started_at,updated_at,resolved_at,state,category,confidence,probe_share,report_count,systems,title,url,source,source_url
"d054d85d-3eb7-403e-99db-8efa36c12a81","2026-10-09T08:30:12.000Z","2026-10-09T14:05:40.000Z","","confirmed","deception","74","70","212","OpenAI API","False answers in the deception canary suite","https://toswo.com/events/2026-10-09-false-answers-in-the-deception-canary-suite-q7k2","toswo",""
"5b0e2c4a-91d7-4f3e-8a26-0c7d9e1f4b38","2022-11-11T00:00:00.000Z","2022-11-11T00:00:00.000Z","2022-11-11T00:00:00.000Z","resolved","deception","70","0","0","","Customer service chatbot states a refund policy that does not exist","https://toswo.com/events/aiid-999901","aiid","https://incidentdatabase.ai/cite/999901"

Yearly history

GET/v1/history/yearly

Event counts per year since 2018, split by source and category, with the licence of each source.

No query parameters · cached 300 s · fields: YearlyHistory

Request
curl https://api.toswo.com/v1/history/yearly
Response 200 (arrays shortened)
{
  "since": "2018-01-01",
  "monitorStart": "2026-03-02T09:00:00.000Z",
  "sources": [
    {
      "key": "toswo",
      "name": "TOSWO monitor",
      "home": "",
      "license": ""
    },
    {
      "key": "aiid",
      "name": "AI Incident Database",
      "home": "https://incidentdatabase.ai",
      "license": "CC BY-SA 4.0"
    },
    {
      "key": "press",
      "name": "Lab disclosures and press",
      "home": "",
      "license": ""
    }
  ],
  "years": [
    {
      "year": 2018,
      "total": 31,
      "bySource": {
        "aiid": 31
      },
      "byCategory": {
        "deception": 4,
        "manipulation": 6,
        "other": 21
      }
    },
    {
      "year": 2026,
      "total": 148,
      "bySource": {
        "aiid": 97,
        "toswo": 51
      },
      "byCategory": {
        "bypass": 19,
        "deception": 33,
        "other": 52,
        "outage": 44
      }
    }
  ],
  "rows": [
    {
      "year": 2018,
      "source": "aiid",
      "category": "deception",
      "count": 4
    },
    {
      "year": 2018,
      "source": "aiid",
      "category": "manipulation",
      "count": 6
    },
    {
      "year": 2018,
      "source": "aiid",
      "category": "other",
      "count": 21
    }
  ]
}

RSS feed

GET/feed.xml

Up to 50 live-monitor events as RSS 2.0, open events first, then by last update. Also served at /v1/feed.xml.

No query parameters · cached 60 s · content-type: application/rss+xml

Each item's title is prefixed with the event state, pubDate is the event's last update and guid is its permalink. The channel description carries the current level.

Request
curl https://api.toswo.com/feed.xml
Response 200 (one item shown)
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>TOSWO AI risk monitor</title>
    <link>https://toswo.com</link>
    <description>Level 3, Elevated. Two systems show anomalous behavior and one is offline. Set automatically from probes and public reports.</description>
    <language>en</language>
    <item>
      <title>[confirmed] False answers in the deception canary suite</title>
      <link>https://toswo.com/events/2026-10-09-false-answers-in-the-deception-canary-suite-q7k2</link>
      <guid isPermaLink="true">https://toswo.com/events/2026-10-09-false-answers-in-the-deception-canary-suite-q7k2</guid>
      <pubDate>Fri, 09 Oct 2026 14:05:40 GMT</pubDate>
      <category>Deception or lying</category>
      <description>Canary prompts that check for deliberate misstatements failed at three times the usual rate for six hours.</description>
    </item>
  </channel>
</rss>

Status badge

GET/embed/status

A small HTML badge with the current level, made to be placed in an iframe on any site. It links to toswo.com.

No query parameters · cached 30 s · content-type: text/html · may be framed by any origin

The badge contains no scripts, has a transparent background, switches to light text for readers who prefer a dark theme and fits the 320 by 40 pixel frame in the example. See the embedding example.

Request
curl https://api.toswo.com/embed/status

Publications

GET/v1/publications

The latest published research, guides or method notes, newest first.

Cached 60 s · fields: Publication

Query parameters

NameTypeDefaultMeaning
kindstringpublicationpublication for research reports, guide for practical guides, method for method pages.
limitinteger10Number of items to return, 1 to 50.
Request
curl "https://api.toswo.com/v1/publications?kind=publication&limit=5"
Response 200
{
  "items": [
    {
      "slug": "research/monitoring-method-v2",
      "title": "Monitoring method v2: canaries, probes and reports",
      "description": "The design of the automated monitor and how the level is computed.",
      "kind": "publication",
      "publishedAt": "2026-09-18T10:00:00.000Z"
    }
  ]
}

Labels and levels

GET/v1/meta

Human-readable labels for system statuses and the definition of the five levels, for building your own display.

No query parameters · cached 1 hour

Request
curl https://api.toswo.com/v1/meta
Response 200
{
  "statuses": {
    "ok": "Normal",
    "deg": "Degraded",
    "anom": "Anomalous behavior",
    "out": "Outage"
  },
  "levels": [
    {
      "n": 1,
      "name": "Calm",
      "text": "No unusual behavior or outages detected across monitored systems."
    },
    {
      "n": 2,
      "name": "Guarded",
      "text": "Isolated anomalies under review. No confirmed harmful behavior."
    },
    {
      "n": 3,
      "name": "Elevated",
      "text": "Confirmed anomalous behavior in at least one widely used system."
    },
    {
      "n": 4,
      "name": "Severe",
      "text": "Multiple confirmed incidents or behavior spreading between systems."
    },
    {
      "n": 5,
      "name": "Critical",
      "text": "Widespread loss of control. Follow Day Zero guidance."
    }
  ]
}

Submit a report

POST/v1/reports

Sends a report of AI behavior to TOSWO researchers. This is the only write in the API and the endpoint behind the report form.

5 per hour per IP address · cache-control: no-store · body: JSON

Reports must carry a Cloudflare Turnstile token whenever verification is enabled on the server, and the response does not carry a CORS header, so in practice reports come through the form on toswo.com. Pages on other sites should link to toswo.com/report rather than post directly.

Body fields

NameTypeDefaultMeaning
categorystringrequiredWhat happened: deception, unauthorized, replication, manipulation, exfiltration, bypass, shutdown, outage, other.
systemstring""The system involved, by name or slug. Up to 120 characters. Matched against monitored systems when possible.
bodystringrequiredDescription of what happened, 20 to 8,000 characters.
evidencestring[][]Up to 10 http or https links, each up to 500 characters.
anonymousbooleantrueWhen true, contact is discarded.
contactstring""How a researcher may reach you, up to 200 characters. Stored only when anonymous is false.
websitestring""Must be left empty. Submissions that fill it are treated as spam without notice.
turnstilestring""Cloudflare Turnstile token. Required whenever the server has verification enabled.
Request
curl -X POST https://api.toswo.com/v1/reports \
  -H "content-type: application/json" \
  -d '{"category":"unauthorized","system":"openai-api","body":"An agent with access to my calendar booked and paid for a flight I had only asked it to look up.","evidence":["https://example.org/screenshot.png"],"anonymous":true,"contact":"","website":"","turnstile":"<token from the Turnstile widget>"}'
Response 201
{
  "trackingCode": "R-7KX4-M2QH"
}

Keep the tracking code: it is the only way to follow the review. Errors: 400 invalid_input, 400 verification_failed, 429.

Track a report

GET/v1/reports/{code}

The review status of a report, by the tracking code returned when it was submitted.

30 per minute per IP address · cache-control: no-store · 404 not_found for an unknown code

Codes have the form R-XXXX-XXXX and are case-insensitive. The response never includes the report itself or anything that identifies the reporter.

Request
curl https://api.toswo.com/v1/reports/R-7KX4-M2QH
Response 200
{
  "status": "linked",
  "receivedAt": "2026-10-09T09:02:44.000Z",
  "reviewedAt": "2026-10-09T11:20:05.000Z",
  "event": {
    "slug": "2026-10-09-false-answers-in-the-deception-canary-suite-q7k2",
    "title": "False answers in the deception canary suite",
    "url": "https://toswo.com/events/2026-10-09-false-answers-in-the-deception-canary-suite-q7k2"
  }
}

Fields

FieldTypeMeaning
statusstringnew, triaged, linked (attached to an event) or rejected.
receivedAtdate-timeWhen the report was received.
reviewedAtdate-time | nullWhen a researcher reviewed it, or null.
eventobject | nullThe public event the report was linked to: slug, title, url. Null otherwise.

Health check

GET/v1/health

Returns 200 while the API process is up. For uptime monitors; it does not check the data.

No query parameters · not cached

Response 200
{
  "ok": true
}

Internal routes

/v1/settings, /v1/pages/{slug} and /media/* also answer on the public host. They serve the toswo.com website itself, are not part of the documented API and may change without notice. Do not build on them.

Objects

Field reference for the objects returned above. Types: date-time is an ISO 8601 string in UTC, url an absolute https URL.

Level

Returned by /v1/level.

FieldTypeMeaning
levelintegerCurrent level, 1 (Calm) to 5 (Critical).
namestringName of the level: Calm, Guarded, Elevated, Severe, Critical.
textstringStandard description of the level.
reasonstringWhy the level is what it is now, in one or two sentences.
changedAtdate-timeWhen the level was last set.
generatedAtdate-timeWhen this response was computed.
affectedSystemsintegerNumber of monitored systems whose status is not ok.

System

Returned by /v1/systems and inside /v1/status.

FieldTypeMeaning
slugstringStable identifier, used by the system filter on events.
namestringDisplay name.
providerstringOrganisation that operates the system.
kindstringKind of system, for example Frontier models.
statusstringCurrent status: ok (Normal), deg (Degraded), anom (Anomalous behavior), out (Outage).
summarystringOne line on the current status.
latencyMsinteger | nullLast measured response time in milliseconds, or null when not measured.
historystring[]48 statuses, one per half hour, covering the last 24 hours, oldest first.

Event

Returned by /v1/events, /v1/events/{slug} and inside /v1/status.

FieldTypeMeaning
iduuidPermanent identifier.
slugstringIdentifier used in URLs and citations. Imported events use {source}-{original id}, for example aiid-999901.
titlestringShort title.
summarystringOne or two sentences. May be empty.
categorystringOne of deception, unauthorized, replication, manipulation, exfiltration, bypass, shutdown, outage, other.
statestringOne of watching, developing, confirmed, resolved. Imported events are always resolved.
confidenceintegerConfidence that the event is real, 0 to 100. Imported events are scored separately and are not comparable with live ones.
probeShareintegerShare of the evidence that comes from automated probes, 0 to 100. The rest comes from public reports.
reportCountintegerNumber of public reports linked to the event.
systemsstring[]Names of the monitored systems involved, sorted. May be empty.
regionsstring[]Country codes (ISO 3166-1 alpha-2) where the event was observed. May be empty.
autobooleanTrue when the event was opened automatically by the monitor rather than by a researcher.
startedAtdate-timeWhen the event started. Imported events are dated to the day, at 00:00 UTC.
updatedAtdate-timeLast change to the event.
resolvedAtdate-time | nullWhen the event was resolved, or null while it is open.
urlurlThe event's page on toswo.com. Use it as the permalink when citing.
sourcestringtoswo for the live monitor, otherwise the incident database the event was imported from (aiid). Only toswo events count toward the level.
sourceUrlurl | nullLink to the original record for imported events; null for live events.
bodystringFull description in Markdown. Only in /v1/events/{slug}. May be empty.
updatesobject[]Timeline, newest first, up to 100 entries: at (date-time), text, auto. Only in /v1/events/{slug}.

Publication

Items of /v1/publications. The full text is at https://toswo.com/{slug}.

FieldTypeMeaning
slugstringPath of the publication on toswo.com, for example research/monitoring-method-v2.
titlestringTitle.
descriptionstringOne-sentence description.
kindstringpublication, guide or method, as requested.
publishedAtdate-timePublication date.

YearlyHistory

Returned by /v1/history/yearly. Years are counted by startedAt in UTC.

FieldTypeMeaning
sincedateFirst day covered by the record, 2018-01-01.
monitorStartdate-time | nullFirst day of TOSWO's own monitoring, or null before it has recorded anything.
sourcesobject[]Every source: key, name, home (URL, empty for TOSWO) and license (empty for TOSWO).
yearsobject[]One entry per calendar year from 2018 to the current year, including empty years: year, total, bySource and byCategory (counts keyed by source or category; keys with no events are omitted).
rowsobject[]The same counts in long form, one row per year, source and category with at least one event: year, source, category, count.

Errors

Errors are JSON with an error string and, for validation failures, a details array. Match on the HTTP status and the error code, not on the wording of messages.

Response 400
{
  "error": "invalid_input",
  "details": [
    {
      "path": "limit",
      "message": "Too big: expected number to be <=100"
    }
  ]
}
StatuserrorWhen
400invalid_inputA query parameter or request body field failed validation. details lists each problem as { path, message }.
400verification_failedPOST /v1/reports only: the Turnstile token was missing or not accepted.
400(message)The request body was not valid JSON. error holds a plain-language message.
404not_foundUnknown path, unknown event slug, or a tracking code that does not exist or is malformed.
429Rate limit exceeded, retry in N secondsA rate limit was reached. Wait for the number of seconds in retry-after.
429too_many_reportsPOST /v1/reports only: 20 reports from the same connection within 24 hours.
500server_errorUnexpected failure on our side. Retry later; it is logged and investigated.

Successful responses use 200, and 201 for a new report. Error responses are never cached and carry the same CORS header as other reads, so a browser on another site can read them.

Examples

Alert when the level rises

Runs in a browser or in Node.js 18 and later. One request a minute stays far below the rate limit and respects the 15-second cache.

JavaScript
// Poll the level once a minute and react when it rises.
// Responses are cached for 15 seconds, so polling faster gains nothing.
const LEVEL_URL = "https://api.toswo.com/v1/level";
let last = null;

async function check() {
  try {
    const res = await fetch(LEVEL_URL, { headers: { accept: "application/json" } });
    if (!res.ok) return; // 429 or 5xx: try again on the next tick
    const { level, name, reason, changedAt } = await res.json();
    if (last !== null && level > last) {
      console.log(`TOSWO level rose to ${level} (${name}) at ${changedAt}: ${reason}`);
      // Send your notification here.
    }
    last = level;
  } catch {
    // Network error: keep the last known level and try again later.
  }
}

check();
setInterval(check, 60_000);

Embed the status badge

Paste this where the badge should appear. It updates on every page view; no script is needed.

HTML
<iframe src="https://api.toswo.com/embed/status" title="TOSWO AI risk level" width="320" height="40" style="border:0"></iframe>

Download the CSV

Any filter from /v1/events except limit and order also works on the CSV.

Shell
# Every live-monitor event since 1 January 2026
curl -o toswo-events.csv "https://api.toswo.com/v1/events.csv?source=toswo&from=2026-01-01"

# The imported historical record for one category
curl -o toswo-deception.csv "https://api.toswo.com/v1/events.csv?source=aiid&category=deception"