{
  "item": [
    {
      "id": "ae75648c-770f-4581-80c4-d939444e6559",
      "name": "Integration Configuration API Suite",
      "description": {
        "content": "Onboarding-time contract: exchange credentials, register your webhook endpoints, and map a Swoop location to your sites. These shapes are provisioned/agreed at onboarding rather than called ad hoc.\n\n**In this suite:**\n\n- `PUT` [Register the integration (credentials + webhook endpoints)](#tag/integration-configuration-api-suite/PUT/integration/registration)\n- `PUT` [Map a Swoop location to your sites and markers](#tag/integration-configuration-api-suite/PUT/integration/locations/{locationId}/mapping)",
        "type": "text/plain"
      },
      "item": [
        {
          "id": "cd6da0e0-d358-4684-874b-febdeb891580",
          "name": "Register the integration (credentials + webhook endpoints)",
          "request": {
            "name": "Register the integration (credentials + webhook endpoints)",
            "description": {
              "content": "**Contract, provided at onboarding — not a self-serve endpoint.** Captures what Swoop and\na partner exchange to connect: the credential your integration authenticates with, and the\nwebhook endpoint(s) + shared secret Swoop calls back on (order status, delivery, menu).\nDocumented so the shape is unambiguous; in practice these values are provisioned during\nonboarding. Secrets travel out of band, never in this body in production.\n",
              "type": "text/plain"
            },
            "url": {
              "path": [
                "integration",
                "registration"
              ],
              "host": [
                "{{baseUrl}}"
              ],
              "query": [],
              "variable": []
            },
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "method": "PUT",
            "auth": null,
            "body": {
              "mode": "raw",
              "raw": "{\n  \"integration\": \"<string>\",\n  \"credential\": {\n    \"kind\": \"<string>\",\n    \"note\": \"<string>\"\n  },\n  \"statusWebhook\": {\n    \"url\": \"<uri>\",\n    \"secret\": \"<string>\"\n  },\n  \"deliveryWebhook\": {\n    \"url\": \"<uri>\",\n    \"secret\": \"<string>\"\n  },\n  \"menuWebhook\": {\n    \"url\": \"<uri>\",\n    \"secret\": \"<string>\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "id": "64e6afff-ef0f-4014-8aa4-2b8f13638126",
              "name": "Registration accepted (echoed back without secrets).",
              "originalRequest": {
                "url": {
                  "path": [
                    "integration",
                    "registration"
                  ],
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "query": [],
                  "variable": []
                },
                "method": "PUT",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"integration\": \"my-pos\",\n  \"credential\": {\n    \"kind\": \"bearer\",\n    \"note\": \"provisioned out of band\"\n  },\n  \"statusWebhook\": {\n    \"url\": \"https://your-pos.example.com/swoop/status\"\n  },\n  \"deliveryWebhook\": {\n    \"url\": \"https://your-pos.example.com/swoop/delivery\"\n  }\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "text/plain"
                }
              ],
              "body": "",
              "cookie": [],
              "_postman_previewlanguage": "text"
            }
          ],
          "event": [],
          "protocolProfileBehavior": {
            "disableBodyPruning": true
          }
        },
        {
          "id": "197c71ed-b39f-4727-a471-65974dea6189",
          "name": "Map a Swoop location to your sites and markers",
          "request": {
            "name": "Map a Swoop location to your sites and markers",
            "description": {
              "content": "**Contract, provided at onboarding.** Binds a Swoop location (club) to your\npoint-of-sale/site ids and maps each on-course marker to a delivery drop-off site.\nUnmapped markers fall back to a human runner; unmapped items dead-letter (see Orders).\n",
              "type": "text/plain"
            },
            "url": {
              "path": [
                "integration",
                "locations",
                ":locationId",
                "mapping"
              ],
              "host": [
                "{{baseUrl}}"
              ],
              "query": [],
              "variable": [
                {
                  "disabled": false,
                  "type": "any",
                  "value": "<string>",
                  "key": "locationId",
                  "description": "(Required) The Swoop location (club) id."
                }
              ]
            },
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "method": "PUT",
            "auth": null,
            "body": {
              "mode": "raw",
              "raw": "{\n  \"posSiteId\": \"<string>\",\n  \"pickupSiteId\": \"<string>\",\n  \"markers\": [\n    {\n      \"markerId\": \"<string>\",\n      \"name\": \"<string>\",\n      \"dropoffSiteId\": \"<string,null>\"\n    },\n    {\n      \"markerId\": \"<string>\",\n      \"name\": \"<string>\",\n      \"dropoffSiteId\": \"<string,null>\"\n    }\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "id": "9bdfac03-75c7-4857-b74b-3f9e957b5a0e",
              "name": "Mapping stored.",
              "originalRequest": {
                "url": {
                  "path": [
                    "integration",
                    "locations",
                    ":locationId",
                    "mapping"
                  ],
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "query": [],
                  "variable": [
                    {
                      "disabled": false,
                      "type": "any",
                      "value": "<string>",
                      "key": "locationId",
                      "description": "(Required) The Swoop location (club) id."
                    }
                  ]
                },
                "method": "PUT",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"posSiteId\": \"store-51\",\n  \"pickupSiteId\": \"site-clubhouse\",\n  \"markers\": [\n    {\n      \"markerId\": \"368\",\n      \"dropoffSiteId\": \"site-drop-04\"\n    },\n    {\n      \"markerId\": \"373\",\n      \"dropoffSiteId\": \"site-drop-09\"\n    }\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "text/plain"
                }
              ],
              "body": "",
              "cookie": [],
              "_postman_previewlanguage": "text"
            }
          ],
          "event": [],
          "protocolProfileBehavior": {
            "disableBodyPruning": true
          }
        }
      ],
      "event": []
    },
    {
      "id": "d91778ba-a562-47f5-9fac-8b45b388dd75",
      "name": "Locations API Suite",
      "description": {
        "content": "The club → outlet/site → on-course marker (delivery drop-off) model your integration reads to route orders and deliveries.\n\n**In this suite:**\n\n- `GET` [Get a location](#tag/locations-api-suite/GET/locations/{locationId})\n- `GET` [List on-course markers (delivery drop-off points)](#tag/locations-api-suite/GET/locations/{locationId}/markers)",
        "type": "text/plain"
      },
      "item": [
        {
          "id": "7a6225b3-668c-45be-8bdd-e8aead6cc068",
          "name": "Get a location",
          "request": {
            "name": "Get a location",
            "description": {
              "content": "The club/outlet/site record your integration is bound to — read it to confirm routing,\nthe delivery pickup site, and the timezone. No member data.\n",
              "type": "text/plain"
            },
            "url": {
              "path": [
                "locations",
                ":locationId"
              ],
              "host": [
                "{{baseUrl}}"
              ],
              "query": [],
              "variable": [
                {
                  "disabled": false,
                  "type": "any",
                  "value": "<string>",
                  "key": "locationId",
                  "description": "(Required) The Swoop location (club) id."
                }
              ]
            },
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "method": "GET",
            "auth": null
          },
          "response": [
            {
              "id": "e8f36c3c-a5f2-4629-8c37-5a3df857347f",
              "name": "The location.",
              "originalRequest": {
                "url": {
                  "path": [
                    "locations",
                    ":locationId"
                  ],
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "query": [],
                  "variable": [
                    {
                      "disabled": false,
                      "type": "any",
                      "value": "<string>",
                      "key": "locationId",
                      "description": "(Required) The Swoop location (club) id."
                    }
                  ]
                },
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "method": "GET",
                "body": {}
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"locationId\": \"51\",\n  \"name\": \"Sample Golf Club\",\n  \"timezone\": \"America/New_York\",\n  \"pickupSiteId\": \"site-clubhouse\"\n}",
              "cookie": [],
              "_postman_previewlanguage": "json"
            }
          ],
          "event": [],
          "protocolProfileBehavior": {
            "disableBodyPruning": true
          }
        },
        {
          "id": "b5ed7dac-d301-40ed-b860-1f6beff9c1f7",
          "name": "List on-course markers (delivery drop-off points)",
          "request": {
            "name": "List on-course markers (delivery drop-off points)",
            "description": {
              "content": "The course's on-course markers (holes / tees / counters) and the delivery drop-off site\neach maps to. A delivery order references a marker; a marker with no mapped drop-off site\nfalls back to a human runner.\n",
              "type": "text/plain"
            },
            "url": {
              "path": [
                "locations",
                ":locationId",
                "markers"
              ],
              "host": [
                "{{baseUrl}}"
              ],
              "query": [],
              "variable": [
                {
                  "disabled": false,
                  "type": "any",
                  "value": "<string>",
                  "key": "locationId",
                  "description": "(Required) The Swoop location (club) id."
                }
              ]
            },
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "method": "GET",
            "auth": null
          },
          "response": [
            {
              "id": "2709f5b4-3c60-4670-bc33-1710ab59ca12",
              "name": "The location's markers.",
              "originalRequest": {
                "url": {
                  "path": [
                    "locations",
                    ":locationId",
                    "markers"
                  ],
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "query": [],
                  "variable": [
                    {
                      "disabled": false,
                      "type": "any",
                      "value": "<string>",
                      "key": "locationId",
                      "description": "(Required) The Swoop location (club) id."
                    }
                  ]
                },
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "method": "GET",
                "body": {}
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"markers\": [\n    {\n      \"markerId\": \"368\",\n      \"name\": \"4th Hole\",\n      \"dropoffSiteId\": \"site-drop-04\"\n    },\n    {\n      \"markerId\": \"381\",\n      \"name\": \"Halfway House\",\n      \"dropoffSiteId\": null\n    }\n  ]\n}",
              "cookie": [],
              "_postman_previewlanguage": "json"
            }
          ],
          "event": [],
          "protocolProfileBehavior": {
            "disableBodyPruning": true
          }
        }
      ],
      "event": []
    },
    {
      "id": "8c98f385-f5e2-467f-9fef-84d8afc294e5",
      "name": "Order API Suite",
      "description": {
        "content": "The order-injection contract, the order-status webhook, and the cancel/void contract. Orders settle at the end of the round, so injected orders are open and unpaid, there is no payment block.\n\n**In this suite:**\n\n- `POST` [Report an order-status change](#tag/order-api-suite/POST/webhook/{integration}/{locationId})\n- `POST` [The order-injection contract](#tag/order-api-suite/POST/integration/orders)\n- `POST` [Cancel / void an order](#tag/order-api-suite/POST/integration/orders/{externalRef}/cancel)",
        "type": "text/plain"
      },
      "item": [
        {
          "id": "acb07a24-985d-40b0-85ba-35f8f735d7e8",
          "name": "Report an order-status change",
          "request": {
            "name": "Report an order-status change",
            "description": {
              "content": "Your integration posts an order-status change here as the order advances. Swoop\napplies it to the member's order (persist + live update). Correlate by `externalRef`\n(`swoop:<orderId>`), echoed from the order Swoop injected.\n\n**Status buckets** — send your native status name; Swoop maps it onto the\nmember-facing lifecycle: `received` → `in_progress` → `ready` → (for delivery)\n`en_route` → `completed`, plus `cancelled` / `failed` (a `failed` order surfaces to\nthe member as cancelled; the `reason` is kept for club staff). Unmapped status names\nare acknowledged and ignored, never guessed.\n\n**Delivery semantics** — at-least-once is expected: retry any non-2xx with backoff.\nSwoop absorbs duplicates and out-of-order events (a monotonic guard means a stale\nevent never walks status backwards). A `200` means \"processed or safely discarded\" —\ndo not retry-loop on it. Events whose `externalRef` is not a Swoop order are ignored.\nThe body is read up to a **1 MiB** limit; request headers are available for signature\nverification.\n\n**No webhooks?** If your POS can't push, Swoop can instead poll a status read you expose\n(arranged at onboarding) on an interval — the same status mapping applies, and Swoop\nstops polling once the order reaches a terminal status (`completed` / `cancelled` /\n`failed`).\n",
              "type": "text/plain"
            },
            "url": {
              "path": [
                "webhook",
                ":integration",
                ":locationId"
              ],
              "host": [
                "{{baseUrl}}"
              ],
              "query": [
                {
                  "disabled": false,
                  "key": "token",
                  "value": "<string>",
                  "description": "(Required) Shared-secret webhook token, issued at onboarding."
                }
              ],
              "variable": [
                {
                  "disabled": false,
                  "type": "any",
                  "value": "<string>",
                  "key": "integration",
                  "description": "(Required) Your integration identifier, issued at onboarding."
                },
                {
                  "disabled": false,
                  "type": "any",
                  "value": "<string>",
                  "key": "locationId",
                  "description": "(Required) The Swoop location (club) id the order belongs to."
                }
              ]
            },
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "method": "POST",
            "auth": {
              "type": "apikey",
              "apikey": [
                {
                  "key": "key",
                  "value": "token"
                },
                {
                  "key": "value",
                  "value": "{{apiKey}}"
                },
                {
                  "key": "in",
                  "value": "query"
                }
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"externalRef\": \"<string>\",\n  \"status\": \"<string>\",\n  \"orderId\": \"<string>\",\n  \"reason\": \"<string>\",\n  \"occurredAt\": \"<dateTime>\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "id": "31eaa4ed-a4ca-403c-90c1-be2b14b131bf",
              "name": "Acknowledged (applied, or intentionally ignored).",
              "originalRequest": {
                "url": {
                  "path": [
                    "webhook",
                    ":integration",
                    ":locationId"
                  ],
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "query": [
                    {
                      "key": "token",
                      "value": "<string>"
                    },
                    {
                      "key": "token",
                      "value": "<API Key>"
                    }
                  ],
                  "variable": [
                    {
                      "disabled": false,
                      "type": "any",
                      "value": "<string>",
                      "key": "integration",
                      "description": "(Required) Your integration identifier, issued at onboarding."
                    },
                    {
                      "disabled": false,
                      "type": "any",
                      "value": "<string>",
                      "key": "locationId",
                      "description": "(Required) The Swoop location (club) id the order belongs to."
                    }
                  ]
                },
                "method": "POST",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"externalRef\": \"swoop:31287\",\n  \"orderId\": \"POS-55012\",\n  \"status\": \"IN_PROGRESS\",\n  \"occurredAt\": \"2026-06-22T10:16:00Z\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "text/plain"
                }
              ],
              "body": "",
              "cookie": [],
              "_postman_previewlanguage": "text"
            },
            {
              "id": "29abbb9f-58fa-4a52-8322-f59f50251de4",
              "name": "Body could not be read.",
              "originalRequest": {
                "url": {
                  "path": [
                    "webhook",
                    ":integration",
                    ":locationId"
                  ],
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "query": [
                    {
                      "key": "token",
                      "value": "<string>"
                    },
                    {
                      "key": "token",
                      "value": "<API Key>"
                    }
                  ],
                  "variable": [
                    {
                      "disabled": false,
                      "type": "any",
                      "value": "<string>",
                      "key": "integration",
                      "description": "(Required) Your integration identifier, issued at onboarding."
                    },
                    {
                      "disabled": false,
                      "type": "any",
                      "value": "<string>",
                      "key": "locationId",
                      "description": "(Required) The Swoop location (club) id the order belongs to."
                    }
                  ]
                },
                "method": "POST",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"externalRef\": \"swoop:31287\",\n  \"orderId\": \"POS-55012\",\n  \"status\": \"IN_PROGRESS\",\n  \"occurredAt\": \"2026-06-22T10:16:00Z\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Bad Request",
              "code": 400,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "text/plain"
                }
              ],
              "body": "",
              "cookie": [],
              "_postman_previewlanguage": "text"
            },
            {
              "id": "7faf1a01-240b-44e2-9c1c-2cfdcccbd43f",
              "name": "Missing or invalid token.",
              "originalRequest": {
                "url": {
                  "path": [
                    "webhook",
                    ":integration",
                    ":locationId"
                  ],
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "query": [
                    {
                      "key": "token",
                      "value": "<string>"
                    },
                    {
                      "key": "token",
                      "value": "<API Key>"
                    }
                  ],
                  "variable": [
                    {
                      "disabled": false,
                      "type": "any",
                      "value": "<string>",
                      "key": "integration",
                      "description": "(Required) Your integration identifier, issued at onboarding."
                    },
                    {
                      "disabled": false,
                      "type": "any",
                      "value": "<string>",
                      "key": "locationId",
                      "description": "(Required) The Swoop location (club) id the order belongs to."
                    }
                  ]
                },
                "method": "POST",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"externalRef\": \"swoop:31287\",\n  \"orderId\": \"POS-55012\",\n  \"status\": \"IN_PROGRESS\",\n  \"occurredAt\": \"2026-06-22T10:16:00Z\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Unauthorized",
              "code": 401,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "text/plain"
                }
              ],
              "body": "",
              "cookie": [],
              "_postman_previewlanguage": "text"
            },
            {
              "id": "456e7fec-7d02-4169-b0b2-6d2c0eb4a43a",
              "name": "Transient failure — please redeliver.",
              "originalRequest": {
                "url": {
                  "path": [
                    "webhook",
                    ":integration",
                    ":locationId"
                  ],
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "query": [
                    {
                      "key": "token",
                      "value": "<string>"
                    },
                    {
                      "key": "token",
                      "value": "<API Key>"
                    }
                  ],
                  "variable": [
                    {
                      "disabled": false,
                      "type": "any",
                      "value": "<string>",
                      "key": "integration",
                      "description": "(Required) Your integration identifier, issued at onboarding."
                    },
                    {
                      "disabled": false,
                      "type": "any",
                      "value": "<string>",
                      "key": "locationId",
                      "description": "(Required) The Swoop location (club) id the order belongs to."
                    }
                  ]
                },
                "method": "POST",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"externalRef\": \"swoop:31287\",\n  \"orderId\": \"POS-55012\",\n  \"status\": \"IN_PROGRESS\",\n  \"occurredAt\": \"2026-06-22T10:16:00Z\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Internal Server Error",
              "code": 500,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "text/plain"
                }
              ],
              "body": "",
              "cookie": [],
              "_postman_previewlanguage": "text"
            }
          ],
          "event": [],
          "protocolProfileBehavior": {
            "disableBodyPruning": true
          }
        },
        {
          "id": "4e0bbe4f-eae8-42c8-88f6-0ec197d4e2ba",
          "name": "The order-injection contract",
          "request": {
            "name": "The order-injection contract",
            "description": {
              "content": "**Direction: Swoop → your integration.** When a member checks out, Swoop builds this\ncanonical order and hands it to your POS integration's create-order path. It is shown\nhere as the **contract your integration receives**, not an endpoint you call on Swoop.\n\nCorrelate by `externalRef` (`swoop:<orderId>`) — your idempotency key. A repeated\ninjection with the same `externalRef` MUST resolve to the same order (a duplicate is\nsuccess, not a second ticket). Items reference the item ids/SKUs you mapped to your POS\nat onboarding, and each line's `modifiers[].sku` is a mapped modifier-option id (see\nMenu → modifier groups); an order referencing an **unmapped** item or modifier is\ndead-lettered for staff, never pushed with a guess.\n\n**Settlement:** golfers settle at the **end of the round**. Injected orders land\n**open and unpaid** — there is no payment block and no card data in this contract.\n",
              "type": "text/plain"
            },
            "url": {
              "path": [
                "integration",
                "orders"
              ],
              "host": [
                "{{baseUrl}}"
              ],
              "query": [],
              "variable": []
            },
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "method": "POST",
            "auth": null,
            "body": {
              "mode": "raw",
              "raw": "{\n  \"externalRef\": \"<string>\",\n  \"locationId\": \"<string>\",\n  \"items\": [\n    {\n      \"sku\": \"<string>\",\n      \"quantity\": \"<integer>\",\n      \"name\": \"<string>\",\n      \"notes\": \"<string>\",\n      \"ageRestricted\": false,\n      \"modifiers\": [\n        {\n          \"sku\": \"<string>\",\n          \"name\": \"<string>\"\n        },\n        {\n          \"sku\": \"<string>\",\n          \"name\": \"<string>\"\n        }\n      ]\n    },\n    {\n      \"sku\": \"<string>\",\n      \"quantity\": \"<integer>\",\n      \"name\": \"<string>\",\n      \"notes\": \"<string>\",\n      \"ageRestricted\": false,\n      \"modifiers\": [\n        {\n          \"sku\": \"<string>\",\n          \"name\": \"<string>\"\n        },\n        {\n          \"sku\": \"<string>\",\n          \"name\": \"<string>\"\n        }\n      ]\n    }\n  ],\n  \"placedAt\": \"<dateTime>\",\n  \"customer\": {\n    \"name\": \"<string>\"\n  },\n  \"fulfillment\": {\n    \"type\": \"<string>\",\n    \"destination\": \"<string>\"\n  },\n  \"collectionCode\": \"<string>\",\n  \"notes\": \"<string>\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "id": "73d118b2-c043-46c1-953e-110aa9c91e74",
              "name": "Your integration accepted the order and returns its POS-side order id.",
              "originalRequest": {
                "url": {
                  "path": [
                    "integration",
                    "orders"
                  ],
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "query": [],
                  "variable": []
                },
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "method": "POST",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"externalRef\": \"swoop:30412\",\n  \"locationId\": \"51\",\n  \"customer\": {\n    \"name\": \"Alex Member\"\n  },\n  \"fulfillment\": {\n    \"type\": \"pickup\",\n    \"destination\": \"Halfway House\"\n  },\n  \"collectionCode\": \"30412\",\n  \"items\": [\n    {\n      \"sku\": \"2643\",\n      \"quantity\": 2\n    }\n  ],\n  \"notes\": \"\",\n  \"placedAt\": \"2026-06-22T09:41:00Z\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"id\": \"POS-55012\"\n}",
              "cookie": [],
              "_postman_previewlanguage": "json"
            }
          ],
          "event": [],
          "protocolProfileBehavior": {
            "disableBodyPruning": true
          }
        },
        {
          "id": "889e58fd-708b-4b88-9249-b3d012f8d47b",
          "name": "Cancel / void an order",
          "request": {
            "name": "Cancel / void an order",
            "description": {
              "content": "**Direction: Swoop → your integration.** When a member or club staff cancels, Swoop asks\nyour integration to void the open order. Because golfers settle at the **end of the\nround**, the order is open and unpaid — voiding simply removes it; there is no refund.\nIdempotent on `externalRef`: voiding an already-voided or unknown order returns `200`.\n\n**Not every POS can void programmatically.** If yours has no void for this order type,\nreturn `501` (or declare cancel unsupported at onboarding) — Swoop then routes the order\nto **club staff** to void it in your back office, and the resulting `cancelled` status\nflows back through the order-status webhook. Swoop treats \"can't cancel\" as staff\nrouting, never as a hard failure.\n",
              "type": "text/plain"
            },
            "url": {
              "path": [
                "integration",
                "orders",
                ":externalRef",
                "cancel"
              ],
              "host": [
                "{{baseUrl}}"
              ],
              "query": [],
              "variable": [
                {
                  "disabled": false,
                  "type": "any",
                  "value": "<string>",
                  "key": "externalRef",
                  "description": "(Required) `swoop:<orderId>` of the order to void."
                }
              ]
            },
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "method": "POST",
            "auth": null
          },
          "response": [
            {
              "id": "689af38a-e3a1-4369-8fd3-2528211dd70b",
              "name": "Voided (or already absent).",
              "originalRequest": {
                "url": {
                  "path": [
                    "integration",
                    "orders",
                    ":externalRef",
                    "cancel"
                  ],
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "query": [],
                  "variable": [
                    {
                      "disabled": false,
                      "type": "any",
                      "value": "<string>",
                      "key": "externalRef",
                      "description": "(Required) `swoop:<orderId>` of the order to void."
                    }
                  ]
                },
                "method": "POST",
                "body": {}
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "text/plain"
                }
              ],
              "body": "",
              "cookie": [],
              "_postman_previewlanguage": "text"
            },
            {
              "id": "2f6e9ec9-3a11-4106-9447-44f82f20cd29",
              "name": "The order can no longer be voided (already settled/closed on your side).",
              "originalRequest": {
                "url": {
                  "path": [
                    "integration",
                    "orders",
                    ":externalRef",
                    "cancel"
                  ],
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "query": [],
                  "variable": [
                    {
                      "disabled": false,
                      "type": "any",
                      "value": "<string>",
                      "key": "externalRef",
                      "description": "(Required) `swoop:<orderId>` of the order to void."
                    }
                  ]
                },
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "method": "POST",
                "body": {}
              },
              "status": "Conflict",
              "code": 409,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"error\": \"already_closed\"\n}",
              "cookie": [],
              "_postman_previewlanguage": "json"
            },
            {
              "id": "fdcf2674-2964-43ab-98c6-d306726b9e2d",
              "name": "This order type has no programmatic void — Swoop routes it to club staff, who void it manually (the `cancelled` status then arrives via the order-status webhook).",
              "originalRequest": {
                "url": {
                  "path": [
                    "integration",
                    "orders",
                    ":externalRef",
                    "cancel"
                  ],
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "query": [],
                  "variable": [
                    {
                      "disabled": false,
                      "type": "any",
                      "value": "<string>",
                      "key": "externalRef",
                      "description": "(Required) `swoop:<orderId>` of the order to void."
                    }
                  ]
                },
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "method": "POST",
                "body": {}
              },
              "status": "Not Implemented",
              "code": 501,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"error\": \"cancel_unsupported\"\n}",
              "cookie": [],
              "_postman_previewlanguage": "json"
            }
          ],
          "event": [],
          "protocolProfileBehavior": {
            "disableBodyPruning": true
          }
        }
      ],
      "event": []
    },
    {
      "id": "e8bc666f-f460-4db8-9024-53baf061331c",
      "name": "Menu API Suite",
      "description": {
        "content": "The menu read contract (items + modifier groups) and item availability / 86'ing, a push event and a poll.\n\n**In this suite:**\n\n- `GET` [Get the menu](#tag/menu-api-suite/GET/locations/{locationId}/menu)\n- `GET` [List modifier groups](#tag/menu-api-suite/GET/locations/{locationId}/menu/modifier-groups)\n- `GET` [Poll item availability (86'ing)](#tag/menu-api-suite/GET/locations/{locationId}/menu/availability)\n- `POST` [Report an item availability change (86 / restore)](#tag/menu-api-suite/POST/webhook/menu/{locationId})",
        "type": "text/plain"
      },
      "item": [
        {
          "id": "577a2466-7d64-4ac5-8e99-02f68ce8d7f4",
          "name": "Get the menu",
          "request": {
            "name": "Get the menu",
            "description": {
              "content": "The menu Swoop maps orders against: items with a stable `sku`, display name, menu\nsection (`category`), price, and active flag. `sku` is the id you map to your POS at\nonboarding and the join key for order injection (see Orders). Swoop models a location's\nmenu as sections (categories) of items; this read returns the items flat, each carrying\nits `category`.\n",
              "type": "text/plain"
            },
            "url": {
              "path": [
                "locations",
                ":locationId",
                "menu"
              ],
              "host": [
                "{{baseUrl}}"
              ],
              "query": [],
              "variable": [
                {
                  "disabled": false,
                  "type": "any",
                  "value": "<string>",
                  "key": "locationId",
                  "description": "(Required) The Swoop location id."
                }
              ]
            },
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "method": "GET",
            "auth": null
          },
          "response": [
            {
              "id": "c5c591d3-bc81-4ac9-954d-6d85a317b358",
              "name": "The menu.",
              "originalRequest": {
                "url": {
                  "path": [
                    "locations",
                    ":locationId",
                    "menu"
                  ],
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "query": [],
                  "variable": [
                    {
                      "disabled": false,
                      "type": "any",
                      "value": "<string>",
                      "key": "locationId",
                      "description": "(Required) The Swoop location id."
                    }
                  ]
                },
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "method": "GET",
                "body": {}
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"items\": [\n    {\n      \"sku\": \"2417\",\n      \"name\": \"Cheeseburger\",\n      \"category\": \"Mains\",\n      \"price\": 12.5,\n      \"active\": true\n    },\n    {\n      \"sku\": \"2643\",\n      \"name\": \"Sparkling Water\",\n      \"category\": \"Drinks\",\n      \"price\": 3,\n      \"active\": true\n    }\n  ]\n}",
              "cookie": [],
              "_postman_previewlanguage": "json"
            }
          ],
          "event": [],
          "protocolProfileBehavior": {
            "disableBodyPruning": true
          }
        },
        {
          "id": "2dbf50c9-c10d-4e61-ae01-dfb43b3c6d4a",
          "name": "List modifier groups",
          "request": {
            "name": "List modifier groups",
            "description": {
              "content": "The menu's modifier groups and their choices, so Swoop can map member-facing options to\nthe option ids your POS expects on an order line — the ids that come back as each\n`modifiers[].sku` on an injected order. Each group's `min`/`max` bound how many choices\na member must / may pick (`0` = unbounded).\n\n**Every group is attached to exactly one menu item** — `itemSku` is the item it belongs\nto (join it against the menu read). \"Modifier group\" and \"modifier\" are the\nindustry-standard names for what Swoop's own data model calls an **option** (the group,\nwith `min`/`max`, owned by an item) and its **option items** (the choices) — same\nshapes, one vocabulary at the API boundary regardless of which POS is behind it.\n",
              "type": "text/plain"
            },
            "url": {
              "path": [
                "locations",
                ":locationId",
                "menu",
                "modifier-groups"
              ],
              "host": [
                "{{baseUrl}}"
              ],
              "query": [],
              "variable": [
                {
                  "disabled": false,
                  "type": "any",
                  "value": "<string>",
                  "key": "locationId",
                  "description": "(Required) The Swoop location id."
                }
              ]
            },
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "method": "GET",
            "auth": null
          },
          "response": [
            {
              "id": "283898ad-2315-4293-a489-81409c49529e",
              "name": "The location's modifier groups, each attached to its menu item.",
              "originalRequest": {
                "url": {
                  "path": [
                    "locations",
                    ":locationId",
                    "menu",
                    "modifier-groups"
                  ],
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "query": [],
                  "variable": [
                    {
                      "disabled": false,
                      "type": "any",
                      "value": "<string>",
                      "key": "locationId",
                      "description": "(Required) The Swoop location id."
                    }
                  ]
                },
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "method": "GET",
                "body": {}
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"modifierGroups\": [\n    {\n      \"id\": \"512\",\n      \"itemSku\": \"2417\",\n      \"name\": \"Size\",\n      \"min\": 1,\n      \"max\": 1,\n      \"modifiers\": [\n        {\n          \"id\": \"2101\",\n          \"name\": \"Regular\",\n          \"price\": 0\n        },\n        {\n          \"id\": \"2102\",\n          \"name\": \"Large\",\n          \"price\": 1.5\n        }\n      ]\n    },\n    {\n      \"id\": \"883\",\n      \"itemSku\": \"2417\",\n      \"name\": \"Add-ons\",\n      \"min\": 0,\n      \"max\": 0,\n      \"modifiers\": [\n        {\n          \"id\": \"2118\",\n          \"name\": \"Add Cheese\",\n          \"price\": 1\n        }\n      ]\n    }\n  ]\n}",
              "cookie": [],
              "_postman_previewlanguage": "json"
            }
          ],
          "event": [],
          "protocolProfileBehavior": {
            "disableBodyPruning": true
          }
        },
        {
          "id": "cc9686e7-dee8-44f4-9d18-4951f3fafcbf",
          "name": "Poll item availability (86'ing)",
          "request": {
            "name": "Poll item availability (86'ing)",
            "description": {
              "content": "Current availability for menu items — the poll seam for kitchens that \"86\" (run out of) an\nitem. Swoop hides unavailable items from members. Pair with the availability webhook for\npush updates.\n",
              "type": "text/plain"
            },
            "url": {
              "path": [
                "locations",
                ":locationId",
                "menu",
                "availability"
              ],
              "host": [
                "{{baseUrl}}"
              ],
              "query": [],
              "variable": [
                {
                  "disabled": false,
                  "type": "any",
                  "value": "<string>",
                  "key": "locationId",
                  "description": "(Required) The Swoop location id."
                }
              ]
            },
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "method": "GET",
            "auth": null
          },
          "response": [
            {
              "id": "c003d4b9-7d35-4354-b35b-91718b2ac481",
              "name": "Availability snapshot.",
              "originalRequest": {
                "url": {
                  "path": [
                    "locations",
                    ":locationId",
                    "menu",
                    "availability"
                  ],
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "query": [],
                  "variable": [
                    {
                      "disabled": false,
                      "type": "any",
                      "value": "<string>",
                      "key": "locationId",
                      "description": "(Required) The Swoop location id."
                    }
                  ]
                },
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "method": "GET",
                "body": {}
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"availability\": [\n    {\n      \"sku\": \"2417\",\n      \"available\": true\n    },\n    {\n      \"sku\": \"2643\",\n      \"available\": false,\n      \"updatedAt\": \"2026-06-22T10:00:00Z\"\n    }\n  ]\n}",
              "cookie": [],
              "_postman_previewlanguage": "json"
            }
          ],
          "event": [],
          "protocolProfileBehavior": {
            "disableBodyPruning": true
          }
        },
        {
          "id": "15f5ae40-d741-431e-ad5d-0685ad20b767",
          "name": "Report an item availability change (86 / restore)",
          "request": {
            "name": "Report an item availability change (86 / restore)",
            "description": {
              "content": "**Direction: your integration → Swoop.** Push an availability change as a kitchen 86s or\nrestores an item; Swoop updates what members can order. Same delivery semantics as the\norder-status webhook (at-least-once, dedupe). Authenticated by the shared `token`.\n",
              "type": "text/plain"
            },
            "url": {
              "path": [
                "webhook",
                "menu",
                ":locationId"
              ],
              "host": [
                "{{baseUrl}}"
              ],
              "query": [
                {
                  "disabled": false,
                  "key": "token",
                  "value": "<string>",
                  "description": "(Required) Shared-secret webhook token."
                }
              ],
              "variable": [
                {
                  "disabled": false,
                  "type": "any",
                  "value": "<string>",
                  "key": "locationId",
                  "description": "(Required) The Swoop location id."
                }
              ]
            },
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "method": "POST",
            "auth": {
              "type": "apikey",
              "apikey": [
                {
                  "key": "key",
                  "value": "token"
                },
                {
                  "key": "value",
                  "value": "{{apiKey}}"
                },
                {
                  "key": "in",
                  "value": "query"
                }
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"sku\": \"<string>\",\n  \"available\": \"<boolean>\",\n  \"reason\": \"<string>\",\n  \"updatedAt\": \"<dateTime>\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "id": "65366439-4ec9-4093-be2f-1288ada9b9e2",
              "name": "Acknowledged.",
              "originalRequest": {
                "url": {
                  "path": [
                    "webhook",
                    "menu",
                    ":locationId"
                  ],
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "query": [
                    {
                      "key": "token",
                      "value": "<string>"
                    },
                    {
                      "key": "token",
                      "value": "<API Key>"
                    }
                  ],
                  "variable": [
                    {
                      "disabled": false,
                      "type": "any",
                      "value": "<string>",
                      "key": "locationId",
                      "description": "(Required) The Swoop location id."
                    }
                  ]
                },
                "method": "POST",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"sku\": \"2417\",\n  \"available\": false,\n  \"updatedAt\": \"2026-06-22T10:00:00Z\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "text/plain"
                }
              ],
              "body": "",
              "cookie": [],
              "_postman_previewlanguage": "text"
            },
            {
              "id": "6aa0d9e6-785c-49bc-9f7c-c27a50487f02",
              "name": "Missing or invalid token.",
              "originalRequest": {
                "url": {
                  "path": [
                    "webhook",
                    "menu",
                    ":locationId"
                  ],
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "query": [
                    {
                      "key": "token",
                      "value": "<string>"
                    },
                    {
                      "key": "token",
                      "value": "<API Key>"
                    }
                  ],
                  "variable": [
                    {
                      "disabled": false,
                      "type": "any",
                      "value": "<string>",
                      "key": "locationId",
                      "description": "(Required) The Swoop location id."
                    }
                  ]
                },
                "method": "POST",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"sku\": \"2417\",\n  \"available\": false,\n  \"updatedAt\": \"2026-06-22T10:00:00Z\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Unauthorized",
              "code": 401,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "text/plain"
                }
              ],
              "body": "",
              "cookie": [],
              "_postman_previewlanguage": "text"
            }
          ],
          "event": [],
          "protocolProfileBehavior": {
            "disableBodyPruning": true
          }
        }
      ],
      "event": []
    },
    {
      "id": "08a0f2f0-b603-477c-81a4-6c13da97cc10",
      "name": "Delivery API Suite",
      "description": {
        "content": "Hand a ready order to a delivery operator: mission create / abort / get, the mission-event webhook, and live position telemetry.\n\n**In this suite:**\n\n- `POST` [Create a delivery mission](#tag/delivery-api-suite/POST/delivery/missions)\n- `POST` [Abort a delivery mission](#tag/delivery-api-suite/POST/delivery/missions/{missionId}/abort)\n- `GET` [Get mission status and live position](#tag/delivery-api-suite/GET/delivery/missions/{missionId})\n- `POST` [Report a mission event (and live position)](#tag/delivery-api-suite/POST/webhook/delivery/{locationId})",
        "type": "text/plain"
      },
      "item": [
        {
          "id": "7e396d1f-fe4f-4b23-9f61-7cd9930707e6",
          "name": "Create a delivery mission",
          "request": {
            "name": "Create a delivery mission",
            "description": {
              "content": "**Direction: Swoop → your delivery API.** When a ready order is dispatched for\ndelivery, Swoop creates one mission from the pickup site to the drop-off site. Shown\nhere as the shape a delivery operator implements (or that Swoop maps to at onboarding).\n\n`externalRef` (`swoop:<orderId>`) is echoed on every event back and is the dedupe key:\na repeated create with the same `externalRef` MUST resolve to the same mission. The\nload manifest carries item names + quantities only — never prices or payment data.\n",
              "type": "text/plain"
            },
            "url": {
              "path": [
                "delivery",
                "missions"
              ],
              "host": [
                "{{baseUrl}}"
              ],
              "query": [],
              "variable": []
            },
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "method": "POST",
            "auth": null,
            "body": {
              "mode": "raw",
              "raw": "{\n  \"externalRef\": \"<string>\",\n  \"origin\": {\n    \"siteId\": \"<string>\"\n  },\n  \"destination\": {\n    \"siteId\": \"<string>\",\n    \"name\": \"<string>\"\n  },\n  \"payload\": {\n    \"items\": [\n      {\n        \"name\": \"<string>\",\n        \"quantity\": \"<integer>\"\n      },\n      {\n        \"name\": \"<string>\",\n        \"quantity\": \"<integer>\"\n      }\n    ],\n    \"weightGrams\": \"<integer>\",\n    \"description\": \"<string>\"\n  },\n  \"recipient\": {\n    \"name\": \"<string>\",\n    \"phone\": \"<string>\"\n  },\n  \"notes\": \"<string>\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "id": "74a0aeaa-33ab-4f00-9b10-2a00e88d2fe7",
              "name": "Mission accepted.",
              "originalRequest": {
                "url": {
                  "path": [
                    "delivery",
                    "missions"
                  ],
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "query": [],
                  "variable": []
                },
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "method": "POST",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"externalRef\": \"swoop:32160\",\n  \"origin\": {\n    \"siteId\": \"site-pickup\"\n  },\n  \"destination\": {\n    \"siteId\": \"site-drop-04\",\n    \"name\": \"4th Hole\"\n  },\n  \"payload\": {\n    \"items\": [\n      {\n        \"name\": \"Burger\",\n        \"quantity\": 2\n      },\n      {\n        \"name\": \"Sparkling Water\",\n        \"quantity\": 1\n      }\n    ],\n    \"weightGrams\": 1350,\n    \"description\": \"2x Burger, 1x Sparkling Water\"\n  },\n  \"recipient\": {\n    \"name\": \"Jane Golfer\",\n    \"phone\": \"+15555550123\"\n  },\n  \"notes\": \"no ice\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"id\": \"msn-77\"\n}",
              "cookie": [],
              "_postman_previewlanguage": "json"
            }
          ],
          "event": [],
          "protocolProfileBehavior": {
            "disableBodyPruning": true
          }
        },
        {
          "id": "dfd0262c-aac9-429a-972f-40f21c30fa9f",
          "name": "Abort a delivery mission",
          "request": {
            "name": "Abort a delivery mission",
            "description": {
              "content": "**Direction: Swoop → your delivery API.** Called when a member cancels. Honoured only\nbefore the operator's point of no return; afterwards the operator refuses with a\ndistinct non-2xx (e.g. `409`) and completes or returns the vehicle under its own\nauthority — Swoop then routes the order to club staff. A terminal mission event still\nfollows.\n",
              "type": "text/plain"
            },
            "url": {
              "path": [
                "delivery",
                "missions",
                ":missionId",
                "abort"
              ],
              "host": [
                "{{baseUrl}}"
              ],
              "query": [],
              "variable": [
                {
                  "disabled": false,
                  "type": "any",
                  "value": "<string>",
                  "key": "missionId",
                  "description": "(Required) "
                }
              ]
            },
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "method": "POST",
            "auth": null
          },
          "response": [
            {
              "id": "b63508e8-7d57-4011-a446-fe6767246487",
              "name": "Abort accepted; a terminal mission event follows.",
              "originalRequest": {
                "url": {
                  "path": [
                    "delivery",
                    "missions",
                    ":missionId",
                    "abort"
                  ],
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "query": [],
                  "variable": [
                    {
                      "disabled": false,
                      "type": "any",
                      "value": "<string>",
                      "key": "missionId",
                      "description": "(Required) "
                    }
                  ]
                },
                "method": "POST",
                "body": {}
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "text/plain"
                }
              ],
              "body": "",
              "cookie": [],
              "_postman_previewlanguage": "text"
            },
            {
              "id": "d149afff-6df1-4391-a9a4-dff5c2f0dca2",
              "name": "Past the point of no return — abort refused; the delivery completes or returns on its own authority.",
              "originalRequest": {
                "url": {
                  "path": [
                    "delivery",
                    "missions",
                    ":missionId",
                    "abort"
                  ],
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "query": [],
                  "variable": [
                    {
                      "disabled": false,
                      "type": "any",
                      "value": "<string>",
                      "key": "missionId",
                      "description": "(Required) "
                    }
                  ]
                },
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "method": "POST",
                "body": {}
              },
              "status": "Conflict",
              "code": 409,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"error\": \"past_point_of_no_return\"\n}",
              "cookie": [],
              "_postman_previewlanguage": "json"
            }
          ],
          "event": [],
          "protocolProfileBehavior": {
            "disableBodyPruning": true
          }
        },
        {
          "id": "f6b886da-c41a-40bb-8f54-14e187e86a4a",
          "name": "Get mission status and live position",
          "request": {
            "name": "Get mission status and live position",
            "description": {
              "content": "**Direction: Swoop → your delivery API.** The optional poll seam for status and live\ntelemetry when the operator cannot push events. Returns the mission's current status\nand, while en route, an optional live `position` that drives the vehicle marker on the\nmember's order map. Without telemetry, tracking degrades to status milestones.\n",
              "type": "text/plain"
            },
            "url": {
              "path": [
                "delivery",
                "missions",
                ":missionId"
              ],
              "host": [
                "{{baseUrl}}"
              ],
              "query": [],
              "variable": [
                {
                  "disabled": false,
                  "type": "any",
                  "value": "<string>",
                  "key": "missionId",
                  "description": "(Required) "
                }
              ]
            },
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "method": "GET",
            "auth": null
          },
          "response": [
            {
              "id": "452c7105-0df4-474e-b459-22d139c6c170",
              "name": "Current mission status, with an optional live position while en route.",
              "originalRequest": {
                "url": {
                  "path": [
                    "delivery",
                    "missions",
                    ":missionId"
                  ],
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "query": [],
                  "variable": [
                    {
                      "disabled": false,
                      "type": "any",
                      "value": "<string>",
                      "key": "missionId",
                      "description": "(Required) "
                    }
                  ]
                },
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "method": "GET",
                "body": {}
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"missionId\": \"msn-77\",\n  \"externalRef\": \"swoop:32160\",\n  \"status\": \"in_transit\",\n  \"position\": {\n    \"lat\": 40.813,\n    \"lon\": -74.174,\n    \"altMeters\": 60,\n    \"heading\": 214,\n    \"etaSeconds\": 95,\n    \"timestamp\": \"2026-07-07T12:01:30Z\"\n  }\n}",
              "cookie": [],
              "_postman_previewlanguage": "json"
            }
          ],
          "event": [],
          "protocolProfileBehavior": {
            "disableBodyPruning": true
          }
        },
        {
          "id": "4f6b4dd8-f4c8-4b25-9832-2a27e563d8c3",
          "name": "Report a mission event (and live position)",
          "request": {
            "name": "Report a mission event (and live position)",
            "description": {
              "content": "**Direction: your delivery API → Swoop.** Post mission lifecycle events here as the\nmission progresses; Swoop maps them to the member's order status. Include the optional\n`position` object at a 2–5 s cadence while en route to drive the live vehicle marker.\nSame delivery semantics as the order-status webhook: at-least-once, dedupe, monotonic.\n",
              "type": "text/plain"
            },
            "url": {
              "path": [
                "webhook",
                "delivery",
                ":locationId"
              ],
              "host": [
                "{{baseUrl}}"
              ],
              "query": [
                {
                  "disabled": false,
                  "key": "token",
                  "value": "<string>",
                  "description": "(Required) Shared-secret webhook token."
                }
              ],
              "variable": [
                {
                  "disabled": false,
                  "type": "any",
                  "value": "<string>",
                  "key": "locationId",
                  "description": "(Required) The Swoop location id."
                }
              ]
            },
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "method": "POST",
            "auth": {
              "type": "apikey",
              "apikey": [
                {
                  "key": "key",
                  "value": "token"
                },
                {
                  "key": "value",
                  "value": "{{apiKey}}"
                },
                {
                  "key": "in",
                  "value": "query"
                }
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"externalRef\": \"<string>\",\n  \"status\": \"<string>\",\n  \"missionId\": \"<string>\",\n  \"reason\": \"<string>\",\n  \"occurredAt\": \"<dateTime>\",\n  \"position\": {\n    \"lat\": \"<double>\",\n    \"lon\": \"<double>\",\n    \"altMeters\": \"<number>\",\n    \"heading\": \"<number>\",\n    \"etaSeconds\": \"<integer>\",\n    \"timestamp\": \"<dateTime>\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "id": "bc41b76e-8f2b-43b8-bbb2-51cb8e8b2484",
              "name": "Acknowledged.",
              "originalRequest": {
                "url": {
                  "path": [
                    "webhook",
                    "delivery",
                    ":locationId"
                  ],
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "query": [
                    {
                      "key": "token",
                      "value": "<string>"
                    },
                    {
                      "key": "token",
                      "value": "<API Key>"
                    }
                  ],
                  "variable": [
                    {
                      "disabled": false,
                      "type": "any",
                      "value": "<string>",
                      "key": "locationId",
                      "description": "(Required) The Swoop location id."
                    }
                  ]
                },
                "method": "POST",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"missionId\": \"msn-77\",\n  \"externalRef\": \"swoop:32160\",\n  \"status\": \"in_transit\",\n  \"occurredAt\": \"2026-07-07T12:00:00Z\",\n  \"position\": {\n    \"lat\": 40.813,\n    \"lon\": -74.174,\n    \"altMeters\": 60,\n    \"heading\": 214,\n    \"etaSeconds\": 95,\n    \"timestamp\": \"2026-07-07T12:00:00Z\"\n  }\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "text/plain"
                }
              ],
              "body": "",
              "cookie": [],
              "_postman_previewlanguage": "text"
            },
            {
              "id": "10cd5de0-f521-4b88-be27-3933a2d579ba",
              "name": "Missing or invalid token.",
              "originalRequest": {
                "url": {
                  "path": [
                    "webhook",
                    "delivery",
                    ":locationId"
                  ],
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "query": [
                    {
                      "key": "token",
                      "value": "<string>"
                    },
                    {
                      "key": "token",
                      "value": "<API Key>"
                    }
                  ],
                  "variable": [
                    {
                      "disabled": false,
                      "type": "any",
                      "value": "<string>",
                      "key": "locationId",
                      "description": "(Required) The Swoop location id."
                    }
                  ]
                },
                "method": "POST",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"missionId\": \"msn-77\",\n  \"externalRef\": \"swoop:32160\",\n  \"status\": \"in_transit\",\n  \"occurredAt\": \"2026-07-07T12:00:00Z\",\n  \"position\": {\n    \"lat\": 40.813,\n    \"lon\": -74.174,\n    \"altMeters\": 60,\n    \"heading\": 214,\n    \"etaSeconds\": 95,\n    \"timestamp\": \"2026-07-07T12:00:00Z\"\n  }\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Unauthorized",
              "code": 401,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "text/plain"
                }
              ],
              "body": "",
              "cookie": [],
              "_postman_previewlanguage": "text"
            },
            {
              "id": "ef4b8023-c95b-4e83-9027-c4ae24088f43",
              "name": "Transient failure — please redeliver.",
              "originalRequest": {
                "url": {
                  "path": [
                    "webhook",
                    "delivery",
                    ":locationId"
                  ],
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "query": [
                    {
                      "key": "token",
                      "value": "<string>"
                    },
                    {
                      "key": "token",
                      "value": "<API Key>"
                    }
                  ],
                  "variable": [
                    {
                      "disabled": false,
                      "type": "any",
                      "value": "<string>",
                      "key": "locationId",
                      "description": "(Required) The Swoop location id."
                    }
                  ]
                },
                "method": "POST",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"missionId\": \"msn-77\",\n  \"externalRef\": \"swoop:32160\",\n  \"status\": \"in_transit\",\n  \"occurredAt\": \"2026-07-07T12:00:00Z\",\n  \"position\": {\n    \"lat\": 40.813,\n    \"lon\": -74.174,\n    \"altMeters\": 60,\n    \"heading\": 214,\n    \"etaSeconds\": 95,\n    \"timestamp\": \"2026-07-07T12:00:00Z\"\n  }\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Internal Server Error",
              "code": 500,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "text/plain"
                }
              ],
              "body": "",
              "cookie": [],
              "_postman_previewlanguage": "text"
            }
          ],
          "event": [],
          "protocolProfileBehavior": {
            "disableBodyPruning": true
          }
        }
      ],
      "event": []
    },
    {
      "id": "d7d83219-04b3-4719-9e16-a26d643c4eed",
      "name": "Operations API Suite",
      "description": {
        "content": "Service liveness, how an order reaches the adapter (the internal orderPlaced push), and the acknowledgement / error model shared by every webhook.\n\n**In this suite:**\n\n- `POST` [Receive an orderPlaced event (Swoop-internal)](#tag/operations-api-suite/POST/pubsub/push)\n- `GET` [Liveness probe](#tag/operations-api-suite/GET/healthz)",
        "type": "text/plain"
      },
      "item": [
        {
          "id": "7ad1a42e-e815-4b00-9df4-152631d5ca8c",
          "name": "Receive an orderPlaced event (Swoop-internal)",
          "request": {
            "name": "Receive an orderPlaced event (Swoop-internal)",
            "description": {
              "content": "Entry point for Swoop's `orderPlaced` event, delivered by a Google Pub/Sub **push**\nsubscription. The adapter decodes the push envelope, re-fetches the authoritative\norder from swoop-api over GraphQL, canonicalizes it, and pushes it to the POS.\n\n> This endpoint is **internal to Swoop** (the orderPlaced topic is owned by Swoop).\n> It is documented here so partners understand how an order reaches the adapter, not\n> as an endpoint a partner calls. Processing is **idempotent** on the order id, so\n> Pub/Sub redelivery is safe.\n\n**Acknowledgement semantics:** `200` for success *and* for poison/non-`orderPlaced`\nmessages (so Pub/Sub stops redelivering); `500` triggers redelivery.\n",
              "type": "text/plain"
            },
            "url": {
              "path": [
                "pubsub",
                "push"
              ],
              "host": [
                "{{baseUrl}}"
              ],
              "query": [
                {
                  "disabled": false,
                  "key": "token",
                  "value": "<string>",
                  "description": "(Required) Shared-secret push token (`PUBSUB_PUSH_TOKEN`)."
                }
              ],
              "variable": []
            },
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "method": "POST",
            "auth": {
              "type": "apikey",
              "apikey": [
                {
                  "key": "key",
                  "value": "token"
                },
                {
                  "key": "value",
                  "value": "{{apiKey}}"
                },
                {
                  "key": "in",
                  "value": "query"
                }
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"subscription\": \"<string>\",\n  \"message\": {\n    \"data\": \"<string>\",\n    \"attributes\": {\n      \"key_0\": \"<string>\"\n    },\n    \"messageId\": \"<string>\",\n    \"publishTime\": \"<dateTime>\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "id": "986af58d-a3e1-48aa-8367-605a5ee3294a",
              "name": "Acknowledged (processed, or dropped as poison/unrelated).",
              "originalRequest": {
                "url": {
                  "path": [
                    "pubsub",
                    "push"
                  ],
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "query": [
                    {
                      "key": "token",
                      "value": "<string>"
                    },
                    {
                      "key": "token",
                      "value": "<API Key>"
                    }
                  ],
                  "variable": []
                },
                "method": "POST",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"subscription\": \"<string>\",\n  \"message\": {\n    \"data\": \"<string>\",\n    \"attributes\": {\n      \"key_0\": \"<string>\",\n      \"key_1\": \"<string>\"\n    },\n    \"messageId\": \"<string>\",\n    \"publishTime\": \"<dateTime>\"\n  }\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "text/plain"
                }
              ],
              "body": "",
              "cookie": [],
              "_postman_previewlanguage": "text"
            },
            {
              "id": "8f5756bb-43e3-4c75-960a-d6e44eef42a3",
              "name": "Body could not be read.",
              "originalRequest": {
                "url": {
                  "path": [
                    "pubsub",
                    "push"
                  ],
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "query": [
                    {
                      "key": "token",
                      "value": "<string>"
                    },
                    {
                      "key": "token",
                      "value": "<API Key>"
                    }
                  ],
                  "variable": []
                },
                "method": "POST",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"subscription\": \"<string>\",\n  \"message\": {\n    \"data\": \"<string>\",\n    \"attributes\": {\n      \"key_0\": \"<string>\",\n      \"key_1\": \"<string>\"\n    },\n    \"messageId\": \"<string>\",\n    \"publishTime\": \"<dateTime>\"\n  }\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Bad Request",
              "code": 400,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "text/plain"
                }
              ],
              "body": "",
              "cookie": [],
              "_postman_previewlanguage": "text"
            },
            {
              "id": "0c348119-b132-43a1-b437-be957c4a329b",
              "name": "Missing or invalid token.",
              "originalRequest": {
                "url": {
                  "path": [
                    "pubsub",
                    "push"
                  ],
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "query": [
                    {
                      "key": "token",
                      "value": "<string>"
                    },
                    {
                      "key": "token",
                      "value": "<API Key>"
                    }
                  ],
                  "variable": []
                },
                "method": "POST",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"subscription\": \"<string>\",\n  \"message\": {\n    \"data\": \"<string>\",\n    \"attributes\": {\n      \"key_0\": \"<string>\",\n      \"key_1\": \"<string>\"\n    },\n    \"messageId\": \"<string>\",\n    \"publishTime\": \"<dateTime>\"\n  }\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Unauthorized",
              "code": 401,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "text/plain"
                }
              ],
              "body": "",
              "cookie": [],
              "_postman_previewlanguage": "text"
            },
            {
              "id": "866f8916-fd3f-46e4-9629-280b2bb41437",
              "name": "Processing failed — Pub/Sub will redeliver.",
              "originalRequest": {
                "url": {
                  "path": [
                    "pubsub",
                    "push"
                  ],
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "query": [
                    {
                      "key": "token",
                      "value": "<string>"
                    },
                    {
                      "key": "token",
                      "value": "<API Key>"
                    }
                  ],
                  "variable": []
                },
                "method": "POST",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"subscription\": \"<string>\",\n  \"message\": {\n    \"data\": \"<string>\",\n    \"attributes\": {\n      \"key_0\": \"<string>\",\n      \"key_1\": \"<string>\"\n    },\n    \"messageId\": \"<string>\",\n    \"publishTime\": \"<dateTime>\"\n  }\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Internal Server Error",
              "code": 500,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "text/plain"
                }
              ],
              "body": "",
              "cookie": [],
              "_postman_previewlanguage": "text"
            }
          ],
          "event": [],
          "protocolProfileBehavior": {
            "disableBodyPruning": true
          }
        },
        {
          "id": "ae922d2e-c583-44e9-b723-1661cbb4f810",
          "name": "Liveness probe",
          "request": {
            "name": "Liveness probe",
            "description": {
              "content": "Returns `200 OK` when the service is up. No authentication.",
              "type": "text/plain"
            },
            "url": {
              "path": [
                "healthz"
              ],
              "host": [
                "{{baseUrl}}"
              ],
              "query": [],
              "variable": []
            },
            "method": "GET",
            "auth": null
          },
          "response": [
            {
              "id": "815c0979-8124-43ba-a4f1-4f9e3fe0a1e2",
              "name": "Service is healthy.",
              "originalRequest": {
                "url": {
                  "path": [
                    "healthz"
                  ],
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "query": [],
                  "variable": []
                },
                "method": "GET",
                "body": {}
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "text/plain"
                }
              ],
              "body": "",
              "cookie": [],
              "_postman_previewlanguage": "text"
            }
          ],
          "event": [],
          "protocolProfileBehavior": {
            "disableBodyPruning": true
          }
        }
      ],
      "event": []
    }
  ],
  "event": [],
  "variable": [
    {
      "type": "string",
      "value": "https://adapter.swoopgolf.com",
      "key": "baseUrl"
    }
  ],
  "info": {
    "_postman_id": "aba5e4bc-dd0d-414b-a44f-7e7b9c19fff8",
    "name": "Swoop API",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
    "description": {
      "content": "The **Swoop API** is the partner-facing contract for integrating an ordering, delivery,\nor course system with Swoop's on-course food & beverage platform. A Swoop member orders\nfrom their phone — at the turn, on the range, or out on the course — and the order flows\nto the systems that fulfil it, with live status flowing back to the member.\n\n> **Access to this API requires a partner sandbox.** Email\n> [partners@swoopgolf.com](mailto:partners@swoopgolf.com) to be provisioned; see the\n> Getting Started guide in the navigation panel.\n\n### Overview\nThe Swoop APIs enable partners to programmatically manage locations, menus, orders, and\non-course delivery on the Swoop platform. Build integrations that automate order\nprocessing, synchronize menus in real time, and hand ready orders to delivery operators.\n\n### What You Can Build\n**Point-of-Sale (POS) integrations** — connect your POS to receive injected orders and\nreport kitchen lifecycle automatically. This is the most common and valuable path.\n\n**Menu management** — keep menus synchronized with real-time pricing, availability, and\n86'ing.\n\n**Delivery operations** — drone, robot, or cart: take dispatches for ready orders and\nreport vehicle-neutral mission progress with live position.\n\n**Multi-location management** — one integration serves every bound club location.\n\n### API Overview\nThis reference is organized into **API Suites**, one per domain:\n\n| API Suite | Purpose | Key Use Cases |\n|---|---|---|\n| Integration Configuration | Onboarding and setup | Credential exchange, webhook registration, mapping a location to your sites and markers |\n| Locations | Course topology | The club → outlet/site → on-course marker (delivery drop-off) model |\n| Order | Order processing | Order injection, status webhooks, cancel/void |\n| Menu | Menu and item management | Menu reads (items + modifier groups), availability / 86'ing (event + poll) |\n| Delivery | Dispatch operations | Mission create/abort/get, mission-event webhook, live position telemetry |\n| Operations | Health and eventing | Service health, how an order reaches the adapter, the shared acknowledgement / error model |\n\n### Settlement\nGolfers settle at the **end of the round**, at the club. Orders injected by Swoop land\n**open and unpaid** — there is no in-app payment, and no payment data crosses this API.\n\n### Conventions\nCorrelate everything by the Swoop order id, carried as `swoop:<orderId>` wherever a string\nreference is needed. Webhook delivery is at-least-once; Swoop de-duplicates and guards\nagainst out-of-order events, so a stale event never walks an order's status backwards.\n\n### Versioning\nThis is **v1**. The API is versioned by **addition**: new fields and new paths are additive\nand backward-compatible, and a field is never removed or repurposed within a version. There\nis no prior public version, so there are no deprecation or \"previous version\" sections yet —\nwhen a breaking change is ever needed it will ship under a new version prefix. Changes are\ntracked in the [changelog](../guides/changelog.html).\n\n### Tooling\nBesides the OpenAPI download above, a ready-to-run\n[Postman collection](../specs/swoop-api.postman_collection.json) is generated from this\ndocument — one request per operation, foldered by suite, example bodies filled in. Import\nit into Postman or Insomnia and point the base URL at your staging host.\n",
      "type": "text/plain"
    }
  }
}