OpenRouter for Agents - Tools & Fallbacks
Pricing
from $3.00 / 1,000 successful agent calls
OpenRouter for Agents - Tools & Fallbacks
Call OpenRouter with full chat messages, custom tools, validated JSON and model fallbacks. No provider keys. Gateway: $0.01/run + $0.003 per usable response; model usage is billed separately.
Pricing
from $3.00 / 1,000 successful agent calls
Rating
0.0
(0)
Developer
Vadim Bezrukov
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
Call OpenRouter models from AI agents using full chat messages, custom tools, structured JSON and model fallbacks - no separate provider API keys.
This Actor is a bounded OpenAI-style LLM invocation primitive for n8n, Make, backend automations and other Apify Actors. It is not a generic agent framework and it does not execute tools.
What this Actor solves
Agent workflows need a reliable chat-completions call with:
- the original
messages[](not a collapsed prompt); - caller-defined
tools[]; - structured JSON (
json_object/json_schema); - OpenRouter native
models[]fallback; - one Dataset row per request, with explicit SUCCESS / FAILED / PARTIAL.
Authentication is the Apify runtime token. You do not need an OpenRouter account or provider keys. Model usage is billed to your Apify account through the official apify/openrouter proxy; this Actor charges a small orchestration event on top.
Why use it instead of a basic OpenRouter wrapper
| Alternative | What it does | Gap |
|---|---|---|
apify/openrouter | Standby OpenAI-compatible proxy | Only callable as APIFY_ACTOR; no Dataset batch contract |
watchful_yotar/openrouter-wrapper | Single prompt string | No messages[], no custom tools, no fallback chain |
fayoussef/bulk-llm-runner | Bulk prompt / spreadsheet generation | Content-generation workflow, not an agent tool-call primitive |
Use this Actor when the caller is a machine that must send conversation state, tool schemas and fallbacks, then decide the next step from tool_calls or structured_output.
Agent / tool-call example
{"requests": [{"id": "req-1","model": "openai/gpt-4o-mini","messages": [{ "role": "user", "content": "Find the weather for Belgrade" }],"tools": [{"type": "function","function": {"name": "get_weather","description": "Get current weather","parameters": {"type": "object","properties": { "city": { "type": "string" } },"required": ["city"],"additionalProperties": false}}}],"toolChoice": "auto","maxTokens": 256,"provider": { "requireParameters": true }}]}
Typical Dataset row when the model requests a tool:
{"id": "req-1","status": "SUCCESS","model_requested": "openai/gpt-4o-mini","model_used": "openai/gpt-4o-mini","fallback_used": false,"assistant_message": { "role": "assistant", "content": null },"tool_calls": [{"id": "call_123","type": "function","name": "get_weather","arguments": { "city": "Belgrade" },"arguments_valid": true}],"finish_reason": "tool_calls"}
Execute get_weather in your workflow, then send a follow-up request with a role=tool message. This Actor stops after returning the model response.
Input
Only requests (1–25 items). Each item:
| Field | Purpose |
|---|---|
id | Stable caller id, returned on the Dataset row |
model or models[] | Primary model and/or ordered fallback chain |
messages | Full conversation (1–40 turns). Roles: system, user, assistant, tool, developer |
tools | Up to 32 OpenAI function tools |
toolChoice | auto / none / required. The Input Schema stores those strings. A function object is accepted by the local runtime only. |
responseFormat | omit, json_object, or json_schema |
maxTokens | 1-8192, default 2048 when omitted. One upstream call waits at most 90 s; a slower generation is TIMEOUT and is not retried |
provider.requireParameters | Prefer endpoints that support the requested tools/schema |
Cross-field rules the Input Schema cannot express: every item needs model or a non-empty models list. Blank message text is INVALID_INPUT and is not sent upstream; an assistant turn may omit content when it carries toolCalls. Duplicate ids fail only the later items.
Default Console prefill asks openai/gpt-4o-mini to reply ping with maxTokens=32. Expect one SUCCESS row and a RUN_SUMMARY within five minutes.
Output
One Dataset row per input request, plus RUN_SUMMARY and BILLING_RECEIPT in the Key-Value Store.
| Field | Meaning |
|---|---|
status | SUCCESS, FAILED or PARTIAL |
model_requested / model_used / fallback_used | Fallback reporting |
assistant_message | Assistant turn; content may be null on tool calls |
tool_calls | Normalized function calls; malformed JSON arguments are not coerced to {} |
structured_output | Parsed JSON when a response format was requested and valid |
error.code | INVALID_INPUT, UNSUPPORTED_MODEL, RATE_LIMIT, AUTH_FAILED, UPSTREAM_4XX, UPSTREAM_5XX, TIMEOUT, DEADLINE_EXCEEDED, MALFORMED_UPSTREAM, STRUCTURED_OUTPUT_INVALID, … |
fingerprint | SHA-256 over semantic fields |
PARTIAL means useful text or a valid tool call was retained, but another part failed validation or the response was truncated. Inspect error before using it. Empty, refused, reasoning-only, and wholly malformed tool responses are uncharged FAILED. A batch containing any partial row has a PARTIAL run summary.
Model fallback
OpenRouter performs fallback. This Actor does not retry across models itself.
modelonly: no fallback chainmodelsonly: first id is primary, the rest are fallbacksmodel+models: primary plus extra fallbacks
fallback_used is true when model_used differs from the first requested model. Transport retries (429/5xx/connection errors) are a separate mechanism.
OpenRouter rejects an unknown model id before it consults models[]. An unknown id in the fallback list is removed and the same request is sent again without it. An unknown primary model stays UNSUPPORTED_MODEL with fallback_used: false and is not replaced or charged.
Structured output
- Plain text: omit
responseFormat json_object: parse assistant content as a JSON objectjson_schema: pass the caller schema upstream and validate the result
Local validation uses JSON Schema Draft 2020-12, including numeric/string bounds, unions and closed objects. Schemas must be self-contained: $ref, $dynamicRef, $recursiveRef and $id are rejected before the model call, so schema validation cannot fetch a URL or file. format remains a JSON Schema annotation; it is not a semantic validator for dates, email addresses or business facts. Nesting is limited to 32 schema levels. Returned JSON and tool arguments must contain finite numbers and stay within 64 data nesting levels; rejected structured output remains explicit rather than being silently changed.
When tools or a response format are present, the Actor sets provider.require_parameters=true unless you override it. Not every model/provider supports tools plus strict schema together; capability errors are returned as UNSUPPORTED_PARAMETER, never as an empty success.
Batch / API usage
from apify_client import ApifyClientclient = ApifyClient("<YOUR_API_TOKEN>")run = client.actor("automa-flow/openrouter-agent-gateway").call(run_input={"requests": [{"id": "req-1","model": "openai/gpt-4o-mini","messages": [{"role": "user", "content": "Reply with exactly: ping"}],"maxTokens": 32,}]},timeout_secs=300,memory_mbytes=256,)for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["id"], item["status"], item.get("assistant_message"))
Schedule the same batch after a new user message, a tool result, or a new project. A copy-pasteable webhook target is the Apify Dataset items URL from RUN_SUMMARY.datasetItemsUrl.
Set maxTotalChargeUsd on the run (minimum $0.013 for gateway start + one successful call). This limit covers gateway events only, not nested OpenRouter charges. Completed rows stay in the Dataset if the budget later runs out; skipped work is FAILED with BUDGET_EXCEEDED.
MCP / AI-agent usage
Direct Actor tool: https://mcp.apify.com?tools=automa-flow/openrouter-agent-gateway
Select this Actor when you need an OpenAI-compatible chat completion with custom tools, structured JSON, or model fallbacks, billed through Apify without provider keys.
Do not select it for scraping websites, executing tools, running an autonomous agent loop, bulk spreadsheet prompting, image generation, or streaming tokens.
Ask: “Call openai/gpt-4o-mini with this conversation and these tools; return tool_calls without executing them.”
allowsAgenticUsers is not claimed until live Store/API verification after deployment. The local contract is PPE-only, limited permissions, non-Standby.
Pricing
Two layers, both on the caller's Apify account:
- Gateway (this Actor, fixed 256 MB):
apify-actor-start$0.01 +agent-call-success$0.003 per SUCCESS or PARTIAL request. Failed requests are not charged. Extra transport attempts are not extra gateway events. - Model usage: nested
apify/openrouteropenrouter-api-usageat OpenRouter rates. Each upstream POST can incur that charge, including a 429/5xx/connection-error retry (up to 3 attempts) and a nativemodels[]fallback. A timed-out generation is sent once and never retried. Gateway PPE does not cover those nested charges.
Gateway prices include this Actor's platform usage. Model usage is separate. At the supported 256 MB, the start event is charged once. A single successful request costs $0.013, 10 requests in one run $0.040, and 25 $0.085, plus model usage. 1,000 calls cost $3.40 when packed into 40 full batches, or $13 in 1,000 separate runs.
The proxy rounds paid-user model usage up to $0.00001. FREE-plan users pay a 10x model-usage rate and have a 2048-output-token proxy limit. Proxy start events may also apply. Raw usage.cost is the upstream model observation, not an invoice. See the official proxy pricing.
Every request sets provider price ceilings of $10 per million input tokens, $30 per million output tokens, and $0 per-request fee. Providers above those ceilings are excluded, including in a fallback chain. Input is text-only and bounded to 32 KiB per request; completion tokens are always capped. These controls bound workload and provider rates. They are not an atomic dollar cap across nested proxy requests, retries, rounding and account charges. Use a funded account whose model spending policy you control; an autonomous agent must not treat maxTotalChargeUsd as the total account bill.
RUN_SUMMARY.gatewayChargedAmountUsd reports gateway start plus custom charges. The legacy chargedAmountUsd remains custom events only, with chargedAmountScope identifying that scope. nestedModelChargedAmountUsd stays null because the gateway does not reconcile the proxy invoice. observedModelUsageCostUsd sums only returned raw usage and may omit timed-out or lost responses.
Failure semantics
| Situation | Row status | Run |
|---|---|---|
| Valid completion | SUCCESS | SUCCEEDED |
| Completion with invalid JSON / malformed tool args | PARTIAL | SUCCEEDED |
| Item-level 400 / invalid input / duplicate id | FAILED | other items continue |
| 429 / 5xx / connection error | retry up to 3 attempts, then FAILED | fail the run only if every attempted call is auth/timeout/transport/5xx; each POST can still incur nested OpenRouter usage |
| No response within 90 s | FAILED TIMEOUT, sent once, not retried | other items continue; lower maxTokens or pick a faster model |
| Run timeout about to expire | FAILED DEADLINE_EXCEEDED: the call is cut short or not sent | the run still ends with RUN_SUMMARY; send fewer requests or lower maxTokens |
Missing APIFY_TOKEN, HTTP 401, or 403 access_denied | AUTH_FAILED | SOURCE_FAILED when every attempted call fails that way |
| Other 403 (content policy, geo, provider refusal) | FAILED UPSTREAM_4XX | other items continue |
HTTP errors never become empty successful LLM responses.
Run timeout
Requests run 4 at a time with a 120-second total batch work budget, including retries and fallback cleanup. Each upstream POST waits at most 90 seconds. Raising the platform timeout does not extend the work budget. The default platform timeout is 180 seconds at 256 MB.
The Actor also reserves 20 seconds before an earlier platform timeout to persist results and its summary. Requests cut short or not sent receive uncharged DEADLINE_EXCEEDED rows. Send smaller batches or lower maxTokens for slow models. Platform termination or storage outages can still prevent final summary delivery; the persisted delivery checkpoint prevents automatic double billing after a restart.
Limitations
- The Actor invokes LLMs and returns requested tool calls. It does not execute those tools or run an autonomous agent loop.
- No streaming in this version.
- No browser, proxy configuration, or arbitrary outbound URLs - only the official Apify OpenRouter endpoint.
- Tool + strict-schema support is model/provider dependent.
- Local/non-Actor HTTP to
openrouter.apify.actoris rejected (APIFY_ACTORonly). Call this Actor on Apify instead. - Nested OpenRouter usage cost is separate from the $0.003 gateway event.
Legal: user-controlled calls to an official Apify LLM proxy. Classification LOW. Do not put secrets in messages; error logs redact tokens and Authorization headers.