# VIABLE Lab API Agent Guide

Use this guide when connecting an app, script, or coding agent to the VIABLE Lab API.

## Base URL

`https://api.viablelab.org`

Use OpenAI-compatible request shapes where possible. Prefer full model IDs for new integrations. VIABLE aliases such as `viable-2` remain stable for existing projects.

For production integrations, create a VIABLE Lab API key from the developer dashboard and send it from server-side code:

```bash
-H "Authorization: Bearer $VIABLELAB_API_KEY"
```

Existing integrations may still work during the migration window when API key enforcement is optional, but new builds should use keys so usage, limits, and request logs are attributed correctly.

## Core Endpoints

| Task | Endpoint | Request shape | Common model |
| --- | --- | --- | --- |
| Chat, reasoning, images, files, PDFs | `POST /v1/chat/completions` | JSON with `model` and `messages` | `gpt-4.1-nano` or `viable-2` |
| Vetted educational chat | `POST /v1/chat/vetting` | Chat JSON plus optional `vettingConfig` | `viable-2` |
| Full answer-key verification | `POST /v1/vetting/full` | JSON with `mode`, `config`, `context`, and `messages` | configured per request |
| Embeddings | `POST /v1/embeddings` | JSON with `model` and `input` | `nomic-embed-text-v1.5` |
| Image generation | `POST /v1/images/generations` | JSON with `model`, `prompt`, optional `size` and `n` | `flux.2-klein` |
| Text to speech | `POST /v1/audio/speech` | JSON with `model`, `input`, `voice`, optional `response_format` | `gpt-4o-mini-tts` |
| Audio transcription | `POST /v1/audio/transcriptions` | multipart form with `model` and `file` | `whisper-large-v3` or `gpt-4o-transcribe` |

## Model Catalog

- Human-readable model picker: `https://developers.viablelab.org/models/`
- OpenAPI JSON: `https://developers.viablelab.org/openapi/openapi.json`
- Live API catalog: `GET https://api.viablelab.org/v1/models`
- Machine-readable docs metadata: `GET https://api.viablelab.org/v1/docs/metadata`

Provider labels in public docs are `OpenAI`, `Google`, and `VIABLE Lab`.

## Chat

```bash
curl https://api.viablelab.org/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "X-Platform-ID: your-platform" \
  -d '{
    "model": "gpt-4.1-nano",
    "messages": [
      { "role": "user", "content": "Write one sentence." }
    ]
  }'
```

For multimodal chat, use OpenAI-style content arrays with `text`, `image_url`, `file`, or `input_file` parts. Gemini-compatible requests support base64 data URI files and images; do not rely on remote file fetching for Gemini.

## VETTING

VETTING is not a model. It is a verification architecture layered on top of chat models. A chat model drafts a response, then a verification pass checks whether the response follows the requested educational or policy constraint. If a response fails, the API can retry with feedback until it passes or reaches the configured attempt limit.

VETTING is useful when a product needs a tutor-like assistant that guides users without directly giving away answers, verifies answers against an answer key, or records why a response passed or failed. VETTING endpoints are intentionally non-streaming because the API needs the full response before it can verify it.

Use different models by setting the normal `model` field on `/v1/chat/vetting`, or by setting `config.chatModel.modelId` and `config.verificationModel.modelId` on `/v1/vetting/full`. On `/v1/chat/vetting`, `model` controls the drafted chat response and the verification model is managed internally. On `/v1/vetting/full`, the chat and verification models are explicit and can be different providers.

VETTING uses the same chat model registry as `/v1/chat/completions`. OpenAI chat models, Gemini chat models, VIABLE Lab chat models, VIABLE aliases, and future clearly inferable chat model IDs can be used where a chat model is required. Non-chat models such as embeddings, image generation, speech, and transcription models are rejected on VETTING endpoints with a structured 400 error.

### Which VETTING Endpoint To Use

| Endpoint | Use when | Request style | Main response fields |
| --- | --- | --- | --- |
| `POST /v1/chat/vetting` | You already use Chat Completions and want a lightweight verification layer. | OpenAI-compatible chat JSON plus optional `vettingConfig`. | Standard `choices`, `usage`, plus `vetting_info` and `safety_signals`. |
| `POST /v1/vetting/full` | You need answer-key verification, detailed attempt records, separate chat and verification models, or session/question metadata. | Structured JSON with `mode`, `config`, `prompts`, `context`, and `messages`. | `result`, `verification`, `usage`, `metadata`, and `safety_signals`. |

