> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbbit.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Commodities

> Market prices for raw ingredients, straight from the USDA: find a series in the catalog, then pull its prices by date.

Use this when you need the price history of a raw ingredient — 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 search the catalog to find the series you want. Then you ask for that series' prices by date.

| Step | Endpoint                     | Scope                  |
| ---- | ---------------------------- | ---------------------- |
| 1    | `GET /v1/commodities`        | `search-commodities`   |
| 2    | `GET /v1/commodities/prices` | `get-commodity-prices` |

## What a series is

A series is one number a USDA report publishes over time — for example, "the daily closing price of Grade AA butter on the CME spot market, in dollars per pound". Each series has a `slug`: a readable, permanent ID such as `butter-cme-spot-close-daily`.

Orbbit publishes a fixed catalog of series that it checks by hand. You never see USDA's raw internal IDs, and a slug never changes meaning. The full list is in the [series catalog](#series-catalog) below.

## Search the catalog

`GET /v1/commodities` lists the series in the catalog, grouped by commodity.

| Parameter   | Type   | Required | Description                                                                                                          |
| ----------- | ------ | -------- | -------------------------------------------------------------------------------------------------------------------- |
| `commodity` | string | No       | Keep only series whose commodity name or slug contains this text, ignoring case. Leave it out for the whole catalog. |

<CodeGroup>
  ```bash Request theme={null}
  curl --request GET \
    --url 'https://api.orbbit.co/v1/commodities?commodity=cheese' \
    --header 'authorization: Bearer YOUR_API_KEY'
  ```

  ```json Response theme={null}
  {
    "data": [
      {
        "commodity": "Cheese",
        "series": [
          {
            "slug": "cheese-block-cme-spot-close-daily",
            "spec": "40 pound Block",
            "market": "CME spot call, Chicago",
            "measure": "close_price",
            "unit": "USD/lb",
            "frequency": "daily",
            "source": "usda-mars",
            "report": "CME Group Daily Cash Trading",
            "first_observed_on": "2019-01-02",
            "last_observed_on": "2026-09-22"
          },
          {
            "slug": "cheese-barrel-cme-spot-close-daily",
            "spec": "Barrels",
            "market": "CME spot call, Chicago",
            "measure": "close_price",
            "unit": "USD/lb",
            "frequency": "daily",
            "source": "usda-mars",
            "report": "CME Group Daily Cash Trading",
            "first_observed_on": "2019-01-02",
            "last_observed_on": "2026-09-22"
          }
        ]
      }
    ]
  }
  ```
</CodeGroup>

Response trimmed for clarity. Values are illustrative.

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 prices.

## Get prices

`GET /v1/commodities/prices` returns dated prices for one or more series.

| Parameter | Type   | Required | Description                                                                         |
| --------- | ------ | -------- | ----------------------------------------------------------------------------------- |
| `series`  | string | Yes      | One or more slugs, comma-separated. At most 100.                                    |
| `from`    | string | No       | First date to include, as `YYYY-MM-DD`. Leave it out to start at the first reading. |
| `to`      | string | No       | Last date to include, as `YYYY-MM-DD`. Leave it out to run to the latest reading.   |

<CodeGroup>
  ```bash Request theme={null}
  curl --request GET \
    --url 'https://api.orbbit.co/v1/commodities/prices?series=butter-cme-spot-close-daily&from=2026-09-18&to=2026-09-22' \
    --header 'authorization: Bearer YOUR_API_KEY'
  ```

  ```json Response theme={null}
  {
    "data": [
      {
        "slug": "butter-cme-spot-close-daily",
        "unit": "USD/lb",
        "points": [
          { "date": "2026-09-18", "value": 2.5125 },
          { "date": "2026-09-21", "value": 2.5 },
          { "date": "2026-09-22", "value": 2.4875 }
        ]
      }
    ]
  }
  ```
</CodeGroup>

Values are illustrative.

### Understanding the response

* `data` has one entry per slug you asked for, in the order you asked.
* `unit` tells you how to read `value` — `USD/lb` is dollars per pound, `USD/cwt` is dollars per hundred pounds.
* `points` is in date order. Days with no reading, such as weekends for a daily series, are simply absent.
* `value` is exactly the number USDA published, with no rounding. CME prices, for example, move in quarter-cents and keep all four decimal places.
* A range with no readings returns the series with an empty `points` array, not an error.

## Compare several series in one call

Pass several slugs to line up prices side by side. This request compares the daily CME block and barrel cheese prices over the same week.

```bash theme={null}
curl --request GET \
  --url 'https://api.orbbit.co/v1/commodities/prices?series=cheese-block-cme-spot-close-daily,cheese-barrel-cme-spot-close-daily&from=2026-09-15&to=2026-09-19' \
  --header 'authorization: Bearer YOUR_API_KEY'
```

If any slug is not in the catalog, the whole request fails with `400` and the message names the unknown slug — so a typo never silently drops a series.

```json 400 — unknown slug theme={null}
{
  "error": {
    "type": "invalid_request",
    "message": "Unknown series: cheese-cme-spot-close-daily"
  }
}
```

## Series catalog

These are all the series you can pass to `GET /v1/commodities/prices`. Call `GET /v1/commodities` for the live list, including each series' first and last date.

### CME spot market (source `usda-mars`)

Prices from the CME Group's daily spot trading session in Chicago, as reported by USDA Market News. Unit: `USD/lb`.

