@lap v0.3
# Machine-readable API spec. Each @endpoint block is one API call.
@api OpenRouter API
@base https://openrouter.ai/api/v1
@version 1.0.0
@auth Bearer bearer | Bearer bearer
@endpoints 122
@hint download_for_search
@toc activity(1), analytics(2), api(1), audio(2), auth(2), benchmarks(1), byok(5), chat(1), classifications(1), containers(4), credits(2), datasets(3), embeddings(2), endpoints(1), files(5), generation(3), guardrails(13), images(3), interns(8), key(1), keys(5), messages(1), model(1), models(4), oauth(2), observability(5), organization(1), presets(7), providers(1), rerank(1), responses(1), scim(8), systemone(1), vault(7), videos(4), workspaces(12)

@group activity
@endpoint GET /activity
@optional {date: str, api_key_hash: str, user_id: str, group_by: str, workspace_id: str}
@returns(200) {data: [map]}
@errors {400, 401, 403, 404, 500}

@endgroup

@group analytics
@endpoint GET /analytics/meta
@returns(200) {data: map{dimensions: [map], granularities: [map], metrics: [map], operators: [map]}}
@errors {401, 403, 500}

@endpoint POST /analytics/query
@required {metrics: [str]}
@optional {classifier_dimensions: map{classifier_id!: str(uuid), dimension_names: [str], include_nulls: bool}, classifier_filters: map{classifier_id!: str(uuid), filters!: [map]}, dimensions: [str], filters: [map{field!: str, include_unset: bool, operator!: str, value!: any}], granularity: str, group_limit: int, limit: int, order_by: map{direction!: str, field!: str}, time_range: map{end!: str(date-time), start!: str(date-time)}}
@returns(200) {data: map{cachedAt: num(double), data: [map], metadata: map{query_time_ms: num(double), row_count: int, truncated: bool}, warnings: [str]}}
@errors {400, 401, 403, 408, 500}

@endgroup

@group api
@endpoint POST /api/alpha/decisions
@required {model: str, questions: map, state: any}
@optional {provider: any, session_id: str, trace: map{generation_name: str, parent_span_id: str, span_name: str, trace_id: str, trace_name: str}, user: str}
@returns(200) {answers: map, id: str, model: str, provider: str, usage: map{cost: num(double), input_tokens: int, output_tokens: int}}
@errors {400, 401, 402, 403, 404, 413, 429, 500, 502, 503, 524, 529}

@endgroup

@group audio
@endpoint POST /audio/speech
@required {input: str, model: str}
@optional {input_references: [any], provider: map{options: map}, response_format: str(mp3/pcm)=pcm, session_id: str, speed: num(double), trace: map{generation_name: str, parent_span_id: str, span_name: str, trace_id: str, trace_name: str}, user: str, voice: str}
@returns(200)
@errors {400, 401, 402, 403, 404, 413, 429, 500, 502, 503, 524, 529}

@endpoint POST /audio/transcriptions
@required {input_audio: map{data!: str, format!: str}, model: str}
@optional {language: str, provider: map{options: map}, response_format: str(json/verbose_json), session_id: str, temperature: num(double), timestamp_granularities: [str], trace: map{generation_name: str, parent_span_id: str, span_name: str, trace_id: str, trace_name: str}, user: str}
@returns(200) {confidence: num(double), duration: num(double), language: str, segments: [map], task: str, text: str, usage: map{cost: num(double), input_tokens: int, output_tokens: int, seconds: num(double), total_tokens: int}, words: [map]}
@errors {400, 401, 402, 403, 404, 413, 429, 500, 502, 503, 504, 524, 529}

@endgroup

@group auth
@endpoint POST /auth/keys
@required {code: str}
@optional {code_challenge_method: str(S256/plain), code_verifier: str}
@returns(200) {key: str, user_id: str?}
@errors {400, 403, 500}

@endpoint POST /auth/keys/code
@required {callback_url: str(uri)}
@optional {code_challenge: str, code_challenge_method: str(S256/plain), expires_at: str(date-time), key_label: str, limit: num(double), spawn_agent: str, spawn_cloud: str, usage_limit_type: str(daily/weekly/monthly), workspace_id: str(uuid)}
@returns(200) {data: map{app_id: int, created_at: str, id: str}}
@errors {400, 401, 403, 409, 500}

@endgroup

@group benchmarks
@endpoint GET /benchmarks
@optional {source: str(artificial-analysis/design-arena/openrouter), task_type: str(coding/intelligence/agentic/search), benchmark_type: str(gpqa_diamond/tau_bench_verified_airline/search_browsecomp/search_hle/search_dsqa/search_widesearch), include_run_config: bool=false, search_engine: str, search_surface: str(server-tool/plugin), arena: str(models/builders/agents), category: str, max_results: int}
@returns(200) {data: [any], meta: map{as_of: str, citation: str?, model_count: int, source: str?, source_url: str?, task_type: str?, version: str}}
@errors {400, 401, 429, 500}

@endgroup

@group byok
@endpoint GET /byok
@optional {offset: int=0, limit: int=50, workspace_id: str(uuid), provider: str(ai21/aion-labs/akashml/alibaba/amazon-bedrock/amazon-bedrock/claude-on-aws/amazon-nova/ambient/anthropic/anthropic/2/arcee-ai/assemblyai/atlas-cloud/avian/azure/baidu/baseten/black-forest-labs/byteplus/cerebras/chutes/cirrascale/clarifai/claude-on-aws/cloudflare/cohere/coreweave/cosine/crusoe/darkbloom/databricks/decart/deepgram/deepinfra/deepseek/dekallm/digitalocean/featherless/fireworks/fish-audio/friendli/gmicloud/google-ai-studio/google-vertex/groq/heygen/inception/inceptron/inferact-vllm/inference-net/infermatic/inflection/io-net/ionstream/krea/liquid/makora/mancer/mara/meta/minimax/mistral/modal/modelrun/modular/moonshotai/morph/near-ai/nebius/nex-agi/nextbit/novita/nvidia/ollama/open-inference/openai/parasail/perceptron/perplexity/phala/poolside/primeintellect/quiver/recraft/reka/relace/runway/sail-research/sakana/sakana-ai/sambanova/scaledown/seed/siliconflow/sourceful/stepfun/streamlake/switchpoint/tencent/tenstorrent/thinkingmachines/together/typesafe/unbiased/upstage/venice/voyageai/wafer/wandb/wandb-legacy/xai/xiaomi/z-ai)}
@returns(200) {data: [map], total_count: int}
@errors {400, 401, 500}