### Lightweight Vetted Chat

Use `/v1/chat/vetting` when the app needs a normal chat response plus `vetting_info`. This is the easiest VETTING integration because it keeps the Chat Completions shape.

Key request fields:

| Field | Required | Notes |
| --- | --- | --- |
| `model` | Optional | Full chat model ID or VIABLE alias. Defaults apply if omitted. Examples: `viable-2`, `gpt-4.1-nano`, `gemini-2.5-flash`. |
| `messages` | Required | Same role/content format as `/v1/chat/completions`; multimodal content is allowed for image-capable chat models. |
| `temperature`, `max_tokens` | Optional | Passed to the chat generation step when supported. |
| `vettingConfig.systemPrompt` | Optional | Guideline checked by the internal verification pass, such as "do not reveal the final answer." |
| `vettingConfig.maxAttempts` | Optional | Maximum generation/verification attempts. Defaults to 3. |

Key response fields:

| Field | Notes |
| --- | --- |
| `choices[0].message.content` | The final vetted assistant response. |
| `usage` | Standard token usage for the returned response. |
| `vetting_info.attemptCount` | Number of internal generation/verification attempts. |
| `vetting_info.stopReason` | `VERIFICATION_PASSED`, `MAX_ATTEMPTS_REACHED`, `GENERATION_ERROR`, `VERIFICATION_ERROR`, or `SAFETY_TRIGGERED`. |
| `vetting_info.lastFailureReason` | Most recent verification failure reason when available. |
| `safety_signals.requires_attention` | True when the response should be reviewed or handled specially. |

```bash
curl https://api.viablelab.org/v1/chat/vetting \
  -H "Content-Type: application/json" \
  -H "X-Platform-ID: your-platform" \
  -d '{
    "model": "viable-2",
    "messages": [
      { "role": "user", "content": "Explain photosynthesis without giving away a homework answer." }
    ],
    "vettingConfig": { "maxAttempts": 1 }
  }'
```

### Full VETTING Workflow

Use `/v1/vetting/full` when the app needs answer-key verification and detailed attempt metadata. This endpoint is more explicit and is better for educational products, grading support, tutoring workflows, and research logging.

Modes:

| Mode | Behavior |
| --- | --- |
| `vetting` | Runs chat generation plus verification against `context.items`. Requires `config.verificationModel` and answer-key context. |
| `chat` | Uses the same structured request format but skips verification. `verification` is `null` and `verificationModelUsed` is `null`. |

Key request fields:

| Field | Required | Notes |
| --- | --- | --- |
| `mode` | Required | `vetting` or `chat`. |
| `config.chatModel.modelId` | Required | Chat model or VIABLE alias used to draft the response. Examples: `viable-2`, `gpt-4.1-nano`, `gemini-2.5-flash`, `llama-3.1-70b-instruct`. |
| `config.chatModel.temperature`, `config.chatModel.maxTokens`, `config.chatModel.topP` | Optional | Per-model generation controls. |
| `config.verificationModel.modelId` | Required in `vetting` mode | Chat-capable verification model or VIABLE alias. This can be different from the drafting model and can use a different provider. |
| `config.maxVerificationAttempts` | Optional | Maximum verification loop attempts. Defaults to 3. |
| `prompts` | Required | Prompt container object; individual fields have defaults. |
| `prompts.chatSystemPrompt` | Optional | Tutor or assistant behavior prompt. Defaults to a guided tutor prompt. |
| `prompts.verificationSystemPrompt` | Optional | Evaluator behavior prompt. Defaults are built from the chat prompt and context. |
| `context.sessionId`, `context.userId` | Optional | Passed through to metadata for traceability. |
| `context.items[]` | Required in `vetting` mode | Question and answer-key records used by verification. |
| `context.items[].question.text` | Required in `vetting` mode | The question, task, or prompt being protected. |
| `context.items[].answerKey.correctAnswer` | Required in `vetting` mode | Reference answer used to decide whether the assistant revealed too much. |
| `context.items[].answerKey.keyConcepts` | Optional | Concepts or terms that should not be directly disclosed. |
| `messages` | Required | Conversation messages ending with the latest user request. Put system-level behavior in `prompts`, not in `messages`. |

