# OpenRouter

> Use hundreds of AI models from OpenAI, Anthropic, Google, Meta, Mistral and more through one OpenRouter account. Have a model write, answer or read pictures and PDFs, sort text and pull out data; make images, speech, transcripts and video; create embeddings and rank documents for search; run prompts in bulk at half price; and keep an eye on spending. Add a management key to see the account's credit and spending reports and to create API keys with their own limits.

App · AI Models · 26 actions. Web page: https://docs.lodol.com/docs/integrations/openrouter

## Actions

### Check API key usage and limit

See what this connection's API key has spent today, this week, this month and in total, against its spending limit. A good first step before a large run.

**Inputs**: None.

**Outputs**

- `byok_usage` (number): Spent through your own provider keys.
- `expires_at` (text): When the key expires, if it does.
- `free_requests_left_today` (number): Requests to free models left today.
- `has_limit` (true/false): Whether the key has a spending limit.
- `is_free_tier` (true/false): Whether the account has never bought credit.
- `label` (text): The key, with most of it hidden.
- `limit` (number): The limit, in US dollars.
- `limit_remaining` (number): Dollars left before the limit.
- `limit_reset` (text): daily, weekly or monthly; empty for never.
- `percent_used` (number): How much of the limit is used, 0 to 100.
- `usage` (number): Spent in total, in US dollars.
- `usage_daily` (number): Spent today (UTC).
- `usage_monthly` (number): Spent this month (UTC).
- `usage_weekly` (number): Spent this week (UTC, from Monday).

**Example output**

```json
{
  "byok_usage": 0.0,
  "expires_at": null,
  "free_requests_left_today": 1000,
  "has_limit": true,
  "is_free_tier": false,
  "label": "sk-or-v1-0e6...1c96",
  "limit": 100.0,
  "limit_remaining": 74.5,
  "limit_reset": "monthly",
  "percent_used": 25.5,
  "usage": 312.4,
  "usage_daily": 1.2,
  "usage_monthly": 25.5,
  "usage_weekly": 8.9
}
```

### Convert text to speech

Read text aloud in a natural voice and save it as an MP3, for voice messages, narration or audio versions of articles.

**Inputs**

- Text (`text`, text, required): What to say, up to 20,000 characters.
- Model (`model`, text): The text-to-speech model. Gemini 3.8 Flash TTS sounds natural in many languages. Default: `google/gemini-3.8-flash-tts`.
- Voice (`voice`, text): The voice to read in; each model has its own. Leave empty for the model's default voice (Kore for Gemini).
- Speed (`speed`, number): From 0.25 (slow) to 4 (fast); 1 is normal. Only some models honour it. From 0.25 to 4.

**Outputs**

- `characters` (number): How many characters it read.
- `content_type` (text): The file's type, such as image/png.
- `document_ref` (text): The saved file, for steps that take a file.
- `documents` (list): Every file saved, in order.
- `filename` (text): The file's name.
- `model` (text): The model that spoke.
- `size_bytes` (number): The file's size in bytes.
- `url` (text): A link that opens the file in Lodol.
- `voice` (text): The voice used.

**Example output**

```json
{
  "characters": 64,
  "content_type": "audio/mpeg",
  "document_ref": "doc_0123456789abcdef0123456789abcdef",
  "documents": [
    {
      "content_type": "audio/mpeg",
      "document_ref": "doc_0123456789abcdef0123456789abcdef",
      "filename": "openrouter-speech.mp3",
      "size_bytes": 48213,
      "url": "/actions/core/serve-document/doc_0123456789abcdef0123456789abcdef?teamId=000000000000000000000000"
    }
  ],
  "filename": "openrouter-speech.mp3",
  "model": "google/gemini-3.8-flash-tts",
  "size_bytes": 48213,
  "url": "/actions/core/serve-document/doc_0123456789abcdef0123456789abcdef?teamId=000000000000000000000000",
  "voice": "Kore"
}
```

### Create an API key

Create an API key with its own spending limit, such as one per customer or teammate. The key itself is returned this once. Needs a management key on the connection.

**Inputs**

- Name (`name`, text, required): A name to tell the key apart, such as the customer it is for.
- Spending limit (`limit`, number): The most the key may spend, in US dollars. Leave empty for no limit. At least 0.
- Limit resets (`limit_reset`, text): How often the spending limit starts over, at midnight UTC (weeks start on Monday). One of: `never` (Never (a lifetime limit)), `daily` (Every day), `weekly` (Every week), `monthly` (Every month). Default: `never`.
- Count your own provider keys (`include_byok_in_limit`, true/false): Count spending through provider keys you added to OpenRouter (BYOK) towards the limit. Default: `false`.
- Expires (`expires_at`, date and time): When the key stops working. Leave empty for never.

**Outputs**

- `created_at` (text): When it was created.
- `disabled` (true/false): Whether the key is switched off.
- `expires_at` (text): When it stops working, if it expires.
- `hash` (text): The key's id, for the other API key steps.
- `include_byok_in_limit` (true/false): Whether spend on your own provider keys counts towards the limit.
- `key` (text): The new key itself. OpenRouter shows it only now, so pass it on or store it in this run.
- `label` (text): How OpenRouter shows the key, with most of it hidden.
- `limit` (number): Its spending limit in US dollars, when it has one.
- `limit_remaining` (number): Dollars left before the limit.
- `limit_reset` (text): daily, weekly or monthly, or empty when it never resets.
- `name` (text): The key's name.
- `updated_at` (text): When it was last changed.
- `usage` (number): Everything it has spent, in US dollars.
- `usage_daily` (number): Spent today (UTC), in US dollars.
- `usage_monthly` (number): Spent this month (UTC), in US dollars.
- `usage_weekly` (number): Spent this week (UTC, from Monday), in US dollars.
- `workspace_id` (text): The OpenRouter workspace it spends in.

**Example output**

