Bilt logo

Bilt

Community
borski
bilt

Search Bilt Rewards travel portal for cash and Bilt Points pricing on hotels and flights. Public REST API, no auth required. Includes Home Away From Home (HaFH) properties with $300+ benefits.

Overview

Publisherborski
Repositorytravel-hacking-toolkit
Skill namebilt
Stars
690
Forks
75
Bundled files
Instructions only
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by borski on GitHub. Read the source before you install it.

Installation

Install the Bilt AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/borski/travel-hacking-toolkit/tree/main/plugins/travel-hacking-toolkit/skills/bilt
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/borski/travel-hacking-toolkit.git /tmp/travel-hacking-toolkit
mkdir -p .claude/skills
cp -r /tmp/travel-hacking-toolkit/plugins/travel-hacking-toolkit/skills/bilt .claude/skills/bilt
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Bilt in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Bilt on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Bilt is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Bilt Travel Portal Search

Search Bilt Rewards travel portal via the public REST API. No authentication required for search. Returns both cash prices in USD and Bilt Points cost for hotels and flights.

Important: Bilt is Whitelabel Duffel

Bilt's travel search is built directly on top of Duffel. All evidence points to a complete white-label arrangement, not a partial integration:

  • Flight offer IDs are off_XXX, slices sli_XXX, segments seg_XXX, aircraft arc_XXX, airlines arl_XXX. All Duffel ID patterns.
  • Carrier and aircraft logos served from assets.duffel.com.
  • Hotel loyalty program logos served from assets.duffel.com/img/stays/loyalty-programmes. So hotels are Duffel Stays.
  • JWT organisation_id: org_0000AaALZyFQ... is a Duffel auth pattern.
  • Field names match Duffel exactly: marketingCarrier, operatingCarrier, cabinClassMarketingName, fareBasisCode, isNDC, ndcRedirectUrl, totalEmissionsKg, slices[].segments[].passengers[].baggages[].

What Bilt adds on top of Duffel:

  • totalPointsRequired (Bilt Points cost at the fixed 1.25 cpp portal rate)
  • isHafh (Home Away From Home flag on hotels)
  • loyaltyProgram.reference (brand affiliation surfacing for hotels)
  • A few Bilt-specific filter fields

What this means for the toolkit:

  • For cash-only flight searches, prefer the duffel skill. It uses an authenticated Duffel API key, returns the same data faster, and supports more parameters (multi-city, time windows, max connections, supplier_timeout tuning).
  • For Bilt Points context (CPP, comparing portal cost to award alternatives, Bilt redemption math), use this skill. The points pricing is exclusive to Bilt's endpoint.
  • For Home Away From Home property research, use this skill. The isHafh flag is Bilt-specific and surfaces the $300+ benefits properties.

Why It Matters

  • 1.25 cpp standard redemption rate on Bilt Points (1 USD = 80 points). One of the better fixed portal rates.
  • Home Away From Home (HaFH) is Bilt's premium hotel program. Gold and Platinum members get $300+ in benefits per stay (daily breakfast for two, $100 property credit, room upgrades on arrival, early check-in / late check-out, dedicated Virtuoso Travel Advisor).
  • Bilt Points transfer 1:1 to Hyatt, Marriott, Hilton, IHG, United, AA, Air Canada Aeroplan, Air France/KLM, Virgin Atlantic, Cathay, Turkish, and more — so this portal is a 1.25 cpp "bottom-of-the-barrel" comparison point for transfer-partner award searches.
  • Flights are Duffel-backed. Same response shape as the duffel skill. Same airlines, same fare classes, same segment structure.
  • No auth needed for search. Browser automation, login, 2FA all unnecessary. Just curl.

When to Use

  • Comparing Bilt portal pricing to seats.aero awards
  • Computing CPP for Bilt Points redemptions
  • Finding HaFH properties for Bilt Gold/Platinum benefit stacking
  • Sanity-checking cash vs points decision when Bilt Points are involved
  • As a "redemption floor" reference: if award flights cost more than the portal price, the portal wins

When NOT to Use

  • Cash-only flight searches without Bilt Points context. Use duffel instead. Bilt is whitelabel-Duffel, so Duffel returns the same cash prices and offer shape, faster, with more parameters supported.
  • Booking flights or hotels. This skill finds offers only. Booking requires login + Bilt Mastercard. Out of scope.
  • Award flight search. Use seats-aero for award availability across loyalty programs.
  • Hotel research outside Bilt's program. Use premium-hotels for Amex FHR/THC + Chase Edit, serpapi for general Google Hotels metasearch.

Bilt Points Valuation

MetricValueNotes
Portal redemption rate1.25 cpp$1 = 80 points (standard, fixed)
Cash → points formulapoints = round(usd / 0.0125)Reverse-derived from observed responses
TPG valuation (transfers)2.05 cppWhen transferred to optimal partners

Decision rule: If transferring Bilt Points to a partner program would yield more than 1.25 cpp, transfer. If not, use the portal.

API Base

https://api.biltrewards.com/public/travel

All endpoints are public, no API key required. Standard JSON responses.

Hotel Search

Step 1: Look up location searchId

bash
curl -s "https://api.biltrewards.com/public/travel/hotels/auto-complete?query=New+York" \
  | jq '.searchResults[0].locationSuggestion'

Returns:

json
{
  "name": "New York",
  "country": {"name": "USA", "code": "US"},
  "region": {"name": "NY", "code": null},
  "searchId": "ChIJOwg_06VPwokRYv534QaPC8g"
}

The searchId is a Google Places ID. You can also pass searchType: HOTEL_SEARCH results to search a specific property.

Step 2: Search hotels

bash
curl -s "https://api.biltrewards.com/public/travel/hotels/search" \
  --get \
  --data-urlencode "checkInDate=2026-08-15" \
  --data-urlencode "checkOutDate=2026-08-18" \
  --data-urlencode "numGuestAdults=2" \
  --data-urlencode "numRooms=1" \
  --data-urlencode "searchId=ChIJOwg_06VPwokRYv534QaPC8g" \
  | jq '.hotelResults | length'

Returns 100 to 200 hotels typically. Synchronous, no polling needed.

Required parameters

ParameterTypeDescription
checkInDateYYYY-MM-DDRequired
checkOutDateYYYY-MM-DDRequired
numGuestAdultsintRequired, 1+
numRoomsintRequired, 1+
searchIdstringGoogle Places ID from auto-complete

Optional parameters

ParameterTypeDescription
childrenAgescsv intsE.g. 5,8 for two children aged 5 and 8
hotelIdstringSearch a specific acc_XXX property

Hotel response shape

{
  stayDetails: { checkInDate, checkOutDate, numRooms, numGuestAdults, childrenAges },
  hotelResults: [
    {
      id: "acc_XXX",
      name: "Park Hyatt New York",
      rating: 5,                      // star rating
      description: "...",
      isHafh: true,                   // Home Away From Home flag
      loyaltyProgram: {               // brand affiliation, if any
        name: "World of Hyatt",
        reference: "world_of_hyatt",
        logoUrl: "..."
      },
      address: { street, city, stateProvince, countryCode, postalCode },
      geolocation: { latitude, longitude },
      amenities: [{ description, category }, ...],
      images: [{ url }, ...],
      lowestRateDetails: {
        usdAmounts: { total },        // cash total in USD
        points: 319681,               // Bilt Points cost
        dueAtHotelAmount, dueAtHotelCurrency,
        ...
      }
    }
  ],
  filterDetails: { ... }
}

Hotel detail (room rates)

bash
curl -s "https://api.biltrewards.com/public/travel/hotels/acc_0000AWPt2s3aNc1GpC5bmU?checkInDate=2026-08-15&checkOutDate=2026-08-18&numGuestAdults=2&numRooms=1" \
  | jq '.hotelDetails | {name, isHafh, rates: .roomTypes[0]}'

Returns hotelDetails with full property info plus roomTypes containing each available rate.

Useful jq filters