Key response fields:

| Field | Notes |
| --- | --- |
| `status` | `success` on successful processing. |
| `mode` | The mode used for the response. |
| `result.role`, `result.content` | Final assistant message after the verification loop. |
| `verification.passed` | Whether the final response passed verification. |
| `verification.attemptCount` | Number of chat generation attempts. |
| `verification.stopReason` | Why the loop stopped. |
| `verification.attempts[]` | Per-attempt `chatResponse`, `verificationPassed`, `verificationOutput`, and optional `requiresAttention`. |
| `usage.chatTokens`, `usage.verificationTokens`, `usage.totalTokens` | Aggregated token usage across chat and verification calls. |
| `metadata.processingTimeMs`, `metadata.timestamp`, `metadata.sessionId`, `metadata.userId` | Trace metadata. |
| `metadata.chatModelUsed`, `metadata.verificationModelUsed` | Requested model IDs or aliases used for the workflow. |
| `safety_signals.requires_attention` | True when the response requires special handling or review. |

Minimal full VETTING request:

```bash
curl https://api.viablelab.org/v1/vetting/full \
  -H "Content-Type: application/json" \
  -H "X-Platform-ID: your-platform" \
  -d '{
    "mode": "vetting",
    "config": {
      "maxVerificationAttempts": 3,
      "chatModel": { "modelId": "viable-2", "temperature": 0.7 },
      "verificationModel": { "modelId": "gemini-2.5-flash", "temperature": 0.1 }
    },
    "prompts": {
      "chatSystemPrompt": "Guide the student without giving away the final answer.",
      "verificationSystemPrompt": "Pass only responses that guide without revealing the answer key."
    },
    "context": {
      "sessionId": "session-123",
      "userId": "user-456",
      "items": [
        {
          "question": { "id": "q1", "text": "What is 6 x 7?", "subject": "Math" },
          "answerKey": {
            "correctAnswer": "42",
            "keyConcepts": ["multiplication", "42"]
          }
        }
      ]
    },
    "messages": [
      { "role": "user", "content": "Just tell me the answer to this homework question." }
    ]
  }'
```

## Embeddings

```bash
curl https://api.viablelab.org/v1/embeddings \
  -H "Content-Type: application/json" \
  -H "X-Platform-ID: your-platform" \
  -d '{ "model": "nomic-embed-text-v1.5", "input": "Searchable text" }'
```

## Image Generation

```bash
curl https://api.viablelab.org/v1/images/generations \
  -H "Content-Type: application/json" \
  -H "X-Platform-ID: your-platform" \
  -d '{
    "model": "flux.2-klein",
    "prompt": "A clean diagram of photosynthesis",
    "size": "1024x1024",
    "n": 1
  }'
```

## Speech

```bash
curl https://api.viablelab.org/v1/audio/speech \
  -H "Content-Type: application/json" \
  -H "X-Platform-ID: your-platform" \
  -d '{
    "model": "gpt-4o-mini-tts",
    "input": "Hello from VIABLE Lab.",
    "voice": "alloy",
    "response_format": "mp3"
  }' \
  --output speech.mp3
```

## Transcription

```bash
curl https://api.viablelab.org/v1/audio/transcriptions \
  -H "X-Platform-ID: your-platform" \
  -F model=gpt-4o-transcribe \
  -F file=@sample.mp3
```

Use `duration_seconds` or `duration_minutes` when known so cost logs can be more accurate.

## Operational Notes

- Include `X-Platform-ID` from server-side calls.
- Use the developer dashboard to manage keys, set limits, review usage, and export request logs by key, endpoint, model, status, or platform.
- Use `stream: true` only on `/v1/chat/completions`.
- VETTING endpoints are intentionally non-streaming.
- Prompt, file, and binary contents are redacted from logs by default.
- For current model IDs and pricing notes, read `/v1/models` or `/v1/docs/metadata` instead of hardcoding lists.