```json
{
  "created_at": "2026-10-01T12:00:00Z",
  "disabled": false,
  "expires_at": null,
  "hash": "f01d52606dc8f0a8303a7b5cc3fa07109c2e346cec7c0a16b40de462992ce943",
  "include_byok_in_limit": false,
  "key": "sk-or-v1-0e6f44a4...1c96",
  "label": "sk-or-v1-0e6...1c96",
  "limit": 25.0,
  "limit_remaining": 24.5,
  "limit_reset": "monthly",
  "name": "Customer: Acme",
  "updated_at": "2026-10-03T09:30:00Z",
  "usage": 0.5,
  "usage_daily": 0.1,
  "usage_monthly": 0.5,
  "usage_weekly": 0.3,
  "workspace_id": "0df9e665-d932-5740-b2c7-b52af166bc11"
}
```

### Create embeddings

Turn texts into vectors for semantic search, deduplication or clustering, with an embedding model from OpenAI, Google, Mistral, Qwen and others.

**Inputs**

- Texts (`texts`, list, required): The texts to turn into vectors, one per entry. Each gives one vector, in the same order.
- Model (`model`, text): The embedding model. Match the model already used for any vectors you will compare these with. OpenAI's text-embedding-3-small is cheap and good for search. Default: `openai/text-embedding-3-small`.
- Vector length (`dimensions`, number): Shorter vectors take less storage. Only some models can be shortened (OpenAI's text-embedding-3 models can); leave empty for the full length. At least 1.

**Outputs**

- `cost` (number): What the request cost, in US dollars of OpenRouter credit.
- `count` (number): How many vectors.
- `dimensions` (number): How many numbers each vector has.
- `embedding` (list): The first text's vector.
- `embeddings` (list): One vector per text, in the same order.
- `model` (text): The model used.
- `total_tokens` (number): Tokens billed.

**Example output**

```json
{
  "cost": 3e-07,
  "count": 2,
  "dimensions": 3,
  "embedding": [
    0.012,
    -0.043,
    0.031
  ],
  "embeddings": [
    [
      0.012,
      -0.043,
      0.031
    ],
    [
      0.018,
      -0.039,
      0.027
    ]
  ],
  "model": "openai/text-embedding-3-small",
  "total_tokens": 14
}
```

### Delete a batch

Delete a finished batch with its prompts and answers. A batch still running cannot be deleted.

**Inputs**

- Batch (`batch_id`, text, required): The batch, from a 'Run prompts as a batch' step or the list.

**Outputs**

- `batch_id` (text): The batch's id.
- `deleted` (true/false): Whether it was deleted.

**Example output**

```json
{
  "batch_id": "batch_01JAB2C3D4E5F6G7H8J9K0",
  "deleted": true
}
```

### Delete an API key

Delete an API key. Anything still using it is refused at once. Needs a management key on the connection.

**Inputs**

- API key (`key_hash`, text, required): The key, by its id (hash) from a list or a 'Create an API key' step.

**Outputs**

- `deleted` (true/false): Whether it was deleted.
- `key_hash` (text): The key's id.

**Example output**

```json
{
  "deleted": true,
  "key_hash": "f01d52606dc8f0a8303a7b5cc3fa07109c2e346cec7c0a16b40de462992ce943"
}
```

### Extract data

Pull the fields you name out of text, pictures or PDFs, such as the total on a photographed receipt or the sender's company in an email, ready for a spreadsheet row or a CRM record.

**Inputs**

- Text (`text`, text): The text to pull the fields out of, such as an email or an invoice. Leave empty when the files hold everything.
- Files (`files`, list): Pictures or PDFs to pull the fields out of, such as a photographed receipt or an invoice: upload them, pick files from an earlier step, or paste public web addresses.
- Fields (`fields`, list): The pieces of information you want, one per entry. Add what each means after a colon to steer it: 'total: the amount due in dollars'. A field the material does not mention comes back empty, never guessed.
- Instructions (`instructions`, text): Extra rules, such as 'Write dates as YYYY-MM-DD'.
- Model (`model`, text): The model that does the work. It has to support structured outputs; GPT-4o mini does, reads pictures and PDFs, and costs a fraction of a cent a call. Default: `openai/gpt-4o-mini`.
- JSON Schema (advanced) (`json_schema`, text): Instead of 'Fields', paste a JSON Schema whose root is an object, for numbers, lists or nested fields. When set, 'Fields' is ignored.

**Outputs**

- `cost` (number): What the request cost, in US dollars of OpenRouter credit.
- `data` (object): The fields, by the names asked for.
- `found_fields` (list): The fields that were filled.
- `generation_id` (text): This request's id.
- `input_tokens` (number): Tokens read, as billed.
- `missing_fields` (list): The fields the material did not mention.
- `model` (text): The model that read it.
- `output_tokens` (number): Tokens written, as billed.
- `total_tokens` (number): Both together.

**Example output**

```json
{
  "cost": 1.2e-05,
  "data": {
    "invoice number": "INV-1042",
    "total": "$1,250.00",
    "vendor": "Acme Ltd"
  },
  "found_fields": [
    "invoice number",
    "vendor",
    "total"
  ],
  "generation_id": "gen-1790000000-abc123",
  "input_tokens": 14,
  "missing_fields": [],
  "model": "openai/gpt-4o-mini",
  "output_tokens": 9,
  "total_tokens": 23
}
```

### Generate a response with OpenRouter

Send a prompt, and any pictures or PDFs, to an AI model on OpenRouter and get back its response text. Optionally let it search the web, think first, or fall back to other models.

**Inputs**

- Prompt (`prompt`, text, required): The prompt or question to send to the AI model.
- Model (`model`, text): The OpenRouter model to use, written as provider/model (for example openai/gpt-4o or anthropic/claude-sonnet-4.5). Leave it as openrouter/auto to let OpenRouter pick a suitable model for your prompt. Add :online to an id for web search or :free for a model's free version, or run a preset you saved on OpenRouter as @preset/your-preset. Browse all models at https://openrouter.ai/models. Default: `openrouter/auto`.
- Instructions (`instructions`, text): How the model should behave, such as 'Answer in one short paragraph' or 'You are a friendly support agent for Acme'.
- Files (`files`, list): Pictures, PDFs, audio, video or text files for the model to read: upload them, pick files from an earlier step, or paste public web addresses of pictures, PDFs and videos. Pick a model that reads that kind of file.
- Search the web (`web_search`, true/false): Let the model look things up on the web first, for current facts. The pages it used come back as citations. Costs a little extra per request. Default: `false`.
- Fallback models (`fallback_models`, list): Up to three models to try, in order, if the main one is down, rate limited or refuses the prompt. You pay for whichever answers; the step reports which one did.
- Thinking (`reasoning`, text): How much a reasoning model thinks before it answers. More is slower and uses more tokens; the thinking comes back separately from the answer. Models that cannot reason ignore this. One of: `default` (Model's default), `none` (Off), `minimal`, `low`, `medium`, `high`, `xhigh` (Extra high). Default: `default`.
- Maximum reply length (`max_tokens`, number): The most tokens the reply may use; a token is about three-quarters of a word. Leave empty to let the model decide. At least 1.
- Creativity (`temperature`, number): From 0 (focused and repeatable) to 2 (most varied). Leave empty for the model's default. From 0 to 2.

**Outputs**

- `citations` (list): The web pages it drew on, with web search.
- `cost` (number): What the request cost, in US dollars of OpenRouter credit.
- `finish_reason` (text): stop when it finished, length when cut off.
- `generation_id` (text): This request's id, for 'Get generation details'.
- `input_tokens` (number): Tokens read, as billed.
- `model` (text): The model that actually generated the response. When the model is left as openrouter/auto, this is the model OpenRouter picked for the prompt.
- `output_tokens` (number): Tokens written, as billed.
- `provider` (text): The provider that served the model.
- `response_text` (text): The text the model generated for your prompt.
- `thinking` (text): Its reasoning, when it thought first.
- `total_tokens` (number): Both together.
- `was_cut_off` (true/false): Whether it hit the maximum reply length.

**Example output**

```json
{
  "citations": [],
  "cost": 1.2e-05,
  "finish_reason": "stop",
  "generation_id": "gen-1790000000-abc123",
  "input_tokens": 14,
  "model": "openai/gpt-4o",
  "output_tokens": 9,
  "provider": "OpenAI",
  "response_text": "Here is the response generated for your prompt.",
  "thinking": null,
  "total_tokens": 23,
  "was_cut_off": false
}
```

### Generate a video

Make a short video from a description, or animate a picture, with a video model such as Veo, Kling or Seedance. The step waits for it, usually a few minutes, and saves the video as a file.

**Inputs**

- Description (`prompt`, text, required): What happens in the video: the subject, the action, the setting and the camera movement.
- Model (`model`, text): The video model. Veo 3.1 Lite makes 4, 6 or 8 second clips with sound; others offer longer clips or lower prices. Video costs a few cents a second. Default: `google/veo-3.1-lite`.
- Length in seconds (`duration`, number): How long the video is. Each model offers its own lengths; leave empty for its default. From 1 to 60.
- Resolution (`resolution`, text): The video's resolution. Higher costs more. One of: `default` (Model's default), `480p`, `720p`, `1080p`. Default: `default`.
- Shape (`aspect_ratio`, text): The video's shape. Not every model offers every shape. One of: `default` (Model's default), `16:9` (Wide (16:9)), `9:16` (Tall (9:16)), `1:1` (Square (1:1)), `4:3` (Landscape (4:3)), `3:4` (Portrait (3:4)). Default: `default`.
- Starting picture (`first_frame`, text): A picture for the video to start from, to animate it: upload it, pick a file from an earlier step, or paste its public web address.
- Sound (`sound`, text): Whether the video has sound, for models that can make it. Sound usually costs more. One of: `default` (Model's default), `on` (With sound), `off` (Silent). Default: `default`.

**Outputs**

- `content_type` (text): The file's type, such as image/png.
- `cost` (number): What it cost, in US dollars.
- `document_ref` (text): The saved file, for steps that take a file.
- `documents` (list): Every file saved, in order.
- `filename` (text): The file's name.
- `generation_id` (text): Its generation id, for 'Get generation details'.
- `job_id` (text): The video job's id, for 'Get a video'.
- `model` (text): The model that made it.
- `size_bytes` (number): The file's size in bytes.
- `status` (text): completed once it is saved.
- `url` (text): A link that opens the file in Lodol.

**Example output**

```json
{
  "content_type": "video/mp4",
  "cost": 0.4,
  "document_ref": "doc_0123456789abcdef0123456789abcdef",
  "documents": [
    {
      "content_type": "video/mp4",
      "document_ref": "doc_0123456789abcdef0123456789abcdef",
      "filename": "openrouter-video.mp4",
      "size_bytes": 2097152,
      "url": "/actions/core/serve-document/doc_0123456789abcdef0123456789abcdef?teamId=000000000000000000000000"
    }
  ],
  "filename": "openrouter-video.mp4",
  "generation_id": "gen-vid-1790000000-abcdefghij0123456789",
  "job_id": "gen-vid-1790000000-abcdefghij0123456789",
  "model": "google/veo-3.1-lite",
  "size_bytes": 2097152,
  "status": "completed",
  "url": "/actions/core/serve-document/doc_0123456789abcdef0123456789abcdef?teamId=000000000000000000000000"
}
```

### Generate an image

Draw a picture from a description with an image model such as Nano Banana, GPT Image or FLUX, optionally working from reference pictures. The pictures are saved as files for later steps.

**Inputs**

- Description (`prompt`, text, required): What to draw: the subject, the setting, the style and the mood. With reference pictures, say how to use them, such as 'Put this product on a marble kitchen counter'.
- Model (`model`, text): The image model. Nano Banana (Gemini 2.5 Flash Image) is quick, good at text in pictures and takes reference pictures. You can also type any image model's id. Default: `google/gemini-2.5-flash-image`.
- Shape (`aspect_ratio`, text): The picture's shape. Not every model offers every shape. One of: `default` (Model's default), `1:1` (Square (1:1)), `16:9` (Wide (16:9)), `9:16` (Tall (9:16)), `4:3` (Landscape (4:3)), `3:4` (Portrait (3:4)), `3:2` (Photo landscape (3:2)), `2:3` (Photo portrait (2:3)), `21:9` (Ultra-wide (21:9)). Default: `default`.
- Reference pictures (`reference_images`, list): Pictures to work from, to edit or to keep consistent with, such as a product photo or a logo: upload them, pick files from an earlier step, or paste public web addresses.
- How many (`count`, number): How many pictures to make, up to 4. Many models make one at a time and return just one. From 1 to 4.
- Seed (`seed`, number): Any whole number, to get the same picture again from the same description. Leave empty for a new one each time. At least 0.

