@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 39
@hint download_for_search
@toc responses(1), messages(1), activity(1), chat(1), credits(2), generation(1), models(4), endpoints(1), providers(1), keys(5), organization(1), guardrails(13), key(1), auth(2), embeddings(2), rerank(2)

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

@endgroup

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

@endgroup

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

@endgroup

@group chat
@endpoint POST /chat/completions
@required {messages: [any]}
@optional {provider: map{allow_fallbacks: bool, require_parameters: bool, data_collection: any, zdr: bool, enforce_distillable_text: bool, order: [any], only: [any], ignore: [any], quantizations: [str], sort: any, max_price: map, preferred_min_throughput: any, preferred_max_latency: any}, plugins: [any], route: str(fallback/sort), user: str, session_id: str, trace: map{trace_id: str, trace_name: str, span_name: str, generation_name: str, parent_span_id: str}, model: str, models: [any], frequency_penalty: num(double), logit_bias: map, logprobs: bool, top_logprobs: int, max_completion_tokens: int, max_tokens: int, metadata: map, presence_penalty: num(double), reasoning: map{effort: str, summary: str}, response_format: any, seed: int, stop: any, stream: bool=false, stream_options: map{include_usage: bool}, temperature: num(double), parallel_tool_calls: bool, tool_choice: any, tools: [any], top_p: num(double), debug: map{echo_upstream_body: bool}, image_config: map, modalities: [str], cache_control: any, service_tier: str(auto/default/flex/priority/scale)}
@returns(200) {id: str, choices: [map], created: int, model: str, object: str, system_fingerprint: str?, service_tier: str?, usage: map{completion_tokens: int, prompt_tokens: int, total_tokens: int, completion_tokens_details: map?{reasoning_tokens: int, audio_tokens: int, accepted_prediction_tokens: int, rejected_prediction_tokens: int}, prompt_tokens_details: map?{cached_tokens: int, cache_write_tokens: int, audio_tokens: int, video_tokens: int}}}
@errors {400, 401, 402, 404, 408, 413, 422, 429, 500, 502, 503, 524, 529}

@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
@errors {410}

@endgroup

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

@endgroup

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

@endpoint GET /models
@optional {category: str(programming/roleplay/marketing/marketing/seo/technology/science/translation/legal/finance/health/trivia/academia), supported_parameters: str, output_modalities: str}
@returns(200) {data: [map]}
@errors {400, 500}

@endpoint GET /models/user
@returns(200) {data: [map]}
@errors {401, 404, 500}

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

@endgroup

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

@endgroup

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

@endgroup

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

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

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

@endgroup

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

@endgroup

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

@endpoint POST /guardrails
@required {name: str}
@optional {description: str, limit_usd: num(double), reset_interval: any, allowed_providers: [str], ignored_providers: [str], allowed_models: [str], enforce_zdr: bool}
@returns(201) {data: any}
@errors {400, 401, 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 {name: str, description: str, limit_usd: num(double), reset_interval: any, allowed_providers: [str], ignored_providers: [str], allowed_models: [str], enforce_zdr: bool}
@returns(200) {data: any}
@errors {400, 401, 404, 500}

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

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

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

@endpoint GET /guardrails/{id}/assignments/keys
@required {id: str(uuid)}
@optional {offset: int, limit: int}
@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, 404, 500}

@endpoint GET /guardrails/{id}/assignments/members
@required {id: str(uuid)}
@optional {offset: int, limit: int}
@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/keys/remove
@required {id: str(uuid), key_hashes: [str]}
@returns(200) {unassigned_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}

@endgroup

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

@endgroup

@group auth
@endpoint POST /auth/keys
@required {code: str}
@optional {code_verifier: str, code_challenge_method: str(S256/plain)}
@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), limit: num(double), expires_at: str(date-time), key_label: str, usage_limit_type: str(daily/weekly/monthly), spawn_agent: str, spawn_cloud: str}
@returns(200) {data: map{id: str, app_id: int, created_at: str}}
@errors {400, 401, 409, 500}

@endgroup

@group embeddings
@endpoint POST /embeddings
@required {input: any, model: str}
@optional {encoding_format: str(float/base64), dimensions: int, user: str, provider: map{allow_fallbacks: bool, require_parameters: bool, data_collection: any, zdr: bool, enforce_distillable_text: bool, order: [any], only: [any], ignore: [any], quantizations: [str], sort: any, max_price: map, preferred_min_throughput: any, preferred_max_latency: any}, input_type: str}
@returns(200) {id: str, object: str, data: [map], model: str, usage: map{prompt_tokens: int, total_tokens: int, cost: num(double)}}
@errors {400, 401, 402, 404, 429, 500, 502, 503, 524, 529}

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

@endgroup

@group rerank
@endpoint POST /rerank
@required {model: str, query: str, documents: [str]}
@optional {top_n: int, provider: map{allow_fallbacks: bool, require_parameters: bool, data_collection: any, zdr: bool, enforce_distillable_text: bool, order: [any], only: [any], ignore: [any], quantizations: [str], sort: any, max_price: map, preferred_min_throughput: any, preferred_max_latency: any}}
@returns(200) {id: str, model: str, provider: str, results: [map], usage: map{total_tokens: int, search_units: int, cost: num(double)}}
@errors {400, 401, 402, 404, 429, 500, 502, 503, 524, 529}

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

@endgroup

@end
