Docs
Versions and SDKs
How /v1 and /v0 relate, what the deprecation headers mean, and the official clients.
Base URL: https://api.162-55-213-24.sslip.io. Every operation answers on /v1, the current version, and on /v0, which is kept as an alias and is deprecated. The two are the same code: same paths below the prefix, same request fields, same response bodies, same status codes, same error codes. There is nothing to negotiate and no header to send: the version lives in the path.
What each version answers
| Path | Status | Response headers |
|---|---|---|
/v1/... | Current version, safe for new integrations | Aimulti-Api-Version: v1 |
/v0/... | Same behaviour, deprecated, no new features | Aimulti-Api-Version: v0, Sunset: Fri, 31 Dec 2027 00:00:00 GMT, Link: </v1/...>; rel="successor-version" |
Aimulti-Api-Version names the version that answered, on either prefix, so a log or a bug report always says which path a client used. Sunset is the last day /v0 is promised to answer, as an HTTP date. Link with rel="successor-version" points at the same operation under /v1, so a client can follow it without guessing how paths map.
curl -s -D - -o /dev/null "https://api.162-55-213-24.sslip.io/v0/me" \
-H "Authorization: Bearer ***"
# HTTP/2 401
# aimulti-api-version: v0
# sunset: Fri, 31 Dec 2027 00:00:00 GMT
# link: </v1/me>; rel="successor-version"Deprecation policy
- Breaking changes ship only in a new version prefix. Within a version we add fields and endpoints, and never rename or remove one, and never change the meaning of a status code or an error code.
- A version is supported for at least twelve months after its successor ships.
/v1shipped in October 2026, so/v0answers until 31 December 2027. - The day a successor ships, the old prefix starts sending
SunsetandLinkon every response: a 200, a 404, an error envelope, a redirect. Deprecation is never silent and never a surprise in a changelog only. - The deprecation is never in the response body.
/v0returns exactly the JSON it always returned, so an old client that parses the envelope keeps working, and a warning cannot break a strict parser. - Announcements go to the address in the console account and to the changelog, at least twelve months before a sunset date. The date in the
Sunsetheader never moves closer without that notice. - An urgent security fix can change behaviour inside a version. When that happens it applies to both prefixes at once, because they are the same handler, and the changelog says what changed.
Moving a client to /v1
- Change the base path from
/v0to/v1. Nothing else in a request changes. - Leave headers and bodies alone.
Idempotency-Key,include_review, pagination tokens and error codes all behave as they did. - Read
Aimulti-Api-Versionin logs, and alert ifSunsetappears: that is a client still on the old prefix. - Watch for a
LocationorLinkvalue that already points at/v1and use it, rather than rebuilding paths by hand.
Go SDK
A small client with no dependencies outside the standard library. One method per operation, a context.Context first, typed values that mirror this reference, and an error type carrying the API code and the request id.
import aimulti "github.com/bertodrew/multi.ai.inbox/sdk/go"
client := aimulti.NewClient(os.Getenv("MAI_API_KEY"))
me, err := client.Me(ctx)
inbox, err := client.CreateInbox(ctx, aimulti.CreateInboxRequest{
Username: "support-agent", ClientID: "support-agent",
})
threads, err := client.ListThreads(ctx, inbox.InboxID, aimulti.ListOptions{Limit: 10})
result, err := client.Send(ctx, inbox.InboxID, aimulti.SendRequest{
To: []string{"person@example.com"}, Subject: "Approved", Text: "It ships today.",
}, aimulti.WithIdempotencyKey("approved-42"))Options cover the deployment (WithBaseURL), the transport (WithHTTPClient) and the deprecated prefix (WithAPIVersion). Errors are *aimulti.Error, with helpers IsCode, StatusCode and RetryAfter. The client speaks /v1 by default. The module lives in sdk/go/, with a README and a compiled example.
TypeScript SDK
Fetch based, no runtime dependencies, and shipped as TypeScript source, so there is no build step to read it. Hand written types mirror this reference and use the API's own field names.
import { AimultiClient, isCode } from "@aimulti/inbox";
const client = new AimultiClient(process.env.MAI_API_KEY!);
const inbox = await client.createInbox({ username: "support-agent", client_id: "support-agent" });
const { threads } = await client.listThreads(inbox.inbox_id, { limit: 10 });
try {
await client.send(inbox.inbox_id, {
to: ["person@example.com"], subject: "Approved", text: "It ships today.",
}, "approved-42");
} catch (err) {
if (isCode(err, "already_exists")) {
// handle it
}
}Errors are AimultiError, with status, code, requestId and retryAfter. events() is an async generator over server sent events. The package lives in sdk/typescript/, with a README.
Supporting another version
Neither SDK sends a version header, so pointing one at /v0 is a single option away, and the default is already /v1. If your language is not covered yet, the REST surface is the contract: every operation in the API reference works on both prefixes.