@endpoint POST /byok
@required {key: str, provider: str(ai21/aion-labs/akashml/alibaba/amazon-bedrock/amazon-bedrock/claude-on-aws/amazon-nova/ambient/anthropic/anthropic/2/arcee-ai/assemblyai/atlas-cloud/avian/azure/baidu/baseten/black-forest-labs/byteplus/cerebras/chutes/cirrascale/clarifai/claude-on-aws/cloudflare/cohere/coreweave/cosine/crusoe/darkbloom/databricks/decart/deepgram/deepinfra/deepseek/dekallm/digitalocean/featherless/fireworks/fish-audio/friendli/gmicloud/google-ai-studio/google-vertex/groq/heygen/inception/inceptron/inferact-vllm/inference-net/infermatic/inflection/io-net/ionstream/krea/liquid/makora/mancer/mara/meta/minimax/mistral/modal/modelrun/modular/moonshotai/morph/near-ai/nebius/nex-agi/nextbit/novita/nvidia/ollama/open-inference/openai/parasail/perceptron/perplexity/phala/poolside/primeintellect/quiver/recraft/reka/relace/runway/sail-research/sakana/sakana-ai/sambanova/scaledown/seed/siliconflow/sourceful/stepfun/streamlake/switchpoint/tencent/tenstorrent/thinkingmachines/together/typesafe/unbiased/upstage/venice/voyageai/wafer/wandb/wandb-legacy/xai/xiaomi/z-ai)}
@optional {allowed_api_key_hashes: [str], allowed_models: [str], allowed_user_ids: [str], declared_zdr: bool, disabled: bool, is_byok_only: bool, is_fallback: bool, is_required: bool, name: str, workspace_id: str(uuid)}
@returns(201) {data: any}
@errors {400, 401, 403, 500}

@endpoint DELETE /byok/{id}
@required {id: str(uuid)}
@returns(200) {deleted: bool}
@errors {401, 404, 500}

@endpoint GET /byok/{id}
@required {id: str(uuid)}
@returns(200) {data: any}
@errors {401, 404, 500}

@endpoint PATCH /byok/{id}
@required {id: str(uuid)}
@optional {allowed_api_key_hashes: [str], allowed_models: [str], allowed_user_ids: [str], declared_zdr: bool, disabled: bool, is_byok_only: bool, is_fallback: bool, is_required: bool, key: str, name: str}
@returns(200) {data: any}
@errors {400, 401, 403, 404, 500}

@endgroup

@group chat
@endpoint POST /chat/completions
@required {messages: [any]}
@optional {X-OpenRouter-Metadata: str, cache_control: map{ttl: str, type!: str}, debug: map{echo_upstream_body: bool}, frequency_penalty: num(double), image_config: map, logit_bias: map, logprobs: bool, max_completion_tokens: int, max_tokens: int, metadata: map, min_p: num(double), modalities: [str], model: str, models: [any], parallel_tool_calls: bool, plugins: [any], prediction: map{content!: any, type!: str}, presence_penalty: num(double), prompt_cache_key: str, prompt_cache_options: map{mode!: str, ttl: str}, provider: map{allow_fallbacks: bool, data_collection: str, enforce_distillable_text: bool, ignore: [any], max_price: map, only: [any], order: [any], preferred_max_latency: any, preferred_min_throughput: any, quantizations: [str], require_parameters: bool, sort: any, zdr: bool}, reasoning: map{effort: str, summary: str}, reasoning_effort: str(max/xhigh/high/medium/low/minimal/none), repetition_penalty: num(double), response_format: any, route: str(fallback/sort), seed: int, service_tier: str(auto/default/fast/flex/priority/scale), session_id: str, stop: any, stop_server_tools_when: [any], stream: bool=false, stream_options: map{include_usage: bool}, temperature: num(double), tool_choice: any, tools: [any], top_a: num(double), top_k: int, top_logprobs: int, top_p: num(double), trace: map{generation_name: str, parent_span_id: str, span_name: str, trace_id: str, trace_name: str}, user: str}
@returns(200) {choices: [map], created: int, id: str, model: str, object: str, openrouter_metadata: map{attempt: int, attempts: [map], endpoints: map{available: [map], total: int}, generation_time: int, is_byok: bool, params: map{quality_floor: num(double), throughput_floor: num(double), version_group: str}, pipeline: [map], region: str?, requested: str, strategy: str, summary: str}, service_tier: str?, system_fingerprint: str?, usage: map{completion_tokens: int, completion_tokens_details: map?, cost: num(double)?, cost_details: map?, is_byok: bool, prompt_tokens: int, prompt_tokens_details: map?, server_tool_use_details: map?, total_tokens: int}}
@errors {400, 401, 402, 403, 404, 408, 413, 422, 429, 500, 502, 503, 524, 529}

@endgroup

@group classifications
@endpoint GET /classifications/task
@optional {window: str=7d}
@returns(200) {data: map{as_of: str, classifications: [map], macro_categories: [map], window_days: int}}
@errors {400, 401, 429, 500}

@endgroup

@group containers
@endpoint GET /containers/{container_id}/files
@required {container_id: str}
@optional {limit: int=100, after: str}
@returns(200) {data: [map], first_id: str?, has_more: bool, last_id: str?, object: str}
@errors {400, 401, 403, 429, 500, 503}

@endpoint GET /containers/{container_id}/files/{file_id}
@required {container_id: str, file_id: str}
@returns(200) {bytes: int, container_id: str, created_at: int, id: str, object: str, path: str, source: str}
@errors {400, 401, 403, 404, 429, 500, 503}

@endpoint GET /containers/{container_id}/files/{file_id}/content
@required {container_id: str, file_id: str}
@returns(200)
@errors {400, 401, 403, 404, 429, 500, 503}

@endpoint POST /containers/{container_id}/files/{file_id}/promote
@required {container_id: str, file_id: str}
@returns(200)
@errors {400, 401, 403, 404, 413, 429, 500, 503}

@endgroup

@group credits
@endpoint GET /credits
@returns(200) {data: map{total_credits: num(double), total_usage: num(double)}}
@errors {401, 403, 500}

@endpoint POST /credits/coinbase
@returns(200)
@errors {410}

@endgroup

