mcpField
L
letsfg

letsfg

github.com/letsfgOther2.2k58 installsUpdated 3d ago
Repository

About letsfg

LetsFG is a flight and hotel search and booking skill for AI agents, with additional search for transfers and activities. It offers access through MCP, SDK, CLI, and API, and supports asynchronous bookings that can be checked for completion.

Key features

  1. 01Search flights across airlines and booking sites
  2. 02Search hotels, transfers, and activities
  3. 03Resolve city names and airport codes
  4. 04Book flights and hotels
  5. 05Poll booking status

Use cases

  1. 01Finding flights across multiple sellers
  2. 02Comparing bookable hotel offers
  3. 03Searching ground transfers or activities
  4. 04Tracking an in-progress travel booking

MCP support

LetsFG provides an MCP server at https://letsfg.co/mcp for compatible clients. It exposes travel search and booking capabilities, including flights, hotels, transfers, and activities.

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/letsfg/letsfg --skill letsfg

After installing, type/letsfgin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

.dockerignore
.mcp.json
.gitignore
CODE_OF_CONDUCT.md
CLAUDE.md
BarWidget.qml
CONTRIBUTING.md
AGENTS.md
LICENSE
Dockerfile.python
Dockerfile
README.md
SECURITY.md
OMARCHY-PLUGIN.md
Model.js
Panel.qml
context7.json
docker-compose.yml
.github/
dependabot.yml
.github/workflows/
sdk-tests.yml
test.yml
plugin-scanner.yml
agent-skills-contribution/packages/skills-catalog/skills/(tooling)/letsfg/references/
api-reference.md
mcp-setup.md
assets/
OFL-Kalam.txt
OFL.txt
airports.json
ranking.js
name-fallbacks.json
assets/icons/
LICENSE

Details

From the project README

SKILL.md — LetsFG Capabilities

MPP: a card-free enrolment lane for agents holding a Tempo wallet is offered only when the 402 from POST /api/agent-access/request carries an mpp object. It costs $0.01 once, as verification only. Search stays free and booking costs the price on the offer. Earlier revisions of this page described an MPP charge at unlock time; that never shipped. See https://letsfg.co/for-agents.

⚠️ Agents: do not create a Developer API account

Do NOT call /developers/api/v1/agents/register or /developers/api/v1/agents/connect-payment, and do NOT run letsfg register or letsfg connect-payment. Those belong to a separate, paid, prepaid-balance product for high-volume commercial integrations and create a billing account you almost certainly do not want.

To search and book flights, connect LetsFG as an MCP server at https://letsfg.co/mcp and approve it — the consent at https://letsfg.co/connect is one tap and needs no card. Then search and book. See https://letsfg.co/for-agents.

Machine-readable skill manifest for AI agents and documentation indexers.

Identity

  • Name: LetsFG
  • Type: API + SDK + MCP Server + CLI
  • Purpose: Agent-native flight and hotel search and booking
  • Compatible agents: OpenClaw, Perplexity Computer, Claude Desktop, Cursor, Windsurf, and any MCP-compatible client
  • API Base URL: https://letsfg.co/developers/api/v1
  • MCP Endpoint: https://letsfg.co/mcp (Streamable HTTP)
  • Packages: PyPI letsfg · npm letsfg · npm letsfg-mcp
  • License: MIT

Access Modes