bash
# Top 10 cheapest hotels with HaFH flag and CPP rounded to 2 decimals
curl -s "$URL" | jq '
  [.hotelResults[]
   | select(.lowestRateDetails.usdAmounts.total != null)
   | {name, isHafh, rating,
      cash: .lowestRateDetails.usdAmounts.total,
      points: .lowestRateDetails.points,
      cpp: (((.lowestRateDetails.usdAmounts.total / .lowestRateDetails.points) * 100) * 100 | round / 100),
      brand: .loyaltyProgram.name}]
  | sort_by(.cash) | .[0:10]'

# Only HaFH properties (worth $300+ benefits if Gold/Platinum)
curl -s "$URL" | jq '
  [.hotelResults[]
   | select(.isHafh == true)
   | {name, rating, cash: .lowestRateDetails.usdAmounts.total, points: .lowestRateDetails.points}]
  | sort_by(.cash)'

Flight Search

Step 1: Submit search

bash
curl -s "https://api.biltrewards.com/public/travel/flights/search" \
  --get \
  --data-urlencode "departureDate=2026-08-15" \
  --data-urlencode "returnDate=2026-08-22" \
  --data-urlencode "origin=SFO" \
  --data-urlencode "destination=NRT" \
  --data-urlencode "adults=1" \
  --data-urlencode "cabinClass=business"

Returns:

json
{
  "data": {
    "id": "orq_0000B5mQkPhO7VxuWClhZI",
    "totalBatches": 35,
    "remainingBatches": 35,
    "createdAt": "...",
    "clientKey": "..."
  }
}

Step 2: Poll for results

bash
curl -s "https://api.biltrewards.com/public/travel/flights/search/$ID"

remainingBatches ticks down to 0 over 5 to 15 seconds. The response includes the offers array as soon as the first batch returns. Poll every 3 to 5 seconds until remainingBatches == 0 for the complete result set.

bash
# Polling loop
for i in 1 2 3 4 5; do
  RESP=$(curl -s "https://api.biltrewards.com/public/travel/flights/search/$ID")
  REMAINING=$(echo "$RESP" | jq -r '.data.remainingBatches')
  echo "Poll $i: $REMAINING batches remaining"
  [ "$REMAINING" = "0" ] && break
  sleep 4
done
echo "$RESP" | jq '.data.offers | length'

Required parameters

ParameterTypeDescription
departureDateYYYY-MM-DDRequired
originIATA airport codeRequired
destinationIATA airport codeRequired
adultsintRequired, 1+

Optional parameters

ParameterTypeDescription
returnDateYYYY-MM-DDRound-trip, omit for one-way
cabinClassstringeconomy, premium_economy, business, first
childrenintNumber of children (with childrenAges)
infantsintLap infants

Flight response shape

Same as Duffel (Bilt is whitelabel-Duffel). Each offer:

{
  id: "off_XXX",
  totalAmount: 1606.60,        // cash total
  totalCurrency: "USD",
  baseAmount: 1132.00,
  taxAmount: 474.60,
  totalPointsRequired: 128528,  // Bilt Points cost
  totalPointsRequiredWithCredits: null,  // applicable airline credits, if any
  expiresAt: "2026-04-29T08:51:40Z",
  owner: {
    name: "KLM", iataCode: "KL", logoSymbolUrl, conditionsOfCarriageUrl
  },
  isNDC: false,
  passengers: [{ type, loyaltyProgrammeAccounts, id }],
  conditions: { refundBeforeDeparture, changeBeforeDeparture },
  slices: [
    {
      id: "sli_XXX",
      duration: "P1DT4H40M",   // ISO 8601 duration
      fareBrandName: "Standard",
      origin: { iataCode, name, cityName, timeZone },
      destination: { iataCode, name, cityName, timeZone },
      segments: [
        {
          id, duration, departingAt, arrivingAt,
          origin: {...}, destination: {...},
          marketingCarrier: { name, iataCode, ... },
          operatingCarrier: { name, iataCode, ... },
          marketingCarrierFlightNumber: "0606",
          aircraft: { name: "Boeing 787-10", iataCode: "781" },
          stops: [],
          passengers: [
            {
              passengerId,
              fareBasisCode: "THA79NMP",
              cabinClassMarketingName: "ECONOMY",
              baggages: [{ type: "checked"|"carry_on", quantity }]
            }
          ]
        }
      ]
    }
  ]
}

