For travel agencies, tour operators, online travel companies, hotels and airlines

Travel Partner API

Sell a tour or destination operator's trips on your own website, app or booking system. You get their trips as a live feed — destinations, day-by-day itineraries, inclusions, photos, dates with seats left, the retail price and your net price — and you can book seats on your own account. Or simply frame their shop in your website: every booking through it is credited to you.

1 · Get your keys from the operator

The operator adds you as a partner, sets your commission and the trips you may sell, and sends you two keys. Or sign up yourself: apply to an operator with your Oxi account and, once it approves you, get your keys on your partner page.

Send the key as Authorization: Bearer <key>. A feed reader that cannot send headers may add the public key as ?key=. Prices are in the operator's currency. Your net price is the retail price less your commission: it is what you owe the operator for bookings on your account.

2 · The quickest way: frame the operator's shop

Your partner code (for example P1A2B3C4) is in the links the operator sends you. Every booking made through these is credited to you; the traveller pays the operator, and the operator owes you your commission.

<iframe src="https://oxishops.com/SHOP?embed=1&p=YOUR_CODE"
        style="width:100%;min-height:900px;border:0" title="Trips"></iframe>

Each trip in the catalogue also carries shop_url, embed_url and, for each date, book_url and book_embed_url with your code already in them: link a single trip or a single date from an email, a WhatsApp message or your own trip page.

3 · Catalogue (public key)

GET https://oxishops.com/v1/travel/catalogue
GET https://oxishops.com/v1/travel/catalogue?since=2026-11-01T00:00:00Z     trips changed since
GET https://oxishops.com/v1/travel/trips/{trip id or slug}

Answer (shortened):

{
  "operator": { "name": "Sunway Tours", "currency": "NGN", "shop_url": "…", "logo_url": "…" },
  "partner":  { "code": "P1A2B3C4", "commission_pct": 10, "may_book": true, "own_price": true, "terms": "…" },
  "generated_at": "2026-10-30T16:00:00.000Z",
  "trips": [{
    "id": "…", "slug": "obudu-highland-escape", "title": "Obudu Highland Escape",
    "type": "nature", "type_label": "Nature and wildlife", "nights": 3, "summary": "…",
    "highlights": ["…"], "included": ["Flights", "Hotel"], "not_included": ["Lunch"], "terms": "…",
    "photo_url": "…", "price_from": 150000, "net_from": 135000,
    "destinations": [{ "name": "Obudu Mountain Resort", "place": "Obanliku, Cross River", "things_to_do": ["…"], "photo_url": "…" }],
    "itinerary": [{ "day": 1, "title": "Fly to Calabar, drive up", "stay": "Resort", "meals": "Dinner" }],
    "package": {
      "components": [{ "kind": "hotel", "kind_label": "Hotel / stay", "title": "3 nights, deluxe double", "provider": "Obudu Mountain Resort", "day_from": 1, "day_to": 3, "details": "…" },
                     { "kind": "flight", "title": "Lagos–Calabar return, economy", "provider": "…", "day_from": 1, "day_to": 4 },
                     { "kind": "tour", "title": "Cable car and canopy walk", "provider": "…", "day_from": 2 }],
      "charges": [{ "id": "…", "kind": "surcharge", "label": "Peak season", "basis": "per_traveller", "amount": 20000, "optional": false },
                  { "id": "…", "kind": "surcharge", "label": "Single room", "basis": "per_traveller", "amount": 45000, "optional": true },
                  { "id": "…", "kind": "tax", "label": "Tourism levy", "basis": "percent", "percent": 5, "optional": false }]
    },
    "departures": [{
      "id": "…", "starts_at": "…", "ends_at": "…", "book_by": "2026-11-29",
      "seats_total": 20, "seats_left": 12, "open": true,
      "prices": [{ "id": "…", "name": "Adult", "retail": 300000, "net": 270000, "left": null },
                 { "id": "…", "name": "Child under 12", "retail": 150000, "net": 135000, "left": null }],
      "book_url": "…?p=P1A2B3C4", "book_embed_url": "…"
    }],
    "shop_url": "…", "embed_url": "…", "updated_at": "…"
  }]
}