**Outputs**

- `content_type` (text): The file's type, such as image/png.
- `cost` (number): What the request cost, in US dollars of OpenRouter credit.
- `count` (number): How many it made.
- `document_ref` (text): The saved file, for steps that take a file.
- `documents` (list): Every file saved, in order.
- `filename` (text): The file's name.
- `model` (text): The model that drew.
- `size_bytes` (number): The file's size in bytes.
- `url` (text): A link that opens the file in Lodol.

**Example output**

```json
{
  "content_type": "image/png",
  "cost": 0.039,
  "count": 1,
  "document_ref": "doc_0123456789abcdef0123456789abcdef",
  "documents": [
    {
      "content_type": "image/png",
      "document_ref": "doc_0123456789abcdef0123456789abcdef",
      "filename": "openrouter-image-1.png",
      "size_bytes": 1048576,
      "url": "/actions/core/serve-document/doc_0123456789abcdef0123456789abcdef?teamId=000000000000000000000000"
    }
  ],
  "filename": "openrouter-image-1.png",
  "model": "google/gemini-2.5-flash-image",
  "size_bytes": 1048576,
  "url": "/actions/core/serve-document/doc_0123456789abcdef0123456789abcdef?teamId=000000000000000000000000"
}
```

### Get a batch

See where a batch stands and, once it has finished, collect every answer matched to its prompt's id.

