directrate

AI agents

A hotel pricing API your agent can budget against, in credits it can read before it calls.

Eleven chains and five OTAs behind one key, every answer a JSON document with its own price in the X-Credits-Charged header. The price list is data (/pricing.json), errors are free, the quota is checked before a call, and a Free key gets 250 credits a month without a card. Also on Apify as an Actor; an MCP server is planned.

Worked example

A Hyatt night, with its price on the response: 1 credit.

One POST /shop on Hyatt Place Chicago/Downtown-The Loop (CHIZP) for 2026-11-10: 58 rate rows, the public and member lowest, and X-Credits-Charged: 1. The same hotel in points cost 1 credit more.

Lowest public, after tax
$621.97
Lowest member, after tax
$609.53
Lowest points (POST /award)
15,000 · 4.06 ¢/pt
X-Credits-Charged
1 + 1
Latency, live
27.7 s · 4.0 s
  • ·Credits, not requests. A shop on 8 of 11 chains is 1 credit; Radisson 3, Best Western 5, Wyndham 6. A cached answer is 0.25×. Errors and unknown codes are free. All of it is in /pricing.json.
  • ·The price is on the answer. X-Credits-Charged on every response, and GET /usage for the account's position, free.
  • ·On Apify already. The hotel-rates-award-points Actor is a thin wrapper around this API, same credits, for agents that live on Apify.
  • ·MCP: planned. The modes as tools behind the same key is on the roadmap, without a date. The OpenAPI document at api.directrate.dev/openapi.json is what to generate a tool set from today.

Shopped 2026-10-11 09:26Z; Starter buys credits at $9.67 per thousand, Growth at $6.6.

curl -si https://api.directrate.dev/v1/shop \
  -H "x-api-key: $DIRECTRATE_API_KEY" \
  -H "content-type: application/json" \
  -d '{"chain":"hyatt","hotel_code":"CHIZP","checkin":"2026-11-10","los":1,"occupancy":{"adults":2}}'
HTTP/2 200
content-type: application/json; charset=utf-8
x-credits-charged: 1

{
  "chain": "hyatt",
  "hotel": {
    "code": "CHIZP",
    "name": "Hyatt Place Chicago/Downtown-The Loop",
    "currency": "USD"
  },
  "checkin": "2026-11-10",
  "los": 1,
  "status": "available",
  "rates_total": 58,
  "lowest": {
    "bar": 621.97,
    "bar_after_tax": 621.97,
    "member_after_tax": 609.53,
  … 5 more lines
}

shopped 2026-10-11 09:26Z, live; the body is trimmed to its summary fields — 58 rate rows came back

{
  "currency": "USD",
  "unit": "credit",
  "tiers": [
    {
      "id": "free",
      "monthly_credits": 250,
      "price_usd_month": 0,
      "usd_per_1000_credits": null
    },
    {
      "id": "starter",
      "monthly_credits": 3000,
      "price_usd_month": 29,
      "usd_per_1000_credits": 9.67
    },
    {
      "id": "growth",
      "monthly_credits": 15000,
      "price_usd_month": 99,
      "usd_per_1000_credits": 6.6
    },
    {
      "id": "scale",
      "monthly_credits": 75000,
      "price_usd_month": 349,
      "usd_per_1000_credits": 4.65
    }
  ],
  "chain_weights": {
    "hyatt": {
      "shop": 1,
      "compset_hotel": 0.25,
      "compset_member_extra": null,
      "calendar_night": 0.1
    },
    "marriott": {
      "shop": 1,
      "compset_hotel": 0.25,
      "compset_member_extra": null,
      "calendar_night": 0.1
    },
    "radisson": {
      "shop": 3,
      "compset_hotel": 0.5,
      "compset_member_extra": 2.5,
      "calendar_night": 0.1
    },
    "wyndham": {
      "shop": 6,
      "compset_hotel": 0.5,
      "compset_member_extra": 5.5,
      "calendar_night": 0.25
    },
    "…": "16 sources"
  },
  "rules": {
    "cache_hit_multiplier": 0.25,
    "errors_billed": false,
    "not_found_billed": false,
    "credits_header": "X-Credits-Charged",
    "quota_checked_before_call": true
  },
  "openapi": "https://api.directrate.dev/openapi.json"
}

an excerpt of https://directrate.dev/pricing.json, built from the same data as the pricing page

{
  "plan": "free",
  "period": "2026-10",
  "credits_used": 41.25,
  "credits_used_this_key": 41.25,
  "credits_limit": 250,
  "credits_remaining": 208.75,
  "rate_limit_rps": 2
}

the shape of GET /v1/usage with illustrative values: free to call, answered even when the quota is exhausted — an agent checks it before a batch

What you'd call

4 endpoints, one key.

GET/pricing.json
The price list as data: tiers, credits per source, the billing rules, a link to the OpenAPI document. Read it once and budget a task in credits before the first call.
POST/v1/shop
One hotel × dates: every room and rate plan with the public and member price kept apart, tax basis stated per row, the lowest of each. 1 credit on 8 of 11 chains.
POST/v1/award
The same stay in points, with cpp against the after-tax cash rate and the certificates that cover it — the answer to "cash or points?".
POST/v1/parity
The direct rate beside the five OTAs for the same room, cheapest channel named — the answer to "where is this cheapest?". Billed as the shops it made.

Every endpoint is in the API reference; the request bodies are the Zod schemas the gateway validates with.

A month in credits

An agent that answers a few hundred hotel questions a month.

Weights are the ones the gateway bills with; a result served from a recent cache is a quarter of the live price, and errors cost nothing.

WhatCallsCredits eachCredits
"What does this hotel cost?" — /shop1 credit on a 1-credit chain; a repeat within the cache window is 0.255001500
"Cash or points?" — /award3001300
"Where is it cheapest?" — /parity5.25 credits as the Choice example on the revenue-managers page cost live1005.25525
"Which hotel is that?" — GET /hotels2001200
A month1,525

Fits the Starter plan (3,000 credits, $29/month). All plans and weights.

Agent answers per month, by plan

Free · 250 credits
34
Starter · 3,000 credits
413
Growth · 15,000 credits
2,068
Scale · 75,000 credits
10,344

One agent answer = 7.25 credits live, as costed above.

FAQ

AI agents: questions before the first call

How does an agent know what a call will cost before it makes it?

From /pricing.json: every source has a fixed weight per shop (1 credit on 13 of 16 sources, up to 6 on Wyndham), a cached answer is 0.25× that, errors and unknown hotel codes are free, and the quota is checked before a call so a request that would exceed it is refused with 429 quota_exceeded rather than half-billed. After the call, X-Credits-Charged on the response is the number written to usage, and GET /usage is free.

Why credits and not requests?

Because the sources are not equally expensive to read: a Wyndham shop rides a TLS appliance and costs six times a Hyatt one, and a 25-hotel comp set on Marriott is one upstream call while the same on Hilton is 25. Credits price the work, so a cheap question stays cheap and a batch is not penalised for being one call. The weights are public and fixed per source; a plan buys credits, from 250 free a month to $99 for 15,000 on Growth.

Is there an MCP server, or an Apify Actor?

The Apify Actor (hotel-rates-award-points) wraps the same API for agents that already run on Apify, with the same credits and the same output rows. An MCP server on the gateway — the six modes and the hotel-code search as tools behind the same key — is planned; there is no date, and the REST API with its OpenAPI document is what to build on today. Ask hello@directrate.dev if MCP is what decides it for you.

Start with 250 credits a month. No card, no call.

Every response states its own price in X-Credits-Charged; the playground runs any of these calls with no code.