# OpenRouter Provider Route & Price Change Monitor (`maydit/openrouter-provider-route-monitor`) Actor

Compare OpenRouter provider-route prices, context limits and supported parameters for a model watchlist. Optional saved changes and workload cost estimates. Public metadata; no inference.

- **URL**: https://apify.com/maydit/openrouter-provider-route-monitor.md
- **Developed by:** [Brandt May](https://apify.com/maydit) (community)
- **Categories:** Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.80 / 1,000 provider route observations

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

![Compare routes behind the same model — illustrative provider metadata table](https://api.apify.com/v2/key-value-stores/nemaYfVcrTgloz8Wn/records/openrouter-provider-route-monitor-2359c931acf2.png?signature=1GgIhGENYG7ZD8RsSDC1S)

### Compare routes behind the same model

Review the public provider routes available for an OpenRouter model before choosing which configurations deserve a closer look. Collect advertised token prices, context and completion limits, quantization and supported parameter names. Add a token scenario to compare base costs, then save observations for later change reviews.

**One result is one provider route.** Endpoint tags keep regional routes distinct even when provider names match. The Actor reads metadata and sends no inference requests.

[Open in Console](https://console.apify.com/actors/4BSug3CtQs9IV54io/input) · [First run](#try-one-model) · [Output preview](#output-preview) · [Saved comparisons](#keep-a-route-change-log) · [Pricing](#pricing)

### Try one model

This example checks GPT-4o mini's public routes, compares the advertised `tools` parameter, and calculates a base scenario for one million input and 250,000 output tokens. It saves at most 20 route rows; route counts can change.

```json
{
  "modelIds": [
    "openai/gpt-4o-mini"
  ],
  "requiredParameters": [
    "tools"
  ],
  "inputTokens": 1000000,
  "outputTokens": 250000,
  "maxResults": 20
}
```

Open the **Dataset** to compare routes and **Run report** to check scope. No API key is required for the public endpoint used by this Actor. Set an Apify maximum total charge before a run. Empty input also checks GPT-4o mini, using the default token scenario.

### Output preview

| Comparison | Fields | How to read them |
| --- | --- | --- |
| Route identity | `modelId`, `endpointTag`, `providerName`, `endpointName` | Use model ID plus endpoint tag; provider name alone is not unique |
| Published token prices | `promptUsdPerMillionTokens`, `completionUsdPerMillionTokens` | Source per-token prices multiplied by one million |
| Your base scenario | `estimatedBaseTokenCostUsd`, `costScenario` | Prompt price × input tokens + completion price × output tokens |
| Token limits | `contextLength`, `maxCompletionTokens`, `maxPromptTokens` | Explicit advertised limits; optional unknown limits stay null |
| Advertised capabilities | `supportedParameters`, `missingParameters`, `meetsRequestedParameters` | Exact parameter-name comparison; routes remain in the output even when requirements are missing |
| Saved changes | `comparisonStatus`, `changedFields`, `previous`, `previousObservedAt` | Differences from the last saved configuration |
| Evidence | `sourceUrl`, `observedAt`, `contentHash` | Public endpoint, observation time and snapshot hash |

`pricingRaw` preserves all returned primitive price fields as normalized decimal/exponent strings, retaining their source units. `inputCacheReadUsdPerMillionTokens` is populated when published. JSON preserves nested prices and prior values; CSV is useful for selected columns.

The base estimate excludes caching, request/tool/media charges, tier or long-context pricing, discounts, credit fees and taxes. It is not a quote or invoice. Advertised support does not prove a request will succeed; the Actor does not infer support from separate flags, measure performance, or test account eligibility.

### Compare a defined GPT-4o workload

```json
{
  "modelIds": [
    "openai/gpt-4o"
  ],
  "inputTokens": 2000000,
  "outputTokens": 500000,
  "maxResults": 20
}
```

### Inspect Llama provider and regional routes

```json
{
  "modelIds": [
    "meta-llama/llama-3.3-70b-instruct"
  ],
  "requiredParameters": [
    "tools"
  ],
  "maxResults": 30
}
```

### Keep a route change log

1. Choose an exact model watchlist. Add `comparePrevious: true` and a dedicated `snapshotName` to its input.
2. Run once to save `new` route observations. Keep the same watchlist, snapshot name and history store on repeats; they return `changed` or `unchanged` rows with prior values.
3. Add `onlyChanges: true` to omit unchanged rows. It also enables comparison. A fully unchanged repeat correctly saves zero rows.
4. In Sheets, Make or n8n, read the completed run's SUMMARY and dataset before upserting by `modelId + "|" + endpointTag`. Keep the run ID for replay and deduplicate using the identity plus `contentHash`.

The snapshot covers model ID, endpoint tag, provider name, prices, token limits, quantization and supported parameters. Publisher status, uptime, latency and throughput remain contextual fields and are excluded from comparisons. Token scenarios and required-parameter checks are also excluded: changing only these settings does not create a source change. Disable changes-only mode when you need freshly calculated scenario rows.

History uses the exact sorted watchlist and snapshot namespace. Only confirmed saved rows advance history; failed, unsaved or unchanged-skipped rows preserve the baseline. Missing routes never produce removal instructions. Run **one writer per scope**: a precommit conflict check is not an atomic lock. Inspect `historyUpdated` and `failedSources.history` before relying on a baseline. Scheduling, alerts and downstream connections are configured by you; the Actor does not buy credits or change your routing.

### Coverage and limits

- Up to 20 models, 300 returned routes per model, 1,000 saved rows and 2 MiB per response. The entire returned list is validated before that model's rows are saved. Identical duplicate tags collapse; conflicting tags fail the model.
- A valid empty route list can succeed without explaining why routes are absent. A result cap is a bounded sample, not a complete route check.
- Requests are sequential, public and unauthenticated, confined to the model endpoint path. One retry is allowed for 502/503/504 within the deadline; access and rate refusals are not bypassed.
- Anonymous access is an upstream dependency. The endpoint worked without a key during preparation, while the reference also shows authenticated examples. If access changes, the run reports it without substituting another source.
- The run budget defaults to 240 seconds and respects the platform deadline minus 25 seconds. SUMMARY records source coverage, unreached models, failures, unchanged skips and spending/time/result stops.

Errors never become paid rows. Source, time and history failures are partial or failed; all-source failure fails the run. Saved comparisons represent observations at your run times, not a continuous record of every route change.

### Pricing

Base result rate on the FREE tier: **$3 per 1,000 saved provider-route observations**, plus the listed **Actor Start** charge. The [Pricing tab](https://apify.com/maydit/openrouter-provider-route-monitor/pricing) is authoritative for your plan's current rates. Saved unchanged rows are billable; changes-only skips create no dataset-item charge. Platform and storage charges may apply under your plan.

### Sources and support

[Model endpoint reference](https://openrouter.ai/docs/api/api-reference/endpoints/list-all-endpoints-for-a-model) · [Model overview and public catalog](https://openrouter.ai/docs/guides/overview/models) · [OpenRouter pricing](https://openrouter.ai/pricing)

OpenRouter's public API and release feeds are free alternatives. This community Actor adds bounded watchlists, saved field comparisons, base token scenarios and Apify exports. It is not an OpenRouter service.

Open **Issues** with the run URL, model ID and expected field, or contact **bmay@mayd-it.com**. Remove credentials and private information before posting.

# Actor input Schema

## `modelIds` (type: `array`):

Up to 20 exact namespace/model identifiers. Omitted or empty uses the listed sample. No URLs, credentials or private models.

## `requiredParameters` (type: `array`):

Up to 20 names, for example tools or response_format. Adds missingParameters and meetsRequestedParameters; does not remove routes or test actual inference.

## `inputTokens` (type: `integer`):

Base estimate uses published per-token prompt price. No request is sent for inference.

## `outputTokens` (type: `integer`):

Base estimate uses published per-token completion price. This is not a quote or invoice.

## `maxResults` (type: `integer`):

Maximum confirmed dataset rows. An unchanged observation skipped by onlyChanges does not use this limit. A capped run can leave selected models/routes unreached; see SUMMARY.

## `comparePrevious` (type: `boolean`):

First observations are new. Later observations are changed or unchanged; only confirmed saved rows can advance history.

## `onlyChanges` (type: `boolean`):

Implies comparePrevious. A fully unchanged run correctly saves zero rows. The initial comparison saves new observations.

## `snapshotName` (type: `string`):

1-80 letters, numbers, underscores or hyphens. History also includes the exact sorted model watchlist. Use one writer per namespace; overlapping runs are unsupported.

## `stateStoreName` (type: `string`):

3-63 letters, numbers or hyphens. Read/written only when comparisons are requested. Use your own dedicated store to isolate a workflow.

## `maxRunSeconds` (type: `integer`):

Includes source and history work, also bounded by the platform deadline minus 25 seconds.

## Actor input object example

```json
{
  "modelIds": [
    "openai/gpt-4o-mini"
  ],
  "requiredParameters": [
    "tools"
  ],
  "inputTokens": 1000000,
  "outputTokens": 1000000,
  "maxResults": 10,
  "comparePrevious": false,
  "onlyChanges": false,
  "snapshotName": "default",
  "stateStoreName": "maydit-openrouter-route-watchlists",
  "maxRunSeconds": 240
}
```

# Actor output Schema

## `results` (type: `string`):

Successful public metadata observations only. Failures are never synthetic paid rows.

## `runReport` (type: `string`):

Readable coverage, limits and history outcome from this run.

## `summary` (type: `string`):

Saved/observed counts, failed sources, unreached models and time/spending stops.

## `csvExport` (type: `string`):

Download the current run observations for spreadsheets.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "modelIds": [
        "openai/gpt-4o-mini"
    ],
    "requiredParameters": [
        "tools"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("maydit/openrouter-provider-route-monitor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "modelIds": ["openai/gpt-4o-mini"],
    "requiredParameters": ["tools"],
}

# Run the Actor and wait for it to finish
run = client.actor("maydit/openrouter-provider-route-monitor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "modelIds": [
    "openai/gpt-4o-mini"
  ],
  "requiredParameters": [
    "tools"
  ]
}' |
apify call maydit/openrouter-provider-route-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,maydit/openrouter-provider-route-monitor"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/4BSug3CtQs9IV54io/builds/DmDoKuwicGBTQgLJF/openapi.json