**Inputs**

- Batch (`batch_id`, text, required): The batch, from a 'Run prompts as a batch' step or the list.

**Outputs**

- `batch_id` (text): The batch's id.
- `completed_requests` (number): How many have an answer.
- `cost` (number): What the batch cost, in US dollars.
- `created_at` (text): When it was submitted.
- `error` (text): Why the whole batch failed, when it did.
- `failed_requests` (number): How many failed.
- `finished_at` (text): When it finished, once it has.
- `is_finished` (true/false): Whether it has stopped running for good.
- `model` (text): The model the batch runs on.
- `replies` (list): Just the answers, in order.
- `result_count` (number): How many answers there are.
- `results` (list): Every answer, once the batch has finished.
- `status` (text): validating, in_progress, finalizing, completed, failed, expired, cancelling or cancelled.
- `total_requests` (number): How many prompts it holds.

**Example output**

```json
{
  "batch_id": "batch_01JAB2C3D4E5F6G7H8J9K0",
  "completed_requests": 2,
  "cost": 2e-05,
  "created_at": "2026-10-05T12:00:00Z",
  "error": null,
  "failed_requests": 0,
  "finished_at": "2026-10-05T13:10:00Z",
  "is_finished": true,
  "model": "openai/gpt-4o-mini",
  "replies": [
    "Positive",
    "Negative"
  ],
  "result_count": 2,
  "results": [
    {
      "error": null,
      "finish_reason": "stop",
      "id": "row-1",
      "reply": "Positive"
    },
    {
      "error": null,
      "finish_reason": "stop",
      "id": "row-2",
      "reply": "Negative"
    }
  ],
  "status": "completed",
  "total_requests": 2
}
```

### Get a model

Look up one model: what it reads and writes, what it costs, how much it takes in and writes out, the settings it accepts, and when it may be retired.

**Inputs**

- Model (`model`, text, required): The model to look up. Pick one, or type its id, such as anthropic/claude-sonnet-4.5.

**Outputs**

- `completion_price_per_million` (number): US dollars per million output tokens. Empty when the price varies.
- `context_length` (number): The most tokens it can take in at once.
- `created_at` (text): When OpenRouter added it.
- `description` (text): What OpenRouter says about it.
- `expiration_date` (text): The day it may be removed (YYYY-MM-DD), if set.
- `hugging_face_id` (text): Its id on Hugging Face, for open models.
- `id` (text): The model's id, to use in any OpenRouter step.
- `image_price` (number): US dollars per input picture, when priced so.
- `input_modalities` (list): What it can read: text, image, audio, file, video.
- `is_free` (true/false): Whether it costs nothing to use.
- `is_moderated` (true/false): Whether its provider screens what it is sent.
- `knowledge_cutoff` (text): How recent its training data is (YYYY-MM-DD).
- `max_output_tokens` (number): The most tokens it writes in one reply.
- `name` (text): Its display name.
- `output_modalities` (list): What it produces: text, image, audio and so on.
- `prompt_price_per_million` (number): US dollars per million input tokens. Empty when the price varies.
- `request_price` (number): US dollars per request, when priced so.
- `supported_parameters` (list): The request settings it accepts.
- `supported_voices` (list): The voices a speech model offers.
- `web_search_price` (number): US dollars per web search.

**Example output**

```json
{
  "completion_price_per_million": 15.0,
  "context_length": 1000000,
  "created_at": "2025-09-29T00:00:00Z",
  "description": "Anthropic's balanced model for coding and agents.",
  "expiration_date": null,
  "hugging_face_id": null,
  "id": "anthropic/claude-sonnet-4.5",
  "image_price": null,
  "input_modalities": [
    "text",
    "image",
    "file"
  ],
  "is_free": false,
  "is_moderated": false,
  "knowledge_cutoff": "2025-07-31",
  "max_output_tokens": 64000,
  "name": "Anthropic: Claude Sonnet 4.5",
  "output_modalities": [
    "text"
  ],
  "prompt_price_per_million": 3.0,
  "request_price": null,
  "supported_parameters": [
    "max_tokens",
    "temperature",
    "tools",
    "reasoning"
  ],
  "supported_voices": [],
  "web_search_price": 0.01
}
```

