The version is in the URL
Every endpoint sits under one base URL, and the version is part of it:v1 is the only version today. There is no version header and no version parameter: the path decides.
Webhook events state the version as well. Every event body carries "api_version": "v1", so a receiver can tell which version of the payload it is reading. See Webhook events.
Changes that arrive without a new version
These changes are additive. We make them within/v1 and list them in the API changelog:
- a new endpoint;
- a new optional query parameter, or a new optional field in a request body;
- a new field in a response or in a webhook payload;
- a new webhook event type;
- a new
error.code, or a new code inside an error’sdetails; - a new value in an enumerated field — for example a new
actionin a prompt sync result, or a newsourceon a prompt.
Build a tolerant client
Write your client so that an additive change cannot break it. Four habits do that.- Ignore fields you do not know. Read the fields you use and let the rest pass. Do not validate a response or a webhook body against a closed list of fields.
- Give every switch a default branch. Do not match enumerated values,
error.codevalues ordetailscodes exhaustively. Treat a value you do not recognise as “other”, not as a failure of your parser. When you meet anerror.codeyou do not know, fall back on the HTTP status to decide what to do. - Treat identifiers as opaque strings. Ids, pagination cursors,
score_versionandpanel_versionare strings to store and to send back unchanged. Do not parse them, do not assume a length or a pattern, and do not try to order them. - Branch on the error code, never on the message.
error.codeis the stable, machine-readable value.error.messageis written for people, and its wording can change. See Errors.
Breaking changes
Removing or renaming a field, or changing a field’s type or what it means, is a breaking change. Changes like these ship under a new version path rather than in/v1.
Data versions are not API versions
Two fields have “version” in their name and describe the data, not the API:score_versionnames the scoring model that produced a score.panel_versionnames the measurement panel — the set of AI models — that produced a measurement.
score_version also appears in the score.threshold_crossed webhook event. Either can be null. Compare two scores only when they share a panel_version and, for the AIS Score, a score_version.
When one of these values changes, the measurement has changed. The API has not: the same fields arrive, with the same types, from the same endpoints. Treat both as opaque strings, as described above. The data model explains how to work with them.