@group datasets
@endpoint GET /datasets/app-rankings
@optional {category: str(coding/creative/productivity/entertainment), subcategory: str(cli-agent/ide-extension/cloud-agent/programming-app/native-app-builder/creative-writing/video-gen/image-gen/audio-gen/roleplay/game/writing-assistant/general-chat/personal-agent/legal), sort: str(popular/trending)=popular, start_date: str, end_date: str, limit: int=50, offset: int=0}
@returns(200) {data: [map], meta: map{as_of: str, end_date: str, start_date: str, version: str}}
@errors {400, 401, 429, 500}

@endpoint GET /datasets/rankings-daily
@optional {start_date: str, end_date: str, period: str(day/week/month), modality: str(text/image/image_output/audio/tool_calling), context_bucket: str(1K/10K/100K/1M/10M), category: str(programming/roleplay/marketing/marketing/seo/technology/science/translation/legal/finance/health/trivia/academia), language_type: str(natural/programming)}
@returns(200) {data: [map], meta: map{as_of: str, end_date: str, start_date: str, version: str}}
@errors {400, 401, 429, 500}

@endpoint GET /datasets/session-cost
@optional {app_slug: str, model: str, turn_range: str(1-turn/2-9-turns/10-49-turns/50-plus-turns), limit: int=100, offset: int=0}
@returns(200) {data: [map], meta: map{as_of: str, version: str, window_days: int?, window_end_date: str?}}
@errors {400, 401, 429, 500}

@endgroup

@group embeddings
@endpoint POST /embeddings
@required {input: any, model: str}
@optional {dimensions: int, encoding_format: str(float/base64), input_type: str, provider: any, session_id: str, trace: map{generation_name: str, parent_span_id: str, span_name: str, trace_id: str, trace_name: str}, user: str}
@returns(200) {data: [map], id: str, model: str, object: str, usage: map{cost: num(double), cost_details: map?, is_byok: bool, prompt_tokens: int, prompt_tokens_details: map{audio_tokens: int, file_tokens: int, image_tokens: int, text_tokens: int, video_tokens: int}, total_tokens: int}}
@errors {400, 401, 402, 403, 404, 408, 413, 429, 500, 502, 503, 524, 529}

@endpoint GET /embeddings/models
@optional {offset: int=0, limit: int=500}
@returns(200) {data: [map], links: map{next: str?}, total_count: int}
@errors {400, 500}

@endgroup

@group endpoints
@endpoint GET /endpoints/zdr
@returns(200) {data: [map]}
@errors {403, 500}

@endgroup

@group files
@endpoint GET /files
@optional {limit: int, cursor: str, workspace_id: str(uuid), provider: str, after: str, after_id: str, before_id: str, order: str(asc/desc)}
@returns(200)
@errors {400, 401, 403, 429, 500, 502, 503}

@endpoint POST /files
@optional {workspace_id: str(uuid), provider: str}
@returns(200)
@errors {400, 401, 403, 413, 429, 500, 502, 503}

@endpoint DELETE /files/{file_id}
@required {file_id: str}
@optional {workspace_id: str(uuid), provider: str}
@returns(200)
@errors {401, 403, 404, 429, 500, 502, 503}

@endpoint GET /files/{file_id}
@required {file_id: str}
@optional {workspace_id: str(uuid), provider: str}
@returns(200)
@errors {401, 403, 404, 429, 500, 502, 503}

@endpoint GET /files/{file_id}/content
@required {file_id: str}
@optional {workspace_id: str(uuid), provider: str}
@returns(200)
@errors {400, 401, 403, 404, 429, 500, 502, 503}

@endgroup

@group generation
@endpoint GET /generation
@required {id: str}
@returns(200) {data: map{api_type: str?, app_id: int?, cache_discount: num(double)?, cancelled: bool?, created_at: str, data_region: str, external_user: str?, finish_reason: str?, generation_time: num(double)?, http_referer: str?, id: str, is_byok: bool, latency: num(double)?, model: str, moderation_latency: num(double)?, native_finish_reason: str?, native_tokens_cached: int?, native_tokens_completion: int?, native_tokens_completion_images: int?, native_tokens_prompt: int?, native_tokens_reasoning: int?, num_fetches: int?, num_input_audio_prompt: int?, num_media_completion: int?, num_media_prompt: int?, num_search_results: int?, origin: str, preset_id: str?, provider_name: str?, provider_responses: [map]?, request_id: str?, response_cache_source_id: str?, router: str?, service_tier: str?, session_id: str?, streamed: bool?, tokens_completion: int?, tokens_prompt: int?, total_cost: num(double), upstream_id: str?, upstream_inference_cost: num(double)?, usage: num(double), user_agent: str?, web_search_engine: str?, workspace_id: str?}}
@errors {401, 402, 404, 429, 500, 502, 524, 529}

@endpoint GET /generation/content
@required {id: str}
@returns(200) {data: map{error: map?, input: any, output: map{completion: str?, reasoning: str?}}}
@errors {401, 403, 404, 429, 500, 502, 524, 529}

@endpoint POST /generation/feedback
@required {category: str(latency/incoherence/incorrect_response/formatting/billing/api_error/other), generation_id: str}
@optional {comment: str}
@returns(200) {data: map{success: bool}}
@errors {400, 401, 404, 429, 500}

@endgroup

@group guardrails
@endpoint GET /guardrails
@optional {offset: int=0, limit: int=50, workspace_id: str(uuid)}
@returns(200) {data: [map], total_count: int}
@errors {400, 401, 500}

@endpoint POST /guardrails
@required {name: str}
@optional {allowed_data_regions: [str], allowed_models: [str], allowed_providers: [str], content_filter_builtins: [map{action!: str, label: str, scan_scope: str, slug!: str}], content_filters: [map{action!: str, label: str, pattern!: str}], description: str, enable_free_model_publication: bool, enable_free_model_training: bool, enable_paid_model_training: bool, enforce_zdr: bool, enforce_zdr_anthropic: bool, enforce_zdr_google: bool, enforce_zdr_openai: bool, enforce_zdr_other: bool, enforce_zdr_xai: bool, ignored_models: [str], ignored_providers: [str], include_byok_in_budgets: bool, limit_usd: num(double), reset_interval: str(daily/weekly/monthly), workspace_id: str(uuid)}
@returns(201) {data: any}
@errors {400, 401, 403, 500}

@endpoint DELETE /guardrails/{id}
@required {id: str(uuid)}
@returns(200) {deleted: bool}
@errors {401, 404, 500}

@endpoint GET /guardrails/{id}
@required {id: str(uuid)}
@returns(200) {data: any}
@errors {401, 404, 500}

