OpenAI API Pricing Scraper avatar

OpenAI API Pricing Scraper

Pricing

from $2.98 / 1,000 results

Go to Apify Store
OpenAI API Pricing Scraper

OpenAI API Pricing Scraper

Collects pricing tables from OpenAI’s public API documentation and returns records with model labels, sections, tiers, and available price fields. Includes input, cached input, output, and long-context rates; non-token prices are retained as notes instead of being converted.

Pricing

from $2.98 / 1,000 results

Rating

0.0

(0)

Developer

Axiom Works

Axiom Works

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

10 hours ago

Last modified

Categories

Share

OpenAI Pricing Scraper

Returns: one row per model price with model, tier, inputPer1M, cachedInputPer1M, outputPer1M, blendedPer1M, cachedDiscountPct, sourceUrl. Input: {"sections": ["Flagship models"], "tiers": ["Standard"], "maxItems": 20} Best for: LLM cost tables, OpenAI price-change monitoring, budgeting and model-routing tools.

{
"model": "gpt-6-astra",
"tier": "Standard",
"inputPer1M": 10,
"cachedInputPer1M": 1,
"outputPer1M": 50,
"blendedPer1M": 20,
"sourceUrl": "https://developers.openai.com/api/docs/pricing.md"
}

What does OpenAI Pricing Scraper do?

OpenAI Pricing Scraper reads the public OpenAI API pricing page and turns every price table into clean, structured records. Each record is one row of one table: a model, a processing tier and the prices that the page lists for it. You get the input price, the cached input price, the output price and, where the page lists them, the long-context rates and cache write price. Prices are returned as numbers in US dollars per 1M tokens, so you can load them straight into a spreadsheet, a database or a cost calculator without any manual cleanup.

The Actor reads the Markdown version of the pricing page. That is a single request, which makes a run fast and cheap and puts almost no load on the site. The parser does not depend on fixed column positions. It tracks the section headings (such as Flagship models or Finetuning) and the tier headings (Standard, Batch, Flex, Fast, Ultrafast), and it maps every column by the name in the table header. When the page adds a column or a model, the Actor picks it up. If no table can be parsed, the run succeeds with zero records and a status message asking you to report the changed source page. No error records are saved.

Typical uses:

  • Loading current model prices into an internal cost table from the numeric price fields.
  • Tracking price changes between runs by comparing the dataset of today with the dataset of last week.
  • Feeding a budgeting or routing tool that needs the current price per 1M tokens of each model.
  • Comparing the Standard and Batch tiers of the same model side by side.
  • Building a dashboard of model prices for a team that uses several OpenAI models.

This Actor is not affiliated with or endorsed by OpenAI. It reads a public page that needs no login.

What data can you get?

Every record has the fields below. Fields that a table does not contain are returned as null. For example, the Finetuning tables have a training price but no long-context columns, and the realtime tables have a modality column but no tier.

FieldTypeDescription
idstringStable 16-character hash of section, tier, model label, modality and category. No duplicates in a run.
sectionstringPricing page section, for example Flagship models or Finetuning.
tierstringStandard, Batch, Flex, Fast or Ultrafast. Null for tables without tiers.
modelstringModel name with context-length suffixes removed.
modelLabelstringModel name exactly as printed on the page.
categorystringCategory or use case column, used by the Specialized and Transcription tables.
modalitystringModality column (Audio, Text, Image) for realtime and image tables.
inputPer1MnumberInput price in USD per 1M tokens.
cachedInputPer1MnumberCached input price in USD per 1M tokens.
cacheWritePer1MnumberCache write price in USD per 1M tokens, when listed.
outputPer1MnumberOutput price in USD per 1M tokens.
longContextInputPer1MnumberInput price per 1M tokens above the long-context threshold.
longContextOutputPer1MnumberOutput price per 1M tokens above the long-context threshold.
longContextCachedInputPer1MnumberCached input rate per 1M tokens above the long-context threshold; null when absent.
longContextCacheWritePer1MnumberCache write rate per 1M tokens above the long-context threshold; null when absent.
blendedPer1MnumberInput and output price blended at a 3:1 input:output token mix, USD per 1M tokens. Null if either price is missing.
cachedDiscountPctnumberPercent saved by cached input versus regular input.
changeStatusstringOnly with trackChanges: baseline, new, changed or unchanged versus the previous tracked run.
previousInputPer1MnumberOnly with trackChanges: input price in the previous tracked run.
previousOutputPer1MnumberOnly with trackChanges: output price in the previous tracked run.
trainingstringFine-tuning training price as printed, for example per hour.
unitPricenumberPrice per priceUnit for rows not priced per 1M tokens (for example 0.006 per minute). Null for token-priced rows.
priceUnitstringUnit of unitPrice, such as minute or 1M characters.
priceNotestringRaw text of price cells that are not plain per-1M-token numbers, such as per minute or per character prices.
currencystringCurrency of all prices, always USD.
sourceUrlstringThe page the record was parsed from.
scrapedAtstringISO timestamp of the run.

