Skip to content

Inventory quick start

Base URL (staging): https://inventory.staging.turnstay.com
Interactive docs: /api/v1/public/docs

All write routes need a Descope Bearer token for your merchant tenant.

In the dashboard: Invoicing → My catalogue → New.

That flow:

  1. Creates a supplier.
  2. Links it to you with kind: owned.
  3. Saves a profile (rooms, photos, destination).
  4. Creates merchant_private products (only your tenant sees them) plus published rack rates.

Demo catalogue for Hotel of Dreams (owned rooms + extras) and the three dummy partners is seeded via the inventory HTTP API, not seed.py. Local or staging only. The script refuses production hosts.

StepMethodPath
Create supplierPOST/api/v1/suppliers
Mark as ownedPOST/api/v1/provider-links body { "kind": "owned", "supplier_id": "…" }
Profile + roomsPUT/api/v1/suppliers/{id}/profile
Private productPOST/api/v1/suppliers/{id}/products body { "visibility": "merchant_private", … }
Rack ratePOST/api/v1/products/{id}/published-components

Invoicing → Inventory → New. Pick the operator, then attach a contract on Agreements.

Three demo partners (API seeder on local or staging, never production):

SupplierGuest productHow they are paid later
Hotel - Mount NelsonDeluxe RoomTurnStay wallet (search mtnelson.example)
Hotel - Victoria FallsFalls View RoomBank / EFT beneficiary
Helicopter ridesScenic Helicopter FlightCash retain on Dreamy Hotel wallets

Payout is not chosen on the order Forex tab. Set it on the supplier, then confirm on the order Fulfillment tab.

StepMethodPath
Browse directoryGET/api/v1/public/suppliers
Create / matchPOST / GET/api/v1/suppliers, /api/v1/suppliers/match
Contracted linkPOST/api/v1/provider-links { "kind": "contracted" }
Contract ratesPOST/api/v1/contracts then components
Payout channelPUT/api/v1/suppliers/{id}/payout-settings

payout_channel is one of treasury_wallet, eft, or cash.

Hotel of Dreams and the dummy partners are created through public inventory APIs. That script will not run against production.

Local seed.py demo still loads Balloon / Chobe / Singita into a dev database. Do not run seed.py in production.

Staging or local via API:

Terminal window
INVENTORY_API_URL=https://inventory.staging.turnstay.com \
INVENTORY_BEARER=<descope-jwt> \
python scripts/seed-demo-catalog-api.py

Local hub helper (DB seed plus API catalog when INVENTORY_BEARER is set):

Terminal window
INVENTORY_BEARER=<descope-jwt> ./scripts/seed-demo.sh

Optional payout IDs: MOUNT_NELSON_WALLET_ID, VF_HOTEL_BENEFICIARY_ID, DREAMY_WALLET_ID.

When you add a line to an order, inventory resolves the rate:

GET /api/v1/products/{product_id}/resolve?tenant_id=…&class_code=adult

Owned products use published rack. Contracted products use the merchant contract when it is active.