@endpoint PATCH /guardrails/{id}
@required {id: str(uuid)}
@optional {allowed_data_regions: [str], allowed_models: [str], allowed_providers: [str], content_filter_builtins: [map{action!: str, label: str, scan_scope: str, slug!: str}], content_filters: [map{action!: str, label: str, pattern!: str}], description: str, enable_free_model_publication: bool, enable_free_model_training: bool, enable_paid_model_training: bool, enforce_zdr: bool, enforce_zdr_anthropic: bool, enforce_zdr_google: bool, enforce_zdr_openai: bool, enforce_zdr_other: bool, enforce_zdr_xai: bool, ignored_models: [str], ignored_providers: [str], include_byok_in_budgets: bool, limit_usd: num(double), name: str, reset_interval: str(daily/weekly/monthly)}
@returns(200) {data: any}
@errors {400, 401, 403, 404, 409, 500}

@endpoint GET /guardrails/{id}/assignments/keys
@required {id: str(uuid)}
@optional {offset: int=0, limit: int=50}
@returns(200) {data: [map], total_count: int}
@errors {401, 404, 500}

@endpoint POST /guardrails/{id}/assignments/keys
@required {id: str(uuid), key_hashes: [str]}
@returns(200) {assigned_count: int}
@errors {400, 401, 403, 404, 500}

@endpoint POST /guardrails/{id}/assignments/keys/remove
@required {id: str(uuid), key_hashes: [str]}
@returns(200) {unassigned_count: int}
@errors {400, 401, 404, 500}

@endpoint GET /guardrails/{id}/assignments/members
@required {id: str(uuid)}
@optional {offset: int=0, limit: int=50}
@returns(200) {data: [map], total_count: int}
@errors {401, 404, 500}

@endpoint POST /guardrails/{id}/assignments/members
@required {id: str(uuid), member_user_ids: [str]}
@returns(200) {assigned_count: int}
@errors {400, 401, 404, 500}

@endpoint POST /guardrails/{id}/assignments/members/remove
@required {id: str(uuid), member_user_ids: [str]}
@returns(200) {unassigned_count: int}
@errors {400, 401, 404, 500}

@endpoint GET /guardrails/assignments/keys
@optional {offset: int=0, limit: int=50}
@returns(200) {data: [map], total_count: int}
@errors {401, 500}

@endpoint GET /guardrails/assignments/members
@optional {offset: int=0, limit: int=50}
@returns(200) {data: [map], total_count: int}
@errors {401, 500}

@endgroup

@group images
@endpoint POST /images
@required {model: str, prompt: str}
@optional {aspect_ratio: str(1:1/1:2/1:4/1:8/2:1/2:3/2.35:1/3:2/3:4/4:1/4:3/4:5/5:2/5:4/8:1/9:16/16:9/9:19.5/19.5:9/9:20/20:9/9:21/21:9/auto), background: str(auto/transparent/opaque), input_references: [map{image_url!: map, type!: str}], n: int, output_compression: int, output_format: str(png/jpeg/webp/svg), provider: map{allow_fallbacks: bool, ignore: [any], only: [any], options: any, order: [any], sort: any}, quality: str(auto/low/medium/high/xhigh/max), resolution: str(512/1K/2K/4K), seed: int, session_id: str, size: str, stream: bool, trace: map{generation_name: str, parent_span_id: str, span_name: str, trace_id: str, trace_name: str}, user: str}
@returns(200) {created: int, data: [map], usage: map{cache_creation: map?, completion_tokens: int, completion_tokens_details: map?, cost: num(double)?, cost_details: map?, is_byok: bool, iterations: [any]?, prompt_tokens: int, prompt_tokens_details: map?, server_tool_use: map?, service_tier: str?, speed: str?, total_tokens: int}}
@errors {400, 401, 402, 403, 404, 413, 429, 500, 502, 524, 529}

@endpoint GET /images/models
@returns(200) {data: [map]}
@errors {500}

@endpoint GET /images/models/{author}/{slug}/endpoints
@required {author: str, slug: str}
@returns(200) {endpoints: [map], id: str}
@errors {404, 500}

@endgroup

@group interns
@endpoint GET /interns
@optional {limit: int, status: [str], starting_after: str, workspace_id: str(uuid)}
@returns(200) {data: [map], has_more: bool, next_cursor: str}
@errors {400, 401, 403, 404, 408, 500}

@endpoint POST /interns
@required {name: str}
@optional {Idempotency-Key: str, description: str, instructions: str, provision: bool=false, vault_id: str(uuid), workspace_id: str(uuid)}
@returns(200) {attached_vault_id: str?, created_at: str, description: str?, hostname: str?, id: str, instructions: str?, last_failure_message: str?, model: str?, name: str, progress: map?, status: str, updated_at: str, vault_id: str?, workspace_id: str}
@returns(201) {attached_vault_id: str?, created_at: str, description: str?, hostname: str?, id: str, instructions: str?, last_failure_message: str?, model: str?, name: str, progress: map?, status: str, updated_at: str, vault_id: str?, workspace_id: str}
@errors {400, 401, 403, 404, 408, 409, 413, 415, 500, 502}

@endpoint DELETE /interns/{internId}
@required {internId: str}
@optional {acknowledge_workspace_loss: bool=false}
@returns(202) {deleting: bool}
@errors {400, 401, 403, 404, 408, 409, 413, 415, 500, 502}

@endpoint GET /interns/{internId}
@required {internId: str}
@returns(200) {attached_vault_id: str?, created_at: str, description: str?, hostname: str?, id: str, instructions: str?, last_failure_message: str?, model: str?, name: str, progress: map?, status: str, updated_at: str, vault_id: str?, workspace_id: str}
@errors {401, 403, 404, 408, 500}

@endpoint PATCH /interns/{internId}
@required {internId: str}
@optional {description: str, instructions: str, model: str, name: str}
@returns(200) {attached_vault_id: str?, created_at: str, description: str?, hostname: str?, id: str, instructions: str?, last_failure_message: str?, model: str?, name: str, progress: map?, status: str, updated_at: str, vault_id: str?, workspace_id: str}
@errors {400, 401, 403, 404, 408, 409, 413, 415, 500}

@endpoint POST /interns/{internId}/chat/completions
@required {internId: str, messages: [any], stream: bool}
@optional {approval_mode: str(manual/self-drive), model: str, session_id: str}
@returns(200)
@returns(202) {session_id: str, status: str}
@errors {400, 401, 403, 404, 408, 409, 410, 413, 429, 502, 503, 504}

@endpoint POST /interns/{internId}/provision
@required {internId: str}
@returns(202) {provisioning: bool}
@errors {400, 401, 403, 404, 408, 409, 413, 415, 500, 502}

