letsfg 2026.5.68 → 2026.5.70

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -151,14 +151,14 @@ print(booking["confirmation"], booking["pay_link"])
151
151
 
152
152
  ### How you pay
153
153
 
154
- **10% now, the rest to the hotel later.** At booking we charge 10% of the price
154
+ **5% now, the rest to the hotel later.** At booking we charge 5% of the price
155
155
  to your card as a reservation fee. The remaining balance is paid **directly to
156
156
  the supplier** through a `pay_link` we return — we never hold it.
157
157
 
158
158
  `balance_due_by` is the supplier's own auto-cancellation date, not a date we
159
159
  invent. Miss it and the room is released.
160
160
 
161
- The 10% is **non-refundable**. Cancelling before `balance_due_by` costs nothing
161
+ The 5% is **non-refundable**. Cancelling before `balance_due_by` costs nothing
162
162
  else; after it, the hotel's own cancellation ladder applies and can reach 100%.
163
163
  That ladder ships in the booking's `terms`, so you can always see the cost before
164
164
  you cancel.
@@ -184,7 +184,7 @@ is not metered, only the search call itself.
184
184
  hotel signup.
185
185
  - **Only free-cancellation, pay-later rates are sold.** Those are the rates where
186
186
  the balance can safely be settled with the supplier after booking, which is
187
- what makes 10%-now/rest-later work at all. You will see fewer results than a
187
+ what makes 5%-now/rest-later work at all. You will see fewer results than a
188
188
  metasearch shows you. Every one of them can actually be booked.
189
189
  - **Booking is asynchronous.** `book_hotel` returns a `booking_job_id`, not a
190
190
  booking — the real thing takes minutes. Poll `hotel_booking(job_id)` until
@@ -1641,10 +1641,17 @@ var LetsFG = class {
1641
1641
  }
1642
1642
  /**
1643
1643
  * Resolve a city/airport name to IATA codes.
1644
+ *
1645
+ * Developer API key only. There is no location endpoint on the PFS Bearer
1646
+ * lane — the same dead end `unlock()` documents below. This used to send
1647
+ * PFS callers to `/api/locations?q=`, a route that has never existed on
1648
+ * letsfg.co (verified 2026-08-16: 404, text/html), so they got a JSON parse
1649
+ * error off the 404 page instead of an answer. Pass an IATA code directly
1650
+ * on the PFS lane; a city code expands to every airport in that city.
1644
1651
  */
1645
1652
  async resolveLocation(query) {
1646
- this.requireAuth();
1647
- const path = this.usingPFS ? `/api/locations?q=${encodeURIComponent(query)}` : `/developers/api/v1/flights/locations/${encodeURIComponent(query)}`;
1653
+ this.requireApiKey();
1654
+ const path = `/developers/api/v1/flights/locations/${encodeURIComponent(query)}`;
1648
1655
  const data = await this.getWithAuth(path);
1649
1656
  return Array.isArray(data) ? data : data.locations || [];
1650
1657
  }
