Skip to content

Overview

Chat completions, audio transcription and image generation for the Optiwork suite.

The Optiwork AI API gives your integrations the same AI capabilities the Optiwork modules use: chat completions streamed as they are written, audio transcription of short recordings, and image generation and editing.

Base URL

All endpoints are served under the fixed AI host: https://ai.work.optidata.cloud/api.

Authentication

Every endpoint requires a Bearer JWT passport, except GET /ping and the signed chat URLs described below. Your personal passport is available in Optiwork at https://work.optidata.cloud/user/settings/security (My account > Profile > Security), where it is shown as the authentication key. Send it on every request:

Authorization: Bearer opk_xxxxxxxxxxxxxxxxxxxxxxxx
Accept: application/json

A request without a key returns 401. A key that is expired or not recognised returns 419; get a fresh authentication key from the same settings page and retry.

Streamed chat responses

The chat operations answer with a server-sent event stream (Content-Type: text/event-stream) instead of JSON, so the answer can be shown while it is being written:

id: 0
event: message
data: ""

id: 1
event: message
data: "Hello"

id: 2
event: message
data: " there."

id: -1
event: content-end
data: {"time": "2026-10-19 11:28:13"}
  • Every message event carries the next piece of the answer as a JSON-encoded string; decode it and append it to what you have. The first piece may be empty.
  • The stream always ends with one content-end event (id: -1), whose time is the server’s local time when the answer finished.
  • With curl, add --no-buffer to see the pieces as they arrive.

Signed chat URLs

A browser EventSource cannot send an Authorization header. For that case, ask for a signed URL first (POST /ai/text/chat/signed or POST /ai/text/chat/contextual/signed, with your authentication key) and open the returned url with a plain GET, no key needed. The prompt is kept on the server for one hour; after that the URL answers 401. Treat a signed URL like a password: anyone holding it can run the prompt again within that hour.

Close the EventSource when content-end arrives. The server ends the response after that event, and a browser EventSource reconnects on its own when a response ends — with a signed URL still valid, every reconnect runs the prompt again, appends a duplicate answer and spends AI usage again.

const source = new EventSource(url);
source.addEventListener("message", (event) => {
  answer += JSON.parse(event.data);
});
source.addEventListener("content-end", () => source.close());

Conventions

  • Uploads (file, image, mask) are sent as multipart/form-data; all other bodies are JSON.
  • Images are returned base64-encoded in image_base64 (PNG).
  • Validation failures return 422 with a per-field errors map. Errors the application raises itself use an { "error", "status", "help" } envelope.

The authentication key (JWT passport) from My account > Profile > Security at work.optidata.cloud/user/settings/security.

Security scheme type: http

Bearer format: JWT