One model-first API for chat, multimodal input, VETTING workflows, published agents, embeddings, image generation, audio, and encryption utilities, documented the way you and your agents read.
Drop the maintained API guide into Claude Code, Codex, Cursor, Gemini CLI, or another AI-assisted workflow. Your agent can use direct endpoints when they fit, or draft VIABLE Lab agent workflow JSON when you need orchestration.
I am building with the VIABLE Lab API. Read https://developers.viablelab.org/agents/viablelab-api.md as the source of truth. Prefer direct endpoints for one-step chat, VETTING, embeddings, image, speech, transcription, or encryption; suggest Dashboard Agents only when a product flow needs branching, loops, or multiple coordinated model/tool calls behind one endpoint. Auth uses Bearer VIABLE Lab API keys with endpoint scopes such as model:request, utils:crypto, and agents:execute. For published agent runs, call POST /v1/agents/{slug}/runs and persist conversation_id per end-user thread + agent slug; run_id is one execution and request_id is for log/support correlation. Treat any direct-endpoint or provider-level session state as separate from this agent conversation_id.
Create project keys in the dashboard, store them as server-side secrets, and send them as bearer tokens to protected model and utility endpoints.
When to use
Use the dashboard whenever you need to reveal, pause, resume, revoke, scope, or limit a key. Client applications should call your own backend, not expose VIABLE Lab API keys directly.
Key details
Authorization
Bearer $VIABLE_API_KEY for protected API calls
Scopes
model:request for model endpoints, utils:crypto for encryption utilities, agents:execute for published agent runs
Optional limits
requests per minute, daily token cap, monthly cost cap
Optional allowedModels list to restrict a key to exact model IDs or aliases
Notes
Bearer keys do not change request bodies.
Paused keys can be resumed without rotation. Revoked keys are permanent.
Dashboard management endpoints are for signed-in dashboard sessions, not normal product integrations.
Bearer header
Authorization: Bearer $VIABLE_API_KEY
POST
Chat completions
OpenAI-compatible chat requests with model-first routing, aliases, multimodal content arrays, and optional streaming.
When to use
Use this endpoint for general generation, analysis, coding, tutoring, classification, and agent workflows that need normal chat responses.
Parameters
model
model ID or supported alias
messages
array of role/content messages
stream
true for server-sent events
provider
optional only when a future model name would be ambiguous
Notes
Do not include provider for ordinary calls; the API resolves it from the model registry.
Streaming starts before logging finishes, and logging continues asynchronously after the response completes.
Unknown future model IDs are allowed when their provider can be inferred from a safe prefix.
OpenAI Python SDK
from openai import OpenAI
client = OpenAI(
base_url="https://api.viablelab.org/v1",
api_key="<VIABLE_API_KEY>", # load from your app's secret store
)
response = client.chat.completions.create(
model="viable-1",
messages=[
{"role": "user", "content": "Write one sentence about retrieval."}
],
)
print(response.choices[0].message.content)
Run a published visual/code agent workflow behind one endpoint. The agent graph can chain models, branch, loop within budgets, and return text plus generated assets.
When to use
Use this endpoint when one product turn needs orchestration, such as deciding whether to call an image model, running several model steps, or coordinating multiple tools behind one stable API path.
Parameters
slug
published agent path segment from the dashboard
input
latest end-user turn as a string, content-part array, or OpenAI Responses-style user message array
message
text-only alias for input
history_mode
server (default), client (full messages), or none (independent turn)
messages
full structured transcript with history_mode client; do not combine with conversation_id
context
arbitrary current-request JSON; receiving nodes opt in and it does not accumulate in conversation history
conversation_id
optional on the first turn; resend the returned value on later turns to continue the same agent chat thread
Notes
Use conversation_id only with published agent runs. For direct chat or VETTING, include the context required by that request and treat any app- or provider-level session state as separate from this field.
For image input, use input_text/text plus input_image/image_url parts. The LLM node that receives the user turn must use a model whose input_modalities include image.
Inline Agent images are limited to 8 MiB each and 10 MiB total (12 MiB JSON body). Up to 8 MiB of prior media is materialized per model request; omitted history media remains downloadable to authorized researchers.
Exact bytes and filenames are archived privately; logs, traces, exports, and conversation history use authenticated research asset references rather than base64.
HTTPS image URLs are retained exactly as restricted provenance, including query parameters, but are not fetched automatically and may expire at the source. URLs with embedded username/password credentials are rejected.
A custom LLM user prompt keeps current media unless includeInputMedia is false. The response input_assets array identifies archived media from that turn.
Save conversation_id per end-user session and agent slug. If a client drops it, the next request starts a new agent conversation even if the input manually includes prior context.
conversation_id is bound to the creating API key or user and the agent. A different key cannot continue someone else's conversation.
Each run returns run_id for one orchestration execution. Request logs show both the run summary and the internal provider calls tagged by agent/run/node.
To design a workflow with a coding agent, create or open an agent in Dashboard > Agents, paste graph JSON in Build > Code & AI, Sync to canvas, Validate, Save, test, then Publish.
Dashboard agent test chat uses the same metered execution path with a selected API key before publish.
All supported endpoints are available after publishing. The selection below changes the example only, not the agent.
POST
https://api.viablelab.org/v1/agents/my-agent/runs
Use a server-side API key with agents:execute. Never include it in browser code.
Send the latest message as input. Save the returned conversation_id per user and thread; include it on subsequent turns.
/runs keeps this HTTP request open until the reply is ready. Read output.text. Start here for ordinary request/response integration; no polling is needed.
{
"input": "Tell me more.",
"conversation_id": "agtc_REPLACE_WITH_RETURNED_ID",
"context": {
"current_document": "The latest version only"
}
}
Use history_mode: "none" for independent requests. Use history_mode: "client" with messages to manage the full history yourself; omit conversation_id.
context accepts your own JSON fields. Enable Use current reference data on each LLM step that needs those fields, or reference them explicitly in its prompt. Send the latest snapshot each time; it is retained in research traces, not automatically added to future chat history. This does not remove older material already stored in a conversation.
Retries, limits and safe integration
Keep API keys on your server. A shared key's rate limit is shared by all its users. Blank key limits inherit the account tier; they do not mean unlimited.
For each logical turn, generate an Idempotency-Key (8–128 letters, digits, dots, underscores, colons or hyphens). Reuse it with the same body after a lost response. Never create a new key to bypass an uncertain pending request.
429 is a rejection with bounded provider retries, not a promise of background completion. Respect Retry-After. A 409 pending response requires retrying the original key or checking logs; a timeout does not prove the provider did no work.
How background jobs and queues work
Background jobs are an optional delivery mode for Native Agent, not a third conversation format. View the background job example above for its URL and code. Your server submits → the platform queues and runs the workflow → your server retrieves the result.
A 202 response includes id and status_url. GET that URL with the same API key every few seconds, respecting Retry-After. A completed job includes the native response in result.
States: queued → running → completed, failed, or recovery_required. Queue waiting expires after 15 minutes; execution still has a separate deadline. Keep one turn outstanding per conversation. Recovery-required means the result is uncertain—do not automatically submit the workflow again.
The platform manages the queue; application developers do not need a Cloudflare account or queue credentials. Neither synchronous endpoint automatically switches to it. It does not bypass key quotas or turn every provider 429 into an eventual success. A 503 before admission means the capability is unavailable; do not switch execution routes after an uncertain response.
curl https://api.viablelab.org/v1/agents/my-writing-tutor/runs \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer $VIABLE_API_KEY' \
-d '{
"input": "Can you show me a cat and help me write about it?"
}'
A structured VETTING workflow with separate chat and verification model configs, prompts, answer keys, context items, attempts, and verification output.
When to use
Use it for educational products that need traceable answer-key verification, multi-attempt generation, and structured fields for downstream review.
Parameters
mode
vetting
config.chatModel.modelId and config.verificationModel.modelId
config.maxVerificationAttempts
prompts.chatSystemPrompt and optional verification prompt fields
context.items[].question and context.items[].answerKey
messages
user conversation that should be answered
Notes
The chat model and verification model can be different chat-capable models.
The endpoint is non-streaming by design because it must evaluate complete generated responses.
prompts.chatSystemPrompt and prompts.verificationSystemPrompt support enc:: encrypted values from the Encryption Tool.
Use lightweight VETTING chat when you do not need answer-key context or detailed verification fields.
Model and utility endpoints use bearer API keys. Create and manage keys in the dashboard; dashboard control-plane APIs are intentionally not part of this public reference.
GETPublic
/
Service status and documentation links.
GETPublic
/v1/models
Public model catalog with modes, providers, capabilities, and pricing notes.
GETPublic
/v1/docs/metadata
Compact machine-readable metadata for developer portals and agents.
POSTAPI key
/v1/chat/completions
OpenAI-compatible chat JSON with optional streaming and multimodal content arrays.
POSTAPI key
/v1/chat/vetting
Chat-completions style JSON plus optional vettingConfig for lightweight verified educational chat.
POSTAPI key
/v1/vetting/full
Structured VETTING JSON with mode, config, prompts, context, and messages.
POSTAPI key
/v1/embeddings
OpenAI-compatible embeddings JSON with model and input.
POSTAPI key
/v1/images/generations
OpenAI Images-compatible JSON with model, prompt, size, and n.
POSTAPI key
/v1/audio/speech
OpenAI Audio Speech-compatible JSON with model, input, voice, and response_format.
POSTAPI key
/v1/audio/transcriptions
Multipart form upload with model and file.
POSTAPI key
/v1/utils/encrypt
JSON utility request with text. Automatic enc:: handling is limited to documented VETTING fields.
POSTAPI key
/v1/utils/decrypt
JSON utility request with encryptedText for QA or recovery from trusted sessions.
Machine-readable
Use metadata for portals and agents
The metadata endpoint returns the model catalog, endpoint list, agent quickstarts, Playground-ready examples, and pricing notes in one compact JSON payload, ideal for keeping a portal or agent in sync without hardcoding.
Metadata
curl https://api.viablelab.org/v1/docs/metadata
Full schema
OpenAPI is the source of truth for public API details
This guide highlights common workflows. The schema-backed reference covers public paths, parameters, responses, and components from the canonical JSON.