API v1 — cURL Samples

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

All requests require an API key passed as a Bearer token in the Authorization header.

Authorization: Bearer pt_<your_api_key>

Generate an API key at Settings → API Keys in your PragmaticTours dashboard.


Tours

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

Response (200) — single-day:

{
  "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"
}

Response (200) — multi-day:

{
  "id": 50,
  "name": "Gamboa Rainforest Expedition",
  "category": "multi",
  "status": "scheduled",
  "pax_count": 15,
  "price_per_pax": 250.0,
  "compensation_type": "gig",
  "pickup_time": null,
  "end_time": null,
  "pickup_address": null,
  "dropoff_address": null,
  "transit_duration_minutes": 30,
  "tour_template_id": 7,
  "start_date": "2026-09-10",
  "end_date": "2026-09-13",
  "child_tours": [
    {
      "id": 51,
      "name": "Gamboa Rainforest Expedition → Day 1: Canal Transit",
      "category": "single",
      "status": "scheduled",
      "pax_count": 15,
      "price_per_pax": 85.0,
      "compensation_type": "gig",
      "pickup_time": "07:00",
      "end_time": null,
      "pickup_address": "Hotel lobby",
      "dropoff_address": null,
      "transit_duration_minutes": 45,
      "tour_template_id": 8,
      "date": "2026-09-10",
      "created_at": "...",
      "updated_at": "..."
    }
  ],
  "created_at": "2026-08-10T14:30:00Z",
  "updated_at": "2026-08-10T14:30:00Z"
}

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
    }
  }'

Response (201):

{
  "id": 55,
  "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-20",
  "created_at": "...",
  "updated_at": "..."
}

Notes: - pickup_time, pickup_address, and transit_duration_minutes are auto-filled from the template if omitted. - category is auto-set to "multi" when the selected template is multi-date. - status defaults to "scheduled". - compensation_type defaults to "gig".


Create a multi-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": 7,
      "pax_count": 15,
      "start_date": "2026-09-10",
      "end_date": "2026-09-13"
    }
  }'

Response (201) — includes the parent tour with nested child_tours (one per template day plan).


Error Responses

401 — Unauthorized (missing or invalid API key)

curl https://youragency.pragmatictours.com/api/v1/tours
{ "error": "Missing Authorization header" }
curl -H "Authorization: Bearer invalid_key" \
  https://youragency.pragmatictours.com/api/v1/tours
{ "error": "Invalid or revoked API key" }

404 — Not found

curl -H "Authorization: Bearer pt_a1b2c3d4e5f6..." \
  https://youragency.pragmatictours.com/api/v1/tours/99999
{ "error": "Not found" }

422 — Validation error

curl -X POST https://youragency.pragmatictours.com/api/v1/tours \
  -H "Authorization: Bearer pt_a1b2c3d4e5f6..." \
  -H "Content-Type: application/json" \
  -d '{ "tour": { "pax_count": -1 } }'
{ "error": ["Tour template is required", "Pax count must be greater than or equal to 0"] }

400 — Bad request (missing required param)

curl -X POST https://youragency.pragmatictours.com/api/v1/tours \
  -H "Authorization: Bearer pt_a1b2c3d4e5f6..." \
  -H "Content-Type: application/json" \
  -d '{}'
{ "error": "param is missing or the value is empty: tour" }