@endpoint POST /interns/{internId}/suspend
@required {internId: str}
@returns(200) {suspended: bool}
@errors {400, 401, 403, 404, 408, 409, 413, 415, 500, 502}

@endgroup

@group key
@endpoint GET /key
@returns(200) {data: map{allowed_data_regions: [str], byok_usage: num(double), byok_usage_daily: num(double), byok_usage_monthly: num(double), byok_usage_weekly: num(double), creator_user_id: str?, expires_at: str(date-time)?, free_model_daily_requests: map{limit: int, remaining: int, used: int}, include_byok_in_limit: bool, is_free_tier: bool, is_management_key: bool, is_provisioning_key: bool, label: str, limit: num(double)?, limit_remaining: num(double)?, limit_reset: str?, organization_id: str?, rate_limit: map{interval: str, note: str, requests: int}, usage: num(double), usage_daily: num(double), usage_monthly: num(double), usage_weekly: num(double), workspace_id: str?}}
@errors {401, 500}

@endgroup

@group keys
@endpoint GET /keys
@optional {include_disabled: bool, offset: int, workspace_id: str(uuid)}
@returns(200) {data: [map]}
@errors {400, 401, 429, 500}

@endpoint POST /keys
@required {name: str}
@optional {creator_user_id: str, expires_at: str(date-time), external: map{api_key: str, user!: str}, include_byok_in_limit: bool, limit: num(double), limit_reset: str(daily/weekly/monthly), workspace_id: str(uuid)}
@returns(201) {data: map{byok_usage: num(double), byok_usage_daily: num(double), byok_usage_monthly: num(double), byok_usage_weekly: num(double), created_at: str, creator_user_id: str?, disabled: bool, expires_at: str(date-time)?, external_user: str?, hash: str, include_byok_in_limit: bool, label: str, limit: num(double)?, limit_remaining: num(double)?, limit_reset: str?, name: str, updated_at: str?, usage: num(double), usage_daily: num(double), usage_monthly: num(double), usage_weekly: num(double), workspace_id: str}, key: str}
@errors {400, 401, 403, 429, 500}

@endpoint DELETE /keys/{hash}
@required {hash: str}
@returns(200) {deleted: bool}
@errors {401, 404, 429, 500}

@endpoint GET /keys/{hash}
@required {hash: str}
@returns(200) {data: map{byok_usage: num(double), byok_usage_daily: num(double), byok_usage_monthly: num(double), byok_usage_weekly: num(double), created_at: str, creator_user_id: str?, disabled: bool, expires_at: str(date-time)?, external_user: str?, hash: str, include_byok_in_limit: bool, label: str, limit: num(double)?, limit_remaining: num(double)?, limit_reset: str?, name: str, updated_at: str?, usage: num(double), usage_daily: num(double), usage_monthly: num(double), usage_weekly: num(double), workspace_id: str}}
@errors {401, 404, 429, 500}

@endpoint PATCH /keys/{hash}
@required {hash: str}
@optional {disabled: bool, include_byok_in_limit: bool, limit: num(double), limit_reset: str(daily/weekly/monthly), name: str}
@returns(200) {data: map{byok_usage: num(double), byok_usage_daily: num(double), byok_usage_monthly: num(double), byok_usage_weekly: num(double), created_at: str, creator_user_id: str?, disabled: bool, expires_at: str(date-time)?, external_user: str?, hash: str, include_byok_in_limit: bool, label: str, limit: num(double)?, limit_remaining: num(double)?, limit_reset: str?, name: str, updated_at: str?, usage: num(double), usage_daily: num(double), usage_monthly: num(double), usage_weekly: num(double), workspace_id: str}}
@errors {400, 401, 404, 429, 500}

@endgroup

@group messages
@endpoint POST /messages
@required {messages: [map{clear_at: str, content!: any, output_config: map, role!: str}], model: str}
@optional {X-OpenRouter-Metadata: str, cache_control: map{ttl: str, type!: str}, context_management: map{edits: [any]}, fallbacks: [map{model!: str}], max_tokens: int, metadata: map{user_id: str}, models: [str], output_config: map{effort: str, format: map, task_budget: map}, plugins: [any], provider: map{allow_fallbacks: bool, data_collection: str, enforce_distillable_text: bool, ignore: [any], max_price: map, only: [any], order: [any], preferred_max_latency: any, preferred_min_throughput: any, quantizations: [str], require_parameters: bool, sort: any, zdr: bool}, route: str(fallback/sort), safeguards: [map{classifier_context: map, type!: str}], service_tier: str, session_id: str, speed: any, stop_sequences: [str], stop_server_tools_when: [any], stream: bool, system: any, temperature: num(double), thinking: any, tool_choice: any, tools: [any], top_k: int, top_p: num(double), trace: map{generation_name: str, parent_span_id: str, span_name: str, trace_id: str, trace_name: str}, user: str}
@returns(200)
@errors {400, 401, 403, 404, 429, 500, 503, 529}

@endgroup

@group model
@endpoint GET /model/{author}/{slug}
@required {author: str, slug: str}
@returns(200) {data: map{alias_target: map{name: str, slug: str}, architecture: map{input_modalities: [str], instruct_type: str?, modality: str?, output_modalities: [str], tokenizer: str}, benchmarks: map{artificial_analysis: map{agentic_index: num(double)?, coding_index: num(double)?, intelligence_index: num(double)?}, design_arena: [map]}, canonical_slug: str, context_length: int?, created: int, default_parameters: map?, description: str, expiration_date: str?, hugging_face_id: str?, id: str, knowledge_cutoff: str?, links: map{details: str}, name: str, per_request_limits: map?, pricing: map{audio: str, audio_output: str, completion: str, discount: num(double), image: str, image_output: str, image_token: str, input_audio_cache: str, input_cache_read: str, input_cache_write: str, input_cache_write_1h: str, internal_reasoning: str, overrides: [map], prompt: str, request: str, web_search: str}, reasoning: map{default_effort: any, default_enabled: bool, mandatory: bool, supported_efforts: [str]?, supports_max_tokens: bool}, supported_parameters: [str], supported_voices: [str]?, top_provider: map{context_length: int?, is_moderated: bool, max_completion_tokens: int?}}}
@errors {403, 404, 500}

@endgroup

