API v1 — cURL Samples & Integration Guide

Base URL: https://youragency.pragmatictours.com/api/v1

Authentication

All requests require account authentication passed either via:

  1. API Key (Bearer Token): http Authorization: Bearer pt_<your_api_key> Generate an API key at Settings → API Keys in your PragmaticTours dashboard.

  2. Account Token Header: http X-Account-Token: <subdomain_or_slug>


Tour Templates API

Use the Tour Templates API to retrieve the list of active tour products offered by your agency. This allows external booking engines, widgets, or custom integrations to select a valid tour_template_id or code when creating bookings.

1. List Tour Templates

curl -H "X-Account-Token: company-a" \
  https://youragency.pragmatictours.com/api/v1/tour_templates

Response (200 OK):

{
  "success": true,
  "tour_templates": [
    {
      "id": 1,
      "name": "Gamboa Rainforest & Monkey Island",
      "code": "GAMBOA-01",
      "category": "single",
      "price_per_pax": 85.0,
      "min_pax": 2,
      "max_pax": 20,
      "duration_hours": 6.0,
      "pickup_time": "08:00",
      "pickup_address": "Hotel Lobby / Pickup Point",
      "location_name": "Gamboa, Panama"
    }
  ]
}

2. Get Single Tour Template Details

curl -H "X-Account-Token: company-a" \
  https://youragency.pragmatictours.com/api/v1/tour_templates/1

Bookings API

Bookings represent customer reservations. Bookings can be submitted manually through the PragmaticTours web dashboard or via the API (e.g., website booking widgets or OTA integrations).

[!IMPORTANT] Payment Handling & Gateway Policy: PragmaticTours does NOT process payments directly or include built-in payment gateways. Tour operators use their own payment processor (e.g., Stripe, PayPal, local bank transfer, or POS). Once payment is received, the operator or API integration simply sets the booking status to "confirmed".

[!NOTE] Tour Schedule & Manifest Integration: - Tour Auto-Creation: When a booking is marked as "confirmed", PragmaticTours checks the dashboard calendar for that date and tour template. If no scheduled tour exists yet, it automatically creates and schedules the tour on the dashboard. - Manifest & Seating Sync: Confirmed bookings automatically add the lead customer and all extra passengers to the tour's Passenger Manifest and seating list. - Pending Status: Bookings with status "pending" do NOT auto-create tours on the dashboard until confirmed. - Cancellation: If a booking is cancelled, its passengers are automatically removed from the scheduled tour manifest. - Customer & Duplicate Validation: Customers are auto-upserted by email. If an active booking for the same customer, date, and tour template already exists, the API updates the existing booking rather than creating a duplicate record.

1. Create a Pending Booking (No Tour Created Yet)

curl -X POST https://youragency.pragmatictours.com/api/v1/bookings \
  -H "Content-Type: application/json" \
  -H "X-Account-Token: company-a" \
  -d '{
    "tour_template_id": 1,
    "booking_date": "2026-10-15",
    "status": "pending",
    "source": "website_widget",
    "customer": {
      "full_name": "Maria Santos",
      "email": "maria.santos@example.com",
      "phone": "+507 6555-1234",
      "language_preference": "es",
      "special_needs": "Wheelchair requested"
    },
    "passengers": [
      {
        "passenger_name": "Maria Santos",
        "age_category": "adult",
        "special_needs": "Wheelchair requested"
      },
      {
        "passenger_name": "Carlos Santos",
        "age_category": "adult",
        "special_needs": "Vegetarian meal"
      }
    ]
  }'

Response (201 Created):

{
  "success": true,
  "message": "Booking successfully created",
  "booking": {
    "id": 101,
    "status": "pending",
    "source": "website_widget",
    "booking_date": "2026-10-15",
    "customer_name": "Maria Santos",
    "customer_email": "maria.santos@example.com",
    "tour_template_id": 1,
    "tour_template_name": "Gamboa Rainforest & Monkey Island",
    "passenger_count": 2
  }
}

2. Create a Confirmed Booking (Auto-Schedules Tour & Syncs Manifest)

curl -X POST https://youragency.pragmatictours.com/api/v1/bookings \
  -H "Content-Type: application/json" \
  -H "X-Account-Token: company-a" \
  -d '{
    "tour_template_id": 1,
    "booking_date": "2026-10-15",
    "status": "confirmed",
    "source": "website_widget",
    "customer": {
      "full_name": "John Smith",
      "email": "john.smith@example.com",
      "phone": "+1 555-0199",
      "language_preference": "en"
    },
    "passengers": [
      {
        "passenger_name": "John Smith",
        "age_category": "adult"
      },
      {
        "passenger_name": "Sarah Smith",
        "age_category": "adult"
      }
    ]
  }'

Response (201 Created):

{
  "success": true,
  "message": "Booking successfully created",
  "booking": {
    "id": 102,
    "status": "confirmed",
    "source": "website_widget",
    "booking_date": "2026-10-15",
    "customer_name": "John Smith",
    "customer_email": "john.smith@example.com",
    "tour_template_id": 1,
    "tour_template_name": "Gamboa Rainforest & Monkey Island",
    "passenger_count": 2
  }
}

