{
  "info": {
    "_postman_id": "7c1e9a24-6b53-4f18-bb90-2f0d7c4a55e3",
    "name": "Booking Window - GT (GlobalTix) Booking Flow",
    "description": "GlobalTix inventory (source GT) on /outApi/*.\n\nAUTH: header  x-api-key: {{api_key}}  (your Agent API Key). Your account must be granted GT.\n\nFLOW\n  1. activity_list / get_activity_by_id (source GT) -- find the product, its OPTIONS and prices\n  2. reserve_booking (source GT)  -- GlobalTix holds the tickets, nothing is charged\n  3. create_booking (booking_ref_no) -- charges your wallet, then confirms at GlobalTix\n     release_booking             -- or give the hold back\n\nWHAT IS DIFFERENT FROM ACT\n  * category_id is REQUIRED: a GlobalTix product sells only through an option.\n    Use categories[].category_id from get_activity_by_id.\n  * Time-slot tickets need time_from, and it must be one of that option's own slots.\n  * Some options require answers: send questions: [{questionCode, answer}]. If an option\n    needs them, reserve is refused with gt_questions_required and lists the questions.\n  * One-step create_booking is NOT allowed for GT (reserve_required) -- always reserve first.\n  * GlobalTix holds its own stock; no inventory of ours is frozen.\n  * Cancelling a CONFIRMED GT booking is not available yet (gt_cancel_unavailable).\n\nEvery response carries an X-Request-Id header. Quote it when contacting support.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "auth": {
    "type": "apikey",
    "apikey": [
      {
        "key": "key",
        "value": "x-api-key",
        "type": "string"
      },
      {
        "key": "value",
        "value": "{{api_key}}",
        "type": "string"
      },
      {
        "key": "in",
        "value": "header",
        "type": "string"
      }
    ]
  },
  "variable": [
    {
      "key": "baseUrl",
      "value": "http://localhost:5558",
      "type": "string"
    },
    {
      "key": "api_key",
      "value": "AGT_XXXXXXXXXXXXXXXX",
      "type": "string"
    },
    {
      "key": "gt_product_id",
      "value": "53082",
      "type": "string"
    },
    {
      "key": "gt_option_id",
      "value": "796511",
      "type": "string"
    },
    {
      "key": "gt_visit_time",
      "value": "10:00:00",
      "type": "string"
    },
    {
      "key": "travel_date",
      "value": "2026-10-10",
      "type": "string"
    },
    {
      "key": "booking_ref_no",
      "value": "",
      "type": "string"
    },
    {
      "key": "booking_id",
      "value": "",
      "type": "string"
    },
    {
      "key": "held_total_price",
      "value": "",
      "type": "string"
    },
    {
      "key": "supplier_reference",
      "value": "",
      "type": "string"
    }
  ],
  "item": [
    {
      "name": "1. Find the GlobalTix product",
      "item": [
        {
          "name": "Activity List (GT only)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"country\": \"Singapore\",\n  \"city\": \"Singapore\",\n  \"travel_date\": \"{{travel_date}}\",\n  \"guest_currency\": \"INR\",\n  \"keyword\": \"Trick Eye\",\n  \"include_bw\": 0,\n  \"page\": 1,\n  \"limit\": 20\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/outApi/activity_list",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "outApi",
                "activity_list"
              ]
            },
            "description": "include_bw: 0 leaves own inventory out, so only GT items come back. Each item's `source` is GT and `id` is the GlobalTix product id. If GlobalTix is slow the list answers without it rather than waiting."
          },
          "response": []
        },
        {
          "name": "Get Activity By Id (GT)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"activity_id\": \"{{gt_product_id}}\",\n  \"source\": \"GT\",\n  \"travel_date\": \"{{travel_date}}\",\n  \"guest_currency\": \"INR\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/outApi/get_activity_by_id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "outApi",
                "get_activity_by_id"
              ]
            },
            "description": "The product's OPTIONS come back as `categories[]` — `category_id` there is what you book with. `time_slots[]` carries `category_id` and the option's start times; use one of those as `time_from`. country/city do not filter a GT lookup."
          },
          "response": []
        }
      ]
    },
    {
      "name": "2. Reserve -> confirm -> release",
      "item": [
        {
          "name": "Reserve Booking (GT)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reference_type\": 1,\n  \"reference_id\": \"{{gt_product_id}}\",\n  \"source\": \"GT\",\n  \"category_id\": \"{{gt_option_id}}\",\n  \"travel_date\": \"{{travel_date}}\",\n  \"time_from\": \"{{gt_visit_time}}\",\n  \"title\": \"GlobalTix activity\",\n  \"city\": \"Singapore\",\n  \"country\": \"Singapore\",\n  \"currency\": \"INR\",\n  \"no_of_travellers\": {\n    \"adult\": 2,\n    \"child\": 1,\n    \"infant\": 0,\n    \"travellers\": 3\n  },\n  \"total_price\": 4500,\n  \"guest_info\": {\n    \"first_name\": \"Harish\",\n    \"last_name\": \"K\",\n    \"email\": \"harish@example.com\",\n    \"contact_no\": \"+919999999999\"\n  },\n  \"questions\": [],\n  \"reference_object\": {\n    \"id\": \"{{gt_product_id}}\",\n    \"source\": \"GT\",\n    \"activity_date\": \"{{travel_date}}\",\n    \"selected_category_id\": \"{{gt_option_id}}\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/outApi/reserve_booking",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "outApi",
                "reserve_booking"
              ]
            },
            "description": "GlobalTix holds the tickets. Nothing is charged; your wallet is only checked.\n\nReturns booking_ref_no, supplier_reference (the GlobalTix reference), hold_expires_at, hold_minutes, total_price (what confirm will charge), price_changed and price_check.\n\nRefusals: gt_option_not_found (bad category_id), gt_visit_time_required / gt_visit_time_invalid, gt_questions_required (answers needed — the questions are in data.questions), gt_ticket_type_missing (that option has no rate for a pax type you sent), gt_reserve_refused (GlobalTix said no), gt_unavailable (503), source_not_granted (403 — your account has no GT grant)."
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const r = pm.response.json();",
                  "pm.test('reserved at GlobalTix', () => pm.expect(r.status).to.eql(true));",
                  "if (r.status && r.data) {",
                  "  pm.collectionVariables.set('booking_ref_no', r.data.booking_ref_no);",
                  "  pm.collectionVariables.set('held_total_price', r.data.total_price);",
                  "  pm.collectionVariables.set('supplier_reference', r.data.supplier_reference || '');",
                  "  console.log('GlobalTix reference', r.data.supplier_reference, 'expires', r.data.hold_expires_at);",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Create Booking (confirm the GT hold)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"booking_ref_no\": \"{{booking_ref_no}}\",\n  \"total_price\": \"{{held_total_price}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/outApi/create_booking",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "outApi",
                "create_booking"
              ]
            },
            "description": "Charges your wallet, then confirms at GlobalTix.\n\nIf GlobalTix refuses or is unreachable, the charge is reversed and the hold goes back to RESERVED: the reply carries data.charged = false and you can retry. In the rare case the reversal itself fails, data.charged = true and the message asks you to contact support with the reference — do not retry.\n\nRefusals: gt_confirm_refused (409), gt_unavailable (503), reservation_expired, already_confirmed, price_mismatch, insufficient_balance."
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const r = pm.response.json();",
                  "pm.test('confirmed', () => pm.expect(r.status).to.eql(true));",
                  "if (r.status && r.data) { pm.collectionVariables.set('booking_id', r.data.booking_id); }",
                  "if (!r.status && r.data) { console.log('charged:', r.data.charged, 'state:', r.data.reservation_status); }"
                ]
              }
            }
          ]
        },
        {
          "name": "Release Booking (GT)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"booking_ref_no\": \"{{booking_ref_no}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/outApi/release_booking",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "outApi",
                "release_booking"
              ]
            },
            "description": "Gives the hold back to GlobalTix. No money moves.\n\n`inventory_restored: false` means GlobalTix did not take the release — the hold is freed on our side anyway and GlobalTix expires it within 60 minutes of the reservation. Releasing an already released or expired hold answers 200."
          },
          "response": []
        }
      ]
    },
    {
      "name": "3. After the booking",
      "item": [
        {
          "name": "Booking Details",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"booking_ref_no\": \"{{booking_ref_no}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/outApi/booking_details",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "outApi",
                "booking_details"
              ]
            },
            "description": "The GlobalTix reference is in `confirmation_no`. `booking_status` is RESERVED while the hold is live, then CONFIRMED.\n\nE-TICKET: for a GlobalTix booking this is also where voucher_pdf is filled in. GlobalTix issues the e-ticket after confirmation and not always instantly, so create_booking can return voucher_pdf: null; this call fetches and stores it once GlobalTix has it. Read the booking again a minute later rather than polling."
          },
          "response": []
        },
        {
          "name": "Bookings List (holds too)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"include_reservations\": 1,\n  \"page\": 1,\n  \"limit\": 20\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/outApi/bookings_list",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "outApi",
                "bookings_list"
              ]
            },
            "description": "include_reservations: 1 lists holds as well. status: \"RESERVED\" lists only holds."
          },
          "response": []
        },
        {
          "name": "Wallet Balance",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"amount\": 4500\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/outApi/wallet_balance",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "outApi",
                "wallet_balance"
              ]
            },
            "description": "Your balance; the optional amount answers \"can I afford this\"."
          },
          "response": []
        },
        {
          "name": "Cancellation Charges (GT)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"booking_ref_no\": \"{{booking_ref_no}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/outApi/cancellation_charges",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "outApi",
                "cancellation_charges"
              ]
            },
            "description": "What cancelling this GlobalTix booking would cost right now.\n\nPriced from the GlobalTix policy snapshot taken at reserve time, so cancellation_policy_source is \"GT\" and cancellation_policy_id is null (fdk_hotels knows nothing about a GlobalTix option). A product whose option declared no policy prices at 100% charge with charge_reason NO_POLICY."
          },
          "response": []
        },
        {
          "name": "Cancel Booking (GT)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"booking_ref_no\": \"{{booking_ref_no}}\",\n  \"remarks\": \"Customer cancelled\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/outApi/cancel_booking",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "outApi",
                "cancel_booking"
              ]
            },
            "description": "Cancels a CONFIRMED GlobalTix booking.\n\nGlobalTix is called FIRST (transaction/cancel). Only once it answers CANCELLED does the wallet get credited, so a 200 here means the tickets are dead AND the refund is in.\n\nThe refund follows GLOBALTIX's terms for that product, snapshotted when you reserved it (percentReturn / refundDuration) -- the response says \"cancellation_policy_source\": \"GT\". Call cancellation_charges first to show the figure.\n\nExtra fields on success: supplier, supplier_reference, supplier_cancelled.\ninventory_restored is always false -- a GT booking holds none of our stock.\n\nRefusals, none of which move money:\n  409 gt_not_cancellable  - non-cancellable product, nothing to retry\n  409 gt_cancel_refused   - GlobalTix declined; the booking is still live\n  503 gt_unavailable      - no answer; nothing changed, safe to retry\n  409 gt_no_reference     - no supplier reference on the booking\n  500 gt_cancelled_not_settled - tickets cancelled, refund did NOT complete. DO NOT RETRY; support settles it by hand.\n\nA GT HOLD is not cancelled here -- release it instead (409 not_confirmed)."
          },
          "response": []
        }
      ]
    },
    {
      "name": "4. Negative examples",
      "item": [
        {
          "name": "Reserve without category_id",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reference_type\": 1,\n  \"reference_id\": \"{{gt_product_id}}\",\n  \"source\": \"GT\",\n  \"travel_date\": \"{{travel_date}}\",\n  \"time_from\": \"{{gt_visit_time}}\",\n  \"title\": \"GlobalTix activity\",\n  \"city\": \"Singapore\",\n  \"country\": \"Singapore\",\n  \"currency\": \"INR\",\n  \"no_of_travellers\": {\n    \"adult\": 2,\n    \"child\": 1,\n    \"infant\": 0,\n    \"travellers\": 3\n  },\n  \"total_price\": 4500,\n  \"guest_info\": {\n    \"first_name\": \"Harish\",\n    \"last_name\": \"K\",\n    \"email\": \"harish@example.com\",\n    \"contact_no\": \"+919999999999\"\n  },\n  \"questions\": [],\n  \"reference_object\": {\n    \"id\": \"{{gt_product_id}}\",\n    \"source\": \"GT\",\n    \"activity_date\": \"{{travel_date}}\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/outApi/reserve_booking",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "outApi",
                "reserve_booking"
              ]
            },
            "description": "400 no_category — a GlobalTix product sells only through an option, and we will not pick one (and therefore a price) for you."
          },
          "response": []
        },
        {
          "name": "Reserve with a wrong time slot",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reference_type\": 1,\n  \"reference_id\": \"{{gt_product_id}}\",\n  \"source\": \"GT\",\n  \"category_id\": \"{{gt_option_id}}\",\n  \"travel_date\": \"{{travel_date}}\",\n  \"time_from\": \"03:00:00\",\n  \"title\": \"GlobalTix activity\",\n  \"city\": \"Singapore\",\n  \"country\": \"Singapore\",\n  \"currency\": \"INR\",\n  \"no_of_travellers\": {\n    \"adult\": 2,\n    \"child\": 1,\n    \"infant\": 0,\n    \"travellers\": 3\n  },\n  \"total_price\": 4500,\n  \"guest_info\": {\n    \"first_name\": \"Harish\",\n    \"last_name\": \"K\",\n    \"email\": \"harish@example.com\",\n    \"contact_no\": \"+919999999999\"\n  },\n  \"questions\": [],\n  \"reference_object\": {\n    \"id\": \"{{gt_product_id}}\",\n    \"source\": \"GT\",\n    \"activity_date\": \"{{travel_date}}\",\n    \"selected_category_id\": \"{{gt_option_id}}\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/outApi/reserve_booking",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "outApi",
                "reserve_booking"
              ]
            },
            "description": "400 gt_visit_time_invalid — the time must be one of that option's own slots."
          },
          "response": []
        },
        {
          "name": "One-step GT booking",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reference_type\": 1,\n  \"reference_id\": \"{{gt_product_id}}\",\n  \"source\": \"GT\",\n  \"category_id\": \"{{gt_option_id}}\",\n  \"travel_date\": \"{{travel_date}}\",\n  \"time_from\": \"{{gt_visit_time}}\",\n  \"title\": \"GlobalTix activity\",\n  \"city\": \"Singapore\",\n  \"country\": \"Singapore\",\n  \"currency\": \"INR\",\n  \"no_of_travellers\": {\n    \"adult\": 2,\n    \"child\": 1,\n    \"infant\": 0,\n    \"travellers\": 3\n  },\n  \"total_price\": 4500,\n  \"guest_info\": {\n    \"first_name\": \"Harish\",\n    \"last_name\": \"K\",\n    \"email\": \"harish@example.com\",\n    \"contact_no\": \"+919999999999\"\n  },\n  \"questions\": [],\n  \"reference_object\": {\n    \"id\": \"{{gt_product_id}}\",\n    \"source\": \"GT\",\n    \"activity_date\": \"{{travel_date}}\",\n    \"selected_category_id\": \"{{gt_option_id}}\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/outApi/create_booking",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "outApi",
                "create_booking"
              ]
            },
            "description": "400 reserve_required — GlobalTix bookings must be reserved first."
          },
          "response": []
        },
        {
          "name": "Confirm with a stale price",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"booking_ref_no\": \"{{booking_ref_no}}\",\n  \"total_price\": 1\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/outApi/create_booking",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "outApi",
                "create_booking"
              ]
            },
            "description": "409 price_mismatch, carrying the held total_price."
          },
          "response": []
        }
      ]
    }
  ]
}