@group models
@endpoint GET /models
@optional {offset: int=0, limit: int=500, category: str(programming/roleplay/marketing/marketing/seo/technology/science/translation/legal/finance/health/trivia/academia), supported_parameters: str, output_modalities: str, sort: str(most-popular/newest/top-weekly/pricing-low-to-high/pricing-high-to-low/context-high-to-low/throughput-high-to-low/latency-low-to-high/intelligence-high-to-low/coding-high-to-low/agentic-high-to-low/design-arena-elo-high-to-low), q: str, input_modalities: str, context: int, min_price: num, max_price: num, arch: str, model_authors: str, providers: str, distillable: str(true/false), zdr: str, region: str(eu/us), min_output_price: num, max_output_price: num, min_age_days: int, max_age_days: int, min_intelligence_index: num, max_intelligence_index: num, min_coding_index: num, max_coding_index: num, min_agentic_index: num, max_agentic_index: num, min_tool_success_rate: num, max_tool_success_rate: num}
@returns(200) {data: [map], links: map{next: str?}, total_count: int}
@errors {400, 403, 500}

@endpoint GET /models/{author}/{slug}/endpoints
@required {author: str, slug: str}
@returns(200) {data: map{architecture: any, created: int, description: str, endpoints: [map], id: str, name: str}}
@errors {403, 404, 500}

@endpoint GET /models/count
@optional {output_modalities: str}
@returns(200) {data: map{count: int}}
@errors {400, 403, 500}

@endpoint GET /models/user
@optional {offset: int=0, limit: int=500, output_modalities: str}
@returns(200) {data: [map], links: map{next: str?}, total_count: int}
@errors {401, 403, 404, 500}

@endgroup

@group oauth
@endpoint GET /oauth/jwks
@returns(200) {keys: [map]}
@errors {500}

@endpoint POST /oauth/token
@returns(200) {access_token: str, expires_in: int, issued_token_type: str, scope: str, token_type: str}
@errors {400, 429, 500, 503}

@endgroup

@group observability
@endpoint GET /observability/destinations
@optional {offset: int=0, limit: int=50, workspace_id: str(uuid)}
@returns(200) {data: [any], total_count: int}
@errors {400, 401, 500}

@endpoint POST /observability/destinations
@required {config: map, name: str, type: str(arize/braintrust/clickhouse/datadog/grafana/langfuse/langsmith/newrelic/opik/otel-collector/posthog/ramp/s3/sentry/snowflake/weave/webhook)}
@optional {api_key_hashes: [str], broadcast_generation_cost: bool=false, broadcast_generation_identity: bool=false, broadcast_generation_request_context: bool=false, enabled: bool=true, filter_rules: map{enabled: bool, groups!: [map]}, privacy_mode: bool=false, regions: [str]=global, sampling_rate: num(double), workspace_id: str(uuid)}
@returns(201) {data: any}
@errors {400, 401, 403, 409, 500}

@endpoint DELETE /observability/destinations/{id}
@required {id: str(uuid)}
@returns(200) {deleted: bool}
@errors {401, 404, 500}

@endpoint GET /observability/destinations/{id}
@required {id: str(uuid)}
@returns(200) {data: any}
@errors {401, 404, 500}

@endpoint PATCH /observability/destinations/{id}
@required {id: str(uuid)}
@optional {api_key_hashes: [str], broadcast_generation_cost: bool, broadcast_generation_identity: bool, broadcast_generation_request_context: bool, config: map, enabled: bool, filter_rules: any, name: str, privacy_mode: bool, regions: [str], sampling_rate: num(double)}
@returns(200) {data: any}
@errors {400, 401, 403, 404, 409, 500}

@endgroup

@group organization
@endpoint GET /organization/members
@optional {offset: int=0, limit: int=50}
@returns(200) {data: [map], total_count: int}
@errors {401, 404, 500}

@endgroup

@group presets
@endpoint GET /presets
@optional {offset: int=0, limit: int=50}
@returns(200) {data: [map], total_count: int}
@errors {400, 401, 500}

@endpoint GET /presets/{slug}
@required {slug: str}
@returns(200) {data: any}
@errors {400, 401, 404, 500}

@endpoint POST /presets/{slug}/chat/completions
@required {slug: str, messages: [any]}
@optional {cache_control: map{ttl: str, type!: str}, debug: map{echo_upstream_body: bool}, frequency_penalty: num(double), image_config: map, logit_bias: map, logprobs: bool, max_completion_tokens: int, max_tokens: int, metadata: map, min_p: num(double), modalities: [str], model: str, models: [any], parallel_tool_calls: bool, plugins: [any], prediction: map{content!: any, type!: str}, presence_penalty: num(double), prompt_cache_key: str, prompt_cache_options: map{mode!: str, ttl: str}, provider: map{allow_fallbacks: bool, data_collection: str, enforce_distillable_text: bool, ignore: [any], max_price: map, only: [any], order: [any], preferred_max_latency: any, preferred_min_throughput: any, quantizations: [str], require_parameters: bool, sort: any, zdr: bool}, reasoning: map{effort: str, summary: str}, reasoning_effort: str(max/xhigh/high/medium/low/minimal/none), repetition_penalty: num(double), response_format: any, route: str(fallback/sort), seed: int, service_tier: str(auto/default/fast/flex/priority/scale), session_id: str, stop: any, stop_server_tools_when: [any], stream: bool=false, stream_options: map{include_usage: bool}, temperature: num(double), tool_choice: any, tools: [any], top_a: num(double), top_k: int, top_logprobs: int, top_p: num(double), trace: map{generation_name: str, parent_span_id: str, span_name: str, trace_id: str, trace_name: str}, user: str}
@returns(200) {data: any}
@errors {400, 401, 403, 404, 409, 500}

@endpoint POST /presets/{slug}/messages
@required {slug: str, messages: [map{clear_at: str, content!: any, output_config: map, role!: str}], model: str}
@optional {cache_control: map{ttl: str, type!: str}, context_management: map{edits: [any]}, fallbacks: [map{model!: str}], max_tokens: int, metadata: map{user_id: str}, models: [str], output_config: map{effort: str, format: map, task_budget: map}, plugins: [any], provider: map{allow_fallbacks: bool, data_collection: str, enforce_distillable_text: bool, ignore: [any], max_price: map, only: [any], order: [any], preferred_max_latency: any, preferred_min_throughput: any, quantizations: [str], require_parameters: bool, sort: any, zdr: bool}, route: str(fallback/sort), safeguards: [map{classifier_context: map, type!: str}], service_tier: str, session_id: str, speed: any, stop_sequences: [str], stop_server_tools_when: [any], stream: bool, system: any, temperature: num(double), thinking: any, tool_choice: any, tools: [any], top_k: int, top_p: num(double), trace: map{generation_name: str, parent_span_id: str, span_name: str, trace_id: str, trace_name: str}, user: str}
@returns(200) {data: any}
@errors {400, 401, 403, 404, 409, 500}

@endpoint POST /presets/{slug}/responses
@required {slug: str}
@optional {background: bool, cache_control: map{ttl: str, type!: str}, debug: map{echo_upstream_body: bool}, frequency_penalty: num(double), image_config: map, include: [str], input: any, instructions: str, max_output_tokens: int, max_tool_calls: int, metadata: map, modalities: [str], model: str, models: [str], parallel_tool_calls: bool, plugins: [any], presence_penalty: num(double), previous_response_id: any, prompt: map{id!: str, variables: map}, prompt_cache_key: str, prompt_cache_options: map{mode!: str, ttl: str}, provider: map{allow_fallbacks: bool, data_collection: str, enforce_distillable_text: bool, ignore: [any], max_price: map, only: [any], order: [any], preferred_max_latency: any, preferred_min_throughput: any, quantizations: [str], require_parameters: bool, sort: any, zdr: bool}, reasoning: any, route: str(fallback/sort), safety_identifier: str, service_tier: str(auto/default/fast/flex/priority/scale)=auto, session_id: str, stop_server_tools_when: [any], store: bool=false, stream: bool=false, temperature: num(double), text: any, tool_choice: any, tools: [any], top_k: int, top_logprobs: int, top_p: num(double), trace: map{generation_name: str, parent_span_id: str, span_name: str, trace_id: str, trace_name: str}, truncation: str(auto/disabled), user: str}
@returns(200) {data: any}
@errors {400, 401, 403, 404, 409, 500}

@endpoint GET /presets/{slug}/versions
@required {slug: str}
@optional {offset: int=0, limit: int=50}
@returns(200) {data: [map], total_count: int}
@errors {400, 401, 404, 500}

@endpoint GET /presets/{slug}/versions/{version}
@required {slug: str, version: str}
@returns(200) {data: map?}
@errors {400, 401, 404, 500}

@endgroup

@group providers
@endpoint GET /providers
@returns(200) {data: [map]}
@errors {500}

@endgroup

@group rerank
@endpoint POST /rerank
@required {documents: [any], model: str, query: str}
@optional {provider: any, session_id: str, top_n: int, trace: map{generation_name: str, parent_span_id: str, span_name: str, trace_id: str, trace_name: str}, user: str}
@returns(200) {id: str, model: str, provider: str, results: [map], usage: map{cost: num(double), search_units: int, total_tokens: int}}
@errors {400, 401, 402, 403, 404, 413, 429, 500, 502, 503, 524, 529}

@endgroup

@group responses
@endpoint POST /responses
@optional {X-OpenRouter-Metadata: str, background: bool, cache_control: map{ttl: str, type!: str}, debug: map{echo_upstream_body: bool}, frequency_penalty: num(double), image_config: map, include: [str], input: any, instructions: str, max_output_tokens: int, max_tool_calls: int, metadata: map, modalities: [str], model: str, models: [str], parallel_tool_calls: bool, plugins: [any], presence_penalty: num(double), previous_response_id: any, prompt: map{id!: str, variables: map}, prompt_cache_key: str, prompt_cache_options: map{mode!: str, ttl: str}, provider: map{allow_fallbacks: bool, data_collection: str, enforce_distillable_text: bool, ignore: [any], max_price: map, only: [any], order: [any], preferred_max_latency: any, preferred_min_throughput: any, quantizations: [str], require_parameters: bool, sort: any, zdr: bool}, reasoning: any, route: str(fallback/sort), safety_identifier: str, service_tier: str(auto/default/fast/flex/priority/scale)=auto, session_id: str, stop_server_tools_when: [any], store: bool=false, stream: bool=false, temperature: num(double), text: any, tool_choice: any, tools: [any], top_k: int, top_logprobs: int, top_p: num(double), trace: map{generation_name: str, parent_span_id: str, span_name: str, trace_id: str, trace_name: str}, truncation: str(auto/disabled), user: str}
@returns(200)
@errors {400, 401, 402, 403, 404, 408, 413, 422, 429, 500, 502, 503, 524, 529}

@endgroup

@group scim
@endpoint GET /scim/group-mappings
@optional {offset: int=0, limit: int=50}
@returns(200) {data: [map], total_count: int}
@errors {401, 404, 500}

@endpoint POST /scim/group-mappings
@required {role: str(admin/member), scim_group_id: str(uuid), workspace_id: str(uuid)}
@returns(201) {data: map{created_at: str, id: str(uuid), organization_id: str, role: str, scim_group_id: str(uuid), updated_at: str, workspace_id: str(uuid)}}
@errors {400, 401, 404, 409, 500}

@endpoint DELETE /scim/group-mappings/{id}
@required {id: str(uuid), keep_members: any}
@returns(200) {deleted: bool}
@errors {400, 401, 404, 500}

@endpoint GET /scim/group-mappings/{id}
@required {id: str(uuid)}
@returns(200) {data: map{created_at: str, id: str(uuid), organization_id: str, role: str, scim_group_id: str(uuid), updated_at: str, workspace_id: str(uuid)}}
@errors {401, 404, 500}

@endpoint PATCH /scim/group-mappings/{id}
@required {id: str(uuid), role: str(admin/member)}
@returns(200) {data: map{created_at: str, id: str(uuid), organization_id: str, role: str, scim_group_id: str(uuid), updated_at: str, workspace_id: str(uuid)}}
@errors {400, 401, 404, 500}

@endpoint GET /scim/groups
@optional {offset: int=0, limit: int=50}
@returns(200) {data: [map], total_count: int}
@errors {401, 404, 500}

@endpoint POST /scim/sync-jobs
@returns(202) {data: map{created_at: str, deleted_groups: int?, error_message: str?, finished_at: str?, id: str(uuid), started_at: str?, status: str, synced_groups: int?}}
@errors {401, 404, 500}

@endpoint GET /scim/sync-jobs/{id}
@required {id: str(uuid)}
@returns(200) {data: map{created_at: str, deleted_groups: int?, error_message: str?, finished_at: str?, id: str(uuid), started_at: str?, status: str, synced_groups: int?}}
@errors {401, 404, 500}

@endgroup