@@ -1709,7 +1716,7 @@ var LetsFG = class {
1709
1716
  //
1710
1717
  // Only free-cancellation, pay-later rates are sold. Those are the rates where
1711
1718
  // the guest's balance can safely be settled with the supplier after booking,
1712
- // which is what makes 10%-now/rest-later work. The result set is smaller than
1719
+ // which is what makes 5%-now/rest-later work. The result set is smaller than
1713
1720
  // a metasearch's, and every row in it can actually be booked.
1714
1721
  /**
1715
1722
  * Resolve a place name to the city id that searchHotels() needs.
@@ -1732,7 +1739,7 @@ var LetsFG = class {
1732
1739
  * — so this gets its own generous timeout rather than the client default.
1733
1740
  *
1734
1741
  * Each offer carries `price` (what the guest pays), `reservation_fee_now`
1735
- * (the 10% taken at booking), `balance_to_supplier`, `balance_due_by` and
1742
+ * (the 5% taken at booking), `balance_to_supplier`, `balance_due_by` and
1736
1743
  * `free_cancellation_until`. There is no wholesale figure to quote by mistake.
1737
1744
  *
1738
1745
  * Keep `session_id` and the chosen offer's `combination_id_v2`: together they
@@ -1758,7 +1765,7 @@ var LetsFG = class {
1758
1765
  * Start a booking. Returns a job immediately — it does NOT book inline.
1759
1766
  *
1760
1767
  * A booking takes minutes: the rate is re-blocked at the supplier, every
1761
- * price and date rail is checked, the 10% reservation fee is charged to your
1768
+ * price and date rail is checked, the 5% reservation fee is charged to your
1762
1769
  * card, and only then is the room committed. No proxy holds a connection that
1763
1770
  * long, so this returns at once and you poll hotelBooking() for the outcome.
1764
1771
  * Use bookHotelAndWait() if you would rather block.
@@ -1840,7 +1847,7 @@ var LetsFG = class {
1840
1847
  *
1841
1848
  * Free until `balance_due_by`; after that the hotel's own cancellation ladder
1842
1849
  * applies and can reach 100%. The ladder ships in the booking's `terms`, so
1843
- * you can see the cost before calling this. The 10% reservation fee is NOT
1850
+ * you can see the cost before calling this. The 5% reservation fee is NOT
1844
1851
  * refunded.
1845
1852
  *
1846
1853
  * This drives a browser at the supplier and takes over a minute. If it times
package/dist/cli.js CHANGED
@@ -537,10 +537,17 @@ var LetsFG = class {
537
537
  }
538
538
  /**
539
539
  * Resolve a city/airport name to IATA codes.
540
+ *
541
+ * Developer API key only. There is no location endpoint on the PFS Bearer
542
+ * lane — the same dead end `unlock()` documents below. This used to send
543
+ * PFS callers to `/api/locations?q=`, a route that has never existed on
544
+ * letsfg.co (verified 2026-08-16: 404, text/html), so they got a JSON parse
545
+ * error off the 404 page instead of an answer. Pass an IATA code directly
546
+ * on the PFS lane; a city code expands to every airport in that city.
540
547
  */
541
548
  async resolveLocation(query) {
542
- this.requireAuth();
543
- const path = this.usingPFS ? `/api/locations?q=${encodeURIComponent(query)}` : `/developers/api/v1/flights/locations/${encodeURIComponent(query)}`;
549
+ this.requireApiKey();
550
+ const path = `/developers/api/v1/flights/locations/${encodeURIComponent(query)}`;
544
551
  const data = await this.getWithAuth(path);
545
552
  return Array.isArray(data) ? data : data.locations || [];
546
553
  }
@@ -605,7 +612,7 @@ var LetsFG = class {
605
612
  //
606
613
  // Only free-cancellation, pay-later rates are sold. Those are the rates where
607
614
  // the guest's balance can safely be settled with the supplier after booking,
608
- // which is what makes 10%-now/rest-later work. The result set is smaller than
615
+ // which is what makes 5%-now/rest-later work. The result set is smaller than
609
616
  // a metasearch's, and every row in it can actually be booked.
610
617
  /**
611
618
  * Resolve a place name to the city id that searchHotels() needs.
@@ -628,7 +635,7 @@ var LetsFG = class {
628
635
  * — so this gets its own generous timeout rather than the client default.
629
636
  *
630
637
  * Each offer carries `price` (what the guest pays), `reservation_fee_now`
631
- * (the 10% taken at booking), `balance_to_supplier`, `balance_due_by` and
638
+ * (the 5% taken at booking), `balance_to_supplier`, `balance_due_by` and
632
639
  * `free_cancellation_until`. There is no wholesale figure to quote by mistake.
633
640
  *
634
641
  * Keep `session_id` and the chosen offer's `combination_id_v2`: together they
@@ -654,7 +661,7 @@ var LetsFG = class {
654
661
  * Start a booking. Returns a job immediately — it does NOT book inline.
655
662
  *
656
663
  * A booking takes minutes: the rate is re-blocked at the supplier, every
657
- * price and date rail is checked, the 10% reservation fee is charged to your
664
+ * price and date rail is checked, the 5% reservation fee is charged to your
658
665
  * card, and only then is the room committed. No proxy holds a connection that
659
666
  * long, so this returns at once and you poll hotelBooking() for the outcome.
660
667
  * Use bookHotelAndWait() if you would rather block.
@@ -736,7 +743,7 @@ var LetsFG = class {
736
743
  *
737
744
  * Free until `balance_due_by`; after that the hotel's own cancellation ladder
738
745
  * applies and can reach 100%. The ladder ships in the booking's `terms`, so
739
- * you can see the cost before calling this. The 10% reservation fee is NOT
746
+ * you can see the cost before calling this. The 5% reservation fee is NOT
740
747
  * refunded.
741
748
  *
742
749
  * This drives a browser at the supplier and takes over a minute. If it times
package/dist/cli.mjs CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  LetsFG,
4
4
  LetsFGError,
5
5
  offerSummary
6
- } from "./chunk-QLCIHPPX.mjs";
6
+ } from "./chunk-SYNHNDEL.mjs";
7
7
  import {
8
8
  BearerTokenError,
9
9
  getBearerToken,
package/dist/index.d.mts CHANGED
@@ -485,6 +485,13 @@ declare class LetsFG {
485
485
  private searchPFS;
486
486
  /**
487
487
  * Resolve a city/airport name to IATA codes.
488
+ *
489
+ * Developer API key only. There is no location endpoint on the PFS Bearer
490
+ * lane — the same dead end `unlock()` documents below. This used to send
491
+ * PFS callers to `/api/locations?q=`, a route that has never existed on
492
+ * letsfg.co (verified 2026-08-16: 404, text/html), so they got a JSON parse
493
+ * error off the 404 page instead of an answer. Pass an IATA code directly
494
+ * on the PFS lane; a city code expands to every airport in that city.
488
495
  */
489
496
  resolveLocation(query: string): Promise<Array<Record<string, unknown>>>;
490
497
  /**
@@ -520,7 +527,7 @@ declare class LetsFG {
520
527
  * — so this gets its own generous timeout rather than the client default.
521
528
  *
522
529
  * Each offer carries `price` (what the guest pays), `reservation_fee_now`
523
- * (the 10% taken at booking), `balance_to_supplier`, `balance_due_by` and
530
+ * (the 5% taken at booking), `balance_to_supplier`, `balance_due_by` and
524
531
  * `free_cancellation_until`. There is no wholesale figure to quote by mistake.
525
532
  *
526
533
  * Keep `session_id` and the chosen offer's `combination_id_v2`: together they
@@ -543,7 +550,7 @@ declare class LetsFG {
543
550
  * Start a booking. Returns a job immediately — it does NOT book inline.
544
551
  *
545
552
  * A booking takes minutes: the rate is re-blocked at the supplier, every
546
- * price and date rail is checked, the 10% reservation fee is charged to your
553
+ * price and date rail is checked, the 5% reservation fee is charged to your
547
554
  * card, and only then is the room committed. No proxy holds a connection that
548
555
  * long, so this returns at once and you poll hotelBooking() for the outcome.
549
556
  * Use bookHotelAndWait() if you would rather block.
@@ -606,7 +613,7 @@ declare class LetsFG {
606
613
  *
607
614
  * Free until `balance_due_by`; after that the hotel's own cancellation ladder
608
615
  * applies and can reach 100%. The ladder ships in the booking's `terms`, so
609
- * you can see the cost before calling this. The 10% reservation fee is NOT
616
+ * you can see the cost before calling this. The 5% reservation fee is NOT
610
617
  * refunded.
611
618
  *
612
619
  * This drives a browser at the supplier and takes over a minute. If it times
package/dist/index.d.ts CHANGED
@@ -485,6 +485,13 @@ declare class LetsFG {
485
485
  private searchPFS;
486
486
  /**
487
487
  * Resolve a city/airport name to IATA codes.
488
+ *
489
+ * Developer API key only. There is no location endpoint on the PFS Bearer
490
+ * lane — the same dead end `unlock()` documents below. This used to send
491
+ * PFS callers to `/api/locations?q=`, a route that has never existed on
492
+ * letsfg.co (verified 2026-08-16: 404, text/html), so they got a JSON parse
493
+ * error off the 404 page instead of an answer. Pass an IATA code directly
494
+ * on the PFS lane; a city code expands to every airport in that city.
488
495
  */
489
496
  resolveLocation(query: string): Promise<Array<Record<string, unknown>>>;
490
497
  /**
@@ -520,7 +527,7 @@ declare class LetsFG {
520
527
  * — so this gets its own generous timeout rather than the client default.
521
528
  *
522
529
  * Each offer carries `price` (what the guest pays), `reservation_fee_now`
523
- * (the 10% taken at booking), `balance_to_supplier`, `balance_due_by` and
530
+ * (the 5% taken at booking), `balance_to_supplier`, `balance_due_by` and
524
531
  * `free_cancellation_until`. There is no wholesale figure to quote by mistake.
525
532
  *
526
533
  * Keep `session_id` and the chosen offer's `combination_id_v2`: together they
@@ -543,7 +550,7 @@ declare class LetsFG {
543
550
  * Start a booking. Returns a job immediately — it does NOT book inline.
544
551
  *
545
552
  * A booking takes minutes: the rate is re-blocked at the supplier, every
546
- * price and date rail is checked, the 10% reservation fee is charged to your
553
+ * price and date rail is checked, the 5% reservation fee is charged to your
547
554
  * card, and only then is the room committed. No proxy holds a connection that
548
555
  * long, so this returns at once and you poll hotelBooking() for the outcome.
549
556
  * Use bookHotelAndWait() if you would rather block.
@@ -606,7 +613,7 @@ declare class LetsFG {
606
613
  *
607
614
  * Free until `balance_due_by`; after that the hotel's own cancellation ladder
608
615
  * applies and can reach 100%. The ladder ships in the booking's `terms`, so
609
- * you can see the cost before calling this. The 10% reservation fee is NOT
616
+ * you can see the cost before calling this. The 5% reservation fee is NOT
610
617
  * refunded.
611
618
  *
612
619
  * This drives a browser at the supplier and takes over a minute. If it times
package/dist/index.js CHANGED
@@ -1689,10 +1689,17 @@ var LetsFG = class {
1689
1689
  }
1690
1690
  /**
1691
1691
  * Resolve a city/airport name to IATA codes.
1692
+ *
1693
+ * Developer API key only. There is no location endpoint on the PFS Bearer
1694
+ * lane — the same dead end `unlock()` documents below. This used to send
1695
+ * PFS callers to `/api/locations?q=`, a route that has never existed on
1696
+ * letsfg.co (verified 2026-08-16: 404, text/html), so they got a JSON parse
1697
+ * error off the 404 page instead of an answer. Pass an IATA code directly
1698
+ * on the PFS lane; a city code expands to every airport in that city.
1692
1699
  */
1693
1700
  async resolveLocation(query) {
1694
- this.requireAuth();
1695
- const path = this.usingPFS ? `/api/locations?q=${encodeURIComponent(query)}` : `/developers/api/v1/flights/locations/${encodeURIComponent(query)}`;
1701
+ this.requireApiKey();
1702
+ const path = `/developers/api/v1/flights/locations/${encodeURIComponent(query)}`;
1696
1703
  const data = await this.getWithAuth(path);
1697
1704
  return Array.isArray(data) ? data : data.locations || [];
1698
1705
  }
@@ -1757,7 +1764,7 @@ var LetsFG = class {
1757
1764
  //
1758
1765
  // Only free-cancellation, pay-later rates are sold. Those are the rates where
1759
1766
  // the guest's balance can safely be settled with the supplier after booking,
1760
- // which is what makes 10%-now/rest-later work. The result set is smaller than
1767
+ // which is what makes 5%-now/rest-later work. The result set is smaller than
1761
1768
  // a metasearch's, and every row in it can actually be booked.
1762
1769
  /**
1763
1770
  * Resolve a place name to the city id that searchHotels() needs.
@@ -1780,7 +1787,7 @@ var LetsFG = class {
1780
1787
  * — so this gets its own generous timeout rather than the client default.
1781
1788
  *
1782
1789
  * Each offer carries `price` (what the guest pays), `reservation_fee_now`
1783
- * (the 10% taken at booking), `balance_to_supplier`, `balance_due_by` and
1790
+ * (the 5% taken at booking), `balance_to_supplier`, `balance_due_by` and
1784
1791
  * `free_cancellation_until`. There is no wholesale figure to quote by mistake.
1785
1792
  *
1786
1793
  * Keep `session_id` and the chosen offer's `combination_id_v2`: together they
@@ -1806,7 +1813,7 @@ var LetsFG = class {
1806
1813
  * Start a booking. Returns a job immediately — it does NOT book inline.
1807
1814
  *
1808
1815
  * A booking takes minutes: the rate is re-blocked at the supplier, every
1809
- * price and date rail is checked, the 10% reservation fee is charged to your
1816
+ * price and date rail is checked, the 5% reservation fee is charged to your
1810
1817
  * card, and only then is the room committed. No proxy holds a connection that
1811
1818
  * long, so this returns at once and you poll hotelBooking() for the outcome.
1812
1819
  * Use bookHotelAndWait() if you would rather block.
@@ -1888,7 +1895,7 @@ var LetsFG = class {
1888
1895
  *
1889
1896
  * Free until `balance_due_by`; after that the hotel's own cancellation ladder
1890
1897
  * applies and can reach 100%. The ladder ships in the booking's `terms`, so
1891
- * you can see the cost before calling this. The 10% reservation fee is NOT
1898
+ * you can see the cost before calling this. The 5% reservation fee is NOT
1892
1899
  * refunded.
1893
1900
  *
1894
1901
  * This drives a browser at the supplier and takes over a minute. If it times
package/dist/index.mjs CHANGED
@@ -22,7 +22,7 @@ import {
22
22
  offerSummary,
23
23
  rankOffers,
24
24
  selectDiverseTop
25
- } from "./chunk-QLCIHPPX.mjs";
25
+ } from "./chunk-SYNHNDEL.mjs";
26
26
  export {
27
27
  AuthenticationError,
28
28
  BoostedTravel,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "letsfg",
3
- "version": "2026.5.68",
3
+ "version": "2026.5.70",
4
4
  "description": "Flights and hotels for AI agents. Server-side engine covers hundreds of airlines; hotels are real bookable inventory with free cancellation and pay-later terms. Includes open-source ranking engine.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",