3. Change Booking Status to Confirmed (Triggers Tour Creation & Manifest Sync)

curl -X PATCH https://youragency.pragmatictours.com/api/v1/bookings/101 \
  -H "Content-Type: application/json" \
  -H "X-Account-Token: company-a" \
  -d '{
    "booking": {
      "status": "confirmed"
    }
  }'

Response (200 OK):

{
  "success": true,
  "message": "Booking successfully updated",
  "booking": {
    "id": 101,
    "status": "confirmed",
    "source": "website_widget",
    "booking_date": "2026-10-15",
    "customer_name": "Maria Santos",
    "customer_email": "maria.santos@example.com",
    "tour_template_id": 1,
    "tour_template_name": "Gamboa Rainforest & Monkey Island",
    "passenger_count": 2
  }
}

4. Change Booking Status to Cancelled (Removes Passengers from Tour Manifest)

curl -X PATCH https://youragency.pragmatictours.com/api/v1/bookings/101 \
  -H "Content-Type: application/json" \
  -H "X-Account-Token: company-a" \
  -d '{
    "booking": {
      "status": "cancelled"
    }
  }'

5. Get Single Booking Details

curl -H "X-Account-Token: company-a" \
  https://youragency.pragmatictours.com/api/v1/bookings/101

6. List All Bookings

curl -H "X-Account-Token: company-a" \
  https://youragency.pragmatictours.com/api/v1/bookings

Tours API

List tours

curl -H "Authorization: Bearer pt_a1b2c3d4e5f6..." \
  https://youragency.pragmatictours.com/api/v1/tours

Optional filters:

Param Type Example
from date 2026-07-01
to date 2026-07-31
template_id integer 5
status string scheduled, in_progress, completed, cancelled
curl -H "Authorization: Bearer pt_a1b2c3d4e5f6..." \
  "https://youragency.pragmatictours.com/api/v1/tours?from=2026-08-01&to=2026-08-31&status=scheduled"

Response (200):

[
  {
    "id": 42,
    "name": "Snorkeling Adventure",
    "category": "single",
    "status": "scheduled",
    "pax_count": 20,
    "price_per_pax": 75.0,
    "compensation_type": "gig",
    "pickup_time": "08:00",
    "end_time": null,
    "pickup_address": "Hotel lobby",
    "dropoff_address": null,
    "transit_duration_minutes": 30,
    "tour_template_id": 3,
    "date": "2026-08-15",
    "created_at": "2026-08-10T14:30:00Z",
    "updated_at": "2026-08-10T14:30:00Z"
  }
]

Get a single tour

curl -H "Authorization: Bearer pt_a1b2c3d4e5f6..." \
  https://youragency.pragmatictours.com/api/v1/tours/42

Create a single-day tour

curl -X POST https://youragency.pragmatictours.com/api/v1/tours \
  -H "Authorization: Bearer pt_a1b2c3d4e5f6..." \
  -H "Content-Type: application/json" \
  -d '{
    "tour": {
      "tour_template_id": 3,
      "pax_count": 20,
      "date": "2026-08-20",
      "pickup_time": "08:00",
      "pickup_address": "Hotel Lobby",
      "transit_duration_minutes": 30,
      "price_per_pax": 75.0
    }
---

### 7. Create a B2B Reseller Booking (Commission Agent)

When `customer_type` is `"reseller"`, the customer (or agency agent) creates a booking on behalf of passengers. Reseller customers are **not** added to the tour passenger manifest and do not consume seats.

```bash
curl -X POST https://youragency.pragmatictours.com/api/v1/bookings \
  -H "Content-Type: application/json" \
  -H "X-Account-Token: company-a" \
  -d '{
    "tour_template_id": 1,
    "booking_date": "2026-10-15",
    "status": "confirmed",
    "source": "api_b2b",
    "customer": {
      "full_name": "Panama Travel Agency",
      "email": "b2b@panamatravel.com",
      "phone": "+507 6000-9999",
      "customer_type": "reseller",
      "commission_percentage": 15.0
    },
    "passengers": [
      {
        "passenger_name": "Alice Johnson",
        "age_category": "adult"
      },
      {
        "passenger_name": "Bob Johnson",
        "age_category": "adult"
      }
    ]
  }'

Reseller & External Supplier Tours API

Create a Reseller (Supplier-Fulfilled) Tour

Tours with fulfillment_type: "reseller" reference an external supplier_id and bypass internal vehicle/driver auto-assignment rules.

curl -X POST https://youragency.pragmatictours.com/api/v1/tours \
  -H "Authorization: Bearer pt_a1b2c3d4e5f6..." \
  -H "Content-Type: application/json" \
  -d '{
    "tour": {
      "tour_template_id": 3,
      "pax_count": 10,
      "date": "2026-08-20",
      "fulfillment_type": "reseller",
      "supplier_id": 4
    }
  }'

Error Responses

401 — Unauthorized (missing or invalid API key / account token)

{ "error": "Missing tenant identification header (X-Account-Token) or account_slug parameter" }

404 — Not found

{ "error": "Not found" }

422 — Validation error

{ "error": "Booking validation failed", "details": ["Customer email is required"] }