### Get a spending report

See what OpenRouter usage cost over a range of days, split by model, API key, app, workspace or person, and by day, week or month. Needs a management key on the connection.

**Inputs**

- From (`start_date`, date): The first day to include (UTC). Leave empty for the start of this month.
- To (`end_date`, date): The last day to include (UTC). Leave empty for today.
- Split by (`breakdown`, text): How to split the spending. One of: `total` (Just the total), `model` (By model), `api_key` (By API key), `app` (By app), `workspace` (By workspace), `user` (By person). Default: `model`.
- Over time (`interval`, text): Also split it by day, week or month. One of: `none` (The whole period), `day` (By day), `week` (By week), `month` (By month). Default: `none`.

**Outputs**

- `end_date` (text): The last day.
- `is_truncated` (true/false): Whether there were too many rows to return.
- `row_count` (number): How many rows.
- `rows` (list): The total, split up.
- `start_date` (text): The first day.
- `total_cost` (number): The total, in US dollars.
- `total_requests` (number): How many requests in all.

**Example output**

```json
{
  "end_date": "2026-10-05",
  "is_truncated": false,
  "row_count": 1,
  "rows": [
    {
      "cost": 12.48,
      "group": "openai/gpt-4o",
      "input_tokens": 1520000,
      "output_tokens": 210000,
      "period": null,
      "reasoning_tokens": 0,
      "requests": 812
    }
  ],
  "start_date": "2026-10-01",
  "total_cost": 12.48,
  "total_requests": 812
}
```

### Get a video

Collect a video whose generation was still running when its step stopped waiting. Waits for it to finish if needed, then saves it as a file.

**Inputs**

- Job ID (`job_id`, text, required): The video's job id, from a 'Generate a video' step that ran out of time or from its error message.

**Outputs**

- `content_type` (text): The file's type, such as image/png.
- `cost` (number): What it cost, in US dollars.
- `document_ref` (text): The saved file, for steps that take a file.
- `documents` (list): Every file saved, in order.
- `filename` (text): The file's name.
- `generation_id` (text): Its generation id, for 'Get generation details'.
- `job_id` (text): The video job's id, for 'Get a video'.
- `model` (text): The model that made it.
- `size_bytes` (number): The file's size in bytes.
- `status` (text): completed once it is saved.
- `url` (text): A link that opens the file in Lodol.

**Example output**

```json
{
  "content_type": "video/mp4",
  "cost": 0.4,
  "document_ref": "doc_0123456789abcdef0123456789abcdef",
  "documents": [
    {
      "content_type": "video/mp4",
      "document_ref": "doc_0123456789abcdef0123456789abcdef",
      "filename": "openrouter-video.mp4",
      "size_bytes": 2097152,
      "url": "/actions/core/serve-document/doc_0123456789abcdef0123456789abcdef?teamId=000000000000000000000000"
    }
  ],
  "filename": "openrouter-video.mp4",
  "generation_id": "gen-vid-1790000000-abcdefghij0123456789",
  "job_id": "gen-vid-1790000000-abcdefghij0123456789",
  "model": null,
  "size_bytes": 2097152,
  "status": "completed",
  "url": "/actions/core/serve-document/doc_0123456789abcdef0123456789abcdef?teamId=000000000000000000000000"
}
```

### Get an API key

Look up one API key: what it has spent, its spending limit and whether it is switched on. Needs a management key on the connection.

**Inputs**

- API key (`key_hash`, text, required): The key, by its id (hash) from a list or a 'Create an API key' step.

**Outputs**

- `created_at` (text): When it was created.
- `disabled` (true/false): Whether the key is switched off.
- `expires_at` (text): When it stops working, if it expires.
- `hash` (text): The key's id, for the other API key steps.
- `include_byok_in_limit` (true/false): Whether spend on your own provider keys counts towards the limit.
- `label` (text): How OpenRouter shows the key, with most of it hidden.
- `limit` (number): Its spending limit in US dollars, when it has one.
- `limit_remaining` (number): Dollars left before the limit.
- `limit_reset` (text): daily, weekly or monthly, or empty when it never resets.
- `name` (text): The key's name.
- `updated_at` (text): When it was last changed.
- `usage` (number): Everything it has spent, in US dollars.
- `usage_daily` (number): Spent today (UTC), in US dollars.
- `usage_monthly` (number): Spent this month (UTC), in US dollars.
- `usage_weekly` (number): Spent this week (UTC, from Monday), in US dollars.
- `workspace_id` (text): The OpenRouter workspace it spends in.

**Example output**

```json
{
  "created_at": "2026-10-01T12:00:00Z",
  "disabled": false,
  "expires_at": null,
  "hash": "f01d52606dc8f0a8303a7b5cc3fa07109c2e346cec7c0a16b40de462992ce943",
  "include_byok_in_limit": false,
  "label": "sk-or-v1-0e6...1c96",
  "limit": 25.0,
  "limit_remaining": 24.5,
  "limit_reset": "monthly",
  "name": "Customer: Acme",
  "updated_at": "2026-10-03T09:30:00Z",
  "usage": 0.5,
  "usage_daily": 0.1,
  "usage_monthly": 0.5,
  "usage_weekly": 0.3,
  "workspace_id": "0df9e665-d932-5740-b2c7-b52af166bc11"
}
```

### Get credit balance

See how much OpenRouter credit the account has bought, used and has left. Needs a management key on the connection.

**Inputs**: None.

**Outputs**

- `remaining` (number): Credit left, in US dollars.
- `total_credits` (number): Credit bought, in US dollars.
- `total_usage` (number): Credit used, in US dollars.

