POST /api/v1/flights/price_flight
Price a cached flight offer to confirm the current fare. Required before booking — book_flight reads the priced offer from this cache.
Price a cached offer to get the current, confirmed fare. This step is required before
calling book_flight. book_flight reads the priced offer from cache; booking without
pricing first will fail.
Permission: Read
Use the supplier-level searchId from suppliers[n].searchId, not the top-level requestId.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
search_id | string | Yes | searchId from the supplier entry in the search response |
offer_id | string | Yes | Offer id from the search results |
Request example
curl --request POST \
--url https://api.fx-port.com/api/v1/flights/price_flight \
--header 'Authorization: Bearer fxp_test_YOUR_KEY' \
--header 'Content-Type: application/json' \
--data '{
"search_id": "fs_dfx_4a861fcd-c5d6-4a1e-a471-97db7a9f9982",
"offer_id": "fx_offer_860f61e3"
}'Response example
Example response for the request above (exchangeRate appears at the top level when
supplier and agency currencies differ — the pricing block itself never contains an exchange
rate field):
{
"success": true,
"environment": "sandbox",
"requestId": "0f5b91b1",
"offerId": "fx_offer_860f61e3",
"offerType": "priced",
"supplierCurrency": "USD",
"agencyCurrency": "DZD",
"exchangeRate": 250.0,
"processingTime": 0.194,
"results": {
"offers": [
{
"id": "fx_offer_860f61e3",
"type": "flight_offer",
"supplier": { "id": "duffel_1", "name": "Duffel", "originalId": "off_0000B9nxOvvmY4qNUnYSFL" },
"supportHold": false,
"supportVoid": false,
"voidDeadline": null,
"bookableSeats": null,
"pricing": {
"supplierCurrency": "USD",
"agencyCurrency": "DZD",
"basePrice": 16270.0,
"taxesAndFees": 5198.2,
"agencyCommission": 21.47,
"finalPrice": 21489.67,
"b2bPrice": 21468.2,
"additionalServices": []
},
"travelerPricing": [
{
"travelerId": "pas_0000B9nxOvjNICv2sJkXtl",
"travelerType": "ADULT",
"price": {
"supplierCurrency": "USD",
"agencyCurrency": "DZD",
"base": 16270.0,
"total": 21489.67,
"b2bPrice": 21468.2
}
}
],
"conditions": {
"refundBeforeDeparture": { "allowed": false },
"changeBeforeDeparture": { "allowed": true }
}
}
]
}
}Response field reference
| Field | Type | Meaning |
|---|---|---|
success | boolean | Whether pricing succeeded |
environment | string | live or sandbox, resolved from your API key |
requestId | string | FX-Port's internal ID for this pricing call — include it when contacting support |
offerId | string | Echoes the offer_id you sent |
offerType | string | priced once confirmed by the supplier |
supplierCurrency / agencyCurrency | string | Currencies used for the conversion — see Flight pricing |
exchangeRate | number | Present only when supplierCurrency ≠ agencyCurrency; the rate used to convert |
processingTime | number | Seconds FX-Port spent calling the supplier for this pricing request |
results.offers[0].id | string | The same offer ID — pass this and search_id to book_flight |
results.offers[0].supportHold | boolean | Re-check this here — it can differ from the value at search time |
results.offers[0].supportVoid / .voidDeadline | — | Same-day void support and cutoff, confirmed at pricing time |
results.offers[0].bookableSeats | number | null | Remaining bookable seats at this fare, when reported |
results.offers[0].pricing | object | Confirmed price — see Flight pricing for every field |
results.offers[0].travelerPricing | array | Confirmed per-traveler price breakdown, same shape as in search |
results.offers[0].conditions | object | Confirmed refund/change eligibility for this exact priced offer |
supportHold and voidDeadline are inside the offer in results.offers[0], not at the top
level. Always check them here — pricing can reveal that a previously holdable offer no longer
supports a hold — before deciding whether to book as hold or issue.
If the offer expired between search and pricing, you get HTTP 410 with "error": "offer_expired".
Re-run the search to get a fresh offer.
See Flight pricing for what each price field means.