Assistants
Create, read, update, delete, and publish pages-mode assistants under /api/v1/factory/assistants.
The Integration API is the machine-to-machine surface of Greentic Designer, served under /api/v1/. It lets a partner’s own backend provision assistants, manage sessions, and push knowledge documents into a tenant’s library over a stable, versioned HTTP contract — without a Designer login and without a browser.
It is a separate contract from the Designer’s own session-authenticated routes. Those routes exist to serve the composer UI and their shapes change with it; /api/v1/* commits to a narrow projection that can be widened but never silently narrowed.
Assistants
Create, read, update, delete, and publish pages-mode assistants under /api/v1/factory/assistants.
Sessions
The general session surface under /api/v1/sessions — both flow and pages rows.
Knowledge
Push documents by your own external_id and attach them to knowledge bases under /api/v1/knowledge/.
Behaviour
Ownership, rate limits, and revocation lag — the three things an integration must be designed around.
Every request carries an integration key in a standard bearer header:
Authorization: Bearer gti_live_...Three facts about that key determine how you deploy against this API.
An integration key is issued by the Greentic admin service, not by the Designer. It is gti_-class, distinct from the gts_ platform service key. The Designer never mints, stores, or rotates one — ask your Greentic operator for a key, and ask them again when you need it rotated or revoked.
The key is the identity. When the admin resolves it, the answer is {tenant, team, integration_id, name, status} — so the tenant and the team a request acts in are properties of the credential, never of the request. There is no request field, header, or query parameter that selects a tenant or a team, which is what makes cross-tenant isolation hold by construction.
Rotating the credential does not change who owns the rows it created: ownership is stamped from the stable integration_id, not from the key material.
On each request the Designer asks the admin to verify the presented key, then acts on the answer. It never inspects the key’s shape itself — the token is opaque to it. Two consequences follow, and both are load-bearing:
Before wiring up anything that writes, confirm the key resolves to the tenant and team you expect.
Export the key and your Designer host.
export GREENTIC_KEY="gti_live_..."export GREENTIC_DESIGNER="https://designer.example.com"Call whoami.
curl -sS "$GREENTIC_DESIGNER/api/v1/knowledge/whoami" \ -H "Authorization: Bearer $GREENTIC_KEY"Check the identity.
{ "tenant": "acme", "team": "support", "integrationId": "<integration-id>", "name": "acme-webchat-backend"}tenant and team are the scope every subsequent call acts in. If either is not what you expected, stop — the key is wrong, not your code.
GET /api/v1/knowledge/whoami is a read that touches nothing. It carries no information the admin did not already give you when it minted the key, so it is safe to call from a health check.
Successful responses are bare JSON — this surface sits outside the Designer’s {ok, data, error} response envelope, so a 200 body is the resource itself with no wrapper:
{ "id": "sess-1756100000000-3f2a91bc", "name": "Support Assistant", "instructions": "...", "model": null }Errors use one shape everywhere:
{ "ok": false, "error": { "code": "assistant_not_found", "message": "No such assistant." }}code is a stable snake_case token — match on it, not on message, which is an English fallback that may change.
These four can be returned by any route on this surface, before the handler runs.
| Status | code | When |
|---|---|---|
401 | invalid_api_key | No Authorization: Bearer <key> header, a non-Bearer scheme, an empty key, or a key the admin does not recognise. |
403 | integration_disabled | The admin recognises the key but its status is not active (disabled, revoked, suspended, or a status this Designer build does not recognise). |
429 | rate_limited | The per-key token bucket is empty. Carries a Retry-After header in whole seconds. See Rate limiting. |
503 | integration_auth_unavailable | No admin backend is attached to this deployment (see below), or verification could not complete — the admin returned 403/429/5xx, timed out, was unreachable, or sent a body that could not be decoded. |
Read these before you design against the API — each one is a deliberate boundary, not a gap waiting for a patch.
For the front-end half of a chat integration, the WebChat widget already covers embedding:
Two further limitations affect what you can build through this API rather than how you call it — MCP tools on agentic workers, and which lane to build workers in. Both are covered in Behaviour and limits.