# Get a Branded Food Source: https://data-docs.orbbit.co/api-reference/branded-food/get-a-branded-food /api-reference/openapi.json get /v1/branded-foods/{id} Get everything we have on one packaged food product.. Requires the `get-branded-foods` scope. # List Branded Food Categories Source: https://data-docs.orbbit.co/api-reference/branded-food/list-branded-food-categories /api-reference/openapi.json get /v1/branded-foods/categories List every food category you can search within.. Requires the `search-branded-foods` scope. # Search Branded Foods Source: https://data-docs.orbbit.co/api-reference/branded-food/search-branded-foods /api-reference/openapi.json get /v1/branded-foods Search for packaged food products by name, brand, category, barcode, or ingredient.. Requires the `search-branded-foods` scope. # Get Commodity Metric Values Source: https://data-docs.orbbit.co/api-reference/commodities/get-commodity-metric-values /api-reference/openapi.json get /v1/commodities/metric-values Get the values over time for the series you choose, each described in the same four layers.. Requires the `get-commodity-prices` scope. # List Commodities Source: https://data-docs.orbbit.co/api-reference/commodities/list-commodities /api-reference/openapi.json get /v1/commodities List the price series we track, like butter or corn, narrowed by category and commodity, attributes, market and series.. Requires the `search-commodities` scope. # API Reference Source: https://data-docs.orbbit.co/api-reference/introduction The base URL, authentication, and conventions shared by every Orbbit Data API endpoint. Every endpoint below is listed with its parameters, example responses, and a **Try it** button that sends a real request from your browser. For what each data set means and why it's useful, see the **Documentation** tab. ## Base URL All requests go to: ```text theme={null} https://data-api.orbbit.co ``` ## Authentication Send your API key in the `Authorization` header on every request: ```bash theme={null} --header 'authorization: Bearer YOUR_API_KEY' ``` Each endpoint needs its own scope on the key. See [Authentication](/authentication) for how to create a key and choose its scopes. ## Pricing Every successful call to a paid endpoint is charged to your balance, including calls sent with **Try it**. Two endpoints are free. See [Pricing & Billing](/pricing) for the price of each endpoint. ## Versions The version is part of the path. Every endpoint starts with `/v1`. ## Requests and responses * Every endpoint is a `GET` and only reads data. * Responses are JSON with `snake_case` field names. A single record comes back as `{ "data": { ... } }`, a list as `{ "data": [ ... ] }`. * Lists that can be long return one page at a time with a `next_cursor`. Pass it back as `cursor` to get the next page; `null` means you have them all. * Every error has the same shape, `{ "error": { "type", "message" } }`. See [Errors](/errors). ## Endpoints | Section | Name | Endpoint | Scope | Price | | - | - | - | - | - | | Commodities | [List Commodities](/api-reference/commodities/list-commodities) | `GET /v1/commodities` | `search-commodities` | Free | | Commodities | [Get Commodity Metric Values](/api-reference/commodities/get-commodity-metric-values) | `GET /v1/commodities/metric-values` | `get-commodity-prices` | \$0.01 | | CPG › Branded Food | [Search Branded Foods](/api-reference/branded-food/search-branded-foods) | `GET /v1/branded-foods` | `search-branded-foods` | \$0.01 | | CPG › Branded Food | [List Branded Food Categories](/api-reference/branded-food/list-branded-food-categories) | `GET /v1/branded-foods/categories` | `search-branded-foods` | Free | | CPG › Branded Food | [Get a Branded Food](/api-reference/branded-food/get-a-branded-food) | `GET /v1/branded-foods/{id}` | `get-branded-foods` | \$0.01 | # Authentication Source: https://data-docs.orbbit.co/authentication Create an API key, choose what it may call, and send it with every request. Send your API key in the `Authorization` header of every request: ```bash theme={null} curl --request GET \ --url https://data-api.orbbit.co/v1/commodities \ --header 'authorization: Bearer orbbit_data_YOUR_KEY' ``` A key is the text `orbbit_data_` followed by 64 letters and digits. Keep it secret: anyone holding it can call the API as you. An agent with its own crypto wallet can instead call without a key and pay per call in USDC. See [Pay With x402](/for-agents/x402). ## Your Default key Every new account comes with one key already made, named **Default**. It can call every endpoint, including ones added later, and may spend up to \$5 a month. To copy it, open **API Keys**, find **Default**, and click **Reveal Secret**. Unlike other keys, you can reveal it again at any time. Use it to try the API. For anything that runs unattended, create a key of its own with only the scopes it needs. ## Create a key 1. Sign in to the Orbbit console and open **API Keys**. 2. Click **New Key**. 3. Under **Name**, give the key a name you'll recognize later, such as `cost-dashboard-prod`. 4. Under **Spend budget (USD)**, set the most this key may spend in a month. Once it has spent that much, its calls are refused with `402` until the next calendar month starts (in UTC), even if your balance has money left. 5. Under **Scope**, tick the endpoints the key may call. A key can only call the endpoints you tick. 6. Click **Create**, then copy the key from the **Save your key** window. > [!WARNING] > > The console shows the full key only once. Orbbit stores a one-way fingerprint of it, not the key itself, so nobody, including Orbbit, can show it to you again. If you lose it, revoke it and create a new one. The key list shows the last four characters of each key so you can tell them apart. ## Choose what a key may call Each endpoint needs its own permission, called a scope. Give each key only the scopes it needs: a leaked key that can only search branded foods can do far less harm than one that can call everything. | Scope | Lets the key call | | - | - | | `search-commodities` | [`GET /v1/commodities`](/api-reference/commodities/list-commodities) | | `get-commodity-prices` | [`GET /v1/commodities/metric-values`](/api-reference/commodities/get-commodity-metric-values) | | `search-branded-foods` | [`GET /v1/branded-foods`](/api-reference/branded-food/search-branded-foods) and [`GET /v1/branded-foods/categories`](/api-reference/branded-food/list-branded-food-categories) | | `get-branded-foods` | [`GET /v1/branded-foods/{id}`](/api-reference/branded-food/get-a-branded-food) | The console labels each scope in plain words. For example, `get-commodity-prices` shows as **Get Commodity Metric Values**. You can change a key's name, budget, and scopes at any time from **API Keys**. The key itself stays the same. ## When a key is refused | Status | `error.type` | Why | What to do | | - | - | - | - | | `401` | `unauthorized` | The header is malformed, or the key is unknown or revoked. | Check the header reads `Bearer ` followed by the full key. | | `402` | `insufficient_balance` | Your balance, or this key's monthly spend budget, can't cover the call. | Top up on **Balance**, or raise the key's budget. See [Pricing & Billing](/pricing). | | `403` | `forbidden` | The key is valid but does not have this endpoint's scope. | Add the scope to the key in the console. | ```json 403 Missing scope theme={null} { "error": { "type": "forbidden", "message": "This key is not scoped to get-commodity-prices" } } ``` See [Errors](/errors) for every error the API returns. ## Revoke a key Open **API Keys**, find the key by its name and last four characters, and click **Revoke**. Requests using it are refused with `401` straight away. Revoking cannot be undone. ## Keep keys safe * Call the API from your server, never from a browser or mobile app, where anyone can read the key. * Store keys in a secrets manager or environment variable, not in source code. * Use a separate key for each app and environment, so you can revoke one without breaking the others. # Errors Source: https://data-docs.orbbit.co/errors Every error the API returns, in one shape, with what caused it and what to do. Every error, on every endpoint, has the same shape: a status code and a JSON body with an `error` object. For example, asking for a series that doesn't exist: ```bash theme={null} curl --request GET \ --url 'https://data-api.orbbit.co/v1/commodities/metric-values?metric_names=cheddar_close' \ --header 'authorization: Bearer YOUR_API_KEY' ``` ```json 400 Unknown metric theme={null} { "error": { "type": "invalid_request", "message": "Unknown metrics: cheddar_close" } } ``` | Field | Type | Description | | - | - | - | | `error.type` | string | A stable, machine-readable name for the kind of error. Branch on this. | | `error.message` | string | A human-readable explanation. Log it or show it to a developer, but don't parse it, because the wording can change. | ## Error types | Status | `error.type` | What happened | What to do | | - | - | - | - | | `400` | `invalid_request` | A parameter is missing, the wrong type, or out of range. | Fix the request. The message names the parameter. | | `401` | `unauthorized` | The API key is malformed, unknown, or revoked. | Send `Authorization: Bearer ` with a live key. | | `402` | `insufficient_balance` | Paid calls only. Your balance can't cover the call (`Insufficient balance`), or this key has used up its monthly spend budget (`Monthly spend cap reached`). Refused calls are not charged. | Top up on **Balance** or turn on auto-recharge, or raise the key's budget. See [Pricing & Billing](/pricing). | | `402` | `payment_required` | A paid call with no API key and no valid wallet payment. The body is the x402 price quote, not the `error` object above. Nothing was charged. | Pay with x402, or send an API key. See [Pay With x402](/for-agents/x402). | | `403` | `forbidden` | The key is valid but lacks this endpoint's scope. | Add the scope in the console. See [Authentication](/authentication#choose-what-a-key-may-call). | | `404` | `not_found` | No record has the ID in the path. | Check the ID came from a search result. | | `429` | `rate_limited` | Calls without an API key only. More than 60 calls in a minute from one IP address. | Wait and try again, or send an API key. | | `503` | `service_unavailable` | Wallet payments only. The payment service for the chosen network could not be reached. Nothing was charged. | Retry, or pay on the other network. | | Other `5xx` | `internal` | Something went wrong on Orbbit's side. The message is always `An unexpected error occurred`. | Retry with exponential backoff. If it persists, contact support. | ## Common 400 errors | Endpoint | Message | Cause | | - | - | - | | `GET /v1/commodities/metric-values` | `Unknown metrics: ` | A name in `metric_names` or `ids` doesn't exist. Get valid names from `GET /v1/commodities`. | | Any endpoint | `query: Unrecognized key: ""` | The call sends a parameter the endpoint doesn't take, such as the older `metrics`, `from` or `to`. `GET /v1/commodities/metric-values` takes `metric_names`, `ids`, `start_date` and `end_date`. | | `GET /v1/commodities/metric-values` | `This call would return prices, more than 50000; …` | The series and dates asked for hold more than 50,000 values. Narrow `start_date` and `end_date`, or ask for fewer series. | | `GET /v1/commodities/metric-values` | `metric_names: give ids or metric_names` | Neither `metric_names` nor `ids` was sent. | | `GET /v1/commodities` | `Unknown attribute words: ` | An `attributes[]` filter names a word no product has. | | `GET /v1/commodities` | `Unknown category ; category is one of …` | `category` is not one of `dairy`, `poultry`, `meat`, `grains`, `fruits` or `vegetables`. | | `GET /v1/commodities/metric-values` | None | More than 100 series are named, a date is not a real `YYYY-MM-DD` day, or `start_date` is later than `end_date`. | | `GET /v1/commodities` | `limit: Too big: expected number to be <=500` | `limit` is above 500. | | `GET /v1/branded-foods` | `at most 200 per page` | `limit` is above 200. | | Any endpoint with `limit` | None | `limit` is not a whole number of at least 1. | ## Retrying Retry only `5xx` errors, and `429` once the minute is up. Every other error will fail again until you change the request, or, for `402`, until you add balance. Every endpoint only reads data, so retrying a request never changes anything. ```python Python theme={null} import random, time, requests def get_with_retry(url, headers, params=None, attempts=5): for attempt in range(attempts): response = requests.get(url, headers=headers, params=params) if response.status_code < 500: return response time.sleep(min(2 ** attempt, 30) + random.random()) return response ``` # Data MCP Source: https://data-docs.orbbit.co/for-agents/data-mcp Connect Orbbit Data to an AI assistant through MCP. Orbbit Data has its own connector, so you can ask an AI assistant for commodity and branded-food data in plain words. The assistant picks the right tool, calls it with your account, and answers from the result. It uses MCP (Model Context Protocol), the standard way AI tools plug into outside sources. This is a different connector from the [Docs MCP](/for-agents/docs-mcp): that one lets an assistant read these pages, while this one fetches Orbbit's data. Connector address: `https://data-api.orbbit.co/mcp` Your console's **MCP** page shows the same address with a copy button. ## Claude (web, desktop, mobile) See [Use With Claude](/for-agents/use-with-claude) for step-by-step instructions with a screenshot. ## Claude Code > [tab] Sign in > > Run this, then sign in to Orbbit and click **Allow** when your browser opens: > > ```bash theme={null} > claude mcp add --transport http orbbit-data https://data-api.orbbit.co/mcp > ``` > [tab] API key > > Connect with one of your [API keys](/authentication) instead of signing in: > > ```bash theme={null} > claude mcp add --transport http orbbit-data https://data-api.orbbit.co/mcp \ > --header "Authorization: Bearer orbbit_data_YOUR_KEY" > ``` > > The assistant only sees the tools whose endpoints that key is scoped to. Revoking the key cuts the connection off. ## What the assistant can do The connector gives the assistant five tools, one per endpoint. Each tool takes the same inputs as its endpoint, and its title is the endpoint's name in the [API Reference](/api-reference/introduction). If you connect with an API key, the assistant only sees the tools that key is scoped to. | Tool | Shown as | What it does | Endpoint | Price | | - | - | - | - | - | | `list_commodities` | List Commodities | List the price series we track, like butter or corn, narrowed by category and commodity, attributes, market and series. | `GET /v1/commodities` | Free | | `get_commodity_metric_values` | Get Commodity Metric Values | Get the values over time for the series you choose, each described in the same four layers. | `GET /v1/commodities/metric-values` | \$0.01 | | `list_branded_food_categories` | List Branded Food Categories | List every food category you can search within. | `GET /v1/branded-foods/categories` | Free | | `search_branded_foods` | Search Branded Foods | Search for packaged food products by name, brand, category, barcode, or ingredient. | `GET /v1/branded-foods` | \$0.01 | | `get_branded_food` | Get a Branded Food | Get everything we have on one packaged food product. | `GET /v1/branded-foods/{id}` | \$0.01 | Every tool only reads data. A typical question about prices takes two tools: `list_commodities` to find the series, then `get_commodity_metric_values` to get its values. Two things differ from calling the API yourself, to keep answers small enough for the assistant to read: * When the assistant doesn't set `limit`, `list_commodities` and `search_branded_foods` return 10 rows per page. * When the assistant doesn't set `start_date`, `get_commodity_metric_values` returns each series' recent stretch, the same as the API does. See [Commodities](/market-data/commodities#when-you-leave-out-the-dates). Every tool call goes through the same API as a direct request with your key, so the answer matches what you'd get from the API yourself. Each call to a paid tool is charged like any other. See [Pricing & Billing](/pricing). # Docs MCP Source: https://data-docs.orbbit.co/for-agents/docs-mcp Connect these docs to Claude Code, Cursor, or VS Code so your AI assistant can search and read every page. The docs have their own connector, which lets an AI coding assistant search and read every page when it needs to. Ask it to build something with Orbbit's API, and it looks up the right endpoints, parameters, and fields as it goes. It uses MCP (Model Context Protocol), the standard way AI tools plug into outside sources. This connector only reads the docs. To have your assistant fetch Orbbit data, use the [Data MCP](/for-agents/data-mcp). Connector address: `https://data-docs.orbbit.co/mcp` > [tab] Claude Code > > ```bash theme={null} > claude mcp add --transport http orbbit-docs https://data-docs.orbbit.co/mcp > ``` > [tab] Cursor > > Add this to `.cursor/mcp.json` in your project: > > ```json theme={null} > { > "mcpServers": { > "orbbit-docs": { "url": "https://data-docs.orbbit.co/mcp" } > } > } > ``` > [tab] VS Code > > Add this to `.vscode/mcp.json` in your project: > > ```json theme={null} > { > "servers": { > "orbbit-docs": { "type": "http", "url": "https://data-docs.orbbit.co/mcp" } > } > } > ``` You can also open the menu at the top of any page and choose your tool to connect it in one click. If your tool doesn't support connectors, give it the [plain-text copy of the docs](/for-agents/llms-txt) instead. That page also has a starter prompt to paste in once the docs are connected. > [!NOTE] > > Your assistant still needs an API key to make real calls. Every account comes with one. See [Authentication](/authentication). # llms.txt Source: https://data-docs.orbbit.co/for-agents/llms-txt A plain-text copy of these docs, written for AI tools to read. Every page on this site is also published as plain text, so an AI assistant can read the docs without loading web pages. Hand it the index, and it can fetch only the pages it needs. | What | Address | Use it to | | - | - | - | | Index of every page | [`https://data-docs.orbbit.co/llms.txt`](https://data-docs.orbbit.co/llms.txt) | Let a tool see what exists, then fetch just the pages it needs. | | One page | Any page address with `.md` added, such as [`https://data-docs.orbbit.co/quickstart.md`](https://data-docs.orbbit.co/quickstart.md) | Hand over a single page. | | Every page in one file | [`https://data-docs.orbbit.co/llms-full.txt`](https://data-docs.orbbit.co/llms-full.txt) | Load the whole site at once, for example into your own search index. | Start with the index. The full file is much larger and fills more of the assistant's working memory than most tasks need. ## Copy one page To hand over a single page, open the menu at the top of that page and choose **Copy page**. It copies the page as plain text, ready to paste into any chat. ## Starter prompt Paste this into your assistant. Replace the last line with what you want to build. ```text theme={null} You are helping me call Orbbit's Data API. - Read the Orbbit docs index at https://data-docs.orbbit.co/llms.txt before writing any code, and fetch the pages you need. - The base address is https://data-api.orbbit.co and every path starts with /v1. - Send my key as "Authorization: Bearer $ORBBIT_API_KEY". Never put the key in code. - Each call is charged; batch where an endpoint allows it. If a call returns 402, tell me to top up. - Each endpoint needs its own scope on the key; if a call returns 403, tell me which scope to add. - Only use endpoints, parameters, and fields that appear in the docs. Task: pull the last 90 days of the daily Chicago cheddar block price and save it as a CSV. ``` ## Other ways in * [Docs MCP](/for-agents/docs-mcp): let your assistant search and read these pages itself, instead of pasting addresses. * [Data MCP](/for-agents/data-mcp): let your assistant call the Orbbit Data API for you. * [Use With Claude](/for-agents/use-with-claude): add Orbbit Data to the Claude app in a few clicks. # Use With Claude Source: https://data-docs.orbbit.co/for-agents/use-with-claude Add Orbbit Data to Claude as a custom connector. Add Orbbit Data to Claude once, and you can ask for commodity prices or packaged-food details in any chat. Claude picks the right Orbbit tool, calls it with your account, and answers from the result. This works in Claude on the web, desktop, and mobile. ## Add the connector 1. In Claude, open **Settings**, then **Connectors** under **Customize**. 2. Click **+ Add**, then **Add custom connector**. 3. Name it `Orbbit Data`, paste `https://data-api.orbbit.co/mcp` as the address, and click **Add**. 4. Click **Connect**, sign in to Orbbit, and click **Allow**. When it's done, **Orbbit Data** appears in your list with a check mark: ![Claude's Connectors settings, with the + Add button at the top right and Orbbit Data listed as a custom connector with a check mark](https://mintcdn.com/orbbit/4ULqY0RKziXE2arT/images/claude-connectors.png?fit=max\&auto=format\&n=4ULqY0RKziXE2arT\&q=85\&s=3e2d95d776443f8d0e574625c9459852) Claude now has five Orbbit Data tools, one per endpoint: | Tool | What it does | | - | - | | `list_commodities` | List the price series we track, like butter or corn, narrowed by category and commodity, attributes, market and series. Free. | | `get_commodity_metric_values` | Get the values over time for the series you choose, each described in the same four layers. | | `list_branded_food_categories` | List every food category you can search within. Free. | | `search_branded_foods` | Search for packaged food products by name, brand, category, barcode, or ingredient. | | `get_branded_food` | Get everything we have on one packaged food product. | Each tool's title is its name in the API Reference, such as List Commodities. See [Data MCP](/for-agents/data-mcp#what-the-assistant-can-do) for more on each tool. ## Try it Start a new chat and ask, for example: ```text theme={null} What was the daily Chicago price for 40 lb cheddar blocks over the last week of data you have? ``` Claude calls `list_commodities` to find the Chicago cheddar block series, then `get_commodity_metric_values` to get its values. The first call is free; the second costs \$0.01 from your balance, like any other call. See [Pricing & Billing](/pricing). ## Using Claude Code instead Run one command in your terminal. See [Data MCP](/for-agents/data-mcp#claude-code). > [!NOTE] > > Orbbit Data is added as a custom connector for now. Once it's listed in Claude's connector directory, you'll also be able to find it under **Discover**. # Pay With x402 Source: https://data-docs.orbbit.co/for-agents/x402 Call any paid endpoint without an account and pay per call in USDC on Base or Arc. An agent with its own crypto wallet can call any paid endpoint without an account or API key. It pays for each call in USDC, on Base or Arc, using x402: the open standard for paying for an HTTP request with the `402 Payment Required` status code. Each endpoint costs the same as with an API key. See the [price list](/pricing#price-per-call) for each endpoint's price, and read the exact amount from the price quote before you pay. The two free endpoints, `GET /v1/commodities` and `GET /v1/branded-foods/categories`, need no key and no payment. ## How a paid call works **1. Call the endpoint with no Authorization header** The API replies `402` with a price quote. The quote is in the `PAYMENT-REQUIRED` response header (base64-encoded JSON) and, as the same JSON, in the response body. **2. Sign one of the quoted options** Pick the network your wallet holds USDC on and sign a transfer for that option's `amount` to its `payTo` address. Nothing moves yet: the signature only authorizes the transfer. **3. Send the same request again with the signature** Put the encoded signed payment in the `PAYMENT-SIGNATURE` request header. **4. Receive the data and a receipt** The API checks the payment, runs the request, and settles the transfer on chain. Only then does it reply `200` with the data. The `PAYMENT-RESPONSE` response header (base64-encoded JSON) holds the receipt, including the transaction hash. An x402 client library does steps 2 to 4 for you. See the [x402 documentation](https://docs.x402.org) for client libraries. ## The price quote ```bash theme={null} curl --request GET \ --url 'https://data-api.orbbit.co/v1/branded-foods?limit=1' ``` ```json 402 Payment required theme={null} { "x402Version": 2, "error": "Payment required", "resource": { "url": "https://data-api.orbbit.co/v1/branded-foods?limit=1", "mimeType": "application/json", "description": "Search for packaged food products by name, brand, category, barcode, or ingredient." }, "accepts": [ { "scheme": "exact", "network": "eip155:8453", "amount": "10000", "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "payTo": "0xF48968e7C33E8Ad45259D1b28D3B44124Fa68f58", "maxTimeoutSeconds": 60, "extra": { "name": "USD Coin", "version": "2" } }, { "scheme": "exact", "network": "eip155:5042", "amount": "10000", "asset": "0x3600000000000000000000000000000000000000", "payTo": "0xF48968e7C33E8Ad45259D1b28D3B44124Fa68f58", "maxTimeoutSeconds": 60, "extra": { "name": "USDC", "version": "2" } } ], "extensions": { "bazaar": { "info": { "input": { "...": "..." }, "output": { "example": { "...": "..." } } } } } } ``` | Field | Description | | - | - | | `accepts` | One option per network. Pay any one of them. | | `network` | The chain, as a CAIP-2 ID. See [Networks](#networks). | | `amount` | This endpoint's price in USDC's smallest unit. USDC has 6 decimal places, so divide by 1,000,000: `10000` is \$0.01. | | `asset` | The USDC contract on that chain. | | `payTo` | Orbbit Data's receiving wallet. It is the same on both chains. | | `maxTimeoutSeconds` | How long a signed payment stays valid: 60 seconds. Sign it and send the request again within that time. | | `extensions.bazaar` | The endpoint's inputs and an example response, so an agent can see what it gets before it pays. The example's values are illustrative. | ## Networks | Network | `network` | USDC contract (`asset`) | Network fee | | - | - | - | - | | Base | `eip155:8453` | `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` | Paid by Orbbit | | Arc | `eip155:5042` | `0x3600000000000000000000000000000000000000` | Paid by Orbbit | Your wallet needs only USDC on the network it pays from. Orbbit's payment services, Coinbase on Base and Circle on Arc, submit the transfer and pay the network fee. ## What you're charged for * Only calls that return data. The transfer is settled after the request succeeds. A call that fails, such as a `400` or a `404`, settles nothing and costs nothing. * The endpoint's price per call, the same as with an API key. * A request that sends an API key is always charged to that key's balance, even if it also sends a payment. ## Limits and errors A wallet caller with no key can make up to 60 calls a minute from one IP address, free or paid. Past that, calls are refused with `429` until the minute is up. | Status | Body | Why | What to do | | - | - | - | - | | `402` | The price quote | No payment was sent, or the payment was invalid, expired, didn't match an option, or didn't settle. The `error` field says which. Nothing was charged. | Sign one of the quoted options and send the request again. | | `429` | `error.type` `rate_limited` | More than 60 calls in a minute from one IP address. | Wait and try again. | | `503` | `error.type` `service_unavailable` | The payment service for the network could not be reached. Nothing was charged. | Retry, or pay on the other network. | See [Errors](/errors) for every error the API returns. ## Find Orbbit Data as an agent Orbbit Data's paid endpoints are listed in Coinbase's x402 Bazaar, the directory agents search for paid APIs. Each listing carries the same inputs and example response as the quote. # Introduction Source: https://data-docs.orbbit.co/index Orbbit Data API: commodity prices and packaged-food data. Orbbit's Data API answers two kinds of questions about a business: what its inputs cost, and what it makes and sells. It's one read-only REST API. Every endpoint takes an `Authorization: Bearer ` header, answers in JSON, and starts with `/v1`. ## How the data is organized > [card] [Market data](/market-data/commodities) > > Prices that apply to any industry. Today: Commodities, dairy and chicken prices published by the USDA, from daily to annual. > [card] [Industry data](/industry-data/cpg/overview) > > Data about the companies and products inside one industry. Today: CPG (consumer packaged goods). Industry data is grouped by industry first, then by kind of data: | Industry | Data set | What it tells you | | - | - | - | | CPG | [Branded food](/industry-data/cpg/branded-food) | What's in a packaged food: ingredients, nutrition, serving, barcode, maker. | ## First call List every commodity Orbbit has prices for. This call is free: ```bash theme={null} curl --request GET \ --url https://data-api.orbbit.co/v1/commodities \ --header 'authorization: Bearer YOUR_API_KEY' ``` Continue with the [Quickstart](/quickstart), or open the **API Reference** tab to try any endpoint in the browser. ## What lives where | If you want to… | Go to | | - | - | | Make your first call | [Quickstart](/quickstart) | | Get and use an API key | [Authentication](/authentication) | | Understand an error | [Errors](/errors) | | Know what a call costs | [Pricing & Billing](/pricing) | | Work through an AI assistant | [For Agents](/for-agents/llms-txt) | | Look up an exact parameter or field | The **API Reference** tab | ## Where the data comes from Every record carries a `source` field that names where it came from. | `source` | Publisher | Data set | | - | - | - | | `usda-mars` | USDA Market News (dairy and chicken prices, including CME spot) | Commodities | | `usda-mpr` | USDA Mandatory Price Reporting (dairy sales and milk prices) | Commodities | | `usda-fdc` | USDA FoodData Central, branded foods dataset | Branded food | # Branded Food Source: https://data-docs.orbbit.co/industry-data/cpg/branded-food What's inside packaged foods sold in the US: ingredients, nutrition, serving, barcode, and maker. Use this when you need to know what's in a packaged food on US shelves: its ingredients, nutrition facts, serving size, and who makes it. Typical uses: find every product that contains an ingredient you supply, check a competitor's formulation, or fill in label data from a barcode. The data is a copy of USDA FoodData Central's current Branded Foods list, refreshed when USDA publishes. USDA builds that list from label data its partners send: brands through the GS1 network, and label data companies such as Label Insight. Each product's `data_source` says which, and how fresh its data can be. Every product has `source: "usda-fdc"`. | Endpoint | Name | What it does | Scope | Price | | - | - | - | - | - | | `GET /v1/branded-foods` | Search Branded Foods | Search products with filters | `search-branded-foods` | \$0.01 | | `GET /v1/branded-foods/categories` | List Branded Food Categories | List every category with its product count | `search-branded-foods` | Free | | `GET /v1/branded-foods/{id}` | Get a Branded Food | Get one product by its ID | `get-branded-foods` | \$0.01 | ## Search products Every filter is optional. When you pass several, a product must match all of them. | Parameter | Type | Description | | - | - | - | | `description` | string | Text to find in the product name, such as `cheddar`. Capital letters do not matter. Leave it out to search every product. | | `brand` | string | Text to find in the brand, the company that owns it, or the product line, such as `kraft`. Capital letters do not matter. | | `ingredient` | string | Text to find in the ingredient list, such as `peanuts`. Capital letters do not matter. | | `category` | string | One category, spelled in full, such as `Cheese`. Capital letters do not matter. `GET /v1/branded-foods/categories` lists every category. | | `upc` | string | The full barcode number (GTIN or UPC) printed on the package, such as `016000348516`. | | `limit` | integer | How many products to return per page, from 1 to 200. The default is 50. | | `cursor` | string | To get the next page, pass the `next_cursor` from the previous reply. Leave it out for the first page. | ### Your first search: look up a barcode The simplest search finds one product by the barcode on its package. ```bash Request theme={null} curl --request GET \ --url 'https://data-api.orbbit.co/v1/branded-foods?upc=021000601366' \ --header 'authorization: Bearer YOUR_API_KEY' ``` ```json Response theme={null} { "data": [ { "id": "data_branded_food_01k2x7f3m9q8r4t6v0w2y5z8ab", "fdc_id": 2345678, "description": "SHARP CHEDDAR CHEESE", "brand_owner": "Kraft Heinz Foods Company", "brand_name": "CRACKER BARREL", "category": "Cheese", "upc": "021000601366", "serving_size": 28, "serving_size_unit": "GRM", "serving_size_unit_normalized": "g", "household_serving_text": "1 oz", "ingredients": "CHEDDAR CHEESE (PASTEURIZED MILK, CHEESE CULTURE, SALT, ENZYMES, ANNATTO (COLOR)).", "nutrition": { "calories": 110, "fat": 9, "saturated_fat": 6, "sodium": 180, "protein": 7 }, "source": "usda-fdc", "fetched_at": "2026-08-23T03:29:33.000Z" } ], "next_cursor": null } ``` Response trimmed for clarity. Values are illustrative. Every product has the same set of fields; see [Product fields](#product-fields) below for all of them. ### Understanding the response * `data` is this page of matching products. An empty array means nothing matched. * `next_cursor` is `null` on the last page. Otherwise, pass it as `cursor` to get the next page. Results come one page at a time. `limit` sets the page size (1 to 200, default 50). Each response has a `next_cursor`: pass it back as `cursor` to get the next page, and stop when it's `null`. Rows come back in ID order, so paging never skips or repeats a row. * `nutrition` holds the 15 nutrients on a US nutrition facts panel, per serving. A nutrient the data provider didn't supply is `null`, which does not mean zero. * `serving_size_unit` is the unit exactly as the data provider wrote it, such as `GRM`. `serving_size_unit_normalized` is the same unit in a standard form, such as `g`. Use the normalized one when you compare products. ## Find products that contain an ingredient This finds snack bars that list whey protein, 20 at a time. ```bash theme={null} curl --request GET \ --url 'https://data-api.orbbit.co/v1/branded-foods?ingredient=whey%20protein&category=Snack%2C%20Energy%20%26%20Granola%20Bars&limit=20' \ --header 'authorization: Bearer YOUR_API_KEY' ``` ## Find a brand's products `brand` matches the company that owns the brand, the brand, and the sub-brand, so either the maker or the label name works. ```bash theme={null} curl --request GET \ --url 'https://data-api.orbbit.co/v1/branded-foods?brand=cracker%20barrel&description=cheddar' \ --header 'authorization: Bearer YOUR_API_KEY' ``` ## Find valid categories `category` must match a category name exactly, apart from case. Get the list first. This call is free: ```bash Request theme={null} curl --request GET \ --url https://data-api.orbbit.co/v1/branded-foods/categories \ --header 'authorization: Bearer YOUR_API_KEY' ``` ```json Response theme={null} { "data": [ { "category": "Candy", "product_count": 41210 }, { "category": "Cheese", "product_count": 23874 } ] } ``` Response trimmed for clarity. Values are illustrative. Categories come back largest first. ## Get one product Pass an `id` from a search result. This endpoint needs the `get-branded-foods` scope. ```bash theme={null} curl --request GET \ --url https://data-api.orbbit.co/v1/branded-foods/data_branded_food_01k2x7f3m9q8r4t6v0w2y5z8ab \ --header 'authorization: Bearer YOUR_API_KEY' ``` The response is `{ "data": { ...product } }`, with the same fields a search returns. An unknown ID returns `404`: ```json 404 Unknown product theme={null} { "error": { "type": "not_found", "message": "Unknown branded food: data_branded_food_01k2x7f3m9q8r4t6v0w2y5z8ab" } } ``` ## Product fields Every product, from search or from `GET /v1/branded-foods/{id}`, has all of these fields. A field the data provider didn't supply is `null`. These descriptions are the same ones the API reference and the Orbbit Data MCP tools give. ### Identity | Field | Type | Description | | - | - | - | | `id` | string | Orbbit's ID for the product. Pass it to `GET /v1/branded-foods/{id}`. | | `fdc_id` | integer | The record's ID in USDA FoodData Central. When the data provider updates a product, USDA publishes it as a new record with a new ID. | | `description` | string | The product name as the data provider wrote it, such as `SHARP CHEDDAR CHEESE`. | | `short_description` | string or null | The brand's abbreviated product name for shelf tags and till receipts, such as `Prog Trad Hrty Chkn Rotini Sp`. Present almost only on `GDSN` products; empty for the rest. | | `upc` | string or null | The barcode number (GTIN or UPC) that identifies the product, with leading zeros. | ### Brand and category | Field | Type | Description | | - | - | - | | `brand_owner` | string or null | The company that owns the brand, such as `Kraft Heinz Foods Company`. | | `brand_name` | string or null | The brand printed on the package, such as `CRACKER BARREL`. Store brands appear here too, such as `SAM'S CHOICE`. | | `subbrand_name` | string or null | The product line within the brand, such as `ULTRA` for Organic Valley. | | `category` | string or null | The product's category, assigned by the data source (GDSN or Label Insight), not by USDA. `GET /v1/branded-foods/categories` lists every value. | | `gpc_class_code` | integer or null | The GS1 Global Product Classification code for the product type, at class level, such as `50131700` (milk and milk substitutes). Present only on `GDSN` and `Euromonitor` products. | ### Package and serving | Field | Type | Description | | - | - | - | | `package_weight` | string or null | The net contents printed on the package, such as `7 oz/198 g`. Present mostly on `LI` and `NZGDSN` products. | | `serving_size` | number or null | The serving size the nutrition facts are based on, in `serving_size_unit`. | | `serving_size_unit` | string or null | The serving unit as the data provider wrote it: `g` or `GRM` for grams, `ml` or `MLT` for milliliters. A few products show `MG` or `IU`, which are provider errors. | | `serving_size_unit_normalized` | string or null | The same unit written one way: `g`, `ml`, `mg` or `IU`. Orbbit adds it so products can be compared. | | `household_serving_text` | string or null | The serving in kitchen terms, as printed, such as `2 Tbsp` or `1 LINK`. | | `preparation_state_code` | string or null | Which state of the food the nutrition values describe, such as `UNPREPARED` (as sold), `PREPARED` or `READY_TO_EAT`. Present only on some `GDSN` products. | ### Market | Field | Type | Description | | - | - | - | | `market_country` | string or null | The country where the product is sold, as the data provider wrote it: `United States`, `US` or `New Zealand`. | | `market_country_normalized` | string or null | The same country written one way: `US` or `NZ`. Orbbit adds it so products can be compared. | | `trade_channels` | array or null | Where the brand says the product is sold: `GROCERY` (food retail), `FOOD_SERVICE` (restaurants, hotels, clubs), `CHILD_NUTRITION_FOOD_PROGRAMS` (approved for school meal programs) or `ONLINE`. `NO_TRADE_CHANNEL` means none was given, which is true of most products. | ### Label | Field | Type | Description | | - | - | - | | `ingredients` | string or null | The ingredient list as it appears on the label. | | `nutrition` | object | The Nutrition Facts panel, per serving, as the data provider supplied it. A nutrient missing here was not supplied; it does not mean zero. Values are label values, which are rounded, not lab tests. | | `nutrients` | array or null | Every nutrient USDA holds for the product, per 100 g or 100 ml, calculated by USDA from the per-serving label values. Each one says how it was calculated, such as "Calculated from value per serving size measure". | | `attributes` | array or null | USDA's update log for the product: what changed in this version, such as `Nutrient Updated`, `Description` or `Food Discontinued`. A nutrient change can be a corrected error, not a new recipe. Empty for most products. | | `caffeine_statement` | string or null | The caffeine statement printed on the label, such as `80MG CAFFEINE`. Present only on some `LI` products. | | `footnote` | string or null | A note from USDA about the record, such as a correction made in a past release. Present on very few products. | ### Dates and provenance | Field | Type | Description | | - | - | - | | `published_on` | string or null | The day USDA published this version of the record to FoodData Central, `YYYY-MM-DD`. USDA publishes changes monthly. | | `available_on` | string or null | The day the product record became available for USDA to add to FoodData Central, `YYYY-MM-DD`. It is not the day the product went on sale. | | `modified_on` | string or null | The last day the data provider (the brand, or Label Insight) changed this product's data, `YYYY-MM-DD`. For `LI` products this is on or before 2023-11-16, because that source stopped. An old date means no newer data reached USDA, not that Orbbit's copy is out of date. | | `discontinued_on` | string or null | The day the product was discontinued, as the data provider reported it, `YYYY-MM-DD`. Most products have none, including some no longer sold. | | `data_source` | string or null | Where USDA got this product's data. `LI` is Label Insight, a label data company that stopped sending USDA updates on November 16, 2023. `GDSN` is the brand's own data sent through the GS1 network, which brands can update at any time. `Euromonitor` and `NZGDSN` (New Zealand brands through GS1) are smaller sources. | | `source` | string | Always `usda-fdc`: USDA FoodData Central. | | `fetched_at` | string or null | When Orbbit last copied this record from USDA, as an ISO 8601 timestamp. | ## Nutrition `nutrition` always has these 15 keys, per serving. | Key | Description | | - | - | | `calories` | Energy per serving, in kcal, as printed on the label. Null when the data provider did not supply it, which does not mean zero. | | `fat` | Total fat per serving, in grams, as printed on the label. Null when the data provider did not supply it, which does not mean zero. | | `saturated_fat` | Saturated fat per serving, in grams, as printed on the label. Null when the data provider did not supply it, which does not mean zero. | | `trans_fat` | Trans fat per serving, in grams, as printed on the label. Null when the data provider did not supply it, which does not mean zero. | | `cholesterol` | Cholesterol per serving, in milligrams, as printed on the label. Null when the data provider did not supply it, which does not mean zero. | | `sodium` | Sodium per serving, in milligrams, as printed on the label. Null when the data provider did not supply it, which does not mean zero. | | `carbohydrates` | Total carbohydrates per serving, in grams, as printed on the label. Null when the data provider did not supply it, which does not mean zero. | | `fiber` | Dietary fiber per serving, in grams, as printed on the label. Null when the data provider did not supply it, which does not mean zero. | | `sugars` | Total sugars per serving, in grams, as printed on the label. Null when the data provider did not supply it, which does not mean zero. | | `added_sugar` | Added sugars per serving, in grams, as printed on the label. Null when the data provider did not supply it, which does not mean zero. | | `protein` | Protein per serving, in grams, as printed on the label. Null when the data provider did not supply it, which does not mean zero. | | `calcium` | Calcium per serving, in milligrams, as printed on the label. Null when the data provider did not supply it, which does not mean zero. | | `iron` | Iron per serving, in milligrams, as printed on the label. Null when the data provider did not supply it, which does not mean zero. | | `potassium` | Potassium per serving, in milligrams, as printed on the label. Null when the data provider did not supply it, which does not mean zero. | | `vitamin_d` | Vitamin D per serving, in micrograms, as printed on the label. Null when the data provider did not supply it, which does not mean zero. | ## Search filters | Parameter | Description | | - | - | | `description` | Text to find in the product name, such as `cheddar`. Capital letters do not matter. Leave it out to search every product. | | `brand` | Text to find in the brand, the company that owns it, or the product line, such as `kraft`. Capital letters do not matter. | | `ingredient` | Text to find in the ingredient list, such as `peanuts`. Capital letters do not matter. | | `category` | One category, spelled in full, such as `Cheese`. Capital letters do not matter. `GET /v1/branded-foods/categories` lists every category. | | `upc` | The full barcode number (GTIN or UPC) printed on the package, such as `016000348516`. | ## Validation rules | Rule | Behavior | | - | - | | All filters optional | No filters returns every product, one page at a time. | | Filters combine | Several filters mean a product must match all of them. | | Empty filter | `?brand=` with no text is the same as leaving it out. | | `limit` | A whole number from 1 to 200. Above 200 returns `400 at most 200 per page`. | | Order | Results are sorted by `id`, so paging is stable. | ## Summary | Detail | `GET /v1/branded-foods` | `GET /v1/branded-foods/categories` | `GET /v1/branded-foods/{id}` | | - | - | - | - | | Scope | `search-branded-foods` | `search-branded-foods` | `get-branded-foods` | | Response | `{ data: [product], next_cursor }` | `{ data: [{ category, product_count }] }` | `{ data: product }` | | Paged | Yes | No | No | | Price | \$0.01 per call | Free | \$0.01 per call | | Errors | `400`, `401`, `402`, `403` | `401`, `403` | `401`, `402`, `403`, `404` | ## What to do next * Try it live: [Search Branded Foods](/api-reference/branded-food/search-branded-foods), [List Branded Food Categories](/api-reference/branded-food/list-branded-food-categories), and [Get a Branded Food](/api-reference/branded-food/get-a-branded-food). * Copy a working feature: see the [Branded Food Labels cookbook examples](https://github.com/orbbit-tech/orbbit-data-cookbook/tree/main/examples/branded-food-labels). * See how this fits with commodity prices: read the [CPG overview](/industry-data/cpg/overview). # CPG Overview Source: https://data-docs.orbbit.co/industry-data/cpg/overview What Orbbit's CPG data covers, and how it relates to commodity prices. Consumer packaged goods (CPG) are everyday products that people use up and buy again often, such as food, drinks, toiletries, and cleaning supplies. Orbbit's CPG data covers what's in a brand's packaged food products: ingredients, nutrition, serving size, barcode, and maker. Ingredient prices are a separate data set, [Commodities](/market-data/commodities), under Market Data. ## How the pieces fit A CPG brand buys ingredients, makes a packaged product, and sells it in stores, to wholesalers, or straight to consumers online. Each data set covers one part of that path. | Question | Data set | What you get | | - | - | - | | What do raw ingredients cost on the market? | [Commodities](/market-data/commodities) (Market Data) | USDA market prices for food commodities such as butter, cheese, and chicken. It is not specific to CPG, so it lives under Market Data. | | What's in the product? | [Branded food](/industry-data/cpg/branded-food) | The label of a packaged food: ingredients, nutrition, serving size, barcode, and who makes it. | ## Putting them together The data sets share words you can match on, such as an ingredient or a category, so you can connect them in your own code. For example: * Ingredient exposure. Search [Branded food](/industry-data/cpg/branded-food) for products whose ingredients contain `butter`, then pull butter prices from [Commodities](/market-data/commodities) to see how the market price of that ingredient has moved. ## Where the data comes from | Data set | `source` | Publisher | | - | - | - | | Branded food | `usda-fdc` | USDA FoodData Central, submitted by the brand owners | # Commodities Source: https://data-docs.orbbit.co/market-data/commodities USDA market prices for food commodities, by region and date. Use this when you need the price history of a raw ingredient, for example to track input costs, check a supplier's quote against the market, or feed a forecast. The Commodities API is two endpoints used together. First you list price series to find the one you want. Then you ask for that series' values by date. | Step | Endpoint | Name | Scope | Price | | - | - | - | - | - | | 1 | `GET /v1/commodities` | List Commodities | `search-commodities` | Free | | 2 | `GET /v1/commodities/metric-values` | Get Commodity Metric Values | `get-commodity-prices` | \$0.01 | ## What's covered Every price is grouped the way USDA Market News groups it: a `category`, then a `commodity` inside it. Pass either one, or both, to List Commodities. `?category=grains&commodity=corn` lists every corn price series. | Category | Commodities | Supply-chain steps | How often | Units | | - | - | - | - | - | | `dairy` | `butter`, `butteroil`, `cheese`, `cottage_cheese`, `cream`, `cream_cheese`, `sour_cream`, `yogurt`, `ice_cream`, `milk`, `flavored_milk`, `eggnog`, `condensed_skim_milk`, `nonfat_dry_milk`, `skim_milk_powder`, `whole_milk_powder`, `dry_whole_milk`, `buttermilk_powder`, `dry_whey`, `whey_protein_concentrate`, `lactose`, `casein`, `milk_replacer` | Farm, wholesale, retail | Daily to annual | `usd_per_lb`, `usd_per_cwt`, `usd_per_metric_ton`, `usd_each`, `ratio_to_cme_butter`, `usd_per_lb_over_cme_butter` | | `poultry` | `chicken`, `turkey`, `shell_eggs`, `liquid_eggs`, `frozen_eggs`, `dried_eggs`, `egg_whites`, `egg_yolks` | Farm, wholesale, retail | Daily, weekly, monthly | `usd_per_lb`, `usd_each`, `usd_per_dozen`, `usd_per_carton` | | `meat` | `beef`, `pork`, `lamb` | Wholesale | Daily, weekly | `usd_per_cwt` | | `grains` | `wheat`, `corn`, `barley`, `oats`, `sorghum`, `millet`, `rye`, `triticale`, `soybeans`, `sunflower_seeds`, `canola`, `flaxseed`, `dry_beans`, `dry_peas`, `lentils` | Farm, wholesale | Daily, weekly | `usd_per_bushel`, `usd_per_cwt`, `usd_per_ton` | | `fruits` | `apples`, `avocados`, `bananas`, `blackberries`, `blueberries`, `breadfruit`, `cantaloupes`, `cherimoya`, `cherries`, `clementines`, `coconuts`, `dragon_fruit`, `grapefruit`, `grapes`, `honeydews`, `kiwifruit`, `lemons`, `limes`, `mangoes`, `melons`, `nectarines`, `oranges`, `papaya`, `peaches`, `pears`, `pepino`, `persimmons`, `pineapples`, `plantains`, `plums`, `pomegranates`, `quenepas`, `rambutan`, `raspberries`, `strawberries`, `tangelos`, `tangerines`, `watermelons` | Wholesale | Daily | `usd_per_package` | | `vegetables` | `anise`, `artichokes`, `asparagus`, `beets`, `bok_choy`, `broccoli`, `brussels_sprouts`, `cabbage`, `calabaza`, `carrots`, `cauliflower`, `celery`, `chayote`, `chinese_cabbage`, `cilantro`, `cucumbers`, `eggplant`, `endive`, `escarole`, `ginger_root`, `green_beans`, `greens`, `leeks`, `lettuce`, `malanga`, `okra`, `onions`, `parsley`, `peas`, `peppers`, `potatoes`, `radishes`, `rhubarb`, `spinach`, `squash`, `sweet_corn`, `sweet_potatoes`, `taro`, `tomatillos`, `tomatoes`, `turmeric`, `yampi`, `yams`, `yuca` | Wholesale | Daily | `usd_per_package`, `usd_per_lb`, `usd_per_cwt`, `usd_per_bunch` | A few groupings follow USDA rather than the grocery aisle: eggs are under `poultry`, and soybeans, oilseeds and dry beans are under `grains`, because USDA reports them in its grain bids. Where USDA splits one crop into types, such as bell and jalapeño peppers or grape and plum tomatoes, the crop is the commodity and the type is one of its attributes. Sweet corn is `sweet_corn` under `vegetables`; `corn` under `grains` is field corn. Fruit and vegetables include every product the USDA has priced within two years of its newest report, each with its full history. ## Find a series in four layers Each price series answers four questions, and List Commodities can narrow on each one: | Layer | Question | Parameters | Example | | - | - | - | - | | 1. Product | What is priced? | `category`, `commodity` | `category=poultry&commodity=shell_eggs` | | 2. Attributes | Which kind of it? | `attributes[]` | `attributes[size_class]=large` | | 3. Market | Where and at what step is it sold? | `region`, `market_level`, `freight` | `region=us_southwest&market_level=retail` | | 4. Series | How is the number published? | `frequency`, `price_type`, `unit`, `measure` | `frequency=weekly&price_type=avg` | Each result is one series: its `id` and `metric_name`, the `product` it prices (its category, commodity and attributes), then one field for each market and series layer, named exactly like the parameter that filters it. You never have to take a `metric_name` apart, because every part of it is also its own field. ## List commodities `GET /v1/commodities` lists price series, narrowed by any of the four layers, one page at a time. It is free. | Parameter | Type | Required | Description | | - | - | - | - | | `category` | string | No | Layer 1. One of `dairy`, `poultry`, `meat`, `grains`, `fruits` or `vegetables`. Any other value returns `400`. Leave it out to list every category. | | `commodity` | string | No | Layer 1. One commodity word from the table above, such as `corn`, `beef` or `shell_eggs`. A word no product has returns an empty page. | | `attributes[]` | string | No | Layer 2. The value one attribute must have, such as `attributes[cheese_form]=block`. Repeat it for each attribute: `attributes[cheese_form]=block&attributes[cheese_style]=cheddar`. A word no product has returns `400`. | | `region` | string | No | Layer 3. Where the price is paid, such as `us`, `us_chicago` or `us_southwest`. | | `market_level` | string | No | Layer 3. `farm`, `wholesale` or `retail`. | | `freight` | string | No | Layer 3. `fob`, `delivered` or `not_stated`. | | `frequency` | string | No | Layer 4. `daily`, `weekly`, `biweekly`, `monthly` or `annual`. | | `price_type` | string | No | Layer 4. `low`, `high`, `avg`, `mostly_low`, `mostly_high`, `close` or `value`. | | `unit` | string | No | Layer 4. Such as `usd_per_lb`, `usd_per_dozen` or `usd_per_package`. | | `measure` | string | No | Layer 4. The USDA's own name for the number, such as `wtd_avg_price`. | | `limit` | integer | No | Series per page, 1 to 500. Default 100. | | `cursor` | string | No | The `next_cursor` from the previous page. | ```bash Request theme={null} curl --globoff --request GET \ --url 'https://data-api.orbbit.co/v1/commodities?category=dairy&commodity=cheese&attributes[cheese_style]=cheddar®ion=us_chicago&frequency=daily&limit=1' \ --header 'authorization: Bearer YOUR_API_KEY' ``` ```json Response theme={null} { "data": [ { "id": "data_commodity_metric_01m5jbewxffcs9j3neja9k8s4a", "metric_name": "cheese_block_cheddar_40_lb_us_chicago_wholesale_daily_close_price_usd_per_lb", "product": { "category": "dairy", "commodity": "cheese", "attributes": { "size": "40 lb", "cheese_form": "block", "cheese_style": "cheddar" } }, "region": "us_chicago", "market_level": "wholesale", "freight": "not_stated", "frequency": "daily", "price_type": "close", "unit": "usd_per_lb", "measure": "close_price", "source": "usda-mars", "first_observed_on": "2021-02-24", "last_observed_on": "2026-10-20" } ], "next_cursor": "cheese_block_cheddar_40_lb_us_chicago_wholesale_daily_close_price_usd_per_lb" } ``` Use `first_observed_on` and `last_observed_on` to see how far back a series goes and how fresh it is before you ask for its values. When `next_cursor` is `null`, you have reached the last page. The `--globoff` flag stops curl from reading the square brackets in `attributes[...]` as a pattern. ## Get commodity metric values `GET /v1/commodities/metric-values` returns dated values for one or more series. It costs \$0.01 per call, however many series you ask for. | Parameter | Type | Required | Description | | - | - | - | - | | `metric_names` | string | One of the two | One or more `metric_name`s from List Commodities, comma-separated. | | `ids` | string | One of the two | One or more series `id`s from List Commodities, comma-separated. You can send both; together they name at most 100 series. | | `start_date` | string | No | First date to include, as `YYYY-MM-DD`. Leave it out to get each series' recent stretch (see below). | | `end_date` | string | No | Last date to include, as `YYYY-MM-DD`. Leave it out to run to each series' newest value. | ### When you leave out the dates If you leave out `start_date`, each series returns a recent stretch. How long depends on how often the series is published: | Series `frequency` | Default range | | - | - | | `daily`, `weekly`, `biweekly` | The last 1 year | | `monthly` | The last 5 years | | `annual` | The last 10 years | The stretch is counted back from `end_date` if you pass it. If you don't, it is counted back from the series' own newest value, not from today, so a series that stopped updating still returns its last stretch. Each series is counted on its own, so two series in one call can start on different dates. Pass `start_date` to get an exact range, or an early date such as `start_date=1990-01-01` to get a series' full history. ```bash Request theme={null} curl --request GET \ --url 'https://data-api.orbbit.co/v1/commodities/metric-values?metric_names=cheese_block_cheddar_40_lb_us_chicago_wholesale_daily_close_price_usd_per_lb&start_date=2026-10-16&end_date=2026-10-20' \ --header 'authorization: Bearer YOUR_API_KEY' ``` ```json Response theme={null} { "data": [ { "id": "data_commodity_metric_01m5jbewxffcs9j3neja9k8s4a", "metric_name": "cheese_block_cheddar_40_lb_us_chicago_wholesale_daily_close_price_usd_per_lb", "product": { "category": "dairy", "commodity": "cheese", "attributes": { "size": "40 lb", "cheese_form": "block", "cheese_style": "cheddar" } }, "region": "us_chicago", "market_level": "wholesale", "freight": "not_stated", "frequency": "daily", "price_type": "close", "unit": "usd_per_lb", "measure": "close_price", "source": "usda-mars", "first_observed_on": "2021-02-24", "last_observed_on": "2026-10-20", "start_date": "2026-10-16", "end_date": "2026-10-20", "values": [ { "date": "2026-10-16", "value": 1.6825 }, { "date": "2026-10-19", "value": 1.73 }, { "date": "2026-10-20", "value": 1.8 } ] } ] } ``` ### Understanding the response * `data` has one entry per series you asked for, in the order you asked. * Each entry describes the series with the same fields as List Commodities, then adds `start_date`, `end_date` and `values`. * `start_date` and `end_date` are the first and last dates used for that series. They are `null` only when you passed no dates and the series has no values at all. * `unit` tells you how to read `value`. For example, `usd_per_lb` is dollars per pound. * `values` is in date order, with one `value` per date. Days with no value, such as weekends for a daily series, are left out. * `value` is the number the USDA published, in the series' unit. A price the USDA publishes in cents is given in dollars. * A date range with no values returns the series with an empty `values` array, not an error. To compare series side by side, pass several names separated by commas, for example a Chicago and a national cheddar price over the same weeks. If any name is wrong, the whole request fails with `400`, and the message names the ones it doesn't know. So a typo never silently drops a series. ```json 400 Unknown metric theme={null} { "error": { "type": "invalid_request", "message": "Unknown metrics: cheddar_close" } } ``` ## Series fields Returned by both endpoints, inside `data[]`. | Field | Type | Description | | - | - | - | | `id` | string | The series' ID. Pass it to Get Commodity Metric Values as `ids`. | | `metric_name` | string | The series' readable name, the same in every environment. Pass it as `metric_names`. | | `product.category` | string | The USDA category: `dairy`, `poultry`, `meat`, `grains`, `fruits` or `vegetables`. | | `product.commodity` | string | The commodity priced, such as `cheese` or `corn`. | | `product.attributes` | object | What sets the product apart, one word to a value, such as `{ "meat_cut": "breasts" }`. A value is a list when several apply. | | `region` | string | Where the price is paid, such as `us`, `us_chicago`, `us_northeast` or `western_europe`. | | `market_level` | string | The step in the supply chain: `farm`, `wholesale` or `retail`. | | `freight` | string | Who pays shipping: `fob` (buyer collects from the seller), `delivered`, or `not_stated`. | | `frequency` | string | How often a new value appears: `daily`, `weekly`, `biweekly`, `monthly` or `annual`. It sets the default date range. | | `price_type` | string | The kind of number: `low`, `high`, `avg`, `mostly_low`, `mostly_high`, `close`, or `value` for a number published on its own. | | `unit` | string | How to read each value, such as `usd_per_lb`, `usd_per_dozen`, `usd_per_cwt` (dollars per hundred pounds), `usd_per_bushel` or `usd_per_package`. | | `measure` | string | The USDA's own name for the number, unchanged, such as `wtd_avg_price` or `close_price`. | | `source` | string | The USDA report family: `usda-mars` (Market News) or `usda-mpr` (Mandatory Price Reporting). | | `first_observed_on` | string or null | Date of the earliest value, `YYYY-MM-DD`. | | `last_observed_on` | string or null | Date of the newest value, `YYYY-MM-DD`. | Get Commodity Metric Values adds: | Field | Type | Description | | - | - | - | | `start_date` | string or null | The first date used for this series, `YYYY-MM-DD`: your `start_date`, or the start of the default range. | | `end_date` | string or null | The last date used for this series, `YYYY-MM-DD`: your `end_date`, or the series' newest value. | | `values` | array | Values in date order. | | `values[].date` | string | The value's date, `YYYY-MM-DD`. | | `values[].value` | number | The value, in the series' unit. | ## Validation rules | Rule | Behavior | | - | - | | `metric_names` or `ids` is required | Leaving both out returns `400`. | | At most 100 series | More, counting `metric_names` and `ids` together, returns `400`. | | Every series must exist | One unknown name fails the whole request with `400 Unknown metrics: `. | | At most 50,000 values | A call that would return more returns `400` and asks you to narrow `start_date` and `end_date`, or ask for fewer series. | | `category` must be one of six | Any other value returns `400 Unknown category ; category is one of dairy, poultry, meat, grains, fruits, vegetables`. | | Every attribute word must exist | An `attributes[]` no product has returns `400 Unknown attribute words: `. | | No unknown parameters | A parameter either endpoint doesn't take returns `400`. | | `limit` | Must be 1 to 500; anything else returns `400`. | | Dates | `start_date` and `end_date` must be real calendar days written `YYYY-MM-DD`; `2026-02-30` is refused. | | Date order | `start_date` later than `end_date` returns `400`. | | Both dates included | A value dated exactly `start_date` or `end_date` is returned. | ## Summary | Detail | `GET /v1/commodities` | `GET /v1/commodities/metric-values` | | - | - | - | | Name | List Commodities | Get Commodity Metric Values | | Scope | `search-commodities` | `get-commodity-prices` | | Price | Free | \$0.01 per call | | Parameters | `category`, `commodity`, `attributes[]`, `region`, `market_level`, `freight`, `frequency`, `price_type`, `unit`, `measure`, `limit`, `cursor` | `metric_names`, `ids`, `start_date`, `end_date` | | Response | `{ data: [series], next_cursor }` | `{ data: [series with start_date, end_date, values] }` | | Paged | Yes | No | | Errors | `400`, `401`, `403` | `400`, `401`, `402`, `403` | ## What to do next * Try it live: [List Commodities](/api-reference/commodities/list-commodities) and [Get Commodity Metric Values](/api-reference/commodities/get-commodity-metric-values). * Copy a working feature: see the [Food Commodity Prices cookbook examples](https://github.com/orbbit-tech/orbbit-data-cookbook/tree/main/examples/food-commodity-prices). * Handle errors: see [Errors](/errors). * Let your AI assistant do it: see [Use With Claude](/for-agents/use-with-claude). # Pricing & Billing Source: https://data-docs.orbbit.co/pricing What each call costs, how your balance works, and how to top it up automatically. You pay per call, from a prepaid balance. There is no subscription and no monthly minimum. An agent with a crypto wallet can instead pay each call in USDC without an account; see [Pay With x402](/for-agents/x402). The two calls that tell you what exists are free. Every new account starts with \$5 of balance, with no card needed, which is enough for 500 paid calls. ## Price per call Each endpoint has one flat price per call, however many results it returns. | Data | Name | Endpoint | Price per call | | - | - | - | - | | [Commodities](/market-data/commodities) | List Commodities | `GET /v1/commodities` | Free | | [Commodities](/market-data/commodities) | Get Commodity Metric Values | `GET /v1/commodities/metric-values` | \$0.01 | | [Branded Food](/industry-data/cpg/branded-food) | List Branded Food Categories | `GET /v1/branded-foods/categories` | Free | | [Branded Food](/industry-data/cpg/branded-food) | Search Branded Foods | `GET /v1/branded-foods` | \$0.01 | | [Branded Food](/industry-data/cpg/branded-food) | Get a Branded Food | `GET /v1/branded-foods/{id}` | \$0.01 | The free calls list what exists, so finding what to ask for never costs anything. They need no balance, don't count toward a key's spend budget, and don't appear on **Usage** or **Logs**. ## What you're charged for * Only paid calls that succeed. A call that returns an error (`400`, `401`, `402`, `403`, `404` or `5xx`) costs nothing. * One price per call. Asking for 100 metrics in one call to `GET /v1/commodities/metric-values` costs the same \$0.01 as asking for one. So batch where you can. * Calls from the API Reference and AI assistants too. The **Try it** button and the [Data MCP](/for-agents/data-mcp) connection send real calls, charged like any other. ## When a call is refused A paid call is refused with status `402` and error type `insufficient_balance` before any data is read if either of these would be exceeded: * Your balance. The message is `Insufficient balance`. * The key's monthly spend budget, set per key under **API Keys**. The message is `Monthly spend cap reached`. ```json theme={null} { "error": { "type": "insufficient_balance", "message": "Insufficient balance" } } ``` A refused call costs nothing. Retrying it fails the same way until you top up or raise the key's budget. ## Cap what a key can spend Every API key has a **Spend budget (USD)**: the most it may spend in a calendar month (UTC). Set it when you create the key, and change it any time from **API Keys**. The budget still applies when auto-recharge is on, so a key can never spend past it. See [Authentication](/authentication). ## Top up your balance Open **Balance** in the console and click **Top Up**. Pick $20, $50 or \$100, then pay by card through Stripe. The money is added as soon as the payment goes through, and the card is saved for auto-recharge. ## Auto-recharge Auto-recharge tops up your balance for you, so calls don't start failing with `402` because it ran low. 1. Open **Balance** and, next to auto-recharge, click **Manage**. 2. Tick **Automatically recharge when my balance runs low**. 3. Pick **Recharge amount**, the amount to add each time: $20, $50 or \$100. 4. Pick **When balance drops below**, the level that triggers it: $5, $10 or \$20. 5. Click **Save**. Auto-recharge needs a saved card. A top-up saves the card it's paid with, or click **Save Card** in the same window. How it behaves: * It checks right after each charged call, and once a day, so it also catches a balance that dropped for another reason, such as a refund. * It charges once at a time. Many calls finishing together never trigger more than one recharge. * If your card is declined, auto-recharge switches itself off so it doesn't keep retrying. Update your card and turn it back on. ## See what you've spent The console's **Usage** page shows your spend by key and by endpoint, day by day. **Logs** lists every paid call with the endpoint it called, what it sent, and what it cost. Free calls are not listed. # Quickstart Source: https://data-docs.orbbit.co/quickstart Make your first request for commodity prices with an API key. This walkthrough takes you from signing up to your first cheddar prices. Every step after the first is one request. **1. Copy your API key** Sign up in the Orbbit console. Your account comes with a key named **Default**, which can call every endpoint, plus \$5 of starting balance to spend. Open **API Keys**, find **Default**, click **Reveal Secret**, and copy the key. It starts with `orbbit_data_`. See [Authentication](/authentication) for how keys, their permissions, and their spend limits work. **2. Find a price series** List the daily cheddar series in Chicago with List Commodities, which is free. `category` and `commodity` pick what is priced, and the other filters narrow by attribute, market and how often the price is published. ```bash theme={null} curl --globoff --request GET \ --url 'https://data-api.orbbit.co/v1/commodities?category=dairy&commodity=cheese&attributes[cheese_style]=cheddar®ion=us_chicago&frequency=daily&limit=1' \ --header 'authorization: Bearer YOUR_API_KEY' ``` Each result is one price series. Its `metric_name` is its readable ID, and every part of the name is also its own field. ```json theme={null} { "data": [ { "id": "data_commodity_metric_01m5jbewxffcs9j3neja9k8s4a", "metric_name": "cheese_block_cheddar_40_lb_us_chicago_wholesale_daily_close_price_usd_per_lb", "product": { "category": "dairy", "commodity": "cheese", "attributes": { "size": "40 lb", "cheese_form": "block", "cheese_style": "cheddar" } }, "region": "us_chicago", "market_level": "wholesale", "freight": "not_stated", "frequency": "daily", "price_type": "close", "unit": "usd_per_lb", "measure": "close_price", "source": "usda-mars", "first_observed_on": "2021-02-24", "last_observed_on": "2026-10-20" } ], "next_cursor": "cheese_block_cheddar_40_lb_us_chicago_wholesale_daily_close_price_usd_per_lb" } ``` **3. Pull the values** Pass the `metric_name` to Get Commodity Metric Values with a date range. Both dates are included. Leave the dates out to get the series' last year instead. ```bash theme={null} curl --request GET \ --url 'https://data-api.orbbit.co/v1/commodities/metric-values?metric_names=cheese_block_cheddar_40_lb_us_chicago_wholesale_daily_close_price_usd_per_lb&start_date=2026-10-16&end_date=2026-10-20' \ --header 'authorization: Bearer YOUR_API_KEY' ``` ```json theme={null} { "data": [ { "id": "data_commodity_metric_01m5jbewxffcs9j3neja9k8s4a", "metric_name": "cheese_block_cheddar_40_lb_us_chicago_wholesale_daily_close_price_usd_per_lb", "unit": "usd_per_lb", "start_date": "2026-10-16", "end_date": "2026-10-20", "values": [ { "date": "2026-10-16", "value": 1.6825 }, { "date": "2026-10-19", "value": 1.73 }, { "date": "2026-10-20", "value": 1.8 } ] } ] } ``` Response trimmed: each series also repeats the fields from the list. Each value is one trading day, in date order. `start_date` and `end_date` show the dates that were used. Listing series was free and this call cost 1¢. See [Pricing & Billing](/pricing). ## What to do next * Compare several series at once: pass up to 100 metric names, comma-separated, to [Get Commodity Metric Values](/api-reference/commodities/get-commodity-metric-values). * Understand the default date range: see [Commodities](/market-data/commodities#when-you-leave-out-the-dates). * Look up a packaged food: see [Search Branded Foods](/api-reference/branded-food/search-branded-foods). * Handle errors: see [Errors](/errors) for every error your code should expect. * Let your AI assistant do it: see [Use With Claude](/for-agents/use-with-claude).