@group systemone
@endpoint POST /systemone
@required {model: str, questions: map, state: any}
@optional {provider: any, session_id: str, trace: map{generation_name: str, parent_span_id: str, span_name: str, trace_id: str, trace_name: str}, user: str}
@returns(200) {answers: map, id: str, model: str, provider: str, usage: map{cost: num(double), input_tokens: int, output_tokens: int}}
@errors {400, 401, 402, 403, 404, 413, 429, 500, 502, 503, 524, 529}

@endgroup

@group vault
@endpoint GET /vault/interns/{internId}/secrets
@required {internId: str(uuid)}
@optional {limit: int=100, offset: int=0}
@returns(200) {data: [map], has_more: bool}
@errors {400, 401, 403, 404, 408, 429, 500, 502, 503, 504}

@endpoint DELETE /vault/interns/{internId}/secrets/{name}
@required {internId: str(uuid), name: str}
@returns(204)
@errors {400, 401, 403, 404, 408, 429, 500, 502, 503, 504}

@endpoint PUT /vault/interns/{internId}/secrets/{name}
@required {internId: str(uuid), name: str, hosts: [str], value: str}
@returns(200) {data: map{created_at: str(date-time), fingerprint: str?, hosts: [str]?, name: str}}
@errors {400, 401, 403, 404, 408, 409, 413, 429, 500, 502, 503, 504}

@endpoint POST /vault/interns/{internId}/secrets/copy
@required {internId: str(uuid), names: [str]}
@returns(200) {data: [map]}
@errors {400, 401, 403, 404, 408, 409, 413, 429, 500, 502, 503, 504}

@endpoint GET /vault/secrets
@optional {limit: int=100, offset: int=0}
@returns(200) {data: [map], has_more: bool}
@errors {400, 401, 403, 404, 408, 429, 500, 502, 503, 504}

@endpoint DELETE /vault/secrets/{name}
@required {name: str}
@returns(204)
@errors {400, 401, 403, 404, 408, 429, 500, 502, 503, 504}

@endpoint PUT /vault/secrets/{name}
@required {name: str, hosts: [str], value: str}
@returns(200) {data: map{created_at: str(date-time), fingerprint: str?, hosts: [str]?, name: str}}
@errors {400, 401, 403, 404, 408, 413, 429, 500, 502, 503, 504}

@endgroup

@group videos
@endpoint POST /videos
@required {model: str}
@optional {aspect_ratio: str(16:9/9:16/1:1/4:3/3:4/3:2/2:3/21:9/9:21), callback_url: str(uri), creativity: int, duration: int, frame_images: [any], generate_audio: bool, input_references: [any], previous_job_id: str, prompt: str, provider: map{options: any}, resolution: str(360p/480p/720p/768p/1080p/1K/2K/4K), seed: int, session_id: str, size: str, trace: map{generation_name: str, parent_span_id: str, span_name: str, trace_id: str, trace_name: str}, upscale_factor: num, user: str}
@returns(202) {error: str, generation_id: str, id: str, polling_url: str, status: str, unsigned_urls: [str], usage: map{cost: num(double)?, is_byok: bool}}
@errors {400, 401, 402, 403, 404, 413, 429, 500}

@endpoint GET /videos/{jobId}
@required {jobId: str}
@returns(200) {error: str, generation_id: str, id: str, polling_url: str, status: str, unsigned_urls: [str], usage: map{cost: num(double)?, is_byok: bool}}
@errors {401, 403, 404, 500}

@endpoint GET /videos/{jobId}/content
@required {jobId: str}
@optional {index: int=0}
@returns(200)
@errors {400, 401, 403, 404, 409, 410, 500, 502}

@endpoint GET /videos/models
@returns(200) {data: [map]}
@errors {400, 500}

@endgroup

@group workspaces
@endpoint GET /workspaces
@optional {offset: int=0, limit: int=50}
@returns(200) {data: [map], total_count: int}
@errors {401, 500}

@endpoint POST /workspaces
@required {name: str, slug: str}
@optional {default_image_model: str, default_provider_sort: str, default_text_model: str, description: str, disabled_server_tools: [str], io_logging_api_key_ids: [int], io_logging_sampling_rate: num(double), is_data_discount_logging_enabled: bool, is_observability_broadcast_enabled: bool, is_observability_io_logging_enabled: bool}
@returns(201) {data: any}
@errors {400, 401, 403, 500}

@endpoint DELETE /workspaces/{id}
@required {id: str}
@optional {confirm_default_workspace_deletion: bool(true/false)}
@returns(200) {deleted: bool}
@errors {400, 401, 403, 404, 500}

@endpoint GET /workspaces/{id}
@required {id: str}
@returns(200) {data: any}
@errors {401, 404, 500}

@endpoint PATCH /workspaces/{id}
@required {id: str}
@optional {default_image_model: str, default_provider_sort: str, default_text_model: str, description: str, disabled_server_tools: [str], io_logging_api_key_ids: [int], io_logging_sampling_rate: num(double), is_data_discount_logging_enabled: bool, is_observability_broadcast_enabled: bool, is_observability_io_logging_enabled: bool, name: str, slug: str}
@returns(200) {data: any}
@errors {400, 401, 403, 404, 500}

@endpoint GET /workspaces/{id}/members
@required {id: str}
@optional {offset: int=0, limit: int=50}
@returns(200) {data: [map], total_count: int}
@errors {401, 403, 404, 500}

@endpoint POST /workspaces/{id}/members/add
@required {id: str, user_ids: [str]}
@returns(200) {added_count: int, data: [map]}
@errors {400, 401, 403, 404, 500}

@endpoint POST /workspaces/{id}/members/remove
@required {id: str, user_ids: [str]}
@returns(200) {removed_count: int}
@errors {400, 401, 403, 404, 500}

@endpoint GET /workspaces/{workspace_ref}/budgets
@required {workspace_ref: str}
@returns(200) {data: [map], include_byok_in_budgets: bool}
@errors {401, 404, 500}

@endpoint DELETE /workspaces/{workspace_ref}/budgets/{interval}
@required {workspace_ref: str, interval: str}
@returns(200) {deleted: bool}
@errors {400, 401, 404, 500}

@endpoint GET /workspaces/{workspace_ref}/budgets/{interval}
@required {workspace_ref: str, interval: str}
@returns(200) {data: any, include_byok_in_budgets: bool}
@errors {400, 401, 404, 500}

@endpoint PUT /workspaces/{workspace_ref}/budgets/{interval}
@required {workspace_ref: str, interval: str, limit_usd: num(double)}
@optional {include_byok_in_budgets: bool}
@returns(200) {data: any, include_byok_in_budgets: bool}
@errors {400, 401, 404, 500}

@endgroup

@end