Long-context cached input and cache write columns are returned separately from short-context rates. Only the seven selectable sections are extracted; tables in other sections, including Life sciences models, are excluded rather than assigned to the preceding section.

A dash on the page means the model has no such price, and the matching field is null. The word Free is returned as 0. Prices that are not per 1M tokens (per minute, per character, per hour) are never forced into the per-1M fields. The number and unit are also given in unitPrice and priceUnit, and the original text is kept in priceNote or training so no information is lost.

How to use

  1. Open the Actor in Apify Console and go to the Input tab.
  2. Pick one or more sections. The default is all sections.
  3. Optionally pick tiers, for example Standard and Batch, or leave the list empty to get all tiers.
  4. Optionally type a model filter such as gpt-5 or a regular expression such as ^gpt-4o.
  5. Set the maximum number of records and start the run.
  6. Open the Output tab or download the dataset as JSON, CSV, Excel or XML.

A run finishes in a few seconds because it needs one request. You can schedule it daily or weekly and compare datasets over time to see price changes.

If your filters match nothing, the run ends successfully with zero items. The final status tells you to clear modelFilter or set sections and tiers to empty lists. If requests stay blocked after bounded retries, the status asks you to retry later or enable Apify Proxy. No placeholder records are written.

Input

The optional trackChanges boolean (default false) stores each run's prices in a named key-value store. Set changeStoreName to keep separate histories for independent scheduled jobs; its default, openai-pricing-previous, preserves the existing history. Reusing a name shares that baseline across runs, so choose a different name when jobs should not affect each other. The first tracked run in a fresh store establishes a baseline. The next run with trackChanges set to true marks every row as new, changed or unchanged and adds the previous input and output prices.

FieldTypeDescription
sectionsarraySections to extract: Flagship models, Cyber models, Realtime and audio generation models, Image generation models, Transcription models, Specialized models, Finetuning. Default: all sections.
tiersarrayTiers to keep: Standard, Batch, Flex, Fast, Ultrafast. Empty means all. Tables without tier headings list one standard price, so they match Standard and are returned with a null tier.
modelFilterstringCase-insensitive substring or regular expression matched against the model name.
modalitiesarray of stringsExact source modality names, case-insensitive; empty includes all. A selection excludes null modality rows.
sortBystringsource (default), model, inputPer1M, outputPer1M, blendedPer1M or cachedInputPer1M. Ascending, null values last; applied before maxItems.
modelsarray of stringsExact model IDs or full model labels, matched without case sensitivity. Empty includes all models.
changeStoreNamestringHistory store used with trackChanges. Defaults to openai-pricing-previous.
maxItemsintegerMaximum total records across sections, tiers and model matches, 1 to 1000. Default 250. The Actor never returns more.
trackChangesbooleanCompare with the previous tracked run and add changeStatus. Default false.
proxyConfigurationobjectProxy settings. The default is no proxy because the page loads without one. Enable Apify Proxy if your requests get blocked.

Example input:

{
"sections": ["Flagship models", "Finetuning"],
"tiers": ["Standard", "Batch"],
"modelFilter": "gpt-4",
"maxItems": 40
}

For exact selection, use models: ["gpt-6-astra"]. This compares complete model IDs or complete modelLabel values without case sensitivity, so a short name cannot accidentally include similarly named models. Keep models empty for discovery, then copy IDs from the returned model field. Exact selection combines with the section, tier and regular expression filters: a row must satisfy every active filter. Unknown IDs return zero rows successfully. Clear models as well as modelFilter when broadening an empty search. This option uses the same public pricing document and does not add network requests.

For modality-specific comparisons, set modalities to ["Audio"] or ["Text"] and select the relevant realtime or image section. Values match the source modality exactly, ignoring case. A row without a modality is excluded when this filter is active, so a flagship text model with a null modality will not match Text. Empty lists retain the existing behavior and include all rows. The filter combines with every other selection; it does not infer a modality from the model name.

Use sortBy: "inputPer1M" or sortBy: "outputPer1M" to select the cheapest matching token rates before applying maxItems. Numeric sorting is ascending and puts missing prices last. blendedPer1M uses the existing fixed 3:1 input-to-output mix; it is not a personalized workload estimate. cachedInputPer1M helps compare listed cache-hit rates. model sorts names alphabetically, while the default source keeps the original page order. Sorting does not change the fields, prices, record IDs or network request count. Ties keep their source order. Non-token unit prices remain separate and are not compared with per-token prices.

Output

Each dataset item is one price row. Example item from the Flagship models section, Standard tier:

{
"id": "67e58a240804cab4",
"section": "Flagship models",
"tier": "Standard",
"model": "gpt-6-astra",
"modelLabel": "gpt-6-astra",
"category": null,
"modality": null,
"inputPer1M": 10,
"cachedInputPer1M": 1,
"cacheWritePer1M": 12.5,
"outputPer1M": 50,
"longContextInputPer1M": 20,
"longContextOutputPer1M": 75,
"blendedPer1M": 20,
"cachedDiscountPct": 90,
"changeStatus": null,
"previousInputPer1M": null,
"previousOutputPer1M": null,
"training": null,
"priceNote": null,
"unitPrice": null,
"priceUnit": null,
"currency": "USD",
"sourceUrl": "https://developers.openai.com/api/docs/pricing.md",
"scrapedAt": "2026-10-13T02:36:13.787Z"
}

An item from a model that has a context-length note on the page keeps the raw text in modelLabel and the cleaned name in model:

{
"section": "Flagship models",
"tier": "Standard",
"model": "gpt-5.5",
"modelLabel": "gpt-5.5 (<272K context length)",
"inputPer1M": 5,
"cachedInputPer1M": 0.5,
"outputPer1M": 30,
"longContextInputPer1M": 10,
"longContextOutputPer1M": 45
}

The dataset has an Overview view that shows the most useful columns: section, tier, model, modality, the input, cached input and output prices, the long-context prices, currency, source URL and scrape time.

How much does it cost?

The Actor is charged per result, which means per price record in the dataset. A typical run with the default settings returns a few dozen records. See the Pricing tab of the Actor for the current rate. Because the Actor makes one request per run, the platform usage of a run is very small. You control the total cost with the maxItems input: the Actor stops exactly at that number and never charges for more.

Use with AI agents (MCP)

You can call this Actor from any MCP-compatible assistant through the Apify MCP server. Add the Actor to your client configuration:

{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com/?tools=axiomworks/openai-pricing-scraper"
}
}
}

Example prompts:

  • "Get the Standard and Batch prices of the flagship OpenAI models and tell me which has the cheapest output price per 1M tokens."
  • "List the image generation models and their input and output prices."
  • "Which fine-tunable models have a training price listed, and what is it?"
  • "Find all models whose name contains gpt-5 and compare their cached input prices."

Integrations and API

You can start the Actor from code, from a schedule or from automation tools such as Make, Zapier or n8n, and read the dataset through the Apify API.

Python:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("axiomworks/openai-pricing-scraper").call(run_input={
"sections": ["Flagship models"],
"tiers": ["Standard"],
"maxItems": 20,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item["model"], item["inputPer1M"], item["outputPer1M"])

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('axiomworks/openai-pricing-scraper').call({
sections: ['Flagship models'],
tiers: ['Standard'],
maxItems: 20,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => process.stdout.write(`${item.model} ${item.inputPer1M}\n`));

cURL:

curl -X POST "https://api.apify.com/v2/acts/axiomworks~openai-pricing-scraper/run-sync-get-dataset-items" \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"sections": ["Flagship models"], "tiers": ["Standard"], "maxItems": 20}'

FAQ

Which models are included? Every model that appears in a table of the selected sections on the pricing page at the time of the run. That includes models that are listed but not yet widely available, because the Actor reports what the page shows.

Why are some price fields null? Either the page shows a dash for that model, or the table has no such column. Long-context prices only exist for some flagship models, and Finetuning tables have a training price instead.

What does priceNote contain? Some rows, such as transcription by the minute or text to speech by the character, are not priced per 1M tokens. The raw text of those cells is kept in priceNote so you can still use it.

Why does a model appear several times? The same model can have several rows: one per tier (Standard, Batch and so on) and, for image and realtime models, one per modality. Use the tier and modality fields to tell them apart.

Why do I get no results when I pick a tier? Tables without tier headings have a null tier. They match Standard, and they are also included when the tier list is empty. Clear tiers to include every table in your selected sections.

How up to date is the data? The Actor reads the live page on every run. scrapedAt tells you when that happened.

What happens if the page layout changes? Columns are matched by header name, so added columns and models are handled. If no table can be parsed at all, the run succeeds with zero records and a status message asking you to report the page layout change.

Does it need a proxy? No. The page is public and loads without one. A proxy option is available if you run into blocks.

The Actor reads one public page that needs no login and contains no personal data. It sends a single request per run, which keeps the load on the site minimal. Prices are factual information. You remain responsible for how you use the data, and you should check the terms of the site and the rules that apply to you. This Actor is an independent tool and is not affiliated with OpenAI. Nothing here is legal advice.

Feedback

If a table is parsed wrongly, a section is missing or you need an extra field, open an issue from the Actor page in Apify Console, including the section and model concerned. Reports with an example row from the pricing page are the fastest to fix.