**Example output**

```json
{
  "remaining": 57.83,
  "total_credits": 100.0,
  "total_usage": 42.17
}
```

### Get daily activity

See spending, requests and tokens per day, model and provider for the last 30 days, for the whole account or one API key. Needs a management key on the connection.

**Inputs**

- Day (`date`, date): Only this day (UTC), within the last 30. Leave empty for all 30 days.
- API key (`api_key_hash`, text): Only this API key's spending. Leave empty for every key.

**Outputs**

- `row_count` (number): How many rows.
- `rows` (list): One row per day, model and provider.
- `total_cost` (number): All the rows' cost, in US dollars.
- `total_requests` (number): All the rows' requests.

**Example output**

```json
{
  "row_count": 1,
  "rows": [
    {
      "byok_cost": 0.0,
      "cached_tokens": 41000,
      "cost": 1.84,
      "date": "2026-10-04",
      "input_tokens": 182000,
      "model": "openai/gpt-4o",
      "output_tokens": 24000,
      "provider": "OpenAI",
      "reasoning_tokens": 0,
      "requests": 120
    }
  ],
  "total_cost": 1.84,
  "total_requests": 120
}
```

### Get generation details

Look up what one request cost, how many tokens it used, how long it took and which provider served it, from the generation id an earlier step returned.

**Inputs**

- Generation ID (`generation_id`, text, required): The request to look up: the 'Generation ID' an earlier OpenRouter step returned, such as gen-1234567890-abc.

**Outputs**

- `api_type` (text): Which OpenRouter API it came through.
- `cache_discount` (number): What prompt caching saved, in US dollars.
- `cached_tokens` (number): Input tokens served from the cache.
- `cost` (number): What it cost, in US dollars.
- `created_at` (text): When it ran.
- `finish_reason` (text): Why it stopped.
- `generation_id` (text): Its id.
- `generation_time_ms` (number): Time spent writing, in milliseconds.
- `input_tokens` (number): Tokens read.
- `is_byok` (true/false): Whether it ran on your own provider key.
- `latency_ms` (number): Time to the first token, in milliseconds.
- `model` (text): The model used.
- `output_tokens` (number): Tokens written.
- `provider` (text): The provider that served it.
- `reasoning_tokens` (number): Tokens spent thinking.
- `router` (text): The router that picked the model, if one did.
- `streamed` (true/false): Whether it was streamed.
- `upstream_cost` (number): What the provider charged, with your own key.
- `was_cancelled` (true/false): Whether it was cancelled.
- `web_search_results` (number): Web results it read, with web search.

**Example output**

```json
{
  "api_type": "completions",
  "cache_discount": null,
  "cached_tokens": 0,
  "cost": 0.00042,
  "created_at": "2026-10-05T12:00:00Z",
  "finish_reason": "stop",
  "generation_id": "gen-1790000000-abc123",
  "generation_time_ms": 903,
  "input_tokens": 120,
  "is_byok": false,
  "latency_ms": 412,
  "model": "openai/gpt-4o",
  "output_tokens": 18,
  "provider": "OpenAI",
  "reasoning_tokens": 0,
  "router": "openrouter/auto",
  "streamed": false,
  "upstream_cost": null,
  "was_cancelled": false,
  "web_search_results": null
}
```

### List API keys

List the account's API keys with what each has spent and its spending limit. Needs a management key on the connection.

**Inputs**

- Include disabled keys (`include_disabled`, true/false): Also list keys that are switched off. Default: `false`.

**Outputs**

- `count` (number): How many there are.
- `key_hashes` (list): Every key's id, in order.
- `keys` (list): The keys.

**Example output**

```json
{
  "count": 1,
  "key_hashes": [
    "f01d52606dc8f0a8303a7b5cc3fa07109c2e346cec7c0a16b40de462992ce943"
  ],
  "keys": [
    {
      "created_at": "2026-10-01T12:00:00Z",
      "disabled": false,
      "expires_at": null,
      "hash": "f01d52606dc8f0a8303a7b5cc3fa07109c2e346cec7c0a16b40de462992ce943",
      "include_byok_in_limit": false,
      "label": "sk-or-v1-0e6...1c96",
      "limit": 25.0,
      "limit_remaining": 24.5,
      "limit_reset": "monthly",
      "name": "Customer: Acme",
      "updated_at": "2026-10-03T09:30:00Z",
      "usage": 0.5,
      "usage_daily": 0.1,
      "usage_monthly": 0.5,
      "usage_weekly": 0.3,
      "workspace_id": "0df9e665-d932-5740-b2c7-b52af166bc11"
    }
  ]
}
```

### List batches

List the batches in this key's workspace, newest first.

**Inputs**

- Status (`status`, list): Only batches in these states. Choose none to list them all. One or more of: `validating`, `in_progress` (In progress), `finalizing`, `completed`, `failed`, `expired`, `cancelling`, `cancelled`.
- How many (`limit`, number): The most batches to return, newest first, up to 100. From 1 to 100. Default: `20`.

**Outputs**

- `batch_ids` (list): Every batch's id, in order.
- `batches` (list): The batches.
- `count` (number): How many returned.
- `has_more` (true/false): Whether there are more than were returned.

**Example output**

```json
{
  "batch_ids": [
    "batch_01JAB2C3D4E5F6G7H8J9K0"
  ],
  "batches": [
    {
      "batch_id": "batch_01JAB2C3D4E5F6G7H8J9K0",
      "completed_requests": 0,
      "created_at": "2026-10-05T12:00:00Z",
      "error": null,
      "failed_requests": 0,
      "finished_at": null,
      "is_finished": false,
      "model": "openai/gpt-4o-mini",
      "status": "in_progress",
      "total_requests": 2
    }
  ],
  "count": 1,
  "has_more": false
}
```

### List models

Find models on OpenRouter by what they do, what they read, their name or their price, sorted by popularity, price, speed or smarts. Each comes with its price and context length.