| Product         | Spec           | Daily close                            | Weekly average                            | Monthly average                            |
| --------------- | -------------- | -------------------------------------- | ----------------------------------------- | ------------------------------------------ |
| Butter          | Grade AA       | `butter-cme-spot-close-daily`          | `butter-cme-spot-average-weekly`          | `butter-cme-spot-average-monthly`          |
| Cheese          | 40 pound Block | `cheese-block-cme-spot-close-daily`    | `cheese-block-cme-spot-average-weekly`    | `cheese-block-cme-spot-average-monthly`    |
| Cheese          | Barrels        | `cheese-barrel-cme-spot-close-daily`   | `cheese-barrel-cme-spot-average-weekly`   | `cheese-barrel-cme-spot-average-monthly`   |
| Nonfat Dry Milk | Grade A        | `nonfat-dry-milk-cme-spot-close-daily` | `nonfat-dry-milk-cme-spot-average-weekly` | `nonfat-dry-milk-cme-spot-average-monthly` |
| Dry Whey        | Extra Grade    | `dry-whey-cme-spot-close-daily`        | `dry-whey-cme-spot-average-weekly`        | `dry-whey-cme-spot-average-monthly`        |

### Manufacturer sales prices (source `usda-mpr`)

Weekly average prices manufacturers actually received, from the USDA's National Dairy Products Sales Report. Unit: `USD/lb`.

| Product         | Spec                      | Slug                                 |
| --------------- | ------------------------- | ------------------------------------ |
| Butter          | Grade AA                  | `butter-sales-price-weekly`          |
| Cheese          | 40 pound Block, Cheddar   | `cheese-block-sales-price-weekly`    |
| Cheese          | 500 pound Barrel, Cheddar | `cheese-barrel-sales-price-weekly`   |
| Nonfat Dry Milk | —                         | `nonfat-dry-milk-sales-price-weekly` |
| Dry Whey        | —                         | `dry-whey-sales-price-weekly`        |

### Milk class prices (source `usda-mpr`)

Monthly minimum prices for raw milk set by the Federal Milk Marketing Orders. Unit: `USD/cwt` (dollars per hundred pounds).

| Spec                          | Slug                           |
| ----------------------------- | ------------------------------ |
| Class I, All Markets Combined | `milk-class-i-price-monthly`   |
| Class II                      | `milk-class-ii-price-monthly`  |
| Class III                     | `milk-class-iii-price-monthly` |
| Class IV                      | `milk-class-iv-price-monthly`  |

## Series fields

Returned by `GET /v1/commodities`, inside `data[].series[]`.

| Field               | Type           | Description                                                                                 |
| ------------------- | -------------- | ------------------------------------------------------------------------------------------- |
| `slug`              | string         | The series ID. Pass it to `GET /v1/commodities/prices`.                                     |
| `spec`              | string or null | The grade or package, as the report states it — for example `Grade AA` or `40 pound Block`. |
| `market`            | string         | Where the price is formed — for example `CME spot call, Chicago`.                           |
| `measure`           | string         | The report's own name for the number, such as `close_price`.                                |
| `unit`              | string         | How to read `value`: `USD/lb` or `USD/cwt`.                                                 |
| `frequency`         | string         | How often a new reading appears: `daily`, `weekly`, or `monthly`.                           |
| `source`            | string         | Who publishes the data: `usda-mars` or `usda-mpr`.                                          |
| `report`            | string         | The USDA report title — for example `CME Group Daily Cash Trading`.                         |
| `first_observed_on` | string or null | Date of the earliest reading, `YYYY-MM-DD`.                                                 |
| `last_observed_on`  | string or null | Date of the latest reading, `YYYY-MM-DD`.                                                   |

Each series is grouped under its `commodity` name (for example `Cheese`), so one commodity can hold several series.

## Price fields

Returned by `GET /v1/commodities/prices`, inside `data[]`.

| Field            | Type   | Description                       |
| ---------------- | ------ | --------------------------------- |
| `slug`           | string | The series you asked for.         |
| `unit`           | string | How to read each `value`.         |
| `points`         | array  | Readings in date order.           |
| `points[].date`  | string | The reading's date, `YYYY-MM-DD`. |
| `points[].value` | number | The price, exactly as published.  |

## Validation rules

| Rule                  | Behavior                                                                                  |
| --------------------- | ----------------------------------------------------------------------------------------- |
| `series` is required  | Leaving it out returns `400`.                                                             |
| At most 100 slugs     | More returns `400`.                                                                       |
| Every slug must exist | One unknown slug fails the whole request with `400 Unknown series: <slug>`.               |
| Dates                 | `from` and `to` must be real calendar days written `YYYY-MM-DD`; `2026-02-30` is refused. |
| Date order            | `from` later than `to` returns `400`.                                                     |
| Both dates included   | A reading dated exactly `from` or `to` is returned.                                       |
| Empty filter          | `?commodity=` with no text is the same as leaving it out.                                 |

## Summary

| Detail     | `GET /v1/commodities`               | `GET /v1/commodities/prices`         |
| ---------- | ----------------------------------- | ------------------------------------ |
| Scope      | `search-commodities`                | `get-commodity-prices`               |
| Parameters | `commodity`                         | `series`, `from`, `to`               |
| Response   | `{ data: [{ commodity, series }] }` | `{ data: [{ slug, unit, points }] }` |
| Paged      | No                                  | No                                   |
| Errors     | `400`, `401`, `403`                 | `400`, `401`, `403`                  |

## What to do next

* **Try it live** — [Search commodity series](/api-reference/commodities/search-commodity-series) and [Get commodity prices](/api-reference/commodities/get-commodity-prices).
* **Handle errors** — see [Errors](/errors).
* **Let your AI assistant do it** — see [AI agents](/ai-agents).