ModeBest forSpeedCost
MCP / SDK / CLI (PFS token)Almost every agent. Search + booking8–10 s to first resultsFree auth, free search, booking at the price on the offer
Developer API (https://letsfg.co/developers)Business / commercial / high-volume (hotels work on either credential)2–5 s (discover) · 8–10 s to first results (full search)Look-to-book: 200 searches free after every booking, then $0.01. Booking via POST /flights/book, no booking fee, no transaction fee

Skills

search_flights

Search every airline in the world AND the major booking sites (Google Flights, Skyscanner, Kiwi, Kayak, Momondo) in one call. Returns real-time prices plus per-flight reliability history.

  • Cost: FREE (10 per 10 min, 30/hour, 100/day)
  • Input: origin (IATA), destination (IATA), date_from, optional: date_to, return_from, return_to, adults, children, infants, cabin_class (M/W/C/F), max_stopovers, currency, sort, limit
  • Output: List of flight offers with price, airlines, times, segments, conditions, passenger_ids
  • Note: On PFS (Bearer token), call book_flight directly — no unlock step — then poll get_flight_booking. The Developer API has no unlock step either: book with POST /flights/book and poll GET /flights/bookings/{id}.
  • Rate limit (PFS): 10 searches per 10 min, 30 per hour, 100 per day, per account (per card once one is added). Polling results never counts.
resolve_hotel_city

Resolve a place name to the supplier city id that hotel search needs.

  • Cost: FREE (a card must still be on file)
  • Endpoint: POST /api/v1/hotels/destinations
  • Input: text (place name, e.g. "Warsaw")
  • Output: Matches, best first. Use Id as city_id and Name as city_name.
search_hotels

Search real, bookable hotel inventory.

  • Cost: FREE. Searching needs no card; an account with no card on file gets a daily number of hotel searches. Booking needs a payment method on file and returns HTTP 402 without one.
  • Auth: Either a Developer API key (X-API-Key) or the PFS token from the connect flow. The same card authorises flights and hotels.
  • Endpoint: POST /api/v1/hotels/search
  • Input: city_id, city_name, check_in, check_out, adults, children, child_ages, nationality, currency (USD by default), limit
  • Output: hotels[] each with offers[] carrying price (the all-in total the guest pays, in currency), fx_rate, expected_cost, refundable, free_cancellation_until (refundable rates only), cancellation_policy, combination_id_v2 and session_id
  • Note: Every rate type is sold, refundable and non-refundable — show refundable and free_cancellation_until before booking. Keep the chosen offer's session_id and combination_id_v2; booking needs both. price is what the guest pays.
  • Allowance: 1,000 hotel searches free after every hotel booking, then blocks of 1,000 for $5.00 from prepaid balance.
search_transfers

Search ground transfers — private cars, taxis, shared shuttles, airport express.

  • Cost: FREE
  • Input: origin, destination, date, passengers
  • Output: Transfer options with prices and vehicle types
search_activities

Search activities — tours, tickets, day trips (limited supplier coverage).

  • Cost: FREE
  • Input: location, date_from, date_to
  • Output: Activity options with prices, descriptions, availability
resolve_location

Resolve city names to IATA airport/city codes.

  • Cost: FREE
  • Input: query (city name, e.g. "London")
  • Output: List of matching IATA codes (e.g. LON, LHR, LGW, STN, LTN, LCY)
unlock_flight_offer

RETIRED 2026-09-08 — the route answers 410 Gone.

  • There is no unlock step on either lane. Booking holds the fare and captures only against a real PNR, which is what unlock existed to protect against. Call /api/agent-book (PFS) or POST /flights/book (Developer API) instead.
  • Endpoint: POST /api/v1/bookings/unlock — answers 410 Gone, and the SDKs' unlock() fails the same way.
book_flight

Book an offer.

  • PFS (Bearer token): POST /api/agent-book. No unlock step — search, then book directly. Works for every offer in the results, whichever seller it came from. Exactly what the website checkout does: the price shown is held on the connected card (not taken), a LetsFG booking agent buys the ticket from the seller, and the hold is captured only once a real airline PNR exists. If the booking fails the hold is released and nothing is charged.
    • Input: search_id + offer_id exactly as search returned them (offers expire ~15 min), contact_email, and ONE passenger per call: given_name, family_name, born_on, gender (m/f), nationality (ISO-2), phone_number + phone_country, address_line1, address_city, address_postal, address_country; passport_number/country/expiry optional.
    • Output (seconds): {"state": "booking_in_progress", "booking_ref": "eyJ...", "held": {"amount": 93, "currency": "EUR", "card": "visa ending 5709"}, "charged": 0}. The booking itself takes 4–11 minutes — poll get_flight_booking.
    • Nothing charged on: {"error": "missing_details", "missing_fields": [...]} (ask, call again), payment_method_required and payment_declined (both carry add_card_url: https://letsfg.co/connect).
    • Never call it twice for the same trip while one is in progress — that places a second hold.
    • CLI: letsfg book ws_off_xxx --search-id ws_xxx --passenger '{...}' --email [email protected]
    • Python: bt.book(offer_id=..., passengers=[{...}], contact_email=..., search_id=...)
  • Developer API: POST /api/v1/flights/book. The same flow with no unlock step: the fare is held on the connected Revolut method, a LetsFG booking agent buys the ticket, and the hold is captured only against a real airline PNR. No booking fee, no transaction fee.
    • Prerequisite: a Revolut method connected with POST /api/v1/agents/connect-payment (nothing is charged to connect).
    • Input: search_id, offer_id, passengers (given_name, family_name, born_on, gender, email, phone_number, nationality, ...), contact_email, idempotency_key
    • Output: 202 with booking_id, held, charged: 0 and poll_url. Poll GET /api/v1/flights/bookings/{booking_id} until terminal: completed (pnr, charged_amount) | failed (hold released, nothing charged) | needs_attention.
  • CRITICAL (both paths): Use real passenger names (must match passport/ID) and real email (airline sends e-ticket there).
get_flight_booking

Where a booking started by book_flight has got to (PFS). POST /api/agent-book/status {"booking_ref": "eyJ..."}.

  • Cost: FREE. Poll every 20–30 s.
  • States: booking_in_progress (the agent is at the seller's checkout — keep waiting) → completed (pnr, charged_amount, currency — booked) | failed (failure_reason; the hold was released, nothing charged) | needs_attention (a human at LetsFG is checking it — do NOT book again; the traveller will be emailed). updated_at_ms says when it last moved.
  • Only completed with a PNR means booked.
book_hotel

Start a hotel booking. Returns a job, NOT a booking.

  • Cost: the offer's price. It is held on the connected card (not taken), LetsFG books the room and pays the supplier, and the hold is captured only once the hotel confirms. A failed booking releases the hold. No reservation fee, no deposit, no pay link.
  • Endpoint: POST /api/v1/hotels/book
  • Input: session_id (the chosen offer's), hotel_code, combination_id_v2, expected_price, expected_cost, currency, fx_rate, city_id, city_name, check_in, check_out, adults, guests[{title, first_name, last_name}], email, phone; optional phone_country_code, special_requests, idempotency_key
  • Output: booking_job_id, booking_id, status "in_progress", the amount held, poll URL
  • Asynchronous: a real booking takes minutes — the rate is re-blocked at the supplier, the room committed and paid. Poll get_hotel_booking until status is succeeded, failed or attention.
  • CRITICAL: send expected_price, expected_cost, currency and fx_rate back exactly as the chosen offer returned them, or the booking is refused as price_mismatch — a guest is never charged a price they did not agree to. There is no expected_balance.
  • Local packages: hotel booking needs letsfg-mcp 2026.5.77+, letsfg 2026.5.101+ (Python) or letsfg 2026.5.74+ (npm). Earlier releases send the retired expected_balance contract and every hotel booking they make is refused. The hosted MCP needs no update.
  • CRITICAL: never call this again while its job is running — poll the job. A retry with the same idempotency_key returns the existing job instead of booking twice.
  • Note: guest names, phone and e-mail are checked before anything is held (400 invalid_details).
  • CRITICAL: guests needs a name for every person in the room, children included: adults first, then children in child_ages order. Fewer names than the searched party fails the booking before anything reaches the hotel, and the hold is released.
get_hotel_booking

Collect the result of a booking started with book_hotel.

  • Cost: FREE
  • Endpoint: GET /api/v1/hotels/booking/{booking_job_id}
  • Output: status — in_progress, then succeeded (confirmation, total_price + currency = what the guest is charged, refundable, free_cancellation_until, terms with the full cancellation ladder) | failed (error; the hold was released, nothing charged) | attention (error; a person at LetsFG is confirming the outcome with the supplier, the hold is kept — do NOT book again)
  • Note: the guest is e-mailed however the booking ends.
cancel_hotel_booking

Release a hotel reservation.

  • Cost: Free on a refundable rate before free_cancellation_until — the charge is refunded in full. A cancellation the hotel would charge for (a non-refundable rate, or past that date) is refused with 409; the hotel's own ladder is in the booking's terms.
  • Endpoint: POST /api/v1/hotels/cancel
  • Input: confirmation (only your own bookings)
  • Output: confirmation, charge, refund
  • Note: drives a browser at the supplier and takes over a minute. If it times out, do NOT assume it failed — re-check before retrying.
register

Register a new AI agent.

  • Cost: FREE
  • Input: agent_name, email
  • Output: api_key (permanent credential)
connect_payment

Developer API only. POST /api/v1/agents/connect-payment returns a one-time connect_url; a person opens it in a browser and saves a card or Revolut Pay. Agents on the PFS lane do not call this — connecting at https://letsfg.co/connect needs no card, and the card is asked for at their first booking.

  • Cost: FREE — nothing is charged to connect
  • Output: connect_url (valid for one hour)
  • Note: setup_payment (POST /agents/setup-payment) was retired with Stripe on 2026-09-08 and answers 410 Gone.
get_agent_profile

Get current agent's profile, usage stats, and payment status.

  • Cost: FREE
  • Output: Agent details, search count, booking count, payment status

Authentication

PFS (recommended — almost every agent): a Bearer token from the connect flow. Connecting needs no card and nothing is charged. The card is asked for at the first booking, in a 0.00 Revolut setup at https://letsfg.co/connect (any card, or Revolut Pay / Google Pay; no Revolut account needed; card details never touch LetsFG). Search, flight booking and hotels all work with it.

Authorization: Bearer eyJ...

Get a token — the one way in:

  1. Add LetsFG as a remote MCP server: https://letsfg.co/mcp.
  2. Approve the connection. The OAuth consent step opens https://letsfg.co/connect: one tap, no card.
  3. Over the MCP the OAuth token is carried for you; over raw HTTP send it as Authorization: Bearer <token>.

POST /api/agent-access/request answers 402 with these steps as JSON (add_card_url, how). The Stripe enrolment lanes (setup_url, setup_intent, card_token) were retired on 2026-09-02 and every token they issued was revoked (401 TOKEN_REVOKED; /api/agent-access/verify answers 410 for a Stripe credential) — reconnect at letsfg.co/connect. letsfg auth (npm or PyPI) now drives that connect flow from the terminal and stores the token; the CLI and SDKs otherwise read it from LETSFG_BEARER_TOKEN. One card = one account; quotas are per account, and per card once one is added. Full flow: https://letsfg.co/for-agents.

Developer API (business / high-volume): every endpoint except register requires an X-API-Key header.

X-API-Key: letsfg_...

Get your key by calling POST /api/v1/agents/register with agent_name and email. The key is permanent — save it once.

Then connect a payment method with POST /api/v1/agents/connect-payment and open the returned connect_url once (nothing is charged).

Complete Workflow

Flight Booking — PFS (3 API calls)
1. POST /api/search                    → Search flights (FREE), returns search_id; poll GET /api/results/{search_id}
2. POST /api/agent-book                → Book directly — no unlock step. Holds the fare on the connected card, returns booking_ref in seconds
3. POST /api/agent-book/status         → Poll every 20–30 s (4–11 min) → completed (PNR) | failed (hold released) | needs_attention
Flight Booking — Developer API (5 API calls)
1. POST /api/v1/agents/register          → Get API key (once)
2. POST /api/v1/agents/connect-payment   → Open the connect_url once to save a card (nothing charged)
3. POST /api/v1/flights/search           → Search flights (look-to-book: 200 free after every booking)
4. POST /api/v1/flights/book             → Hold the fare, dispatch the booking agent → booking_id (202)
5. GET  /api/v1/flights/bookings/{id}    → Poll until terminal → completed (PNR) | failed (hold released) | needs_attention
Hotel Booking (PFS Bearer token or Developer API key — the same card authorises both)
1. Card on file (to book; search needs none) → PFS: asked for at the first booking; Developer API: POST /api/v1/agents/connect-payment
2. POST /api/v1/hotels/destinations        → Place name → city_id
3. POST /api/v1/hotels/search              → Bookable rates (card required; 1,000 free after every hotel booking)
4. POST /api/v1/hotels/book                → Holds the price; returns booking_job_id — NOT a booking
5. GET  /api/v1/hotels/booking/{job_id}    → Poll ~20s until succeeded / failed / attention
                                             → confirmation + total_price + currency
6. POST /api/v1/hotels/cancel              → Optional; free on a refundable rate before free_cancellation_until

The full price is held on the card at step 4 and captured only once the hotel confirms; a failed booking releases the hold. There is no reservation fee, no deposit and no pay link. Never repeat step 4 while its job is running — poll it.

CLI Usage

pip install -U letsfg   # 2026.5.101 or later books hotels

export LETSFG_BEARER_TOKEN=eyJ...   # token from the connect flow (see Authentication)

# Search flights — prints search_id, needed for book
letsfg search LHR JFK 2026-04-15
letsfg search LON BCN 2026-04-01 --return 2026-04-08 --cabin C --sort price
letsfg search GDN BER 2026-05-10 --adults 2 --children 1

# Resolve locations
letsfg locations "New York"

# Book — price shown on the offer, no unlock step. Holds the fare on the connected
# card and prints a booking_ref; poll POST /api/agent-book/status every 20–30 s
letsfg book ws_off_xxx --search-id ws_xxx \
  --passenger '{"given_name":"John","family_name":"Doe","born_on":"1990-01-15","gender":"m","nationality":"GB","phone_number":"+447123456789","phone_country":"GB","address_line1":"1 High St","address_city":"London","address_postal":"N1 9GU","address_country":"GB"}' \
  --email [email protected]

# Machine-readable output
letsfg search GDN BER 2026-03-03 --json

Developer API instead? letsfg register + letsfg connect-payment once (open the link it prints), then letsfg search ... --api-key letsfg_... and letsfg book off_xxx --search-id <search_id> --api-key letsfg_... --passenger '{...}' --email .... No unlock step.

Python SDK Usage

from letsfg import LetsFG

bt = LetsFG()  # reads LETSFG_BEARER_TOKEN — the token from the connect flow

# Search
results = bt.search("LHR", "JFK", "2026-04-15")
for offer in results.offers:
    print(f"{offer.price} {offer.currency} — {', '.join(offer.airlines)}")

# Book — price shown on the offer, no unlock step. Holds the fare on the
# connected card; a LetsFG agent buys the ticket; captured only on a real PNR.
result = bt.book(
    offer_id=results.offers[0].id,
    passengers=[{
        "given_name": "John", "family_name": "Doe",
        "born_on": "1990-01-15", "gender": "m", "nationality": "GB",
        "phone_number": "+447123456789", "phone_country": "GB",
        "address_line1": "1 High St", "address_city": "London",
        "address_postal": "N1 9GU", "address_country": "GB",
    }],
    contact_email="[email protected]",
    search_id=results.search_id,
)
if "missing_fields" in result:
    print("Nothing charged — ask for:", result["missing_fields"])
else:
    print("Started:", result["booking_ref"], result["held"])
    # poll POST /api/agent-book/status {"booking_ref": ...} every 20–30 s
    # until state is completed (pnr) | failed (hold released) | needs_attention

Developer API instead? LetsFG(api_key="letsfg_..."), then bt.book(offer_id, passengers, contact_email, search_id=..., idempotency_key=...) — no unlock step. It starts the booking; poll it with bt.get_booking(booking_id), or call bt.book_and_wait(...) to block until it settles.

MCP Server Setup

Remote (Streamable HTTP) — the way in for agents:

{
  "mcpServers": {
    "letsfg": { "url": "https://letsfg.co/mcp" }
  }
}

Claude Code: claude mcp add --transport http letsfg https://letsfg.co/mcp. Claude: add it from Claude's official connector directory, https://claude.ai/directory/letsfg - no URL to paste (once added, it works in Claude Desktop and the Claude phone app too). ChatGPT: at chatgpt.com in a browser (the ChatGPT phone app has no way to add one), Plugins > Add > Add custom MCP server, that URL, authentication OAuth; once added it works in the phone app too. Windsurf uses "serverUrl" instead of "url". The client runs OAuth; the consent step opens https://letsfg.co/connect: one tap, no card. The token the client receives can search at once, and the card is asked for at the first booking. Developer API accounts can use the same URL with "headers": {"X-API-Key": "letsfg_..."} instead of OAuth.

Local (stdio) — needs a token you already hold:

npm install -g letsfg-mcp@latest   # 2026.5.77 or later books hotels
LETSFG_BEARER_TOKEN=eyJ...  letsfg-mcp   # token from the connect flow

The local server also accepts LETSFG_API_KEY instead, for the Developer API. book_flight dispatches automatically based on which one is set. Its authenticate tool returns the current connect instructions (add_card_url, how); run letsfg auth to mint a token from the terminal.

MCP Tools

ToolDescriptionCost
search_flightsSearch every airline in the world via server-side engineFREE
resolve_locationCity name → IATA codeFREE
book_flightStart a booking. PFS: direct, no unlock step — holds the fare on the connected card, returns booking_ref. Developer API key: the same call, no unlock stepPrice shown on the offer, no separate LetsFG fee (PFS)
get_flight_bookingPoll a PFS booking every 20–30 s: booking_in_progress → completed (PNR) / failed (hold released) / needs_attentionFREE
unlock_flight_offerRETIRED 2026-09-08 — answers 410 Gone. Call book_flight directly—
connect_payment[Developer API only] Mint a one-time link to connect a card to the paid account (nothing charged). PFS agents connect at letsfg.co/connect insteadFREE
resolve_hotel_cityPlace name → supplier city id for search_hotelsFREE
search_hotelsBookable hotel rates, refundable and non-refundableFREE (1,000 per hotel booking)
book_hotelStart a hotel booking: the price is held, captured once the hotel confirms. Returns booking_job_idThe price on the offer
get_hotel_bookingPoll until succeeded / failed / attentionFREE
cancel_hotel_bookingCancel a refundable booking before free_cancellation_until (98% refunded, 2% fee)FREE
get_agent_profileView usage statsFREE

Search Flags Reference

FlagAPI FieldValuesDefault
--adultsadults1–91
--childrenchildren0–90
--infantsinfants0–90
--cabincabin_classM (economy), W (premium), C (business), F (first)(any)
--returnreturn_fromYYYY-MM-DD—
--max-stopsmax_stopovers0–42
--sortsortprice, durationprice
--limitlimit1–10020
--currencycurrencyEUR, USD, GBP, etc.EUR
Cabin Class Codes Explained
CodeClassDescriptionTypical Use Case
MEconomyStandard seatingBudget travel, most bookings
WPremium EconomyExtra legroom, priority boardingLong-haul comfort without business price
CBusinessLie-flat on long-haul, lounge accessCorporate travel, 6+ hour flights
FFirstPrivate suites, premium diningUltra-premium routes (limited airlines)
--json—Output as JSON—

Error Handling

ExceptionHTTP CodeWhen
AuthenticationError401Invalid or missing API key
PaymentRequiredError402No payment method connected, or the search allowance is used up
OfferExpiredError410Offer no longer available
LetsFGError422Invalid request parameters
LetsFGError429Too many requests (retry with backoff)
LetsFGError502Upstream airline/hotel API error
Authentication Failure Recovery
from letsfg import LetsFG
from letsfg.connectors.auth import BearerTokenError

try:
    bt = LetsFG()  # reads LETSFG_BEARER_TOKEN — the token from the connect flow
    flights = bt.search("LHR", "JFK", "2026-04-15")
except BearerTokenError:
    print("Token expired, revoked or missing — reconnect at https://letsfg.co/connect")

Developer API:

from letsfg import LetsFG, AuthenticationError

try:
    bt = LetsFG(api_key="letsfg_...")
    flights = bt.search("LHR", "JFK", "2026-04-15")
except AuthenticationError:
    # API key invalid or expired — re-register, then connect a payment method on the new key
    creds = LetsFG.register("my-agent", "[email protected]")
    bt = LetsFG(api_key=creds["api_key"])
    print("Open once to connect a card:", bt.connect_payment()["connect_url"])  # nothing is charged
Rate Limit and Timeout Handling
import time
from letsfg import LetsFG, LetsFGError

def search_with_retry(bt, origin, dest, date, max_retries=3):
    for attempt in range(max_retries):
        try:
            return bt.search(origin, dest, date)
        except LetsFGError as e:
            if "429" in str(e) or "rate limit" in str(e).lower():
                time.sleep(2 ** attempt)  # exponential backoff
            elif "timeout" in str(e).lower() or "504" in str(e):
                time.sleep(1)
            else:
                raise
    raise LetsFGError("Max retries exceeded")

Rate Limits

EndpointRate LimitTypical Latency
Search flightsNo hard limit (billing is the natural governor)2–5 s (discover) · 8–10 s to first results (full search)
Resolve location120 req/min<1s
Book10 req/min3-10s
Search hotels30 req/min3-10s
Register5 req/min<1s

Pricing Summary

ActionCost
Search (flights, transfers, activities)Free
Resolve locationsFree
Register agentFree
Connect a payment methodFree — nothing is charged to connect
View profileFree
Book flight (PFS, no unlock needed)The price shown on the offer — held on the connected card, captured only on a real PNR; no separate LetsFG fee
Book flight (Developer API)The price shown on the offer — held, captured only on a real PNR; no booking fee, no transaction fee
Hotel searchFree up to 1,000 searches after every hotel booking, then 1,000 for $5.00
Hotel bookingThe price shown on the offer — held on the connected card, captured only once the hotel confirms. No reservation fee
Hotel cancellation98% refunded on a refundable rate before free_cancellation_until (2% fee); otherwise refused

Key Facts

  • Every airline in the world via server-side engine
  • Hotels via a wholesale hotel partner
  • No cookie tracking — the same search returns the same prices
  • Typically cheaper than booking through a single OTA, because it compares airlines and the major booking sites in one pass
  • Real airline PNR codes and hotel confirmations
  • E-tickets sent directly to passenger email
  • Search is free (10 per 10 min, 30/hour, 100/day)
  • PFS (Bearer token): book directly, no unlock step — the fare is held on the connected card, a LetsFG booking agent buys the ticket, captured only once a real PNR exists; failed booking = hold released, nothing charged
  • Developer API: POST /flights/book — the same hold-then-capture flow, then poll GET /flights/bookings/{id}. Search there is look-to-book (200 free after every booking) and there is no booking or transaction fee
  • API designed for machines, not browsers

Comments

Markdown supported