Useful jq filters

bash
# Top 5 cheapest offers with CPP calculation (rounded to 2 decimals)
echo "$RESP" | jq '
  [.data.offers[]
   | {airline: .owner.name,
      cash: .totalAmount,
      points: .totalPointsRequired,
      cpp: (((.totalAmount / .totalPointsRequired) * 100) * 100 | round / 100),
      stops: ([.slices[].segments | length] | map(. - 1)),
      route: ([.slices[] | (.origin.iataCode + " -> " + .destination.iataCode)])}]
  | sort_by(.cash) | .[0:5]'

# Group by airline, show cheapest per carrier
echo "$RESP" | jq '
  [.data.offers[]
   | {airline: .owner.name, cash: .totalAmount, points: .totalPointsRequired}]
  | group_by(.airline)
  | map({airline: .[0].airline, cheapest: (min_by(.cash))})'

# Filter to nonstop only
echo "$RESP" | jq '
  [.data.offers[]
   | select(([.slices[].segments | length] | add) == ([.slices | length]))
   | {airline: .owner.name, cash: .totalAmount, points: .totalPointsRequired}]'

Output Format

Always use markdown tables. When showing both flights and hotels, separate tables.

Hotels

HotelStarsHaFHBrandCashPointsCPP
Park Hyatt New York5yesHyatt$3,996319,6811.25
The St. Regis NY5noMarriott$4,210336,8001.25

Flights (one-way SFO to NRT)

AirlineStopsDurationCashPointsCPP
Air Canada1 (YVR)14h 5m$87169,7201.25
KLM1 (AMS)28h 40m$1,607128,5281.25

After tables: highlight the cheapest, flag any HaFH stays the user qualifies for (Bilt Gold or Platinum status required), and call out anything where CPP is wildly off (would indicate a special promo or a points-only "boost" rate).

Comparison Workflow

For a complete trip cost analysis:

  1. Bilt Points balance via awardwallet. Note: Bilt is in AwardWallet.
  2. Award alternatives via seats-aero. Compare to portal price at 1.25 cpp.
  3. Transfer partners via transfer-partners. If a partner program redeems Bilt Points at >1.25 cpp, transfer instead of using portal.
  4. Other portals via chase-travel (dynamic Points Boost on CSR/CSP, ~1.5-2.0 cpp on select bookings, not a guaranteed floor) and amex-travel (~1.0 cpp on flights). Pull actual portal quotes, not assumed rates.
  5. HaFH benefits add ~$300+ in value per stay if the user has Bilt Gold or Platinum status. Apply this when computing effective rate.

Important Notes

  • isHafh: true identifies Home Away From Home properties. Roughly 200 to 300 luxury hotels worldwide. Always flag when present.
  • Bilt has no transfer fees. Unlike some portal-points conversions, Bilt → partner transfers are 1:1 instant.
  • Booking requires the Bilt card. Most premium benefits (HaFH, Rent Day points multipliers, status) are gated by holding the Bilt Mastercard.
  • API responses don't include the agent's user context. This is the public unauthenticated path. Authenticated calls would return personalized data (your saved searches, points balance), but those require login. Out of scope for this skill.
  • Stellate (bilt-rewards.stellate.sh) is Bilt's CMS endpoint, not a search backend. It serves marketing copy and benefit descriptions. The actual hotel/flight search data comes from api.biltrewards.com/public/travel and is fully covered above.

Frequently asked questions

What does the Bilt AI skill do?

Search Bilt Rewards travel portal for cash and Bilt Points pricing on hotels and flights. Public REST API, no auth required. Includes Home Away From Home (HaFH) properties with $300+ benefits.

Why use Bilt on TypingMind?

Because you install it once and use it with any model. Bilt is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Bilt in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/borski/travel-hacking-toolkit/tree/main/plugins/travel-hacking-toolkit/skills/bilt. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Bilt?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Bilt?

As many as you like. As long as a model supports skills, you can use Bilt with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Bilt AI skill free?

Yes. It is published on GitHub by borski under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