Only open dates are listed. Read the catalogue as often as every few minutes; check a date's availability just before you sell it.

Packages only. A trip is sold as one package: its hotels, flights, meals, cars, experiences and tours are listed in package.components for you to show, never sold on their own. package.charges are added to the fare: surcharges (a percentage is of the fare; your commission applies to them) and taxes and levies (a percentage is of the fare and surcharges; passed on in full, no commission). Optional surcharges are chosen by their id in options when you book.

4 · Availability of one date (public key)

GET https://oxishops.com/v1/travel/departures/{departure id}

Seats left, whether it is open, and each price with its retail and net amounts. Never cached.

5 · Book on your account (secret key)

You collect from the travellers; you owe the operator the net. Send an Idempotency-Key (for example your own order number): sending the same key again returns the same booking and never books twice.

POST https://oxishops.com/v1/travel/bookings
Authorization: Bearer tp_sk_…
Idempotency-Key: SKY-48213
Content-Type: application/json

{
  "departure_id": "…",
  "lead": { "name": "Ngozi Okafor", "email": "ngozi@example.com", "phone": "+2348030000000", "price": "Adult" },
  "travellers": [ { "name": "Emeka Okafor", "price": "Adult" }, { "name": "Ada Okafor", "price": "Child under 12" } ],
  "options": ["…"],
  "partner_ref": "SKY-48213",
  "sell_total": 780000
}

Answer 201 (or 200 for a repeated key):

{
  "ref": "TR-3F9A1C", "partner_ref": "SKY-48213", "channel": "api", "status": "confirmed",
  "trip": { "slug": "obudu-highland-escape", "title": "Obudu Highland Escape" },
  "departure": { "id": "…", "starts_at": "…", "meeting_point": "MMA2, Lagos" },
  "travellers": [ { "name": "Ngozi Okafor", "lead": true, "price": "Adult", "pass_url": "https://oxishops.com/SHOP/pass/…" }, … ],
  "currency": "NGN", "retail_total": 750000, "commission_pct": 10, "commission": 75000, "net_total": 675000, "sell_total": 780000
}

Each traveller has a pass with a QR code: send the links to your travellers, or let the operator's email reach the lead traveller. The guide checks every traveller in on the day.

6 · Look up or cancel a booking (secret key)

GET  https://oxishops.com/v1/travel/bookings/{ref}
POST https://oxishops.com/v1/travel/bookings/{ref}/cancel

A booking on your account can be cancelled before the date, while nobody on it has been checked in; the seats go back on sale. Refunds to your travellers follow your own terms; between you and the operator, their terms apply.

7 · Your statement (secret key)

GET https://oxishops.com/v1/travel/statement

Every booking you made or sent, with you_owe (what is unpaid on the operator's invoices to you: the net on bookings on your account), owed_to_you (your commission on paid bookings through your link) and the balance. Each booking on your account comes with an invoice from the operator's OxiSeller shop for the net; it drops out of the totals once the operator records your payment, and your commission drops out once the operator marks it paid to you.

8 · Errors

Errors come as { "error": "…", "code": "…" } with the HTTP status:

StatuscodeMeaning
401bad_keyUnknown or revoked key
403partner_paused, partner_endedThe operator has paused or ended the partnership
403needs_secret, secret_in_browser, originWrong key for the call, or a website the operator has not listed
403booking_not_allowedYou sell through your link only
404unknown_trip, unknown_departure, unknown_bookingNot found, or not one you may sell
400unknown_price, below_net, price_fixedA price that does not exist; a selling price under the net, or one you may not set
409full, closed, departed, checked_in, paidNo seats left, not open for booking, too late to cancel, or already paid toward