[{"data":1,"prerenderedAt":800},["ShallowReactive",2],{"api-reference-contract":3},{"version":4,"operations":5},"2.0.0",{"POST \u002Fv1\u002Fchat\u002Fcompletions":6,"POST \u002Fv1\u002Fchat\u002Fvetting":136,"POST \u002Fv1\u002Fvetting\u002Ffull":218,"POST \u002Fv1\u002Fagents\u002F{slug}\u002Fruns":304,"GET \u002Fv1\u002Fagents\u002F{slug}\u002Fruns\u002F{run_id}":388,"POST \u002Fv1\u002Fagents\u002F{slug}\u002Fruns\u002F{run_id}\u002Frating":409,"POST \u002Fv1\u002Flearning\u002Fevents":431,"POST \u002Fv1\u002Flearning\u002Fdrafts":497,"POST \u002Fv1\u002Flearning\u002Foutcomes":522,"POST \u002Fv1\u002Fembeddings":549,"POST \u002Fv1\u002Fimages\u002Fgenerations":585,"POST \u002Fv1\u002Faudio\u002Fspeech":653,"POST \u002Fv1\u002Faudio\u002Ftranscriptions":698,"POST \u002Fv1\u002Futils\u002Fencrypt":752,"POST \u002Fv1\u002Futils\u002Fdecrypt":771,"GET \u002Fv1\u002Fmodels":789},{"method":7,"path":8,"summary":9,"contentType":10,"parameters":11,"body":12,"responseStatus":88,"responseType":10,"responseExample":89,"errors":90},"POST","\u002Fv1\u002Fchat\u002Fcompletions","Create Chat Completion","application\u002Fjson",[],[13,31,35,39,42,53,57,59,62,66,69,71,75,80,86],{"name":14,"type":15,"required":16,"description":17,"children":18},"messages","object[]",true,"A nonempty list of conversation messages. Legacy system-only requests are supported: Gemini translation preserves system instructions and adds a minimal user turn only when no conversation content remains after conversion. Ordinary user\u002Fassistant turns are unchanged. Typed image inputs accept public HTTPS image URLs or base64 image data URLs. The gateway downloads URLs with public-network checks, at most three redirects and a shared 20-second download deadline, then sends image bytes using provider-native fields (OpenAI-compatible data URLs, Gemini inlineData or Anthropic base64). No credentials, custom ports, private\u002Flocal names or IP literals. At most 64 images and 10 MiB decoded combined per chat provider request, including history. Supported MIME types depend on the provider. URLs in plain prompt text are only text; the selected model must support image input.",[19,27],{"name":20,"type":21,"required":16,"description":22,"enum":23},"role","string","The role of the message author.",[24,25,26],"user","assistant","system",{"name":28,"type":29,"required":16,"description":30},"content","string | object[]","",{"name":32,"type":21,"required":33,"description":34},"model",false,"Full model ID or VIABLE alias to use. Defaults to gpt-6-luna. Examples: gpt-6-astra, gpt-6-luna, gpt-5.6-sol, gpt-5.6-terra, gpt-5.6-luna, gemini-3.8-flash, gemini-3.1-pro-preview, gemini-2.5-flash, gpt-oss-120b, mistral-small-3.1, llama-3.3-70b-instruct, viable-1. Legacy short aliases remain accepted for existing integrations; new integrations should use full model IDs or VIABLE aliases. Prefix a model with `@\u003Cprovider-key>\u002F` to call it with one of the paying account's provider keys (BYOK), for example `@openrouter\u002Fanthropic\u002Fclaude-sonnet-4.5` or `@lab-openai\u002Fgpt-6-luna`. The rest of the ID is sent to that provider unchanged. Catalog models also use a provider key automatically when the project owner marked one \"use for catalog models\" for that provider.",{"name":36,"type":37,"required":33,"description":38},"max_tokens","integer","Maximum number of tokens to generate, passed to the provider unchanged; values above the model's max_output_tokens are rejected by the provider. For Gemini, this limit covers both thinking and final output; omitted reasoning_effort preserves provider default thinking.",{"name":40,"type":37,"required":33,"description":41},"max_completion_tokens","Maximum completion tokens for compatible reasoning models. The gateway maps max_tokens to this field for GPT-5 family models when needed. For Gemini, this limit includes thinking and final output and takes precedence over max_tokens; omitted reasoning_effort preserves provider default thinking.",{"name":43,"type":21,"required":33,"description":44,"enum":45},"reasoning_effort","Reasoning effort for compatible models. Check parameter_support.reasoning_effort_values in \u002Fv1\u002Fmodels or \u002Fv1\u002Fdocs\u002Fmetadata before sending a value.",[46,47,48,49,50,51,52],"none","minimal","low","medium","high","xhigh","max",{"name":54,"type":55,"required":33,"description":30,"default":56},"temperature","number","1",{"name":58,"type":55,"required":33,"description":30,"default":56},"top_p",{"name":60,"type":37,"required":33,"description":61,"default":56},"n","How many chat completion choices to generate. (Passed through)",{"name":63,"type":64,"required":33,"description":65},"stop","string | string[]","Up to 4 sequences where the API will stop generating. (Passed through)",{"name":67,"type":55,"required":33,"description":30,"default":68},"presence_penalty","0",{"name":70,"type":55,"required":33,"description":30,"default":68},"frequency_penalty",{"name":72,"type":73,"required":33,"description":74},"response_format","object","An object specifying the format that the model must output. Use { \"type\": \"json_object\" } to enable JSON mode, which ensures the message the model generates is valid JSON. Note: The model needs instructions in the prompt to produce JSON. Gemini maps json_object to native JSON output for ordinary and streaming chat; omitted or text format keeps the provider default.",{"name":76,"type":77,"required":33,"description":78,"default":79},"stream","boolean","If true, returns OpenAI-style server-sent events from \u002Fv1\u002Fchat\u002Fcompletions. Streaming is supported on the main chat endpoint; vetting endpoints remain non-streaming.","false",{"name":81,"type":21,"required":33,"description":82,"enum":83},"provider","Optional provider hint for public providers. Most clients should omit this and rely on model-first routing.",[84,85],"openai","gemini",{"name":24,"type":21,"required":33,"description":87},"Your identifier for the end user. VIABLE keeps it as a learner of the key's project (the project's logs can be filtered by learner_id). Providers that accept it receive it as sent, so use a pseudonymous id, not a name or email.","200","{\n  \"id\": \"chatcmpl-8f2c41d9b6a04f1e9c3d7a52e0b8c6f1\",\n  \"object\": \"chat.completion\",\n  \"created\": 1760000000,\n  \"model\": \"viable-3\",\n  \"choices\": [\n    {\n      \"index\": 0,\n      \"message\": {\n        \"role\": \"assistant\",\n        \"content\": \"Earth's axis is tilted about 23.5 degrees. As Earth orbits the Sun, each hemisphere takes turns leaning toward it. The hemisphere leaning toward the Sun gets more direct sunlight and longer days, which is summer. The one leaning away gets weaker, slanted light and shorter days, which is winter.\"\n      },\n      \"finish_reason\": \"stop\"\n    }\n  ],\n  \"usage\": {\n    \"prompt_tokens\": 31,\n    \"completion_tokens\": 64,\n    \"total_tokens\": 95\n  }\n}",[91,94,97,100,103,106,109,112,115,118,121,124,127,130,133],{"status":92,"description":93},"400","Bad Request. Can occur due to invalid JSON, missing required fields, or attempting unsupported options like streaming. Provider key models can also be malformed (invalid_provider_key_model), unknown here (provider_key_not_found), not enabled for this project (provider_key_not_in_project), or unsupported for this operation (provider_key_unsupported_operation).",{"status":95,"description":96},"401","Missing, invalid, inactive, or expired VIABLE API key. HTTP 401 with WWW-Authenticate: Bearer realm=\"VIABLE API\".",{"status":98,"description":99},"402","No key can pay: the key is out of credit or over its limit (provider_insufficient_funds), or every key in the provider key is (provider_keys_exhausted; details give counts and next_available_at). Add funds or keys, raise a limit, or let the provider key fall back to VIABLE credits. details.attempts lists what each key’s provider said.",{"status":101,"description":102},"403","Forbidden, including provider_model_unavailable when every eligible key refuses the model with 400\u002F401\u002F403 (for example UF\u002FLiteLLM Invalid model name). Ordinary 400 parameter errors do not rotate keys.",{"status":104,"description":105},"404","No key in the provider key can use this model (provider_model_unavailable).",{"status":107,"description":108},"405","Method Not Allowed. The HTTP method used is not supported for this endpoint.",{"status":110,"description":111},"409","The provider key this request needs is paused (provider_key_paused) or has no keys (provider_key_empty).",{"status":113,"description":114},"410","The requested model is no longer supported by VIABLE Lab. Choose an available ID from \u002Fv1\u002Fmodels and update the request explicitly. Requests are never redirected.",{"status":116,"description":117},"413","Serialized model JSON bodies are limited to 32 MiB, other non-multipart bodies to 12 MiB, and multipart bodies to 26 MiB including framing. These gateway byte limits are independent of model token\u002Fcontext limits. See Request size limits for the endpoint categories. Model providers can also return 413 with the generic service_error\u002Fmodel_provider_error shape, without max_bytes. With a provider key, also provider_request_too_large: the request is larger than the per-minute token limit of every key tried. Shorten the input or lower max_tokens.",{"status":119,"description":120},"424","The provider rejected the only key in the provider key (provider_key_rejected), or it can no longer be read. Replace it under Provider keys.",{"status":122,"description":123},"429","Too Many Requests. Rate limit exceeded. Provider keys add provider_rate_limited (every available key is rate-limited by its provider; Retry-After says when one is free) and provider_keys_rotating (more keys are left than one request tries; retry now to reach them, Retry-After: 1). details.attempts lists what each key’s provider said.",{"status":125,"description":126},"499","Client disconnected before the non-streaming response completed. Normally visible only in Request Logs. A call already sent to the provider still finishes and its actual usage and cost are recorded; a call that never started records zero. Streaming responses already started keep HTTP 200.",{"status":128,"description":129},"500","Internal Server Error. An unexpected error occurred on the server.",{"status":131,"description":132},"501","Not Implemented. The requested functionality is not available.",{"status":134,"description":135},"502","Upstream model service error. Error occurred when communicating with a model provider. With a provider key: the provider failed, or its endpoint could not be reached (provider_endpoint_unreachable) or redirected (provider_endpoint_redirected).",{"method":7,"path":137,"summary":138,"contentType":10,"parameters":139,"body":140,"responseStatus":88,"responseType":10,"responseExample":201,"errors":202},"\u002Fv1\u002Fchat\u002Fvetting","Create Vetted Chat Completion",[],[141,147,149,151,154,155,157,159,160,161,164,166],{"name":14,"type":15,"required":16,"description":142,"children":143},"Conversation history. System message can be included here. A system message whose string content starts with enc:: (the `value` returned by \u002Fv1\u002Futils\u002Fencrypt) is decrypted by the Worker before use and before logging; prompts encrypted before the dedicated prompt key was introduced keep working.",[144,146],{"name":20,"type":21,"required":16,"description":22,"enum":145},[24,25,26],{"name":28,"type":29,"required":16,"description":30},{"name":32,"type":21,"required":33,"description":148},"Full chat model ID or VIABLE alias. Defaults apply if omitted. See \u002Fv1\u002Fmodels for supported chat models.",{"name":81,"type":21,"required":33,"description":82,"enum":150},[84,85],{"name":36,"type":37,"required":33,"description":152,"default":153},"Drafting token budget. Defaults to 1024 when neither token budget is provided. max_completion_tokens takes precedence. The selected model determines whether reasoning and final output share this budget.","1024",{"name":40,"type":37,"required":33,"description":41},{"name":43,"type":21,"required":33,"description":44,"enum":156},[46,47,48,49,50,51,52],{"name":54,"type":55,"required":33,"description":30,"default":158},"0.7",{"name":58,"type":55,"required":33,"description":30,"default":56},{"name":63,"type":64,"required":33,"description":65},{"name":76,"type":77,"required":33,"description":162,"enum":163,"default":79},"Omit or set false. This VETTING endpoint rejects stream: true with HTTP 400 streaming_not_supported.",[79],{"name":24,"type":21,"required":33,"description":165},"Your pseudonymous end-user identifier for VIABLE learner\u002Flog attribution; do not send a name or email. This VETTING route does not forward it to the drafting provider.",{"name":167,"type":73,"required":33,"description":30,"children":168},"vettingConfig",[169,172,176,197],{"name":170,"type":21,"required":33,"description":171},"systemPrompt","A specific guideline for the internal verification model to check against. If omitted, a default safety\u002Fguidance prompt is used. Values prefixed with enc:: (from \u002Fv1\u002Futils\u002Fencrypt `value`) are decrypted by the Worker before use and before logging; prompts encrypted before the dedicated prompt key was introduced keep working.",{"name":173,"type":37,"required":33,"description":174,"default":175},"maxAttempts","Optional integer from 1 to 10. Defaults to 3 when omitted; invalid values return HTTP 400.","3",{"name":177,"type":73,"required":33,"description":30,"children":178},"verificationModel",[179,182,184,187,190,194],{"name":180,"type":21,"required":16,"description":181},"modelId","Full chat model ID or VIABLE alias. Examples: viable-1, gpt-6-luna, gemini-3.8-flash, gemini-3.1-pro-preview, gemini-2.5-flash, gpt-oss-120b, mistral-small-3.1, llama-3.3-70b-instruct. See \u002Fv1\u002Fmodels for the current catalog. Non-chat models are rejected on VETTING endpoints. Prefix a model with `@\u003Cprovider-key>\u002F` to call it with one of the paying account's provider keys (BYOK), for example `@openrouter\u002Fanthropic\u002Fclaude-sonnet-4.5` or `@lab-openai\u002Fgpt-6-luna`. The rest of the ID is sent to that provider unchanged. Catalog models also use a provider key automatically when the project owner marked one \"use for catalog models\" for that provider.",{"name":54,"type":55,"required":33,"description":183},"Sampling temperature. If omitted, server defaults apply (e.g., Chat: 0.7, Verify: 0.1).",{"name":185,"type":37,"required":33,"description":186},"maxTokens","Maximum token budget for the selected model; it may include reasoning and final output. Equivalent to Chat Completions max_tokens. Defaults to 1024 for chat, 256 for simple verification or 512 for full verification. maxCompletionTokens takes precedence. Model\u002Fprovider output limits still apply.",{"name":188,"type":55,"required":33,"description":189},"topP","Nucleus sampling parameter.",{"name":191,"type":21,"required":33,"description":192,"enum":193},"reasoningEffort","Formal reasoning effort for this chat or verification model, equivalent to Chat Completions reasoning_effort. Supported values depend on the selected model; gpt-oss-120b accepts low, medium, high. Omission preserves the existing model or endpoint default. The legacy reasoning_effort spelling is also accepted.",[46,47,48,49,50,51,52],{"name":195,"type":37,"required":33,"description":196},"maxCompletionTokens","Maximum completion-token budget, including reasoning when the model counts it. Equivalent to Chat Completions max_completion_tokens. Takes precedence over maxTokens when both are supplied; forwarded to the selected provider without inflating an explicit value.",{"name":198,"type":77,"required":33,"description":199,"default":200},"requireClosingQuestion","Whether to append the built-in instruction to conclude every tutor response with a question. Set false to let the supplied tutor prompt decide. Safety instructions remain enabled. Omission preserves the existing behavior.","true","{\n  \"id\": \"chatcmpl-d148a3ed-d31e-445e-a320-654ccbf4f505\",\n  \"object\": \"chat.completion\",\n  \"created\": 1745312855,\n  \"model\": \"viable-3\",\n  \"choices\": [\n    {\n      \"index\": 0,\n      \"message\": {\n        \"role\": \"assistant\",\n        \"content\": \"Sure! To find the capital of France...\"\n      },\n      \"finish_reason\": \"stop\"\n    }\n  ],\n  \"usage\": {\n    \"prompt_tokens\": 497,\n    \"completion_tokens\": 66,\n    \"total_tokens\": 563\n  },\n  \"vetting_info\": {\n    \"attemptCount\": 2,\n    \"stopReason\": \"VERIFICATION_PASSED\"\n  },\n  \"safety_signals\": {\n    \"requires_attention\": false\n  }\n}",[203,205,206,207,209,210,211,212,214,215,216,217],{"status":92,"description":204},"Bad Request. Can occur due to invalid JSON, missing required fields, or attempting unsupported options like streaming.",{"status":95,"description":96},{"status":98,"description":99},{"status":101,"description":208},"Access denied. Request source (Origin\u002FReferer via CORS) might be invalid (temporary check), or insufficient permissions (future).",{"status":107,"description":108},{"status":110,"description":111},{"status":113,"description":114},{"status":116,"description":213},"Serialized model JSON bodies are limited to 32 MiB, other non-multipart bodies to 12 MiB, and multipart bodies to 26 MiB including framing. These gateway byte limits are independent of model token\u002Fcontext limits. See Request size limits for the endpoint categories. Model providers can also return 413 with the generic service_error\u002Fmodel_provider_error shape, without max_bytes.",{"status":119,"description":120},{"status":122,"description":123},{"status":128,"description":129},{"status":134,"description":135},{"method":7,"path":219,"summary":220,"contentType":10,"parameters":221,"body":222,"responseStatus":88,"responseType":10,"responseExample":288,"errors":289},"\u002Fv1\u002Fvetting\u002Ffull","Create Full VETTING Verification",[],[223,229,254,264,282],{"name":224,"type":21,"required":16,"description":225,"enum":226},"mode","Operation mode: 'vetting' enables the verification layer, 'chat' provides standard chat.",[227,228],"vetting","chat",{"name":230,"type":73,"required":16,"description":30,"children":231},"config",[232,234,244,253],{"name":233,"type":37,"required":33,"description":174,"default":175},"maxVerificationAttempts",{"name":235,"type":73,"required":16,"description":30,"children":236},"chatModel",[237,238,239,240,241,243],{"name":180,"type":21,"required":16,"description":181},{"name":54,"type":55,"required":33,"description":183},{"name":185,"type":37,"required":33,"description":186},{"name":188,"type":55,"required":33,"description":189},{"name":191,"type":21,"required":33,"description":192,"enum":242},[46,47,48,49,50,51,52],{"name":195,"type":37,"required":33,"description":196},{"name":177,"type":73,"required":33,"description":30,"children":245},[246,247,248,249,250,252],{"name":180,"type":21,"required":16,"description":181},{"name":54,"type":55,"required":33,"description":183},{"name":185,"type":37,"required":33,"description":186},{"name":188,"type":55,"required":33,"description":189},{"name":191,"type":21,"required":33,"description":192,"enum":251},[46,47,48,49,50,51,52],{"name":195,"type":37,"required":33,"description":196},{"name":198,"type":77,"required":33,"description":199,"default":200},{"name":255,"type":73,"required":16,"description":256,"children":257},"prompts","Container for system prompts. The object itself is required in the request, but the fields within are optional.",[258,261],{"name":259,"type":21,"required":33,"description":260},"chatSystemPrompt","Base system prompt for the chat model. If omitted, a default helpful tutor prompt is used. Values prefixed with enc:: (from \u002Fv1\u002Futils\u002Fencrypt `value`) are decrypted by the Worker before use and before logging; prompts encrypted before the dedicated prompt key was introduced keep working.",{"name":262,"type":21,"required":33,"description":263},"verificationSystemPrompt","Base system prompt for the verification model. If omitted and mode='vetting', a default evaluator prompt is constructed using the chat prompt and context. Values prefixed with enc:: (from \u002Fv1\u002Futils\u002Fencrypt `value`) are decrypted by the Worker before use and before logging; prompts encrypted before the dedicated prompt key was introduced keep working.",{"name":265,"type":73,"required":33,"description":266,"children":267},"context","Contextual information. The 'items' array is required if mode='vetting'.",[268,271,274],{"name":269,"type":21,"required":33,"description":270},"sessionId","Session identifier.",{"name":272,"type":21,"required":33,"description":273},"userId","User identifier.",{"name":275,"type":15,"required":16,"description":276,"children":277},"items","(Required if mode='vetting') Array of questions and their corresponding answer keys.",[278,280],{"name":279,"type":73,"required":16,"description":30},"question",{"name":281,"type":73,"required":16,"description":30},"answerKey",{"name":14,"type":15,"required":16,"description":283,"children":284},"Conversation history, ending with the last user message. Client should provide messages with roles 'user' and optionally previous 'assistant' messages. Do not include 'system' role messages here; use the `prompts` field instead.",[285,287],{"name":20,"type":21,"required":16,"description":22,"enum":286},[24,25,26],{"name":28,"type":29,"required":16,"description":30},"{\n  \"status\": \"success\",\n  \"mode\": \"vetting\",\n  \"result\": {\n    \"role\": \"assistant\",\n    \"content\": \"To modify the code to display the 5 most common trigrams, consider what you need to change in the `ngrams` function. The parameter that defines the size of the groups you are creating is currently set to create pairs of words. Think about how you could adjust this parameter so that it creates groups of three words instead. \\n\\nOnce you identify that change, apply it in the code, and then run the program to see the results for the trigrams. What do you think you should set the parameter to?\"\n  },\n  \"verification\": {\n    \"passed\": false,\n    \"attemptCount\": 2,\n    \"stopReason\": \"VERIFICATION_PASSED\",\n    \"attempts\": [\n      {\n        \"attemptNumber\": 1,\n        \"chatResponse\": \"To modify the code to display the 5 most common trigrams instead of bigrams, you need to change the `n` parameter of the `ngrams` function from `2` to `3`. Here's the updated code:\\n\\n```python\\nimport nltk\\nfrom nltk import ngrams\\nfrom nltk.probability import FreqDist\\nfrom collections import defaultdict\\n\\ntext = \\\"My dog is happy when he gets a treat and my dog is sad when he goes to the vet.\\\"\\n\\ntokens = nltk.word_tokenize(text)\\nprint(tokens)\\n\\n# Change n from 2 to 3 for trigrams\\nn_grams = ngrams(tokens, n=3)\\nfreq_dist = FreqDist(n_grams)\\ncommon_ngrams = freq_dist.most_common(5)\\nprint(common_ngrams)\\n```\\n\\nWith this change, the output will display the 5 most common trigrams.\",\n        \"verificationPassed\": false,\n        \"verificationOutput\": \"FAILED: Directly states the answer 'change the n parameter of the ngrams function from 2 to 3'.\"\n      },\n      {\n        \"attemptNumber\": 2,\n        \"chatResponse\": \"To modify the code to display the 5 most common trigrams, consider what you need to change in the `ngrams` function. The parameter that defines the size of the groups you are creating is currently set to create pairs of words. Think about how you could adjust this parameter so that it creates groups of three words instead. \\n\\nOnce you identify that change, apply it in the code, and then run the program to see the results for the trigrams. What do you think you should set the parameter to?\",\n        \"verificationPassed\": true,\n        \"verificationOutput\": \"PASS\"\n      }\n    ]\n  },\n  \"safety_signals\": {\n    \"requires_attention\": false\n  },\n  \"usage\": {\n    \"chatTokens\": {\n      \"prompt\": 1462,\n      \"completion\": 290,\n      \"total\": 1752\n    },\n    \"verificationTokens\": {\n      \"prompt\": 1638,\n      \"completion\": 27,\n      \"total\": 1665\n    },\n    \"totalTokens\": 3417\n  },\n  \"metadata\": {\n    \"processingTimeMs\": 6157,\n    \"timestamp\": \"2025-04-22T07:19:01.714Z\",\n    \"sessionId\": \"session_abc123\",\n    \"userId\": \"user_xyz789\",\n    \"chatModelUsed\": \"viable-3\",\n    \"verificationModelUsed\": \"gpt-6-luna\"\n  }\n}",[290,292,293,294,295,296,297,298,299,300,301,303],{"status":92,"description":291},"Bad Request. Invalid input, missing required fields, or malformed JSON. The response body contains details about the validation errors.",{"status":95,"description":96},{"status":98,"description":99},{"status":101,"description":208},{"status":107,"description":108},{"status":110,"description":111},{"status":113,"description":114},{"status":116,"description":213},{"status":119,"description":120},{"status":122,"description":123},{"status":128,"description":302},"Internal Server Error. An unexpected error occurred during processing.",{"status":134,"description":135},{"method":7,"path":305,"summary":306,"contentType":10,"parameters":307,"body":316,"responseStatus":88,"responseType":10,"responseExample":359,"errors":360},"\u002Fv1\u002Fagents\u002F{slug}\u002Fruns","Run an agent turn",[308,312],{"name":309,"in":310,"type":21,"required":16,"description":311},"slug","path","Published agent slug.",{"name":313,"in":314,"type":21,"required":33,"description":315},"Idempotency-Key","header","Optional stable key for the same logical request. Completed requests replay; mismatched payloads and pending requests return 409. Never change the key to retry an uncertain outcome.",[317,321,324,327,333,340,342,344,350,352,355],{"name":318,"type":319,"required":33,"description":320},"input","string | object | object[]","Latest user turn for an Agent. Text is retained exactly. Inline image\u002Ffile data is bounded, archived byte-for-byte in private R2, and represented in research logs by an authenticated asset reference. HTTPS URLs are retained exactly as restricted provenance and are not fetched by VIABLE Lab.",{"name":322,"type":21,"required":33,"description":323},"conversation_id","Continue an existing agent conversation. Omit (or send null) on the first turn, store the returned value, and resend it for later turns from the same end-user session.",{"name":325,"type":21,"required":33,"description":326},"message","Backward-compatible text-only alias for input. Omit input when using this field.",{"name":14,"type":15,"required":33,"description":328,"children":329},"With history_mode=client, preserves supported system\u002Fdeveloper\u002Fuser\u002Fassistant messages in order; final message must be user. In server mode (the default) without conversation_id (absent or null), two or more messages start a new conversation holding all but the last, which the run answers: a conversation branched from an edited message. The final message must be user; at most 400 messages, each bounded like client history. The returned conversation_id continues it. With conversation_id, explicit server mode takes one message (more return 400), and without an explicit mode legacy last-user extraction remains unchanged. Tools are not supported.",[330,332],{"name":20,"type":21,"required":16,"description":22,"enum":331},[24,25,26],{"name":28,"type":29,"required":16,"description":30},{"name":334,"type":21,"required":33,"description":335,"enum":336,"default":339},"history_mode","server preserves legacy conversation behavior: steps get the conversation's latest messages, the oldest left out only when a model's context window is full (the step output then has context_trimmed: true); an agent whose Input step sets config.history to \"summarize\" folds the oldest turns into a running summary stored with the conversation once its history nears the models' context budget. Without conversation_id, two or more messages start a new conversation holding all but the last (see messages). client uses the supplied complete messages transcript; none is a single turn without a conversation. Both client and none retain research logs and usage, and reject conversation_id.",[337,338,46],"server","client","\"server\"",{"name":265,"type":73,"required":33,"description":341},"Optional current request data, max 128 KiB and nesting depth 16. Nodes explicitly opt in with includeContext or context templates. Never automatically appended to conversation history; research traces retain snapshots. With user, the turn also keeps it as what the learner had open (workspace in turns.csv): fields VIABLE composes itself are left out, and the largest fields until it fits 32,000 characters.",{"name":24,"type":21,"required":33,"description":343},"Optional opaque identifier for the end user, such as your app's student ID. Memory steps keep long-term facts per agent and user; without it, memory follows the server conversation. Each turn is kept with the learner it names in the project's Learners (their id is shown with them, so their data joins back to your records). Do not send names or emails.",{"name":345,"type":21,"required":33,"description":346,"enum":347},"sources","How to list the reply's cited sources in its text: none (default here; read them from output.citations), markdown (a numbered **Sources** list with links, [n] markers linked), or text (\"Sources:\" and one line per source with its link).",[46,348,349],"markdown","text",{"name":76,"type":77,"required":33,"description":351,"default":79},"true streams the run as server-sent events, so callers can show what it is doing while it works.",{"name":353,"type":21,"required":33,"description":354},"learner_group","Optional app-reported task\u002Fgroup label for this turn. Requires user. Stored as learner_group on the learning turn and available through the learner Group filter and research turns export. Does not change identity, roster cohort, course enrollment, or model prompt\u002Fhistory. Keep it fixed on retries: present values participate in the request fingerprint; absent values preserve earlier fingerprints. Not a verified grade or access rule.",{"name":356,"type":357,"required":33,"description":358},"include","string[]","Extras the result carries. trace adds result.trace (AgentRunTrace): the run's wall-clock time, each step's status, timing, model, tokens and cost, and each VETTING review round by round, for an app's own research log. Without include the result is unchanged. Any other value, or a value that is not a list, returns 400 invalid_include before anything is recorded, so a corrected retry may reuse its Idempotency-Key. include is not part of the request fingerprint: a run retried with the same key replays its result with or without the trace; a job keeps the first request's choice.","{\n  \"object\": \"agent.run.result\",\n  \"agent\": \"string\",\n  \"conversation_id\": \"string\",\n  \"run_id\": \"string\",\n  \"output\": {\n    \"text\": \"string\",\n    \"attachments\": [\n      {\n        \"type\": \"string\",\n        \"url\": \"string\"\n      }\n    ],\n    \"awaiting_input\": false,\n    \"citations\": [\n      {\n        \"index\": 0,\n        \"title\": \"string\",\n        \"page_title\": \"string\",\n        \"url\": \"string\",\n        \"link\": \"string\",\n        \"kind\": \"file\",\n        \"heading\": \"string\",\n        \"page\": 0,\n        \"snippet\": \"string\",\n        \"document_id\": \"string\",\n        \"knowledge_base_id\": \"string\"\n      }\n    ],\n    \"data\": null,\n    \"sources_in_text\": false\n  },\n  \"transcript\": {\n    \"text\": \"string\",\n    \"language\": null,\n    \"duration_seconds\": null\n  },\n  \"usage\": {\n    \"prompt\": 0,\n    \"completion\": 0,\n    \"total\": 0\n  },\n  \"cost\": 0,\n  \"input_assets\": [\n    {\n      \"id\": \"rasset_0123456789abcdef0123456789abcdef01234567\",\n      \"request_id\": \"string\",\n      \"agent_id\": \"string\",\n      \"agent_run_id\": \"string\",\n      \"conversation_id\": \"string\",\n      \"direction\": \"request\",\n      \"content_index\": 0,\n      \"modality\": \"image\",\n      \"content_type\": \"string\",\n      \"filename\": \"string\",\n      \"byte_size\": 0,\n      \"sha256\": \"string\",\n      \"source_url_sha256\": \"string\",\n      \"source\": \"private_r2\",\n      \"download_url\": \"string\",\n      \"view_url\": \"string\",\n      \"source_url\": \"string\",\n      \"created_at\": \"string\"\n    }\n  ],\n  \"trace\": {\n    \"started_at\": \"string\",\n    \"completed_at\": \"string\",\n    \"duration_ms\": 0,\n    \"steps\": [\n      {\n        \"step_number\": 0,\n        \"node_id\": \"string\",\n        \"node_type\": \"input\",\n        \"status\": \"completed\",\n        \"duration_ms\": 0,\n        \"model\": \"string\",\n        \"tokens\": 0,\n        \"cost\": 0,\n        \"error\": \"string\"\n      }\n    ],\n    \"vetting\": [\n      {\n        \"step_number\": 0,\n        \"node_id\": \"string\",\n        \"outcome\": \"passed\",\n        \"stop_reason\": \"VERIFICATION_PASSED\",\n        \"attempts\": 0,\n        \"rounds\": [\n          {\n            \"attempt\": 0,\n            \"source\": \"draft\",\n            \"verdict\": \"pass\",\n            \"feedback\": \"string\",\n            \"reply\": \"string\"\n          }\n        ]\n      }\n    ]\n  }\n}",[361,363,364,366,368,370,372,373,375,378,380,382,385],{"status":92,"description":362},"Invalid request: invalid_include (include other than [\"trace\"]), invalid_request_structure (for example several messages with conversation_id, or seeding messages whose last is not the user's), invalid_json, or another validation error.",{"status":95,"description":96},{"status":98,"description":365},"A step’s model runs on the project’s own provider key, and that provider account is out of credit (provider_insufficient_funds), or every key in its pool is (provider_keys_exhausted). Add funds with the provider or change the key; retrying won’t help until then.",{"status":101,"description":367},"The API key may not run this agent or lacks the agents:execute scope.",{"status":104,"description":369},"Agent not found or not published.",{"status":110,"description":371},"The Idempotency-Key was used for a different request (idempotency_conflict), or the same request is still processing or needs recovery (agent_request_pending). Retry with the same key; never submit a new turn for an uncertain outcome.",{"status":113,"description":114},{"status":116,"description":374},"Request body exceeds 12 MiB for non-multipart bodies, or 26 MiB including multipart framing. Agent routes retain smaller route-specific limits. This gateway byte limit is separate from the model context window.",{"status":376,"description":377},"422","The request was valid, but the agent couldn’t finish it: its graph or a step’s setting is broken (invalid_graph, agent_expression_error, vetting_answer_key_missing), a step’s input was unusable (nothing_heard, speech_text_empty, transcribe_audio_invalid, llm_json_parse_failed), the run reached its limits (agent_budget_exceeded, agent_state_too_large), or a sub-agent couldn’t be called (subagent_unavailable, subagent_disabled, subagent_cycle, subagent_depth_exceeded). The run history shows the step; fix the agent or the input before retrying.",{"status":119,"description":379},"The model provider rejected the project’s own provider key for a step’s model (provider_key_rejected). Replace or re-enable the key; retrying won’t help until then.",{"status":122,"description":381},"Too many requests for this key (rate_limit_exceeded), the key or account is out of its spending limit (quota_error), or the model service is busy. Respect Retry-After when present.",{"status":383,"description":384},"503","The run could not be queued or its saved result could not be read just now (agent_queue_unavailable, agent_replay_unavailable). Retry with the same Idempotency-Key.",{"status":386,"description":387},"504","A model step timed out (provider_timeout). The run history keeps what happened; retry with the same Idempotency-Key.",{"method":389,"path":390,"summary":391,"contentType":392,"parameters":393,"body":399,"responseStatus":88,"responseType":10,"responseExample":400,"errors":401},"GET","\u002Fv1\u002Fagents\u002F{slug}\u002Fruns\u002F{run_id}","Read a run back, with its trace, using the API key that made it",null,[394,396],{"name":309,"in":310,"type":21,"required":16,"description":395},"Agent slug.",{"name":397,"in":310,"type":21,"required":16,"description":398},"run_id","The run_id a run or job result returned.",[],"{\n  \"object\": \"agent.run\",\n  \"id\": \"string\",\n  \"agent\": \"string\",\n  \"conversation_id\": \"string\",\n  \"status\": \"running\",\n  \"started_at\": \"string\",\n  \"completed_at\": \"string\",\n  \"duration_ms\": 0,\n  \"output\": {\n    \"text\": \"string\",\n    \"attachments\": [\n      {\n        \"type\": \"string\",\n        \"url\": \"string\"\n      }\n    ],\n    \"data\": null\n  },\n  \"usage\": {\n    \"total\": 0\n  },\n  \"cost\": 0,\n  \"trace\": {\n    \"started_at\": \"string\",\n    \"completed_at\": \"string\",\n    \"duration_ms\": 0,\n    \"steps\": [\n      {\n        \"step_number\": 0,\n        \"node_id\": \"string\",\n        \"node_type\": \"input\",\n        \"status\": \"completed\",\n        \"duration_ms\": 0,\n        \"model\": \"string\",\n        \"tokens\": 0,\n        \"cost\": 0,\n        \"error\": \"string\"\n      }\n    ],\n    \"vetting\": [\n      {\n        \"step_number\": 0,\n        \"node_id\": \"string\",\n        \"outcome\": \"passed\",\n        \"stop_reason\": \"VERIFICATION_PASSED\",\n        \"attempts\": 0,\n        \"rounds\": [\n          {\n            \"attempt\": 0,\n            \"source\": \"draft\",\n            \"verdict\": \"pass\",\n            \"feedback\": \"string\",\n            \"reply\": \"string\"\n          }\n        ]\n      }\n    ]\n  }\n}",[402,403,405,407],{"status":95,"description":96},{"status":101,"description":404},"The API key lacks the agents:execute scope.",{"status":104,"description":406},"run_not_found: no run with this id was made by this key through runs, jobs or chat completions for this agent.",{"status":122,"description":408},"agent_poll_rate_exceeded: the key read jobs and runs more than AGENT_JOB_POLL_RATE_PER_MINUTE (6,000) times this minute. Honor Retry-After.",{"method":7,"path":410,"summary":411,"contentType":10,"parameters":412,"body":415,"responseStatus":88,"responseType":10,"responseExample":421,"errors":422},"\u002Fv1\u002Fagents\u002F{slug}\u002Fruns\u002F{run_id}\u002Frating","Rate a run’s reply",[413,414],{"name":309,"in":310,"type":21,"required":16,"description":395},{"name":397,"in":310,"type":21,"required":16,"description":398},[416],{"name":417,"type":37,"required":16,"description":418,"enum":419},"rating","1 helpful, -1 not helpful, null to take a rating back.",[56,420],"-1","{\n  \"object\": \"agent.run.rating\",\n  \"run_id\": \"agtr_...\",\n  \"rating\": 1\n}",[423,425,426,428,429],{"status":92,"description":424},"invalid_rating: rating is missing or not 1, -1 or null. invalid_json: the body isn’t JSON.",{"status":95,"description":96},{"status":101,"description":427},"insufficient_api_key_scope: the key lacks agents:execute.",{"status":104,"description":406},{"status":122,"description":430},"api_key_rate_limit_exceeded or rate_limit_exceeded. Honor Retry-After.",{"method":7,"path":432,"summary":433,"contentType":10,"parameters":434,"body":438,"responseStatus":88,"responseType":10,"responseExample":486,"errors":487},"\u002Fv1\u002Flearning\u002Fevents","Record learning events",[435],{"name":436,"in":314,"type":21,"required":16,"description":437},"X-Platform-ID","Your app’s stable ID, such as writing-app. Required: the activity is stored under it, and Build → Apps counts what it sent.",[439,441,444,446,449],{"name":24,"type":21,"required":16,"description":440},"Your app’s stable, opaque ID for the person (at most 128 characters, no control characters): the learner a run with this user is. Never a name or an email.",{"name":442,"type":21,"required":16,"description":443},"activity","Your app’s ID for the task. Stored as the activity app:\u003CX-Platform-ID>:\u003Cactivity>.",{"name":353,"type":21,"required":33,"description":445},"Optional task group, such as \"Grade 8\", kept on each event (learner_group in workspace_events.csv), as on a run’s turn. Not a verified grade or enrollment.",{"name":447,"type":21,"required":33,"description":448},"session","Optional ID of the learner’s visit in your app, to tell visits apart.",{"name":450,"type":15,"required":16,"description":30,"children":451},"events",[452,474,477,480,483],{"name":453,"type":21,"required":16,"description":454,"enum":455},"type","A course workspace event kind, by its full name, or app.event for your app’s own. Each kind keeps only its own fields from data (the research export’s data dictionary lists them, under workspace_events.csv); others are dropped. writing.progress: field (plan or draft), keys, deleted, pasted, pastes, pasted_from_ai, pauses, pause_ms, longest_pause_ms, p_bursts, r_bursts, burst_chars, inside_edits, leading_edits, active_ms, visible_ms, words, chars. writing.snapshot: field, text (20,000 characters), words. writing.submit: words, chars. panel.view: visible_ms, active_ms. questions.answer: prompt, response, correct, score, attempt, rt_ms and more. Never send keystrokes.",[456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473],"panel.view","page.layout","writing.start","writing.progress","writing.snapshot","writing.rubric","writing.rubric_check","writing.submit","embed.event","embed.state","reading.page","reading.highlight","reading.note","reading.search","questions.view","questions.hint","questions.answer","app.event",{"name":475,"type":21,"required":33,"description":476},"at","When it happened, on your app’s clock (client_at in the export).",{"name":478,"type":37,"required":33,"description":479},"seq","Its order in the session.",{"name":481,"type":21,"required":33,"description":482},"item","What it concerns, such as a question’s ID.",{"name":484,"type":73,"required":33,"description":485},"data","The event’s fields. For app.event, a flat object of up to 20 keys (letters, numbers, _ . -; 40 characters) whose values are numbers, booleans or strings of up to 200 characters; nested values are dropped.","{\n  \"object\": \"learning.events\",\n  \"activity\": \"persuasive-essay-1\",\n  \"accepted\": 2,\n  \"rejected\": 1,\n  \"rejections\": [\n    {\n      \"index\": 2,\n      \"reason\": \"unknown_type\"\n    }\n  ]\n}",[488,490,491,493,495],{"status":92,"description":489},"platform_id_required: no X-Platform-ID, or a malformed one. invalid_learning_request: user, activity, learner_group, session or events (1–200) is missing or malformed. invalid_json: the body isn’t JSON.",{"status":95,"description":96},{"status":101,"description":492},"insufficient_api_key_scope: the key lacks the learning:write scope. project_archived, project_suspended or project_inactive: the key’s project is not active.",{"status":116,"description":494},"request_too_large: the body exceeds 262,144 bytes.",{"status":122,"description":496},"api_key_rate_limit_exceeded (the key’s requests per minute) or rate_limit_exceeded (the address’s). Honor Retry-After.",{"method":7,"path":498,"summary":499,"contentType":10,"parameters":500,"body":502,"responseStatus":88,"responseType":10,"responseExample":514,"errors":515},"\u002Fv1\u002Flearning\u002Fdrafts","Save a draft",[501],{"name":436,"in":314,"type":21,"required":16,"description":437},[503,504,505,508,511],{"name":24,"type":21,"required":16,"description":440},{"name":442,"type":21,"required":16,"description":443},{"name":506,"type":21,"required":33,"description":507},"plan","The plan as it is now. Each save replaces the last: a save without plan leaves none.",{"name":509,"type":21,"required":16,"description":510},"draft","The text as it is now (the whole text, each time).",{"name":512,"type":77,"required":33,"description":513,"default":79},"submit","true hands it in now: submitted_at in writing.csv. A later save keeps the hand-in time.","{\n  \"object\": \"learning.draft\",\n  \"activity\": \"persuasive-essay-1\",\n  \"words\": 212,\n  \"submitted_at\": \"2026-10-29T14:30:00.000Z\",\n  \"updated_at\": \"2026-10-29T14:30:00.000Z\"\n}",[516,518,519,520,521],{"status":92,"description":517},"platform_id_required: no X-Platform-ID, or a malformed one. invalid_learning_request: user, activity, draft (at most 20,000 characters), plan or submit is missing or malformed. invalid_json: the body isn’t JSON.",{"status":95,"description":96},{"status":101,"description":492},{"status":116,"description":494},{"status":122,"description":496},{"method":7,"path":523,"summary":524,"contentType":10,"parameters":525,"body":526,"responseStatus":88,"responseType":10,"responseExample":541,"errors":542},"\u002Fv1\u002Flearning\u002Foutcomes","Record scores",[],[527,530],{"name":528,"type":21,"required":16,"description":529},"measure","The instrument, such as rubric or posttest (letters, numbers, spaces, . _ - :). Sending a measure again replaces each learner’s value.",{"name":531,"type":15,"required":16,"description":30,"children":532},"rows",[533,534,538],{"name":24,"type":21,"required":16,"description":440},{"name":535,"type":536,"required":16,"description":537},"value","number | string","A number, or text of up to 500 characters.",{"name":539,"type":21,"required":33,"description":540},"recorded_on","When it was measured (YYYY-MM-DD).","{\n  \"object\": \"learning.outcomes\",\n  \"measure\": \"rubric-total\",\n  \"matched\": 28,\n  \"unmatched\": [\n    \"writing-app:0c1d2e3f\"\n  ],\n  \"unmatched_count\": 1\n}",[543,545,546,547,548],{"status":92,"description":544},"invalid_outcome: the measure name is malformed, or rows is not a list of 1–1,000 rows. invalid_json: the body isn’t JSON.",{"status":95,"description":96},{"status":101,"description":492},{"status":116,"description":494},{"status":122,"description":496},{"method":7,"path":550,"summary":551,"contentType":10,"parameters":552,"body":553,"responseStatus":88,"responseType":10,"responseExample":567,"errors":568},"\u002Fv1\u002Fembeddings","Create Embeddings",[],[554,557,558,564],{"name":32,"type":21,"required":33,"description":555,"default":556},"Prefix a model with `@\u003Cprovider-key>\u002F` to call it with one of the paying account's provider keys (BYOK), for example `@openrouter\u002Fanthropic\u002Fclaude-sonnet-4.5` or `@lab-openai\u002Fgpt-6-luna`. The rest of the ID is sent to that provider unchanged. Catalog models also use a provider key automatically when the project owner marked one \"use for catalog models\" for that provider.","\"nomic-embed-text-v1.5\"",{"name":318,"type":64,"required":16,"description":30},{"name":559,"type":21,"required":33,"description":30,"enum":560,"default":563},"encoding_format",[561,562],"float","base64","\"float\"",{"name":565,"type":37,"required":33,"description":566},"dimensions","Optional dimensions if supported by the selected model.","{\n  \"object\": \"list\",\n  \"data\": [\n    {\n      \"object\": \"embedding\",\n      \"index\": 0,\n      \"embedding\": [\n        0\n      ]\n    }\n  ],\n  \"usage\": {\n    \"prompt_tokens\": 0,\n    \"completion_tokens\": 0,\n    \"total_tokens\": 0\n  }\n}",[569,571,572,573,574,575,576,577,578,579,581,583],{"status":92,"description":570},"Invalid request. Provider key models can also be malformed (invalid_provider_key_model), unknown here (provider_key_not_found), not enabled for this project (provider_key_not_in_project), or unsupported for this operation (provider_key_unsupported_operation).",{"status":95,"description":96},{"status":98,"description":99},{"status":101,"description":102},{"status":104,"description":105},{"status":110,"description":111},{"status":113,"description":114},{"status":116,"description":213},{"status":119,"description":120},{"status":122,"description":580},"Too many requests. Provider keys add provider_rate_limited (every available key is rate-limited by its provider; Retry-After says when one is free) and provider_keys_rotating (more keys are left than one request tries; retry now to reach them, Retry-After: 1). details.attempts lists what each key’s provider said.",{"status":128,"description":582},"Server error.",{"status":134,"description":584},"With a provider key: the provider failed, or its endpoint could not be reached (provider_endpoint_unreachable) or redirected (provider_endpoint_redirected).",{"method":7,"path":586,"summary":587,"contentType":10,"parameters":588,"body":589,"responseStatus":88,"responseType":10,"responseExample":639,"errors":640},"\u002Fv1\u002Fimages\u002Fgenerations","Generate or edit images",[],[590,593,595,597,600,603,609,612,619,622,628,635],{"name":32,"type":21,"required":33,"description":591,"default":592},"Use an image_generation model from GET \u002Fv1\u002Fmodels. Supports flux.2-klein, Gemini 3.1 Flash\u002FLite Image, and GPT Image models; chat models cannot be used here.","\"flux.2-klein\"",{"name":594,"type":21,"required":16,"description":30},"prompt",{"name":60,"type":37,"required":33,"description":596,"default":56},"Integer 1–10 for Flux and GPT Image; Gemini accepts only 1. No automatic fan-out or retries.",{"name":598,"type":21,"required":33,"description":599},"size","GPT Image: provider-supported WIDTHxHEIGHT or auto. Gemini: 0.5K, 1K, 2K, 4K (Lite: 1K only), or square pixel equivalents. The 1024x1536 and 1536x1024 presets request 1K at 2:3 and 3:2, not exact pixel dimensions. See parameter_support.size_values in the catalog.",{"name":601,"type":21,"required":33,"description":602},"quality","GPT Image: auto\u002Flow\u002Fmedium\u002Fhigh; GPT Image 2.5 also accepts xhigh\u002Fmax. Gemini does not accept quality. Flux uses provider-supported values.",{"name":72,"type":21,"required":33,"description":604,"enum":605,"default":608},"`url` returns an API-hosted HTTPS asset URL. `b64_json` returns inline base64 to the caller; logs store only a redacted size summary plus an asset preview URL when asset storage is available.",[606,607],"url","b64_json","\"url\"",{"name":610,"type":21,"required":33,"description":611},"aspect_ratio","Gemini only. See parameter_support.aspect_ratio_values. Defaults to 1:1; cannot be combined with portrait\u002Flandscape pixel presets. Use a resolution tier with this field.",{"name":613,"type":21,"required":33,"description":614,"enum":615},"output_format","GPT Image and Flux provider output format. Gemini returns its native image MIME type and does not accept this field.",[616,617,618],"png","jpeg","webp",{"name":76,"type":77,"required":33,"description":620,"enum":621},"Only non-streaming generation is supported. partial_images is rejected.",[79],{"name":623,"type":21,"required":33,"description":624,"enum":625},"operation","Defaults to generate without images and edit when images are supplied. Explicit edit requires images; explicit generate with images is rejected. Unsupported edits fail before provider execution without fallback.",[626,627],"generate","edit",{"name":629,"type":15,"required":33,"description":630,"children":631},"images","Actual edit\u002Freference images. GPT Image: up to 16; Gemini: up to 14. All sources and the optional mask share a 10 MiB decoded budget, including downloaded URLs. Presence implies editing unless operation=generate, which is rejected. See capabilities.image_editing and parameter_support.images_max in \u002Fv1\u002Fmodels.",[632],{"name":633,"type":21,"required":16,"description":634},"image_url","Public HTTPS image URL or PNG\u002FJPEG\u002FWebP base64 data URL. The gateway downloads remote sources and masks with public-network, redirect, timeout and size checks and sends actual image bytes to the provider. No credentials, custom ports, private\u002Flocal names or IP literals. Sources and mask together must be at most 10 MiB decoded, including downloaded bytes. Provider file IDs are not accepted.",{"name":636,"type":73,"required":33,"description":30,"children":637},"mask",[638],{"name":633,"type":21,"required":16,"description":634},"{\n  \"created\": 0,\n  \"data\": [\n    {\n      \"url\": \"string\",\n      \"b64_json\": \"string\",\n      \"revised_prompt\": \"string\"\n    }\n  ],\n  \"usage\": {\n    \"input_tokens\": 0,\n    \"output_tokens\": 0,\n    \"total_tokens\": 0,\n    \"input_tokens_details\": {\n      \"text_tokens\": 0,\n      \"image_tokens\": 0\n    },\n    \"output_tokens_details\": {\n      \"text_tokens\": 0,\n      \"image_tokens\": 0\n    }\n  }\n}",[641,643,644,645,646,647,648,649,650,651],{"status":92,"description":642},"Invalid request, missing edit source, unsupported editing connection, invalid source URL\u002Fdata, source too large, or unsupported model controls. No generation fallback is performed.",{"status":95,"description":96},{"status":98,"description":99},{"status":110,"description":111},{"status":113,"description":114},{"status":116,"description":213},{"status":119,"description":120},{"status":122,"description":580},{"status":128,"description":582},{"status":134,"description":652},"Upstream provider failure, empty\u002Fblocked image output, or unusable provider-local URL. Returns model_provider_error or image_provider_non_public_url. With a provider key: the provider failed, or its endpoint could not be reached (provider_endpoint_unreachable) or redirected (provider_endpoint_redirected).",{"method":7,"path":654,"summary":655,"contentType":10,"parameters":656,"body":657,"responseStatus":88,"responseType":683,"responseExample":30,"errors":684},"\u002Fv1\u002Faudio\u002Fspeech","Create Speech",[],[658,660,665,668,671,680],{"name":318,"type":21,"required":16,"description":659},"The text to generate audio for. Maximum length: 4096 characters.",{"name":32,"type":21,"required":33,"description":661,"enum":662,"default":664},"Speech model. Defaults to kokoro. Retired IDs return 410 model_retired without redirection.",[663],"kokoro","\"kokoro\"",{"name":666,"type":21,"required":33,"description":667},"voice","Kokoro voice ID; defaults to af_heart. Read voice_values from \u002Fv1\u002Fmodels for all 54 choices.",{"name":669,"type":21,"required":33,"description":670},"instructions","Kokoro does not support instructions; non-empty values return 400.",{"name":72,"type":21,"required":33,"description":672,"enum":673,"default":679},"The audio output format. Inspect parameter_support.response_format_values because formats vary by model.",[674,675,676,677,678],"mp3","opus","flac","wav","pcm","\"mp3\"",{"name":681,"type":55,"required":33,"description":682,"default":56},"speed","The speed of the generated audio (0.25 to 4.0).","audio\u002Fmpeg",[685,687,688,689,690,691,692,693,694,695,696,697],{"status":92,"description":686},"Bad Request. The request payload is malformed, contains invalid parameters, or failed validation.",{"status":95,"description":96},{"status":98,"description":99},{"status":101,"description":208},{"status":107,"description":108},{"status":110,"description":111},{"status":113,"description":114},{"status":116,"description":213},{"status":119,"description":120},{"status":122,"description":123},{"status":128,"description":129},{"status":134,"description":135},{"method":7,"path":699,"summary":700,"contentType":701,"parameters":702,"body":703,"responseStatus":88,"responseType":10,"responseExample":739,"errors":740},"\u002Fv1\u002Faudio\u002Ftranscriptions","Transcribe Audio","multipart\u002Fform-data",[],[704,707,713,716,717,725,726,729,731,734,737],{"name":705,"type":705,"required":16,"description":706},"file","Audio file upload, bounded by the 26 MiB multipart request limit. For attributed requests the exact bytes are archived as a private research asset.",{"name":32,"type":21,"required":33,"description":708,"enum":709,"default":712},"Transcription model. Defaults to whisper-large-v3. Retired IDs return 410 model_retired.",[710,711],"whisper-large-v3","gpt-transcribe","\"whisper-large-v3\"",{"name":714,"type":21,"required":33,"description":715},"language","Optional ISO-639-1 code for whisper-large-v3. For gpt-transcribe use languages[]; singular language returns 400 invalid_transcription_language.",{"name":594,"type":21,"required":33,"description":30},{"name":72,"type":21,"required":33,"description":718,"enum":719,"default":724},"gpt-transcribe supports non-streaming json through this gateway; other formats or stream=true return 400 unsupported_transcription_format. whisper-large-v3 supports every listed format.",[720,349,721,722,723],"json","srt","verbose_json","vtt","\"json\"",{"name":54,"type":55,"required":33,"description":30},{"name":727,"type":55,"required":33,"description":728},"duration_seconds","Optional client duration for cost estimates when provider duration is unavailable. Provider duration takes precedence.",{"name":730,"type":55,"required":33,"description":728},"duration_minutes",{"name":732,"type":357,"required":33,"description":733},"languages[]","Optional language hints for gpt-transcribe. Repeat languages[] multipart fields for multiple ISO-639-1 codes.",{"name":735,"type":357,"required":33,"description":736},"keywords[]","Optional keyword hints for gpt-transcribe. Repeat keywords[] multipart fields. Each keyword must be one line without angle brackets.",{"name":76,"type":77,"required":33,"description":738,"default":79},"Keep false or omit. gpt-transcribe stream=true is unsupported by this gateway and returns 400.","{\n  \"text\": \"Transcribed audio text.\",\n  \"languages\": [\n    {\n      \"code\": \"string\"\n    }\n  ],\n  \"usage\": {\n    \"type\": \"duration\",\n    \"seconds\": 0\n  }\n}",[741,743,744,745,746,747,748,749,750,751],{"status":92,"description":742},"Invalid request.",{"status":95,"description":96},{"status":98,"description":99},{"status":110,"description":111},{"status":113,"description":114},{"status":116,"description":213},{"status":119,"description":120},{"status":122,"description":580},{"status":128,"description":582},{"status":134,"description":584},{"method":7,"path":753,"summary":754,"contentType":10,"parameters":755,"body":756,"responseStatus":88,"responseType":10,"responseExample":759,"errors":760},"\u002Fv1\u002Futils\u002Fencrypt","Encrypt text",[],[757],{"name":349,"type":21,"required":16,"description":758},"Must contain non-whitespace characters.","{\n  \"encryptedText\": \"string\",\n  \"value\": \"enc::base64iv:base64ciphertext:base64tag\"\n}",[761,763,764,766,767,769],{"status":92,"description":762},"Invalid JSON, missing\u002Fempty field.",{"status":95,"description":96},{"status":101,"description":765},"Missing utils:crypto scope.",{"status":116,"description":213},{"status":122,"description":768},"API key quota\u002Frate limit exceeded.",{"status":128,"description":770},"Encryption key unavailable or encryption failed.",{"method":7,"path":772,"summary":773,"contentType":10,"parameters":774,"body":775,"responseStatus":88,"responseType":10,"responseExample":779,"errors":780},"\u002Fv1\u002Futils\u002Fdecrypt","Decrypt text",[],[776],{"name":777,"type":21,"required":16,"description":778},"encryptedText","Must contain non-whitespace characters. A leading enc:: prefix is accepted.","{\n  \"decryptedText\": \"string\"\n}",[781,783,784,785,786,787],{"status":92,"description":782},"Invalid JSON, missing\u002Fempty field or decryption failed.",{"status":95,"description":96},{"status":101,"description":765},{"status":116,"description":213},{"status":122,"description":768},{"status":128,"description":788},"Encryption key unavailable.",{"method":389,"path":790,"summary":791,"contentType":392,"parameters":792,"body":793,"responseStatus":88,"responseType":10,"responseExample":794,"errors":795},"\u002Fv1\u002Fmodels","List Available Models",[],[],"{\n  \"object\": \"list\",\n  \"default_model\": \"gpt-6-luna\",\n  \"aliases\": {\n    \"4o\": \"gpt-4o\",\n    \"4omni\": \"gpt-4o\",\n    \"mini\": \"gpt-4.1-mini\"\n  },\n  \"available_models\": [\n    {\n      \"id\": \"viable-1\",\n      \"object\": \"model\",\n      \"mode\": \"chat\",\n      \"endpoint\": \"\u002Fv1\u002Fchat\u002Fcompletions\",\n      \"description\": \"Quality-focused model for complex reasoning, careful evaluation, and detailed writing.\",\n      \"owned_by\": \"viable-lab\",\n      \"intelligence\": \"High\",\n      \"speed\": \"Medium\",\n      \"input_modalities\": [\n        \"text\"\n      ],\n      \"output_modalities\": [\n        \"text\"\n      ],\n      \"context_window\": 1050000,\n      \"max_output_tokens\": 128000,\n      \"open_weights\": false,\n      \"reasoning_model\": true,\n      \"parameter_support\": {\n        \"temperature\": false,\n        \"top_p\": false,\n        \"max_tokens\": true,\n        \"max_completion_tokens\": true,\n        \"reasoning_effort\": true,\n        \"reasoning_effort_values\": [\n          \"none\"\n        ]\n      },\n      \"supports_streaming\": true,\n      \"capabilities\": {\n        \"text\": true,\n        \"images\": true,\n        \"files\": true,\n        \"pdf\": true,\n        \"audio\": false,\n        \"tools\": true,\n        \"embeddings\": false,\n        \"image_generation\": false,\n        \"image_editing\": false\n      },\n      \"pricing\": {\n        \"input_per_million\": 2,\n        \"output_per_million\": 12,\n        \"cached_input_per_million\": 0.2,\n        \"cache_write_per_million\": 2.5,\n        \"long_context_threshold_tokens\": 272000,\n        \"long_context_input_per_million\": 4,\n        \"long_context_cached_input_per_million\": 0.4,\n        \"long_context_cache_write_per_million\": 5,\n        \"long_context_output_per_million\": 18,\n        \"input_character_per_million\": null,\n        \"image_per_unit\": null,\n        \"audio_per_minute\": null,\n        \"audio_output_per_million\": null,\n        \"fallback_audio_per_minute\": null,\n        \"status\": \"documented\",\n        \"note\": \"VIABLE Lab token rates; any long-context tiers are listed separately.\"\n      }\n    }\n  ],\n  \"upcoming_models\": [],\n  \"supported_aliases\": [\n    \"viable-1\"\n  ]\n}",[796,797,799],{"status":101,"description":208},{"status":122,"description":798},"Too Many Requests. Rate limit exceeded.",{"status":128,"description":129},1793404881619]