Versioning and changelog
How Constaia versions its API (v1 in the path) and SDKs, which compatible changes may ship without notice and how to write code that doesn't break.
API version
The version is in the path: every call is https://api.constaia.com/v1/…. The OpenAPI spec
(https://api.constaia.com/openapi.json) declares info.version 1.0.0.
Within v1 we keep backwards compatibility: code that works against v1 today should keep working.
Compatible changes (may ship without notice)
Within v1 we may release, at any time, changes that don't break well-written integrations:
- New fields in responses (for example, a new object in the analysis).
- New codes for reasons (
verdict.reasons[].code), checks (checks[].code), signals (warnings) and errors (error.code). - New document types in the catalogue and new fields on existing types.
- New optional parameters in requests and new options in
optionsoroptions.checks. - New webhook events (you only get them if you subscribe to them or use
*). - Changes to the wording of
message.
Your code must be ready for them:
| Do | Don't |
|---|---|
| Ignore fields you don't know. | Validate responses with a strict schema that rejects extra fields. |
Treat an unknown reason code according to its severity. | Fail with a switch that has no default case. |
Treat an unknown error code according to the HTTP status and type. | Assume the list of codes is closed. |
| Treat an unknown signal as one more hint for review. | Reject a document because of a signal you don't know. |
Write logic against code, never against message. | Compare message strings. |
| Ignore webhook events you don't handle and answer 2xx. | Answer an error to an unknown event type (it would be retried for days). |
import type { Analysis } from "@constaia/sdk";
export function decide(analysis: Analysis): "accept" | "reject" | "review" {
const reasons = analysis.verdict?.reasons ?? [];
if (reasons.some((r) => r.severity === "error")) return "reject";
if (reasons.some((r) => r.severity === "warning")) return "review";
return "accept"; // also covers codes we don't know yet
}Strict options
The options you send are strict: a key that doesn't exist returns 422 invalid_parameter. That way a typo is
never silently ignored. So if you use a new option, make sure it is already available (the changelog
says so).
Breaking changes
Our policy: a change that breaks existing integrations (removing or renaming a field, changing its type or meaning,
making an optional parameter required) is not released within v1. It would ship as a new path version (/v2),
announced in advance in the changelog, and v1 would keep working during a transition period.
SDKs
The SDKs follow semantic versioning: breaking changes only ship in a new major version. While
they are on 0.x, a minor version (0.1 → 0.2) may include breaking changes; pin the minor version in your
dependency manager and read the changelog before upgrading.
| Package | Registry | Current version |
|---|---|---|
@constaia/sdk (JavaScript / TypeScript) | npm | 0.2.0 |
constaia/constaia-php | Packagist | 0.2.0 |
constaia (Python) | PyPI | 0.2.0 |
@constaia/widget | npm | 0.1.0 |
@constaia/mcp | npm | 0.1.0 |
npm i @constaia/sdk@~0.2.0
composer require constaia/constaia-php:~0.2.0
pip install "constaia~=0.2.0"Guides: JavaScript, PHP, Python, widget and MCP.
Changelog
Every change to the API, the catalogue and the SDKs is published in the changelog.
Next steps
Credits & billing
How credits are calculated per page, what is not charged, the free plan of 150 credits a month, packs in EUR and USD, expiry, balance, alerts and 402 errors.
Security
Security with Constaia, how to store and rotate API keys, verify webhooks, protect your upload endpoint and avoid trusting verdicts from the browser.