Resources
Versioning & changelog
How the API evolves, and what has changed.
The Krallo API is versioned in the URL path. The current and only major is
v1, and every request goes to
https://exe.krallo.com/api/v1. This page states exactly what we may and may not change
under a major version, so you can build a client that keeps working across releases without pinning to
a moving target.
Versioning policy
There are two distinct version identifiers, and it is worth keeping them separate in your head:
| Identifier | Where it appears | Form | What it governs |
|---|---|---|---|
| API major | The URL path (/api/v1/…) and the api_version field of GET /api/v1/ping. | v1 | The request surface — routes, request/response field names, status codes, and semantics. |
| Webhook payload version | The api_version field inside every webhook envelope. | Date, e.g. 2026-07-12 | The shape of the delivered event payload. See Webhook payload versioning. |
/api/v1 is frozen
Once an endpoint, field, or behaviour ships under v1, it will not change under
v1. That means:
- A route that exists will keep its path, HTTP method, and meaning.
- A response field that exists will keep its name and type. We will not rename
tokens_balancetobalance, or turn a string into an object, underv1. - A request field that exists will keep its name, type, and default. We will not make an optional field required, tighten a validation rule so a previously-accepted value is now rejected, or change a default.
- A stable error slug (
error.codeon native endpoints,error.typeon the OpenAI-compatible ones) will keep mapping to the same failure and the same HTTP status. See Errors.
Changes within a major are additive-only
Freezing does not mean the API stops growing — it means it only grows in ways that cannot break a correctly-written client. Under a single major we may, at any time and without notice:
- Add new endpoints under
/api/v1. - Add new optional request fields whose omission preserves the existing behaviour.
- Add new response fields to existing responses (including new fields nested inside
the
errorobject, as noted in Errors). - Add new webhook event types to the events catalog,
and add new fields to the
datablock of an existing event. - Add new scopes to the scope vocabulary, and move a reserved scope to grantable, without affecting keys that never requested it.
- Add new enum values (for example a new model id, a new delivery status).
Ignore unknown fields. The single most important rule for a durable client: parse defensively and skip any JSON field or enum value you do not recognise, rather than rejecting the whole response. Because additions are the only in-major change we make, a client that tolerates unknown fields never breaks on a Krallo release. Do not assume the set of fields is closed, and do not treat a new enum value as an error.
Breaking changes ship under a new major
Anything that is not additive — removing or renaming a field, removing an endpoint, changing a
default, tightening validation, changing a status code, or altering the meaning of an existing
response — is a breaking change, and a breaking change only ever ships under a new major
at a new path prefix (/api/v2). The two majors run side by side; /api/v1 keeps
working while you migrate, and we will publish a migration guide and a deprecation timeline before any
major is retired. Your existing keys and scopes are not silently repointed at a new major — you opt in
by changing the base URL.
Writing a forward-compatible client
- Pin the major, not the minor. Hard-code
/api/v1in your base URL and nothing finer. There is no minor version to negotiate and no version header to send. - Tolerate unknown fields and enum values everywhere you deserialize — responses, error bodies, and webhook payloads.
- Match on stable slugs, not messages. Branch on
error.code/error.typeand on HTTP status; treat human-readablemessagetext as display copy that may be reworded at any time. - Do not depend on field ordering or on the absence of a field.
- Read the webhook
api_versionbefore trusting a payload's shape, so a future payload revision is a branch rather than a crash.
Webhook payload versioning
Webhook payloads carry their own version, independent of the API major, because the delivered JSON is a
contract with your endpoint rather than a response to a request. Every envelope pins an
api_version — a date string, currently 2026-07-12 — alongside
the event id, type, created_at, scope, optional
resource_id, and the event data:
{
"id": "01J8ZC5Q9K4P2XABCD3EFG7HJK",
"type": "imagine.completed",
"api_version": "2026-07-12",
"created_at": 1752470400,
"scope": "user",
"resource_id": "7f2c1ab4-9b0d-4e21-8a77-1c2d3e4f5a6b",
"data": { }
}
Payload changes follow the same additive rule as the rest of the API: new fields may appear in
data, and new event type values may appear, without the
api_version date advancing. The date advances only if the payload shape changes in a way
that is not additive — at which point we ship the new shape under a new date and give existing
endpoints a migration path rather than reshaping payloads underneath them. Read the field, branch on it,
and you are insulated either way. The full delivery, signing, and verification contract is in
Webhooks.
The webhook api_version is a date; the API major in the URL is
v1. They are not the same value and do not move together — do not compare one against
the other.
Changelog
Entries are newest-first. Because in-major changes are additive, a changelog entry never asks you to change working code — it tells you what is newly available.
v1 — initial release
The first public major. Krallo's developer API launched AI-first: the surface is built around programmatic access to the same AI, persona, memory, and image capabilities the platform runs internally, exposed under a single OpenAI-compatible base URL.
| Area | What shipped |
|---|---|
| OpenAI-compatible chat | POST/api/v1/chat/completions and
GET/api/v1/models, speaking the OpenAI wire
format so a stock OpenAI SDK, Aider, or Continue works by pointing its base URL at
/api/v1. Curated model ids krallo-code, krallo-chat,
krallo-reasoning, and krallo-fast, with streaming support. See
Chat completions and
Streaming. |
| Image generation | POST/api/v1/ai/imagine for synchronous
image generation. See Images. |
| Personas | GET / POST
/api/v1/personas and the /api/v1/personas/{id} item routes to manage
your own personas, including attaching a persona of your own to a chat request. See
Personas. |
| Memories | GET / POST
/api/v1/memories and DELETE
/api/v1/memories/{id} for the account's long-term memory store. See
Memories. |
| Account & identity | GET/api/v1/ping (unauthenticated liveness),
GET/api/v1/me (authenticated app, owner, and
granted scopes), GET/api/v1/guilds, and the
unmetered GET/api/v1/usage. See
Authentication. |
| Scoped bearer keys | Per-resource <resource>:<action> scopes
(ai:invoke, ai:imagine, personas:read/write,
memories:read/write, guilds:read, webhooks:read/write,
usage:read) enforced per request. See Scopes. |
| Signed webhooks | Outbound event delivery with HMAC-signed envelopes, a durable delivery outbox, a delivery
log at GET/api/v1/webhooks/deliveries, and replay
of a delivery. Every envelope pins api_version. See
Webhooks. |
| opencode auto-config | GET/.well-known/opencode serves opencode's
remote provider-config document, so an opencode user sets KRALLO_API_KEY and the
Krallo provider plus every curated model load automatically — no hand-written
opencode.json. See opencode. |
| Prepaid billing & rate limits | Metering against the owner's prepaid wallet with a free daily quota that resets at
00:00 UTC, automatic refunds on failed metered calls, and per-key rate limits
with Retry-After / X-RateLimit-* headers. See
Billing & quotas and
Rate limits. |
See also
- Quickstart — make your first authenticated call.
- Errors — the stable error slugs that are part of the frozen contract.
- Webhooks — the signed envelope and its
api_versionfield. - Scopes — the grant vocabulary and its reserved, forward-compatible entries.