**Inputs**

- What it does (`purpose`, text): Only models that produce this. One of: `text` (Writes text), `image` (Makes images), `embeddings` (Creates embeddings), `speech` (Speaks (text to speech)), `transcription` (Transcribes audio), `rerank` (Ranks documents), `video` (Makes video), `all` (Anything). Default: `text`.
- Name contains (`search`, text): Only models whose name or id contains this, such as 'claude'.
- Reads (`reads`, text): Only models that can read this kind of input. One of: `any` (Anything), `image` (Reads images), `file` (Reads files such as PDFs), `audio` (Hears audio). Default: `any`.
- Order (`sort`, text): How to order the models. One of: `most-popular` (Most used), `top-weekly` (Most used this week), `newest`, `pricing-low-to-high` (Cheapest), `pricing-high-to-low` (Most expensive), `context-high-to-low` (Longest context), `throughput-high-to-low` (Fastest output), `latency-low-to-high` (Quickest to start), `intelligence-high-to-low` (Smartest), `coding-high-to-low` (Best at coding). Default: `most-popular`.
- Free models only (`free_only`, true/false): Only models that cost nothing to use. Default: `false`.
- Highest input price (`max_price`, number): Only models that charge at most this many US dollars per million input tokens. At least 0.
- How many (`limit`, number): The most models to return, up to 1,000. From 1 to 1000. Default: `100`.

**Outputs**

- `count` (number): How many returned.
- `model_ids` (list): Every model's id, in the same order.
- `models` (list): The models, in order.
- `total_count` (number): How many match, before 'How many' cut it.

**Example output**

```json
{
  "count": 1,
  "model_ids": [
    "anthropic/claude-sonnet-4.5"
  ],
  "models": [
    {
      "completion_price_per_million": 15.0,
      "context_length": 1000000,
      "created_at": "2025-09-29T00:00:00Z",
      "description": "Anthropic's balanced model for coding and agents.",
      "expiration_date": null,
      "id": "anthropic/claude-sonnet-4.5",
      "input_modalities": [
        "text",
        "image",
        "file"
      ],
      "is_free": false,
      "name": "Anthropic: Claude Sonnet 4.5",
      "output_modalities": [
        "text"
      ],
      "prompt_price_per_million": 3.0,
      "supported_parameters": [
        "max_tokens",
        "temperature",
        "tools",
        "reasoning"
      ]
    }
  ],
  "total_count": 1
}
```

### Rank documents by relevance

Order a list of texts by how well each answers a question, best first, with a relevance score. Useful for picking the passages to hand an AI step.

**Inputs**

- Question (`query`, text, required): What you are looking for, written as a question or a search.
- Documents (`documents`, list, required): The texts to rank, one per entry.
- How many to return (`top_n`, number): Keep only the best matches. Leave empty to rank them all. At least 1.
- Model (`model`, text): The ranking model. Cohere Rerank v3.5 handles many languages. Default: `cohere/rerank-v3.5`.

**Outputs**

- `cost` (number): What the request cost, in US dollars of OpenRouter credit.
- `count` (number): How many were returned.
- `model` (text): The model used.
- `query` (text): The question.
- `results` (list): The documents, best match first.
- `top_document` (text): The best match's text.
- `top_position` (number): Where the best match was in the list, from 1.
- `top_score` (number): The best match's score.

**Example output**

```json
{
  "cost": 0.002,
  "count": 2,
  "model": "cohere/rerank-v3.5",
  "query": "What is the capital of France?",
  "results": [
    {
      "document": "Paris is the capital of France.",
      "position": 2,
      "rank": 1,
      "score": 0.98
    },
    {
      "document": "The Loire is France's longest river.",
      "position": 1,
      "rank": 2,
      "score": 0.07
    }
  ],
  "top_document": "Paris is the capital of France.",
  "top_position": 2,
  "top_score": 0.98
}
```

### Run prompts as a batch

Queue many prompts to run in the background at half the usual price, such as one per spreadsheet row. Answers arrive within a day; collect them with 'Get a batch'.

**Inputs**

- Prompts (`prompts`, list, required): The prompts to run, one per entry, such as one per spreadsheet row. Each gets its own answer.
- Model (`model`, text): The model to run every prompt on. It needs a batch endpoint: models from OpenAI, Anthropic, Google, xAI and Mistral usually have one, and the model's page on openrouter.ai says. Default: `openai/gpt-4o-mini`.
- Instructions (`instructions`, text): How the model should behave, such as 'Answer in one short paragraph' or 'You are a friendly support agent for Acme'.
- Your ids (`ids`, list): An id for each prompt, in the same order, such as row numbers or record ids, so each answer can be matched back. Leave empty to number them 1, 2, 3.
- Maximum reply length (`max_tokens`, number): The most tokens the reply may use; a token is about three-quarters of a word. Leave empty to let the model decide. At least 1.
- Creativity (`temperature`, number): From 0 (focused and repeatable) to 2 (most varied). Leave empty for the model's default. From 0 to 2.

**Outputs**

- `batch_id` (text): The batch's id.
- `completed_requests` (number): How many have an answer.
- `created_at` (text): When it was submitted.
- `error` (text): Why the whole batch failed, when it did.
- `failed_requests` (number): How many failed.
- `finished_at` (text): When it finished, once it has.
- `is_finished` (true/false): Whether it has stopped running for good.
- `model` (text): The model the batch runs on.
- `prompt_count` (number): How many prompts were queued.
- `status` (text): validating, in_progress, finalizing, completed, failed, expired, cancelling or cancelled.
- `total_requests` (number): How many prompts it holds.

**Example output**

```json
{
  "batch_id": "batch_01JAB2C3D4E5F6G7H8J9K0",
  "completed_requests": 0,
  "created_at": "2026-10-05T12:00:00Z",
  "error": null,
  "failed_requests": 0,
  "finished_at": null,
  "is_finished": false,
  "model": "openai/gpt-4o-mini",
  "prompt_count": 2,
  "status": "validating",
  "total_requests": 2
}
```

