Created
May 20, 2026 09:56
-
-
Save fabiosussetto/7d0c8c82e53b7a17576c2631d3aad8c8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "info": { | |
| "_postman_id": "ec-storefront-checkout-seatsio", | |
| "name": "Eventcube Storefront API — Checkout Fields & Seats.io", | |
| "description": "Storefront API (`/api/v1`) endpoints added/extended on this branch:\n\n- **Checkout fields** — CRUD for custom checkout questions\n- **Cart custom fields** — resolved on `GET /carts/{id}` for checkout UX\n- **Seats.io** — event config, cart seat holds, seat selections, order booking\n\n## Setup\n1. Set collection variables `store_domain` and `api_key`.\n2. `base_url` defaults to `http://{{store_domain}}/api/v1`.\n3. Run folders top-to-bottom; scripts save `event_id`, `ticket_id`, `cart_id`, etc.\n\n**Auth:** Bearer token (`store.api_key`). Requests resolve the store from the domain in `base_url`.\n\n**Note:** Store must have Seats.io connected (admin: store `seatsio` meta) before reserved seating works.", | |
| "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" | |
| }, | |
| "auth": { | |
| "type": "bearer", | |
| "bearer": [ | |
| { | |
| "key": "token", | |
| "value": "{{api_key}}", | |
| "type": "string" | |
| } | |
| ] | |
| }, | |
| "variable": [ | |
| { | |
| "key": "store_domain", | |
| "value": "your-store.eventcu.be", | |
| "type": "string" | |
| }, | |
| { | |
| "key": "api_key", | |
| "value": "your-store-api-key", | |
| "type": "string" | |
| }, | |
| { | |
| "key": "base_url", | |
| "value": "http://{{store_domain}}/api/v1", | |
| "type": "string" | |
| }, | |
| { | |
| "key": "checkout_field_id", | |
| "value": "", | |
| "type": "string" | |
| }, | |
| { | |
| "key": "event_id", | |
| "value": "", | |
| "type": "string" | |
| }, | |
| { | |
| "key": "ticket_id", | |
| "value": "", | |
| "type": "string" | |
| }, | |
| { | |
| "key": "cart_id", | |
| "value": "", | |
| "type": "string" | |
| }, | |
| { | |
| "key": "cart_token", | |
| "value": "", | |
| "type": "string" | |
| }, | |
| { | |
| "key": "order_id", | |
| "value": "", | |
| "type": "string" | |
| }, | |
| { | |
| "key": "seatsio_event_key", | |
| "value": "5a9bb1cc-779d-4d16-ba2b-0567c487cd10", | |
| "type": "string" | |
| }, | |
| { | |
| "key": "reservation_token", | |
| "value": "paste-from-seatsio-chart", | |
| "type": "string" | |
| } | |
| ], | |
| "item": [ | |
| { | |
| "name": "Checkout Fields", | |
| "description": "Manage custom checkout questions (`/checkout-fields`). Core/system fields are excluded from this API.", | |
| "item": [ | |
| { | |
| "name": "List checkout fields", | |
| "request": { | |
| "method": "GET", | |
| "header": [], | |
| "url": "{{base_url}}/checkout-fields" | |
| } | |
| }, | |
| { | |
| "name": "Create checkout field (text)", | |
| "event": [ | |
| { | |
| "listen": "test", | |
| "script": { | |
| "exec": [ | |
| "if (pm.response.code === 200) {", | |
| " const json = pm.response.json();", | |
| " if (json.id) pm.collectionVariables.set('checkout_field_id', String(json.id));", | |
| "}" | |
| ], | |
| "type": "text/javascript" | |
| } | |
| } | |
| ], | |
| "request": { | |
| "method": "POST", | |
| "header": [ | |
| { | |
| "key": "Content-Type", | |
| "value": "application/json" | |
| } | |
| ], | |
| "body": { | |
| "mode": "raw", | |
| "raw": "{\n \"label\": \"What is your favourite colour?\",\n \"type\": \"text\",\n \"is_required\": true,\n \"published\": true\n}" | |
| }, | |
| "url": "{{base_url}}/checkout-fields" | |
| } | |
| }, | |
| { | |
| "name": "Create checkout field (select)", | |
| "request": { | |
| "method": "POST", | |
| "header": [ | |
| { | |
| "key": "Content-Type", | |
| "value": "application/json" | |
| } | |
| ], | |
| "body": { | |
| "mode": "raw", | |
| "raw": "{\n \"label\": \"Choose a t-shirt size\",\n \"type\": \"select\",\n \"is_required\": true,\n \"options\": [\n { \"label\": \"Small\" },\n { \"label\": \"Medium\" },\n { \"label\": \"Large\" }\n ]\n}" | |
| }, | |
| "url": "{{base_url}}/checkout-fields" | |
| } | |
| }, | |
| { | |
| "name": "Create checkout field (visible for ticket)", | |
| "request": { | |
| "method": "POST", | |
| "header": [ | |
| { | |
| "key": "Content-Type", | |
| "value": "application/json" | |
| } | |
| ], | |
| "body": { | |
| "mode": "raw", | |
| "raw": "{\n \"label\": \"Only when VIP ticket is in basket\",\n \"type\": \"text\",\n \"show_if\": {\n \"ticket\": [{{ticket_id}}]\n }\n}" | |
| }, | |
| "url": "{{base_url}}/checkout-fields", | |
| "description": "Set `ticket_id` collection variable first (from Seats.io flow or create a ticket manually)." | |
| } | |
| }, | |
| { | |
| "name": "Show checkout field", | |
| "request": { | |
| "method": "GET", | |
| "header": [], | |
| "url": "{{base_url}}/checkout-fields/{{checkout_field_id}}" | |
| } | |
| }, | |
| { | |
| "name": "Update checkout field", | |
| "request": { | |
| "method": "PUT", | |
| "header": [ | |
| { | |
| "key": "Content-Type", | |
| "value": "application/json" | |
| } | |
| ], | |
| "body": { | |
| "mode": "raw", | |
| "raw": "{\n \"label\": \"What is your favorite colour?\",\n \"published\": true,\n \"is_required\": false\n}" | |
| }, | |
| "url": "{{base_url}}/checkout-fields/{{checkout_field_id}}" | |
| } | |
| }, | |
| { | |
| "name": "Delete checkout field", | |
| "request": { | |
| "method": "DELETE", | |
| "header": [], | |
| "url": "{{base_url}}/checkout-fields/{{checkout_field_id}}" | |
| } | |
| } | |
| ] | |
| }, | |
| { | |
| "name": "Cart — Custom Fields", | |
| "description": "Published custom fields applicable to the cart are returned on cart detail as `custom_fields` (internal keys like `show_if` are stripped).", | |
| "item": [ | |
| { | |
| "name": "Create cart", | |
| "event": [ | |
| { | |
| "listen": "test", | |
| "script": { | |
| "exec": [ | |
| "if (pm.response.code === 200) {", | |
| " const json = pm.response.json();", | |
| " if (json.id) pm.collectionVariables.set('cart_id', String(json.id));", | |
| " if (json.token) pm.collectionVariables.set('cart_token', json.token);", | |
| "}" | |
| ], | |
| "type": "text/javascript" | |
| } | |
| } | |
| ], | |
| "request": { | |
| "method": "POST", | |
| "header": [ | |
| { | |
| "key": "Content-Type", | |
| "value": "application/json" | |
| } | |
| ], | |
| "body": { | |
| "mode": "raw", | |
| "raw": "{\n \"items\": [\n {\n \"ticket_id\": {{ticket_id}},\n \"quantity\": 1\n }\n ]\n}" | |
| }, | |
| "url": "{{base_url}}/carts" | |
| } | |
| }, | |
| { | |
| "name": "Get cart (custom_fields + seating)", | |
| "request": { | |
| "method": "GET", | |
| "header": [], | |
| "url": "{{base_url}}/carts/{{cart_id}}", | |
| "description": "Response includes:\n- `custom_fields[]` — fields to render at checkout\n- `seating` — store Seats.io public key (when connected)\n- `items[].seating` — per-line seating config/state" | |
| } | |
| } | |
| ] | |
| }, | |
| { | |
| "name": "Seats.io — Event Config", | |
| "description": "Configure reserved seating on events. Requires store Seats.io connection in admin.", | |
| "item": [ | |
| { | |
| "name": "Create event with reserved seating", | |
| "event": [ | |
| { | |
| "listen": "test", | |
| "script": { | |
| "exec": [ | |
| "if (pm.response.code === 200) {", | |
| " const json = pm.response.json();", | |
| " if (json.id) pm.collectionVariables.set('event_id', String(json.id));", | |
| "}" | |
| ], | |
| "type": "text/javascript" | |
| } | |
| } | |
| ], | |
| "request": { | |
| "method": "POST", | |
| "header": [ | |
| { | |
| "key": "Content-Type", | |
| "value": "application/json" | |
| } | |
| ], | |
| "body": { | |
| "mode": "raw", | |
| "raw": "{\n \"title\": \"Reserved Seating Show\",\n \"start\": \"2026-06-01 19:00:00\",\n \"end\": \"2026-06-01 23:00:00\",\n \"reserved_seating\": {\n \"enabled\": true,\n \"event_key\": \"{{seatsio_event_key}}\",\n \"tickets\": {}\n }\n}" | |
| }, | |
| "url": "{{base_url}}/events" | |
| } | |
| }, | |
| { | |
| "name": "Create ticket", | |
| "event": [ | |
| { | |
| "listen": "test", | |
| "script": { | |
| "exec": [ | |
| "if (pm.response.code === 200) {", | |
| " const json = pm.response.json();", | |
| " if (json.id) pm.collectionVariables.set('ticket_id', String(json.id));", | |
| "}" | |
| ], | |
| "type": "text/javascript" | |
| } | |
| } | |
| ], | |
| "request": { | |
| "method": "POST", | |
| "header": [ | |
| { | |
| "key": "Content-Type", | |
| "value": "application/json" | |
| } | |
| ], | |
| "body": { | |
| "mode": "raw", | |
| "raw": "{\n \"title\": \"VIP\",\n \"quantity\": 100,\n \"price\": 5000,\n \"booking_fee\": 500,\n \"type\": \"barcode\"\n}" | |
| }, | |
| "url": "{{base_url}}/events/{{event_id}}/tickets" | |
| } | |
| }, | |
| { | |
| "name": "Update event — map ticket category keys", | |
| "request": { | |
| "method": "PUT", | |
| "header": [ | |
| { | |
| "key": "Content-Type", | |
| "value": "application/json" | |
| } | |
| ], | |
| "body": { | |
| "mode": "raw", | |
| "raw": "{\n \"reserved_seating\": {\n \"enabled\": true,\n \"event_key\": \"{{seatsio_event_key}}\",\n \"tickets\": {\n \"{{ticket_id}}\": {\n \"category_key\": \"vip\"\n }\n }\n }\n}" | |
| }, | |
| "url": "{{base_url}}/events/{{event_id}}", | |
| "description": "Run after creating tickets so you have ticket IDs for the category map." | |
| } | |
| }, | |
| { | |
| "name": "Show event", | |
| "request": { | |
| "method": "GET", | |
| "header": [], | |
| "url": "{{base_url}}/events/{{event_id}}", | |
| "description": "Returns `reserved_seating`, `seatsio_event_key`, and nested tickets with `seatsio_category_key`." | |
| } | |
| }, | |
| { | |
| "name": "Disable reserved seating on event", | |
| "request": { | |
| "method": "PUT", | |
| "header": [ | |
| { | |
| "key": "Content-Type", | |
| "value": "application/json" | |
| } | |
| ], | |
| "body": { | |
| "mode": "raw", | |
| "raw": "{\n \"reserved_seating\": {\n \"enabled\": false\n }\n}" | |
| }, | |
| "url": "{{base_url}}/events/{{event_id}}" | |
| } | |
| } | |
| ] | |
| }, | |
| { | |
| "name": "Seats.io — Cart & Checkout", | |
| "description": "Headless seat selection flow for external platforms running the Seats.io chart.", | |
| "item": [ | |
| { | |
| "name": "1. Create cart (seated tickets)", | |
| "event": [ | |
| { | |
| "listen": "test", | |
| "script": { | |
| "exec": [ | |
| "if (pm.response.code === 200) {", | |
| " const json = pm.response.json();", | |
| " if (json.id) pm.collectionVariables.set('cart_id', String(json.id));", | |
| " if (json.token) pm.collectionVariables.set('cart_token', json.token);", | |
| "}" | |
| ], | |
| "type": "text/javascript" | |
| } | |
| } | |
| ], | |
| "request": { | |
| "method": "POST", | |
| "header": [ | |
| { | |
| "key": "Content-Type", | |
| "value": "application/json" | |
| } | |
| ], | |
| "body": { | |
| "mode": "raw", | |
| "raw": "{\n \"items\": [\n {\n \"ticket_id\": {{ticket_id}},\n \"quantity\": 2\n }\n ]\n}" | |
| }, | |
| "url": "{{base_url}}/carts" | |
| } | |
| }, | |
| { | |
| "name": "2. Get cart (seating config, no holds yet)", | |
| "request": { | |
| "method": "GET", | |
| "header": [], | |
| "url": "{{base_url}}/carts/{{cart_id}}" | |
| } | |
| }, | |
| { | |
| "name": "3. Create seat holds (bulk)", | |
| "event": [ | |
| { | |
| "listen": "test", | |
| "script": { | |
| "exec": [ | |
| "if (pm.response.code === 200) {", | |
| " const json = pm.response.json();", | |
| " const first = (json.items || [])[0];", | |
| " if (first && first.hold_token) {", | |
| " pm.collectionVariables.set('hold_token', first.hold_token);", | |
| " }", | |
| "}" | |
| ], | |
| "type": "text/javascript" | |
| } | |
| } | |
| ], | |
| "request": { | |
| "method": "POST", | |
| "header": [ | |
| { | |
| "key": "Content-Type", | |
| "value": "application/json" | |
| } | |
| ], | |
| "body": { | |
| "mode": "raw", | |
| "raw": "{\n \"ticket_ids\": [{{ticket_id}}],\n \"refresh\": false\n}" | |
| }, | |
| "url": "{{base_url}}/carts/{{cart_id}}/seat-holds", | |
| "description": "Creates Seats.io hold tokens server-side. Omit `ticket_ids` to prepare all seated lines.\n\nUse returned `hold_token` + cart `seating.public_key` in your Seats.io chart (`session: manual`)." | |
| } | |
| }, | |
| { | |
| "name": "4. Save seat selections (PATCH)", | |
| "request": { | |
| "method": "PATCH", | |
| "header": [ | |
| { | |
| "key": "Content-Type", | |
| "value": "application/json" | |
| } | |
| ], | |
| "body": { | |
| "mode": "raw", | |
| "raw": "{\n \"items\": [\n {\n \"ticket_id\": {{ticket_id}},\n \"seat_labels\": [\"A-1\", \"A-2\"],\n \"reservation_token\": \"{{reservation_token}}\"\n }\n ]\n}" | |
| }, | |
| "url": "{{base_url}}/carts/{{cart_id}}/seat-selections", | |
| "description": "After user picks seats in Seats.io chart, paste `reservation_token` into the `reservation_token` collection variable.\n\n`seat_labels` count must equal cart line quantity." | |
| } | |
| }, | |
| { | |
| "name": "Get seat selections", | |
| "request": { | |
| "method": "GET", | |
| "header": [], | |
| "url": "{{base_url}}/carts/{{cart_id}}/seat-selections" | |
| } | |
| }, | |
| { | |
| "name": "Release seat holds", | |
| "request": { | |
| "method": "DELETE", | |
| "header": [], | |
| "url": { | |
| "raw": "{{base_url}}/carts/{{cart_id}}/seat-holds?ticket_ids={{ticket_id}}", | |
| "host": ["{{base_url}}"], | |
| "path": ["carts", "{{cart_id}}", "seat-holds"], | |
| "query": [ | |
| { | |
| "key": "ticket_ids", | |
| "value": "{{ticket_id}}", | |
| "description": "Optional. Omit query to clear all seated lines." | |
| } | |
| ] | |
| } | |
| } | |
| }, | |
| { | |
| "name": "5. Create order", | |
| "event": [ | |
| { | |
| "listen": "test", | |
| "script": { | |
| "exec": [ | |
| "if (pm.response.code === 200) {", | |
| " const json = pm.response.json();", | |
| " if (json.id) pm.collectionVariables.set('order_id', String(json.id));", | |
| "}" | |
| ], | |
| "type": "text/javascript" | |
| } | |
| } | |
| ], | |
| "request": { | |
| "method": "POST", | |
| "header": [ | |
| { | |
| "key": "Content-Type", | |
| "value": "application/json" | |
| } | |
| ], | |
| "body": { | |
| "mode": "raw", | |
| "raw": "{\n \"cart_token\": \"{{cart_token}}\",\n \"customer\": {\n \"email\": \"buyer@example.com\",\n \"first_name\": \"Ann\",\n \"last_name\": \"Bee\",\n \"address_1\": \"1 High Street\",\n \"city\": \"London\",\n \"postcode\": \"E1 1AA\",\n \"country\": \"GB\",\n \"phone\": \"+447700900000\"\n }\n}" | |
| }, | |
| "url": "{{base_url}}/orders", | |
| "description": "Reads seat selections from cart meta, books via Seats.io on `order.completed`, returns `items[].reserved_seat`." | |
| } | |
| }, | |
| { | |
| "name": "Show order (reserved seats)", | |
| "request": { | |
| "method": "GET", | |
| "header": [], | |
| "url": "{{base_url}}/orders/{{order_id}}" | |
| } | |
| } | |
| ] | |
| } | |
| ] | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment