Deals API
Publish a round-trip flight deal with a single HTTP request, authenticated with a shared key. Publishing is treated as the key-holder's own assertion that the fare was checked at the booking page - verifiedAt is required, not inferred. Publishing again for the same origin and destination (e.g. a weekly re-check) replaces the existing listing rather than creating a duplicate.
Publish a deal
POST https://fareletter.com/api/dealsContent-Type: application/jsonAuthorization: Bearer <your key>
| Field | Required | Notes |
|---|---|---|
| origin | yes | Departure airport code: DEL, BOM, BLR, CCU or MAA |
| destCode | yes | Destination airport code, e.g. BKK |
| dest | yes | Destination city name, e.g. "Bangkok" |
| img | yes | A valid http(s) image URL for the deal's cover photo |
| priceN | yes | The fare, as a number (e.g. 18400 for ₹18,400) |
| usualN | yes | The usual/reference price, as a number; must be >= priceN |
| days | yes | Trip length, e.g. "8 days" |
| window | yes | Travel window, e.g. "Feb 2027" |
| airline | yes | Airline(s), e.g. "IndiGo" |
| stops | yes | e.g. "Non-stop" or "1 stop each way" |
| via | no | Connection note, e.g. "via Kuala Lumpur (KUL)" |
| dates | yes | An example date range, e.g. "9 - 16 Feb 2027" |
| bag | yes | Baggage note, e.g. "7 kg cabin bag; check-in extra" |
| datePairs | no | Up to 6 [dates, price] pairs for the month/budget filter; defaults to a single pair built from dates/priceN |
| verifiedAt | yes | ISO date you checked the fare at the booking page, e.g. "2026-10-25" |
Request example
{
"origin": "DEL",
"destCode": "BKK",
"dest": "Bangkok",
"img": "https://example.com/bangkok.jpg",
"priceN": 18400,
"usualN": 26000,
"days": "8 days",
"window": "Feb 2027",
"airline": "Air India Express",
"stops": "Non-stop",
"dates": "9 - 16 Feb 2027",
"bag": "7 kg cabin bag; check-in extra",
"verifiedAt": "2026-10-25"
}Success response - 201 Created
{
"ok": true,
"id": "del-bkk",
"url": "https://fareletter.com/deal/del-bkk",
"cities": "Delhi to Bangkok",
"price": "₹18,400",
"usual": "₹26,000",
"verifiedAt": "2026-10-25"
}Errors
| Status | error | When |
|---|---|---|
| 400 | validation | A field fails the rules above - the response includes a fields object naming each problem |
| 400 | invalid_json | Body isn't valid JSON |
| 401 | unauthorized | Missing or wrong Authorization: Bearer key |
| 413 | payload_too_large | Request body over ~20,000 bytes |
| 415 | unsupported_media_type | Content-Type isn't application/json |
| 429 | rate_limited | More than 20 publishes from the same IP in an hour |
List deals
GET https://fareletter.com/api/deals returns every listed deal as JSON, including its page url.
curl example
curl -X POST https://fareletter.com/api/deals \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_KEY" \
-d '{"origin":"DEL","destCode":"BKK","dest":"Bangkok","img":"https://example.com/bangkok.jpg","priceN":18400,"usualN":26000,"days":"8 days","window":"Feb 2027","airline":"Air India Express","stops":"Non-stop","dates":"9 - 16 Feb 2027","bag":"7 kg cabin bag; check-in extra","verifiedAt":"2026-10-25"}'Limits
- 20 publishes per IP address per hour
- Total request body: ~20,000 bytes
- No file uploads - the cover image is referenced by URL only