### Sort text into a category

Have a model pick the one category that fits a piece of text, such as routing a support email. The answer is always exactly one of the categories you list.

**Inputs**

- Text (`text`, text, required): The text to sort, such as an email, a review or a support ticket.
- Categories (`categories`, list, required): The categories to choose from, one per entry. The step always returns exactly one of them, spelled as you wrote it.
- How to decide (`instructions`, text): Rules for borderline cases, such as 'Anything that mentions money back is a Refund request'.
- Model (`model`, text): The model that does the work. It has to support structured outputs; GPT-4o mini does, reads pictures and PDFs, and costs a fraction of a cent a call. Default: `openai/gpt-4o-mini`.

**Outputs**

- `categories` (list): The categories it chose from.
- `category` (text): The category chosen.
- `cost` (number): What the request cost, in US dollars of OpenRouter credit.
- `generation_id` (text): This request's id.
- `input_tokens` (number): Tokens read, as billed.
- `model` (text): The model that chose.
- `output_tokens` (number): Tokens written, as billed.
- `total_tokens` (number): Both together.

**Example output**

```json
{
  "categories": [
    "Refund request",
    "Bug report",
    "Sales question"
  ],
  "category": "Refund request",
  "cost": 1.2e-05,
  "generation_id": "gen-1790000000-abc123",
  "input_tokens": 14,
  "model": "openai/gpt-4o-mini",
  "output_tokens": 9,
  "total_tokens": 23
}
```

### Transcribe audio

Turn speech in a recording into text, such as a call, a meeting or a voice note, optionally with timestamps.

**Inputs**

- Audio (`audio`, text, required): The recording to transcribe: upload it, pick a file from an earlier step, or paste its public web address. MP3, WAV, FLAC, OGG, M4A, AAC or WebM, up to 25 MB uploaded; a web address has no size limit but only some models fetch one.
- Model (`model`, text): The speech-to-text model. GPT-4o mini Transcribe is accurate and inexpensive; Whisper and others are in the list too. Default: `openai/gpt-4o-mini-transcribe`.
- Language (`language`, text): The language spoken, as a two-letter code such as en, es or ja. Leave empty to detect it; setting it helps with short or noisy recordings.
- Include timestamps (`timestamps`, true/false): Also return the transcript in timed segments, for subtitles or jumping to a moment. Not every model can. Default: `false`.

**Outputs**

- `cost` (number): What the request cost, in US dollars of OpenRouter credit.
- `duration_seconds` (number): How long the recording is.
- `language` (text): The language, when the model reports it.
- `model` (text): The model that listened.
- `segments` (list): The transcript in timed pieces, with timestamps on.
- `text` (text): What was said.
- `word_count` (number): How many words were said.

**Example output**

```json
{
  "cost": 0.0001,
  "duration_seconds": 3.2,
  "language": "en",
  "model": "openai/gpt-4o-mini-transcribe",
  "segments": [],
  "text": "Thanks for calling Acme, how can I help?",
  "word_count": 8
}
```

### Update an API key

Rename an API key, switch it on or off, or change or remove its spending limit. Needs a management key on the connection.

**Inputs**

- API key (`key_hash`, text, required): The key, by its id (hash) from a list or a 'Create an API key' step.
- New name (`name`, text): Leave empty to keep the name.
- Status (`status`, text): Switch the key on or off. A disabled key is refused at once. One of: `keep` (Leave as it is), `enabled`, `disabled`. Default: `keep`.
- New spending limit (`limit`, number): In US dollars. Leave empty to keep the limit. At least 0.
- Remove the limit (`remove_limit`, true/false): Let the key spend without a limit. Default: `false`.
- Limit resets (`limit_reset`, text): How often the spending limit starts over. One of: `keep` (Leave as it is), `never` (Never (a lifetime limit)), `daily` (Every day), `weekly` (Every week), `monthly` (Every month). Default: `keep`.
- Count your own provider keys (`include_byok_in_limit`, text): Whether spending through provider keys you added to OpenRouter (BYOK) counts towards the limit. One of: `keep` (Leave as it is), `include` (Count it), `exclude` (Don't count it). Default: `keep`.

**Outputs**

- `created_at` (text): When it was created.
- `disabled` (true/false): Whether the key is switched off.
- `expires_at` (text): When it stops working, if it expires.
- `hash` (text): The key's id, for the other API key steps.
- `include_byok_in_limit` (true/false): Whether spend on your own provider keys counts towards the limit.
- `label` (text): How OpenRouter shows the key, with most of it hidden.
- `limit` (number): Its spending limit in US dollars, when it has one.
- `limit_remaining` (number): Dollars left before the limit.
- `limit_reset` (text): daily, weekly or monthly, or empty when it never resets.
- `name` (text): The key's name.
- `updated_at` (text): When it was last changed.
- `usage` (number): Everything it has spent, in US dollars.
- `usage_daily` (number): Spent today (UTC), in US dollars.
- `usage_monthly` (number): Spent this month (UTC), in US dollars.
- `usage_weekly` (number): Spent this week (UTC, from Monday), in US dollars.
- `workspace_id` (text): The OpenRouter workspace it spends in.

**Example output**

```json
{
  "created_at": "2026-10-01T12:00:00Z",
  "disabled": true,
  "expires_at": null,
  "hash": "f01d52606dc8f0a8303a7b5cc3fa07109c2e346cec7c0a16b40de462992ce943",
  "include_byok_in_limit": false,
  "label": "sk-or-v1-0e6...1c96",
  "limit": 25.0,
  "limit_remaining": 24.5,
  "limit_reset": "monthly",
  "name": "Customer: Acme",
  "updated_at": "2026-10-03T09:30:00Z",
  "usage": 0.5,
  "usage_daily": 0.1,
  "usage_monthly": 0.5,
  "usage_weekly": 0.3,
  "workspace_id": "0df9e665-d932-5740-b2c7-b52af166bc11"
}
```
