{
  "info": {
    "name": "Airdesk Partner API 2026-10-01",
    "description": "Generated from the OpenAPI document. Set baseUrl, secretKey and publishableKey in the collection variables.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "auth": {
    "type": "bearer",
    "bearer": [
      {
        "key": "token",
        "value": "{{secretKey}}",
        "type": "string"
      }
    ]
  },
  "variable": [
    {
      "key": "baseUrl",
      "value": "https://api.example.com"
    },
    {
      "key": "secretKey",
      "value": "adk_sk_test_…"
    },
    {
      "key": "publishableKey",
      "value": "adk_pk_test_…"
    }
  ],
  "item": [
    {
      "name": "Account",
      "item": [
        {
          "name": "Who am I",
          "request": {
            "method": "GET",
            "description": "The integration, mode, environment and scopes of the calling key.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/partner/me",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "partner", "me"],
              "query": [],
              "variable": []
            }
          }
        },
        {
          "name": "Check a key",
          "request": {
            "method": "GET",
            "description": "A cheap authenticated call for setup screens.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/partner/ping",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "partner", "ping"],
              "query": [],
              "variable": []
            }
          }
        }
      ]
    },
    {
      "name": "Catalogue",
      "item": [
        {
          "name": "List group fares",
          "request": {
            "method": "GET",
            "description": "Active groups with seats left, minus any your agreement excludes. Needs scope `catalogue:read`.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/partner/catalogue/groups",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "partner", "catalogue", "groups"],
              "query": [
                {
                  "key": "cursor",
                  "value": "",
                  "disabled": true
                },
                {
                  "key": "limit",
                  "value": "",
                  "disabled": true
                },
                {
                  "key": "from",
                  "value": "KHI",
                  "disabled": true
                },
                {
                  "key": "to",
                  "value": "JED",
                  "disabled": true
                },
                {
                  "key": "departureFrom",
                  "value": "",
                  "disabled": true
                },
                {
                  "key": "departureTo",
                  "value": "",
                  "disabled": true
                },
                {
                  "key": "airline",
                  "value": "PK",
                  "disabled": true
                }
              ],
              "variable": []
            }
          }
        },
        {
          "name": "One group",
          "request": {
            "method": "GET",
            "description": "Segments, baggage, and cabins with a price and availability per passenger type.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/partner/catalogue/groups/:groupId",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "partner", "catalogue", "groups", ":groupId"],
              "query": [],
              "variable": [
                {
                  "key": "groupId",
                  "value": "",
                  "description": ""
                }
              ]
            }
          }
        },
        {
          "name": "List Umrah packages",
          "request": {
            "method": "GET",
            "description": "Published packages you may resell, with your retail prices. Needs scope `catalogue:read`.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/partner/catalogue/packages",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "partner", "catalogue", "packages"],
              "query": [
                {
                  "key": "cursor",
                  "value": "",
                  "disabled": true
                },
                {
                  "key": "limit",
                  "value": "",
                  "disabled": true
                },
                {
                  "key": "month",
                  "value": "2026-12",
                  "disabled": true
                },
                {
                  "key": "durationNights",
                  "value": "",
                  "disabled": true
                },
                {
                  "key": "departureCity",
                  "value": "LHE",
                  "disabled": true
                },
                {
                  "key": "tier",
                  "value": "",
                  "disabled": true
                },
                {
                  "key": "maxRetailPrice",
                  "value": "",
                  "disabled": true
                }
              ],
              "variable": []
            }
          }
        },
        {
          "name": "One package",
          "request": {
            "method": "GET",
            "description": "Hotels, itinerary, inclusions and exclusions, terms, media and departures.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/partner/catalogue/packages/:packageIdOrSlug",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "partner", "catalogue", "packages", ":packageIdOrSlug"],
              "query": [],
              "variable": [
                {
                  "key": "packageIdOrSlug",
                  "value": "ramadan-economy-14n",
                  "description": ""
                }
              ]
            }
          }
        },
        {
          "name": "Departures of a package",
          "request": {
            "method": "GET",
            "description": "Dated departures with a price per room type and an availability hint.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/partner/catalogue/packages/:packageIdOrSlug/departures",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "partner", "catalogue", "packages", ":packageIdOrSlug", "departures"],
              "query": [],
              "variable": [
                {
                  "key": "packageIdOrSlug",
                  "value": "",
                  "description": ""
                }
              ]
            }
          }
        }
      ]
    },
    {
      "name": "Requests",
      "item": [
        {
          "name": "Create a customer request (Package request)",
          "request": {
            "method": "POST",
            "description": "One body for both products; `productType` selects which fields apply.\n\n- **Package:** `packageId`, `departureId` (fixed departures), `rooms` (adults and children per room; bed capacity is checked).\n- **Group:** `groupId`, a cabin (`cabinId`, or the stable `cabinCode` Y/W/C/F), and either `pax` or `passengers`.\n\n**Passengers (group requests).** Send `passengers[]` with your own `ref` per traveller, plus name, `type` (ADULT/CHILD/INFANT), and optionally `dob`, `nationality` (ISO alpha-3), `passportNumber` and `passportExpiry`. Seat counts are taken from the list (`pax` may be omitted; if sent it must agree). `ref` must be unique within the request. It is the key ticket numbers come back on: we never match travellers by name. Passport numbers are returned masked.\n\n**Holds.** `hold: true` creates a normal booking in your agency's name (`PAYMENT_PENDING`) and takes the seats immediately. The payment deadline is the group's `paymentDeadlineHours` (`paymentDeadlineAt` / `holdExpiresAt`); callers cannot override it. Needs a secret key with `holds:write` on a hold-enabled integration, and is limited by concurrent-seat and daily-hold caps. Works in both Direct and Connected mode at create time (Connected can also hold on `/forward`). Approve with `POST /requests/{id}/approve` or reject with `/reject` (reject cancels the booking and releases seats). Extend the deadline with `POST /requests/{id}/extension-request` (Airdesk head office must approve). The seats return to sale if you cancel/reject, the deadline passes (`request.expired`), or the booking is cancelled.\n\n**Retries.** `partnerReference` is unique per integration (and per environment). Sending it again, even with a new `Idempotency-Key`, returns `200` with the original request, so a retried push can never double-book.\n\n**Browser keys** must send `turnstileToken` and the call must come from an allowed website. The answer contains only `id`, `reference`, `status`, `createdAt`: contact data is never echoed back to a browser.\n**Secret keys** get the full request. In connected mode the request waits in your inbox (`RECEIVED`) unless you send `forwardImmediately: true`.\nSandbox (test key) requests are created and tracked but never reach head office.\n\nThe same call repeated with the same `Idempotency-Key`, the same `partnerReference`, or the same customer double-clicking within 10 minutes, returns `200` with the original request instead of creating a second one.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/partner/requests",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "partner", "requests"],
              "query": [],
              "variable": []
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"productType\": \"PACKAGE\",\n  \"packageId\": \"9f87e56a-0d08-4f58-93b1-83c0352d6095\",\n  \"departureId\": \"3d7744e0-c7a4-489f-b556-c3a9119e60a5\",\n  \"rooms\": [\n    {\n      \"type\": \"QUAD\",\n      \"adults\": 2\n    }\n  ],\n  \"contact\": {\n    \"name\": \"Ali Khan\",\n    \"phone\": \"+923001234567\",\n    \"email\": \"ali@example.com\",\n    \"city\": \"Lahore\"\n  },\n  \"notes\": \"Prefers a room on a high floor.\",\n  \"partnerReference\": \"WEB-2026-00042\",\n  \"consent\": {\n    \"accepted\": true,\n    \"textVersion\": \"v1\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Create a customer request (Group seats)",
          "request": {
            "method": "POST",
            "description": "One body for both products; `productType` selects which fields apply.\n\n- **Package:** `packageId`, `departureId` (fixed departures), `rooms` (adults and children per room; bed capacity is checked).\n- **Group:** `groupId`, a cabin (`cabinId`, or the stable `cabinCode` Y/W/C/F), and either `pax` or `passengers`.\n\n**Passengers (group requests).** Send `passengers[]` with your own `ref` per traveller, plus name, `type` (ADULT/CHILD/INFANT), and optionally `dob`, `nationality` (ISO alpha-3), `passportNumber` and `passportExpiry`. Seat counts are taken from the list (`pax` may be omitted; if sent it must agree). `ref` must be unique within the request. It is the key ticket numbers come back on: we never match travellers by name. Passport numbers are returned masked.\n\n**Holds.** `hold: true` creates a normal booking in your agency's name (`PAYMENT_PENDING`) and takes the seats immediately. The payment deadline is the group's `paymentDeadlineHours` (`paymentDeadlineAt` / `holdExpiresAt`); callers cannot override it. Needs a secret key with `holds:write` on a hold-enabled integration, and is limited by concurrent-seat and daily-hold caps. Works in both Direct and Connected mode at create time (Connected can also hold on `/forward`). Approve with `POST /requests/{id}/approve` or reject with `/reject` (reject cancels the booking and releases seats). Extend the deadline with `POST /requests/{id}/extension-request` (Airdesk head office must approve). The seats return to sale if you cancel/reject, the deadline passes (`request.expired`), or the booking is cancelled.\n\n**Retries.** `partnerReference` is unique per integration (and per environment). Sending it again, even with a new `Idempotency-Key`, returns `200` with the original request, so a retried push can never double-book.\n\n**Browser keys** must send `turnstileToken` and the call must come from an allowed website. The answer contains only `id`, `reference`, `status`, `createdAt`: contact data is never echoed back to a browser.\n**Secret keys** get the full request. In connected mode the request waits in your inbox (`RECEIVED`) unless you send `forwardImmediately: true`.\nSandbox (test key) requests are created and tracked but never reach head office.\n\nThe same call repeated with the same `Idempotency-Key`, the same `partnerReference`, or the same customer double-clicking within 10 minutes, returns `200` with the original request instead of creating a second one.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/partner/requests",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "partner", "requests"],
              "query": [],
              "variable": []
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"productType\": \"GROUP\",\n  \"groupId\": \"4dece828-160a-4782-bea7-1c20ae185c29\",\n  \"cabinCode\": \"Y\",\n  \"passengers\": [\n    {\n      \"ref\": \"pax-1\",\n      \"givenNames\": \"Sara\",\n      \"familyName\": \"Khan\",\n      \"type\": \"ADULT\",\n      \"dob\": \"1988-04-12\",\n      \"nationality\": \"PAK\",\n      \"passportNumber\": \"AB1234567\",\n      \"passportExpiry\": \"2031-06-30\"\n    },\n    {\n      \"ref\": \"pax-2\",\n      \"givenNames\": \"Imran\",\n      \"familyName\": \"Khan\",\n      \"type\": \"ADULT\"\n    },\n    {\n      \"ref\": \"pax-3\",\n      \"givenNames\": \"Hira\",\n      \"familyName\": \"Khan\",\n      \"type\": \"CHILD\",\n      \"dob\": \"2018-09-01\"\n    }\n  ],\n  \"hold\": true,\n  \"partnerReference\": \"ORDER-88213\",\n  \"contact\": {\n    \"name\": \"Sara Khan\",\n    \"phone\": \"+923331234567\"\n  },\n  \"consent\": {\n    \"accepted\": true\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "List your requests",
          "request": {
            "method": "GET",
            "description": "Newest first. `updatedSince` supports incremental sync. Needs a **secret key**; browser keys get `403 partner_api.scope_missing`. Needs scope `requests:read`.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/partner/requests",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "partner", "requests"],
              "query": [
                {
                  "key": "status",
                  "value": "",
                  "disabled": true
                },
                {
                  "key": "productType",
                  "value": "",
                  "disabled": true
                },
                {
                  "key": "updatedSince",
                  "value": "",
                  "disabled": true
                },
                {
                  "key": "partnerReference",
                  "value": "",
                  "disabled": true
                },
                {
                  "key": "cursor",
                  "value": "",
                  "disabled": true
                },
                {
                  "key": "limit",
                  "value": "",
                  "disabled": true
                }
              ],
              "variable": []
            }
          }
        },
        {
          "name": "One request",
          "request": {
            "method": "GET",
            "description": "Look up by id, or by your own reference with `ref:<partnerReference>`. Once head office has booked a group request, `fulfilment` carries the booking reference, every PNR, and each passenger's PNR and ticket number keyed by your passenger `ref` (null values until issued). A `request.fulfilled` event fires when the booking is ticketed, whoever ticketed it. Needs a **secret key**; browser keys get `403 partner_api.scope_missing`.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/partner/requests/:id",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "partner", "requests", ":id"],
              "query": [],
              "variable": [
                {
                  "key": "id",
                  "value": "ref:WEB-2026-00042",
                  "description": ""
                }
              ]
            }
          }
        },
        {
          "name": "Cancel a request",
          "request": {
            "method": "POST",
            "description": "Before head office confirms, the request is cancelled at once. After confirmation a cancellation request is raised (`CANCELLATION_REQUESTED`) and head office decides. Needs a **secret key**; browser keys get `403 partner_api.scope_missing`. Needs scope `requests:manage`.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/partner/requests/:id/cancel",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "partner", "requests", ":id", "cancel"],
              "query": [],
              "variable": [
                {
                  "key": "id",
                  "value": "",
                  "description": ""
                }
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reason\": \"Customer cannot travel on these dates.\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Forward an inbox request to head office",
          "request": {
            "method": "POST",
            "description": "Connected mode only: `RECEIVED` becomes `UNDER_REVIEW`. Send `rooms` (package) or `pax` (group) to change what is forwarded; the request is re-priced. Send `hold: true` (group, needs `holds:write`) to take the seats as it is forwarded; the request becomes `HELD`. Needs a **secret key**; browser keys get `403 partner_api.scope_missing`. Needs scope `requests:manage`.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/partner/requests/:id/forward",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "partner", "requests", ":id", "forward"],
              "query": [],
              "variable": [
                {
                  "key": "id",
                  "value": "",
                  "description": ""
                }
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Approve a held partner booking",
          "request": {
            "method": "POST",
            "description": "Approve a held group booking created with `hold: true`. The booking stays `PAYMENT_PENDING` in your agency tenant; pay or confirm it the usual way. Needs a **secret key**; browser keys get `403 partner_api.scope_missing`. Needs scope `requests:manage`.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/partner/requests/:id/approve",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "partner", "requests", ":id", "approve"],
              "query": [],
              "variable": [
                {
                  "key": "id",
                  "value": "",
                  "description": ""
                }
              ]
            }
          }
        },
        {
          "name": "Decline an inbox request or reject a held booking",
          "request": {
            "method": "POST",
            "description": "Connected inbox: `RECEIVED` becomes `AGENT_REJECTED` (head office never sees it). Held partner bookings awaiting approval: cancels the booking, releases seats, and sets `AGENT_REJECTED`. Needs a **secret key**; browser keys get `403 partner_api.scope_missing`. Needs scope `requests:manage`.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/partner/requests/:id/reject",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "partner", "requests", ":id", "reject"],
              "query": [],
              "variable": [
                {
                  "key": "id",
                  "value": "",
                  "description": ""
                }
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reason\": \"Customer unreachable.\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Ask Airdesk to extend the payment deadline",
          "request": {
            "method": "POST",
            "description": "For a held partner booking in your agency's name. Head office must approve; on approval `holdExpiresAt` / `paymentDeadlineAt` move and `request.deadline_extended` is emitted. Needs a **secret key**; browser keys get `403 partner_api.scope_missing`. Needs scope `requests:manage`.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/partner/requests/:id/extension-request",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "partner", "requests", ":id", "extension-request"],
              "query": [],
              "variable": [
                {
                  "key": "id",
                  "value": "",
                  "description": ""
                }
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"extensionMinutes\": 60,\n  \"reason\": \"Customer payment delayed\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        }
      ]
    },
    {
      "name": "Events",
      "item": [
        {
          "name": "Event feed",
          "request": {
            "method": "GET",
            "description": "Everything that happened to your requests, in order. This is the polling alternative to webhooks and the way to recover anything a webhook missed.\n\nPass the highest `sequence` you have processed as `after`. Events younger than three seconds are held back so a slow transaction cannot appear behind your cursor; re-reading a few events is harmless because every event has a unique `id`.\nNeeds a **secret key**; browser keys get `403 partner_api.scope_missing`. Needs scope `events:read`.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/partner/events",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "partner", "events"],
              "query": [
                {
                  "key": "after",
                  "value": "",
                  "disabled": true
                },
                {
                  "key": "limit",
                  "value": "",
                  "disabled": true
                }
              ],
              "variable": []
            }
          }
        },
        {
          "name": "Your webhook endpoints",
          "request": {
            "method": "GET",
            "description": "Read only: endpoints are created and changed in the portal. Secrets are never returned. Needs a **secret key**; browser keys get `403 partner_api.scope_missing`. Needs scope `events:read`.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/partner/webhook-endpoints",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "partner", "webhook-endpoints"],
              "query": [],
              "variable": []
            }
          }
        },
        {
          "name": "Send a test event",
          "request": {
            "method": "POST",
            "description": "Sends a `webhook.test` event to one endpoint and reports what your receiver answered. Needs a **secret key**; browser keys get `403 partner_api.scope_missing`. Needs scope `events:read`.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/partner/webhook-endpoints/:id/test",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "partner", "webhook-endpoints", ":id", "test"],
              "query": [],
              "variable": [
                {
                  "key": "id",
                  "value": "",
                  "description": ""
                }
              ]
            }
          }
        }
      ]
    }
  ]
}
