openapi: 3.0.3 info: title: 'Shift Collect API Documentation' description: 'Welcome to the Shift Collect API - A RESTful API for managing locker bookings and account access.' version: 1.0.0 servers: - url: 'https://api.shiftcollect.com' tags: - name: Accounts description: '' - name: Authentication description: '' - name: 'Booking Item Sizes' description: '' - name: 'Booking Tracking' description: '' - name: Bookings description: '' - name: Cabinets description: '' - name: 'Collection Schedules' description: '' - name: 'Despatch Centres' description: '' - name: Labels description: '' - name: 'Reverse Flows' description: '' - name: 'Service Products' description: '' - name: Serviceability description: '' - name: Sites description: '' - name: 'Token Management' description: '' - name: Webhooks description: '' components: securitySchemes: default: type: http scheme: bearer description: 'Generate API tokens using the `POST /v1/auth/token` endpoint. See the `Authentication` section below for more information.' security: - default: [] paths: /v1/account: get: summary: 'Get the current account context.' operationId: getTheCurrentAccountContext description: "Returns detailed information about the currently active account, including\nreverse flow strategies, locker assignment strategy, service products, users, and settings." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: id: 01ARZ3NDEKTSV4RRFFQ69G5FAW name: 'Acme Corp' description: 'A leading logistics company' website: 'https://acme.example.com' phone: '+44 20 1234 5678' email: info@acme.example.com address: '123 Business Street, London, SW1A 1AA' is_active: true created_at: '2025-01-01T00:00:00.000000Z' updated_at: '2025-01-01T00:00:00.000000Z' reverse_flow_strategies: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAX name: return_to_sender description: 'Return to Sender' is_active: true is_default: true - id: 01ARZ3NDEKTSV4RRFFQ69G5FAY name: hold_at_sort description: 'Hold at Sort Centre' is_active: true is_default: false locker_assignment_strategy: id: 01ARZ3NDEKTSV4RRFFQ69G5FAZ name: 'Just-in-time Assignment' description: 'Assign lockers on day of delivery' is_active: true service_products: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAZ name: 'DC to Locker' description: 'Direct delivery from despatch centre to locker' requires_collection: true requires_delivery: true requires_locker: true requires_sorting_hub: false is_active: true is_default: true users: - id: 01ARZ3NDEKTSV4RRFFQ69G5FBA name: 'John Doe' created_at: '2025-01-01T00:00:00.000000Z' last_accessed_at: '2025-01-15T10:30:00.000000Z' is_active: true role: owner settings: - name: default_currency description: 'Default currency for pricing' type: string value: GBP - name: vat_rate description: 'VAT rate as decimal (e.g., 0.20 for 20%)' type: decimal value: 0.2 - name: sla_min_days description: 'Minimum SLA days for delivery' type: integer value: 2 - name: reverse_flow_allow_consumer_reschedule description: 'Allow consumers to reschedule reverse flow deliveries' type: boolean value: true - name: reverse_flow_alternative_address description: 'Alternative address for reverse flow returns' type: address value: line_1: '123 Return Street' line_2: null line_3: null city: London postcode: 'SW1A 1AA' country: 'United Kingdom' properties: data: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAW name: type: string example: 'Acme Corp' description: type: string example: 'A leading logistics company' website: type: string example: 'https://acme.example.com' phone: type: string example: '+44 20 1234 5678' email: type: string example: info@acme.example.com address: type: string example: '123 Business Street, London, SW1A 1AA' is_active: type: boolean example: true created_at: type: string example: '2025-01-01T00:00:00.000000Z' updated_at: type: string example: '2025-01-01T00:00:00.000000Z' reverse_flow_strategies: type: array example: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAX name: return_to_sender description: 'Return to Sender' is_active: true is_default: true - id: 01ARZ3NDEKTSV4RRFFQ69G5FAY name: hold_at_sort description: 'Hold at Sort Centre' is_active: true is_default: false items: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAX name: type: string example: return_to_sender description: type: string example: 'Return to Sender' is_active: type: boolean example: true is_default: type: boolean example: true locker_assignment_strategy: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAZ name: type: string example: 'Just-in-time Assignment' description: type: string example: 'Assign lockers on day of delivery' is_active: type: boolean example: true service_products: type: array example: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAZ name: 'DC to Locker' description: 'Direct delivery from despatch centre to locker' requires_collection: true requires_delivery: true requires_locker: true requires_sorting_hub: false is_active: true is_default: true items: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAZ name: type: string example: 'DC to Locker' description: type: string example: 'Direct delivery from despatch centre to locker' requires_collection: type: boolean example: true requires_delivery: type: boolean example: true requires_locker: type: boolean example: true requires_sorting_hub: type: boolean example: false is_active: type: boolean example: true is_default: type: boolean example: true users: type: array example: - id: 01ARZ3NDEKTSV4RRFFQ69G5FBA name: 'John Doe' created_at: '2025-01-01T00:00:00.000000Z' last_accessed_at: '2025-01-15T10:30:00.000000Z' is_active: true role: owner items: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FBA name: type: string example: 'John Doe' created_at: type: string example: '2025-01-01T00:00:00.000000Z' last_accessed_at: type: string example: '2025-01-15T10:30:00.000000Z' is_active: type: boolean example: true role: type: string example: owner settings: type: array example: - name: default_currency description: 'Default currency for pricing' type: string value: GBP - name: vat_rate description: 'VAT rate as decimal (e.g., 0.20 for 20%)' type: decimal value: 0.2 - name: sla_min_days description: 'Minimum SLA days for delivery' type: integer value: 2 - name: reverse_flow_allow_consumer_reschedule description: 'Allow consumers to reschedule reverse flow deliveries' type: boolean value: true - name: reverse_flow_alternative_address description: 'Alternative address for reverse flow returns' type: address value: line_1: '123 Return Street' line_2: null line_3: null city: London postcode: 'SW1A 1AA' country: 'United Kingdom' items: type: object properties: name: type: string example: default_currency description: type: string example: 'Default currency for pricing' type: type: string example: string value: type: string example: GBP 400: description: '' content: application/json: schema: type: object example: message: 'No account context set' properties: message: type: string example: 'No account context set' 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Accounts /v1/auth/token: post: summary: 'Generate API token from credentials.' operationId: generateAPITokenFromCredentials description: "Authenticates a user with email and password and returns an API token.\nThis is useful for programmatic access without needing to login via the SPA first.\nRequires Admin or Owner role in the specified account." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: token: 1|abcdefghijklmnopqrstuvwxyz1234567890 token_name: 'Production API Token' account_id: 01ARZ3NDEKTSV4RRFFQ69G5FAW user: id: 01ARZ3NDEKTSV4RRFFQ69G5FAW name: 'John Doe' email: user@example.com abilities: - '*' expires_at: '2025-12-31T23:59:59.000000Z' created_at: '2025-01-01T00:00:00.000000Z' message: 'API token generated successfully' properties: token: type: string example: 1|abcdefghijklmnopqrstuvwxyz1234567890 token_name: type: string example: 'Production API Token' account_id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAW user: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAW name: type: string example: 'John Doe' email: type: string example: user@example.com abilities: type: array example: - '*' items: type: string expires_at: type: string example: '2025-12-31T23:59:59.000000Z' created_at: type: string example: '2025-01-01T00:00:00.000000Z' message: type: string example: 'API token generated successfully' 403: description: '' content: application/json: schema: oneOf: - description: '' type: object example: message: 'This action is unauthorised. Only admins and owners can generate API tokens.' properties: message: type: string example: 'This action is unauthorised. Only admins and owners can generate API tokens.' - description: '' type: object example: message: 'User does not belong to the specified account.' properties: message: type: string example: 'User does not belong to the specified account.' 422: description: '' content: application/json: schema: oneOf: - description: '' type: object example: message: 'The given data was invalid.' errors: email: - 'The email field is required.' password: - 'The password field is required.' account_id: - 'The account id field is required.' expires_at: - 'The expires at must be a date after now.' properties: message: type: string example: 'The given data was invalid.' errors: type: object properties: email: type: array example: - 'The email field is required.' items: type: string password: type: array example: - 'The password field is required.' items: type: string account_id: type: array example: - 'The account id field is required.' items: type: string expires_at: type: array example: - 'The expires at must be a date after now.' items: type: string - description: '' type: object example: message: 'The given data was invalid.' errors: email: - 'These credentials do not match our records.' properties: message: type: string example: 'The given data was invalid.' errors: type: object properties: email: type: array example: - 'These credentials do not match our records.' items: type: string tags: - Authentication requestBody: required: true content: application/json: schema: type: object properties: email: type: string description: 'User email address' example: user@example.com password: type: string description: 'User password' example: password123 account_id: type: string description: 'Account ID (ULID) for which to generate the token' example: 01ARZ3NDEKTSV4RRFFQ69G5FAW token_name: type: string description: 'Name for the token (optional, defaults to "API Token")' example: 'Production API Token' expires_at: type: string description: 'Expiration date and time (ISO 8601). Must be in the future' example: '2025-12-31T23:59:59Z' required: - email - password - account_id /v1/booking-item-sizes: get: summary: 'List effective parcel size presets for the authenticated account.' operationId: listEffectiveParcelSizePresetsForTheAuthenticatedAccount description: "Returns merged global defaults and account-specific overrides for the requested\nservice product (or all catalogued service products when omitted)." parameters: - in: query name: service_product_id description: 'Filter by service product ULID' example: architecto required: false schema: type: string description: 'Filter by service product ULID' example: architecto responses: 200: description: '' content: application/json: schema: type: object example: data: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAX code: small label: Small service_product_id: 01ARZ3NDEKTSV4RRFFQ69G5FAY max_height_cm: 50 max_width_cm: 90 max_depth_cm: 150 max_weight_kg: 25 max_value_gbp: 10000 properties: data: type: array example: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAX code: small label: Small service_product_id: 01ARZ3NDEKTSV4RRFFQ69G5FAY max_height_cm: 50 max_width_cm: 90 max_depth_cm: 150 max_weight_kg: 25 max_value_gbp: 10000 items: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAX code: type: string example: small label: type: string example: Small service_product_id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAY max_height_cm: type: integer example: 50 max_width_cm: type: integer example: 90 max_depth_cm: type: integer example: 150 max_weight_kg: type: integer example: 25 max_value_gbp: type: integer example: 10000 tags: - 'Booking Item Sizes' /v1/tracking/booking: post: summary: 'Track a booking by reference ID (public endpoint).' operationId: trackABookingByReferenceIDpublicEndpoint description: "Allows public users to track their booking using reference ID and email, phone, or delivery postcode verification.\nAt least one of email, phone, or postcode must be provided." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: reference_id: BK65A3F2E1 package_info: tracking_number: BK65A3F2E1 status: confirmed locker_assignments: - locker_id: 01ARZ3NDEKTSV4RRFFQ69G5FAV locker_name: A1-01 cabinet: id: 01ARZ3NDEKTSV4RRFFQ69G5FAU name: 'Cabinet A1' status: active starts_at: '2025-01-15T09:00:00.000000Z' ends_at: '2025-01-20T17:00:00.000000Z' items_count: 3 items: - name: 'Item 1' quantity: 1 events: [] last_updated: '2025-01-15T09:00:00.000000Z' properties: reference_id: type: string example: BK65A3F2E1 package_info: type: object properties: tracking_number: type: string example: BK65A3F2E1 status: type: string example: confirmed locker_assignments: type: array example: - locker_id: 01ARZ3NDEKTSV4RRFFQ69G5FAV locker_name: A1-01 cabinet: id: 01ARZ3NDEKTSV4RRFFQ69G5FAU name: 'Cabinet A1' status: active starts_at: '2025-01-15T09:00:00.000000Z' ends_at: '2025-01-20T17:00:00.000000Z' items: type: object properties: locker_id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAV locker_name: type: string example: A1-01 cabinet: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAU name: type: string example: 'Cabinet A1' status: type: string example: active starts_at: type: string example: '2025-01-15T09:00:00.000000Z' ends_at: type: string example: '2025-01-20T17:00:00.000000Z' items_count: type: integer example: 3 items: type: array example: - name: 'Item 1' quantity: 1 items: type: object properties: name: type: string example: 'Item 1' quantity: type: integer example: 1 events: type: array example: [] last_updated: type: string example: '2025-01-15T09:00:00.000000Z' 404: description: '' content: application/json: schema: type: object example: message: 'Booking not found' properties: message: type: string example: 'Booking not found' 422: description: '' content: application/json: schema: type: object example: message: 'The given data was invalid.' properties: message: type: string example: 'The given data was invalid.' tags: - 'Booking Tracking' requestBody: required: true content: application/json: schema: type: object properties: id: type: string description: 'Booking ID, reference ID, label/tracking ID, or ticket reference' example: BK691B2516D28B2 email: type: string description: 'Customer email address for verification' example: customer@example.com phone: type: string description: 'Customer phone number for verification' example: '+447700900123' postcode: type: string description: 'Delivery postcode for verification' example: 'SW1A 1AA' required: - id '/v1/bookings/{id}/tracking': get: summary: 'Track a booking by ID (authenticated endpoint).' operationId: trackABookingByIDauthenticatedEndpoint description: 'Allows authenticated accounts to track their bookings.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: reference_id: BK65A3F2E1 package_info: tracking_number: BK65A3F2E1 status: confirmed locker_assignments: - locker_id: 01ARZ3NDEKTSV4RRFFQ69G5FAV locker_name: A1-01 cabinet: id: 01ARZ3NDEKTSV4RRFFQ69G5FAU name: 'Cabinet A1' status: active starts_at: '2025-01-15T09:00:00.000000Z' ends_at: '2025-01-20T17:00:00.000000Z' items_count: 3 items: - name: 'Item 1' quantity: 1 events: [] last_updated: '2025-01-15T09:00:00.000000Z' properties: reference_id: type: string example: BK65A3F2E1 package_info: type: object properties: tracking_number: type: string example: BK65A3F2E1 status: type: string example: confirmed locker_assignments: type: array example: - locker_id: 01ARZ3NDEKTSV4RRFFQ69G5FAV locker_name: A1-01 cabinet: id: 01ARZ3NDEKTSV4RRFFQ69G5FAU name: 'Cabinet A1' status: active starts_at: '2025-01-15T09:00:00.000000Z' ends_at: '2025-01-20T17:00:00.000000Z' items: type: object properties: locker_id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAV locker_name: type: string example: A1-01 cabinet: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAU name: type: string example: 'Cabinet A1' status: type: string example: active starts_at: type: string example: '2025-01-15T09:00:00.000000Z' ends_at: type: string example: '2025-01-20T17:00:00.000000Z' items_count: type: integer example: 3 items: type: array example: - name: 'Item 1' quantity: 1 items: type: object properties: name: type: string example: 'Item 1' quantity: type: integer example: 1 events: type: array example: [] last_updated: type: string example: '2025-01-15T09:00:00.000000Z' 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 404: description: '' content: application/json: schema: type: object example: message: 'Booking not found' properties: message: type: string example: 'Booking not found' tags: - 'Booking Tracking' parameters: - in: path name: id description: 'The ID of the booking.' example: architecto required: true schema: type: string /v1/bookings: get: summary: 'Display a listing of bookings.' operationId: displayAListingOfBookings description: "Returns a paginated list of bookings for the current account context.\nYou can filter by status. When we have more detail about *why* the booking\nis in its current state, each booking includes `status_reason_id`,\n`status_reason`, and `status_reason_label`; the same fields appear on each\n`status_history` entry where they were recorded." parameters: - in: query name: status description: 'Filter bookings by status' example: confirmed required: false schema: type: string description: 'Filter bookings by status' example: confirmed - in: query name: per_page description: 'Number of items per page (max 100)' example: 20 required: false schema: type: integer description: 'Number of items per page (max 100)' example: 20 - in: query name: page description: 'Page number' example: 1 required: false schema: type: integer description: 'Page number' example: 1 responses: 200: description: '' content: application/json: schema: type: object example: data: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAV reference_id: SC689PUY74F service_product_id: 01ARZ3NDEKTSV4RRFFQ69G5FAX service_product: 'DC to Locker' status_id: 01ARZ3NDEKTSV4RRFFQ69G5FAX status: confirmed status_reason_id: null status_reason: null status_reason_label: null site_id: 01ARZ3NDEKTSV4RRFFQ69G5FAS site: id: 01ARZ3NDEKTSV4RRFFQ69G5FAS name: 'Example Locker Site' city: London postcode: 'N1 1AA' status_history: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAX status: confirmed label: Confirmed description: 'Booking has been confirmed' status_reason_id: null status_reason: null status_reason_label: null status_changed_at: '2025-01-01T00:00:00.000000Z' items: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAB name: 'Box of documents' description: 'Important business documents' quantity: 1 size: code: large label: Large is_override: false weight: 30 height: 50 width: 90 depth: 170 value: 10000 volume: 765000 created_at: '2025-01-01T00:00:00.000000Z' updated_at: '2025-01-01T00:00:00.000000Z' collections: [] labels: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAD zpl_available: true pdf_available: true png_available: false zpl: 'https://api.shiftcollect.com/v1/labels/1234567890/zpl' pdf: 'https://api.shiftcollect.com/v1/labels/1234567890/pdf' png: 'https://api.shiftcollect.com/v1/labels/1234567890/png' locker_reservation_window: null locker_assignments: null authorisations: null contacts: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAC name: 'Jane Doe' email: jane@example.com phone: '+447700900123' returns: null created_at: '2025-01-01T00:00:00.000000Z' updated_at: '2025-01-01T00:00:00.000000Z' created_by: 01ARZ3NDEKTSV4RRFFQ69G5FAY pagination: current_page: 1 per_page: 15 total: 100 last_page: 7 from: 1 to: 15 has_more_pages: true links: first: 'http://example.com/api/v1/bookings?page=1' last: 'http://example.com/api/v1/bookings?page=7' prev: null next: 'http://example.com/api/v1/bookings?page=2' properties: data: type: array example: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAV reference_id: SC689PUY74F service_product_id: 01ARZ3NDEKTSV4RRFFQ69G5FAX service_product: 'DC to Locker' status_id: 01ARZ3NDEKTSV4RRFFQ69G5FAX status: confirmed status_reason_id: null status_reason: null status_reason_label: null site_id: 01ARZ3NDEKTSV4RRFFQ69G5FAS site: id: 01ARZ3NDEKTSV4RRFFQ69G5FAS name: 'Example Locker Site' city: London postcode: 'N1 1AA' status_history: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAX status: confirmed label: Confirmed description: 'Booking has been confirmed' status_reason_id: null status_reason: null status_reason_label: null status_changed_at: '2025-01-01T00:00:00.000000Z' items: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAB name: 'Box of documents' description: 'Important business documents' quantity: 1 size: code: large label: Large is_override: false weight: 30 height: 50 width: 90 depth: 170 value: 10000 volume: 765000 created_at: '2025-01-01T00:00:00.000000Z' updated_at: '2025-01-01T00:00:00.000000Z' collections: [] labels: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAD zpl_available: true pdf_available: true png_available: false zpl: 'https://api.shiftcollect.com/v1/labels/1234567890/zpl' pdf: 'https://api.shiftcollect.com/v1/labels/1234567890/pdf' png: 'https://api.shiftcollect.com/v1/labels/1234567890/png' locker_reservation_window: null locker_assignments: null authorisations: null contacts: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAC name: 'Jane Doe' email: jane@example.com phone: '+447700900123' returns: null created_at: '2025-01-01T00:00:00.000000Z' updated_at: '2025-01-01T00:00:00.000000Z' created_by: 01ARZ3NDEKTSV4RRFFQ69G5FAY items: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAV reference_id: type: string example: SC689PUY74F service_product_id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAX service_product: type: string example: 'DC to Locker' status_id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAX status: type: string example: confirmed status_reason_id: type: string example: null nullable: true status_reason: type: string example: null nullable: true status_reason_label: type: string example: null nullable: true site_id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAS site: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAS name: type: string example: 'Example Locker Site' city: type: string example: London postcode: type: string example: 'N1 1AA' status_history: type: array example: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAX status: confirmed label: Confirmed description: 'Booking has been confirmed' status_reason_id: null status_reason: null status_reason_label: null status_changed_at: '2025-01-01T00:00:00.000000Z' items: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAX status: type: string example: confirmed label: type: string example: Confirmed description: type: string example: 'Booking has been confirmed' status_reason_id: type: string example: null nullable: true status_reason: type: string example: null nullable: true status_reason_label: type: string example: null nullable: true status_changed_at: type: string example: '2025-01-01T00:00:00.000000Z' items: type: array example: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAB name: 'Box of documents' description: 'Important business documents' quantity: 1 size: code: large label: Large is_override: false weight: 30 height: 50 width: 90 depth: 170 value: 10000 volume: 765000 created_at: '2025-01-01T00:00:00.000000Z' updated_at: '2025-01-01T00:00:00.000000Z' items: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAB name: type: string example: 'Box of documents' description: type: string example: 'Important business documents' quantity: type: integer example: 1 size: type: object properties: code: type: string example: large label: type: string example: Large is_override: type: boolean example: false weight: type: integer example: 30 height: type: integer example: 50 width: type: integer example: 90 depth: type: integer example: 170 value: type: integer example: 10000 volume: type: integer example: 765000 created_at: type: string example: '2025-01-01T00:00:00.000000Z' updated_at: type: string example: '2025-01-01T00:00:00.000000Z' collections: type: array example: [] labels: type: array example: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAD zpl_available: true pdf_available: true png_available: false zpl: 'https://api.shiftcollect.com/v1/labels/1234567890/zpl' pdf: 'https://api.shiftcollect.com/v1/labels/1234567890/pdf' png: 'https://api.shiftcollect.com/v1/labels/1234567890/png' items: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAD zpl_available: type: boolean example: true pdf_available: type: boolean example: true png_available: type: boolean example: false zpl: type: string example: 'https://api.shiftcollect.com/v1/labels/1234567890/zpl' pdf: type: string example: 'https://api.shiftcollect.com/v1/labels/1234567890/pdf' png: type: string example: 'https://api.shiftcollect.com/v1/labels/1234567890/png' locker_reservation_window: type: string example: null nullable: true locker_assignments: type: string example: null nullable: true authorisations: type: string example: null nullable: true contacts: type: array example: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAC name: 'Jane Doe' email: jane@example.com phone: '+447700900123' items: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAC name: type: string example: 'Jane Doe' email: type: string example: jane@example.com phone: type: string example: '+447700900123' returns: type: string example: null nullable: true created_at: type: string example: '2025-01-01T00:00:00.000000Z' updated_at: type: string example: '2025-01-01T00:00:00.000000Z' created_by: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAY pagination: type: object properties: current_page: type: integer example: 1 per_page: type: integer example: 15 total: type: integer example: 100 last_page: type: integer example: 7 from: type: integer example: 1 to: type: integer example: 15 has_more_pages: type: boolean example: true links: type: object properties: first: type: string example: 'http://example.com/api/v1/bookings?page=1' last: type: string example: 'http://example.com/api/v1/bookings?page=7' prev: type: string example: null nullable: true next: type: string example: 'http://example.com/api/v1/bookings?page=2' 400: description: '' content: application/json: schema: type: object example: message: 'No account context set' properties: message: type: string example: 'No account context set' 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 403: description: '' content: application/json: schema: type: object example: message: 'This action is unauthorised.' properties: message: type: string example: 'This action is unauthorised.' tags: - Bookings post: summary: 'Store a newly created booking.' operationId: storeANewlyCreatedBooking description: "Creates a new booking associated with the current account context and the authenticated user.\nThe booking will be processed according to the specified service product.\n\n## Parcel sizes on booking items\n\nFor service products with a size catalogue (see `GET /v1/booking-item-sizes`), each entry in `items` can be described in three ways:\n\n1. **Size shortcut** — send `size` (`small`, `large`, or `xlarge`). Any omitted `height`, `width`, `depth`, `weight`, or `value` are set from that tier’s catalogue maximums before the booking is saved.\n2. **Explicit dimensions** — send `height`, `width`, `depth`, and `weight` (centimetres and kilograms). We assign the **smallest** tier that fits. `width` and `depth` are rotation-invariant (you may swap them; matching sorts all three edges).\n3. **Size plus dimensions** — send both; dimensions must fit within the declared `size` tier.\n\nIf there is no catalogue for the chosen service product, each item still requires `height`, `width`, `depth`, and `weight` as today.\n\nInvalid or unknown `size` values, dimensions that exceed the tier, or parcels too large for any tier return `422` validation errors on the relevant `items.*` fields." parameters: [] responses: 201: description: '' content: application/json: schema: type: object example: message: 'Booking created successfully' booking_id: 01ARZ3NDEKTSV4RRFFQ69G5FAV reference_id: BK-2025-001 service: sorted_home_delivery label_ids: - '1111111119' - '1111111120' properties: message: type: string example: 'Booking created successfully' booking_id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAV reference_id: type: string example: BK-2025-001 service: type: string example: sorted_home_delivery label_ids: type: array example: - '1111111119' - '1111111120' items: type: string 400: description: '' content: application/json: schema: type: object example: message: 'No account context set' properties: message: type: string example: 'No account context set' 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 403: description: '' content: application/json: schema: type: object example: message: 'This action is unauthorised.' properties: message: type: string example: 'This action is unauthorised.' 422: description: '' content: application/json: schema: oneOf: - description: '' type: object example: message: 'The given data was invalid.' errors: delivery: - 'The delivery field is required.' collection.address_id: - 'The collection address id field is required when collection is present.' locker_reservation_window.site_id: - 'The locker reservation window site must match the delivery site.' properties: message: type: string example: 'The given data was invalid.' errors: type: object properties: delivery: type: array example: - 'The delivery field is required.' items: type: string collection.address_id: type: array example: - 'The collection address id field is required when collection is present.' items: type: string locker_reservation_window.site_id: type: array example: - 'The locker reservation window site must match the delivery site.' items: type: string - description: 'Validation failed (including invalid `size` or dimensions that do not fit any tier).' type: object example: message: 'The given data was invalid.' errors: items.0.size: - 'The selected size is not available for this service product.' items.0.height: - 'The item dimensions and weight exceed the maximum allowed parcel size for this service product.' properties: message: type: string example: 'The given data was invalid.' errors: type: object properties: items.0.size: type: array example: - 'The selected size is not available for this service product.' items: type: string items.0.height: type: array example: - 'The item dimensions and weight exceed the maximum allowed parcel size for this service product.' items: type: string tags: - Bookings requestBody: required: true content: application/json: schema: type: object properties: service_product_id: type: string description: "Service product identifier. Accepts either the service product ULID or exact name. If not provided, the account's default service will be used. The service_product_id of an existing record in the account_service_products table." example: 01ARZ3NDEKTSV4RRFFQ69G5FAX nullable: true reference_id: type: string description: 'Optional custom reference ID for the booking. Must be unique within the account. If not provided, a reference ID will be auto-generated. Must not be greater than 255 characters.' example: ORD-12345 nullable: true collection: type: object description: 'Collection details (required if service requires collection). Must contain exactly one of: site_id, despatch_centre_id, or address.' example: null properties: site_id: type: string description: 'The site ID from where the booking will be collected (if collecting from a locker site). This field is required when none of collection.despatch_centre_id and collection.address are present. The id of an existing record in the sites table.' example: 01ARZ3NDEKTSV4RRFFQ69G5FAY nullable: true despatch_centre_id: type: string description: 'The despatch centre ID from where the booking will be collected. This field is required when none of collection.site_id and collection.address are present. The id of an existing record in the despatch_centres table.' example: 01ARZ3NDEKTSV4RRFFQ69G5FAY nullable: true address: type: object description: 'Inline address object for collection (if not using site_id or despatch_centre_id). This field is required when none of collection.site_id and collection.despatch_centre_id are present.' example: null properties: recipient: type: string description: 'Recipient name. Must not be greater than 255 characters.' example: 'John Smith' nullable: true line_1: type: string description: 'Address line 1. This field is required when collection.address is present. Must not be greater than 255 characters.' example: '123 Main Street' line_2: type: string description: 'Address line 2. Must not be greater than 255 characters.' example: 'Flat 3' nullable: true line_3: type: string description: 'Address line 3. Must not be greater than 255 characters.' example: 'Building A' nullable: true city: type: string description: 'City. Must not be greater than 255 characters.' example: Plymouth nullable: true postcode: type: string description: 'Postcode. This field is required when collection.address is present. Must not be greater than 20 characters.' example: 'SW1A 1AA' country: type: string description: 'Country. Must not be greater than 255 characters.' example: 'United Kingdom' nullable: true phone: type: string description: 'Phone number. Must not be greater than 50 characters.' example: '+44 1234 567890' nullable: true email: type: string description: 'Email address. Must be a valid email address. Must not be greater than 255 characters.' example: recipient@example.com nullable: true special_instructions: type: string description: 'Special delivery instructions. Must not be greater than 1000 characters.' example: 'Leave at side gate' nullable: true latitude: type: number description: 'Must be between -90 and 90.' example: -89 nullable: true longitude: type: number description: 'Must be between -180 and 180.' example: -179 nullable: true nullable: true t_earliest_collection: type: string description: 'Earliest collection time (ISO 8601 datetime). Must be a valid date. Must be a date after now.' example: '2025-01-15T09:00:00Z' nullable: true t_latest_collection: type: string description: 'Latest collection time (ISO 8601 datetime). Must be a valid date. Must be a date after collection.t_earliest_collection.' example: '2025-01-15T17:00:00Z' nullable: true delivery: type: object description: 'Delivery details (required if service product requires delivery). Must contain exactly one of: site_id, despatch_centre_id, or address.' example: null properties: site_id: type: string description: 'The site ID to where items will be delivered (if to a locker site). This field is required when none of delivery.despatch_centre_id and delivery.address are present. The id of an existing record in the sites table.' example: 01ARZ3NDEKTSV4RRFFQ69G5FAZ nullable: true despatch_centre_id: type: string description: 'The despatch centre ID to where items will be delivered. This field is required when none of delivery.site_id and delivery.address are present. The id of an existing record in the despatch_centres table.' example: 01ARZ3NDEKTSV4RRFFQ69G5FAZ nullable: true address: type: object description: 'Inline address object for delivery (if not using site_id or despatch_centre_id). This field is required when none of delivery.site_id and delivery.despatch_centre_id are present.' example: null properties: recipient: type: string description: 'Recipient name. Must not be greater than 255 characters.' example: 'John Smith' nullable: true line_1: type: string description: 'Address line 1. This field is required when delivery.address is present. Must not be greater than 255 characters.' example: '123 Main Street' line_2: type: string description: 'Address line 2. Must not be greater than 255 characters.' example: 'Flat 3' nullable: true line_3: type: string description: 'Address line 3. Must not be greater than 255 characters.' example: 'Building A' nullable: true city: type: string description: 'City. Must not be greater than 255 characters.' example: Plymouth nullable: true postcode: type: string description: 'Postcode. This field is required when delivery.address is present. Must not be greater than 20 characters.' example: 'SW1A 1AA' country: type: string description: 'Country. Must not be greater than 255 characters.' example: 'United Kingdom' nullable: true phone: type: string description: 'Phone number. Must not be greater than 50 characters.' example: '+44 1234 567890' nullable: true email: type: string description: 'Email address. Must be a valid email address. Must not be greater than 255 characters.' example: recipient@example.com nullable: true special_instructions: type: string description: 'Special delivery instructions. Must not be greater than 1000 characters.' example: 'Leave at side gate' nullable: true latitude: type: number description: 'Must be between -90 and 90.' example: -90 nullable: true longitude: type: number description: 'Must be between -180 and 180.' example: -179 nullable: true nullable: true locker_reservation_window: type: object description: 'Locker reservation window details.' example: null properties: site_id: type: string description: 'The site ID for the locker reservation window. This field is required when locker_reservation_window is present. The id of an existing record in the sites table.' example: 01ARZ3NDEKTSV4RRFFQ69G5FAZ t_earliest_arrival: type: string description: 'Earliest booking arrival time at the locker site (ISO 8601). This field is required when locker_reservation_window is present. Must be a valid date. Must be a date after now.' example: '2025-01-15T09:00:00Z' t_latest_collection: type: string description: 'Latest customer collection time from the locker site (ISO 8601). This field is required when locker_reservation_window is present. Must be a valid date. Must be a date after locker_reservation_window.t_earliest_arrival.' example: '2025-01-22T17:00:00Z' contacts: type: array description: 'Array of contacts to notify about tracking events and booking updates.' example: null items: type: object properties: name: type: string description: 'Contact name. Must not be greater than 255 characters.' example: 'John Doe' nullable: true email: type: string description: 'Contact email. This field is required when contacts.*.phone is not present. Must be a valid email address.' example: john@example.com nullable: true phone: type: string description: 'Contact phone. Must be in international format (e.g. +447700900123). This field is required when contacts.*.email is not present.' example: '+447700900123' nullable: true items: type: array description: 'Packages on the booking. Each object requires `name` and `quantity`. Use `size` and/or physical dimensions as described in the endpoint introduction.' example: - [] items: type: object properties: name: type: string description: 'Display name for the package. This field is required when items is present. Must not be greater than 255 characters.' example: 'Standard parcel' description: type: string description: 'Optional description. Max 1000 characters. Must not be greater than 1000 characters.' example: 'Customer order #12345' nullable: true quantity: type: integer description: 'Number of identical physical packages represented by this line. Must be >= 1. This field is required when items is present. Must be at least 1.' example: 1 size: type: string description: 'Parcel tier: `small`, `large`, or `xlarge`. Available codes depend on the service product — use `GET /v1/booking-item-sizes`. When provided, omitted dimensions and weight may be back-filled from the catalogue.' example: large weight: type: number description: 'Weight in kilograms. Required per item when `size` is not used and no catalogue exists; optional when `size` is used (back-filled if omitted).' example: 30 height: type: number description: 'Height in centimetres. Required per item when `size` is not used and no catalogue exists; optional when `size` is used (back-filled if omitted).' example: 50 width: type: number description: 'Width in centimetres. Interchangeable with `depth` for tier matching.' example: 90 depth: type: number description: 'Depth in centimetres (longest horizontal edge in commercial terms). Interchangeable with `width` for tier matching.' example: 170 value: type: number description: 'Declared value in GBP. Back-filled to the tier maximum when `size` is used and `value` is omitted.' example: 10000 authorisation_group_ids: type: array description: 'Authorisation group ID. The id of an existing record in the authorisation_groups table.' example: - 01ARZ3NDEKTSV4RRFFQ69G5FAY items: type: string locker_user_ids: type: array description: 'Locker user ID. The id of an existing record in the locker_users table.' example: - 01ARZ3NDEKTSV4RRFFQ69G5FAZ items: type: string required: - items '/v1/bookings/{id}': get: summary: 'Display the specified booking.' operationId: displayTheSpecifiedBooking description: "Returns full details for one booking in your current account context.\nWhen available, `status_reason_id`, `status_reason`, and `status_reason_label`\ndescribe why the booking has its current overall status; each past step in\n`status_history` can include the same three fields where they were recorded." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: id: 01ARZ3NDEKTSV4RRFFQ69G5FAV reference_id: SC689PUY74F service_product_id: 01ARZ3NDEKTSV4RRFFQ69G5FAX service_product: 'DC to Locker' status_id: 01ARZ3NDEKTSV4RRFFQ69G5FAX status: confirmed status_reason_id: null status_reason: null status_reason_label: null site_id: 01ARZ3NDEKTSV4RRFFQ69G5FAS site: id: 01ARZ3NDEKTSV4RRFFQ69G5FAS name: 'Example Locker Site' city: London postcode: 'N1 1AA' status_history: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAX status: confirmed label: Confirmed description: 'Booking has been confirmed' status_reason_id: null status_reason: null status_reason_label: null status_changed_at: '2025-01-01T00:00:00.000000Z' items: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAB name: 'Box of documents' description: 'Important business documents' quantity: 1 size: code: large label: Large is_override: false weight: 30 height: 50 width: 90 depth: 170 value: 10000 volume: 765000 created_at: '2025-01-01T00:00:00.000000Z' updated_at: '2025-01-01T00:00:00.000000Z' collections: [] labels: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAD zpl_available: true pdf_available: true png_available: false locker_reservation_window: null locker_assignments: null authorisations: null contacts: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAC name: 'Jane Doe' email: jane@example.com phone: '+447700900123' returns: null created_at: '2025-01-01T00:00:00.000000Z' updated_at: '2025-01-01T00:00:00.000000Z' created_by: 01ARZ3NDEKTSV4RRFFQ69G5FAY properties: data: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAV reference_id: type: string example: SC689PUY74F service_product_id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAX service_product: type: string example: 'DC to Locker' status_id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAX status: type: string example: confirmed status_reason_id: type: string example: null nullable: true status_reason: type: string example: null nullable: true status_reason_label: type: string example: null nullable: true site_id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAS site: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAS name: type: string example: 'Example Locker Site' city: type: string example: London postcode: type: string example: 'N1 1AA' status_history: type: array example: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAX status: confirmed label: Confirmed description: 'Booking has been confirmed' status_reason_id: null status_reason: null status_reason_label: null status_changed_at: '2025-01-01T00:00:00.000000Z' items: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAX status: type: string example: confirmed label: type: string example: Confirmed description: type: string example: 'Booking has been confirmed' status_reason_id: type: string example: null nullable: true status_reason: type: string example: null nullable: true status_reason_label: type: string example: null nullable: true status_changed_at: type: string example: '2025-01-01T00:00:00.000000Z' items: type: array example: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAB name: 'Box of documents' description: 'Important business documents' quantity: 1 size: code: large label: Large is_override: false weight: 30 height: 50 width: 90 depth: 170 value: 10000 volume: 765000 created_at: '2025-01-01T00:00:00.000000Z' updated_at: '2025-01-01T00:00:00.000000Z' items: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAB name: type: string example: 'Box of documents' description: type: string example: 'Important business documents' quantity: type: integer example: 1 size: type: object properties: code: type: string example: large label: type: string example: Large is_override: type: boolean example: false weight: type: integer example: 30 height: type: integer example: 50 width: type: integer example: 90 depth: type: integer example: 170 value: type: integer example: 10000 volume: type: integer example: 765000 created_at: type: string example: '2025-01-01T00:00:00.000000Z' updated_at: type: string example: '2025-01-01T00:00:00.000000Z' collections: type: array example: [] labels: type: array example: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAD zpl_available: true pdf_available: true png_available: false items: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAD zpl_available: type: boolean example: true pdf_available: type: boolean example: true png_available: type: boolean example: false locker_reservation_window: type: string example: null nullable: true locker_assignments: type: string example: null nullable: true authorisations: type: string example: null nullable: true contacts: type: array example: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAC name: 'Jane Doe' email: jane@example.com phone: '+447700900123' items: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAC name: type: string example: 'Jane Doe' email: type: string example: jane@example.com phone: type: string example: '+447700900123' returns: type: string example: null nullable: true created_at: type: string example: '2025-01-01T00:00:00.000000Z' updated_at: type: string example: '2025-01-01T00:00:00.000000Z' created_by: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAY 400: description: '' content: application/json: schema: type: object example: message: 'No account context set' properties: message: type: string example: 'No account context set' 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 404: description: '' content: application/json: schema: type: object example: message: 'Booking not found' properties: message: type: string example: 'Booking not found' tags: - Bookings delete: summary: 'Cancel the specified booking (DELETE).' operationId: cancelTheSpecifiedBookingDELETE description: "Cancels a booking, removing it from active status. The booking\nmust belong to the current account context. Only bookings with\nstatus Pending, Confirmed, In Progress or Ready for Collection can be cancelled." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: message: 'Booking cancelled' booking_id: 01ARZ3NDEKTSV4RRFFQ69G5FAV reference_id: BK-2025-001 status: cancelled properties: message: type: string example: 'Booking cancelled' booking_id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAV reference_id: type: string example: BK-2025-001 status: type: string example: cancelled 400: description: '' content: application/json: schema: type: object example: message: 'No account context set' properties: message: type: string example: 'No account context set' 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 404: description: '' content: application/json: schema: type: object example: message: 'Booking not found' properties: message: type: string example: 'Booking not found' 422: description: '' content: application/json: schema: type: object example: message: 'Booking cannot be cancelled. Only bookings with status Pending, Confirmed, In Progress or Ready for Collection can be cancelled.' properties: message: type: string example: 'Booking cannot be cancelled. Only bookings with status Pending, Confirmed, In Progress or Ready for Collection can be cancelled.' tags: - Bookings parameters: - in: path name: id description: 'The ID of the booking' example: 01ARZ3NDEKTSV4RRFFQ69G5FAV required: true schema: type: string '/v1/bookings/{id}/cancel': post: summary: 'Cancel the specified booking (POST shortcut).' operationId: cancelTheSpecifiedBookingPOSTShortcut description: "Shortcut for cancelling a booking. Same behaviour as DELETE /v1/bookings/{id}.\nOnly bookings with status Pending, Confirmed, In Progress or Ready for Collection can be cancelled." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: message: 'Booking cancelled' booking_id: 01ARZ3NDEKTSV4RRFFQ69G5FAV reference_id: BK-2025-001 status: cancelled properties: message: type: string example: 'Booking cancelled' booking_id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAV reference_id: type: string example: BK-2025-001 status: type: string example: cancelled 400: description: '' content: application/json: schema: type: object example: message: 'No account context set' properties: message: type: string example: 'No account context set' 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 404: description: '' content: application/json: schema: type: object example: message: 'Booking not found' properties: message: type: string example: 'Booking not found' 422: description: '' content: application/json: schema: type: object example: message: 'Booking cannot be cancelled. Only bookings with status Pending, Confirmed, In Progress or Ready for Collection can be cancelled.' properties: message: type: string example: 'Booking cannot be cancelled. Only bookings with status Pending, Confirmed, In Progress or Ready for Collection can be cancelled.' tags: - Bookings parameters: - in: path name: id description: 'The ID of the booking to cancel' example: 01ARZ3NDEKTSV4RRFFQ69G5FAV required: true schema: type: string '/v1/bookings/{id}/send-booking-confirmation': post: summary: 'Send booking confirmation to customer.' operationId: sendBookingConfirmationToCustomer description: "Sends booking confirmation notification via email and SMS.\nThis includes any access codes if the booking has locker assignments." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: message: 'Booking confirmation notification queued successfully' recipients: - email: customer@example.com phone: '+44 1234 567890' properties: message: type: string example: 'Booking confirmation notification queued successfully' recipients: type: array example: - email: customer@example.com phone: '+44 1234 567890' items: type: object properties: email: type: string example: customer@example.com phone: type: string example: '+44 1234 567890' 400: description: '' content: application/json: schema: type: object example: message: 'No customer contact information available' properties: message: type: string example: 'No customer contact information available' 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 403: description: '' content: application/json: schema: type: object example: message: 'This action is unauthorised.' properties: message: type: string example: 'This action is unauthorised.' 404: description: '' content: application/json: schema: type: object example: message: 'Booking not found' properties: message: type: string example: 'Booking not found' tags: - Bookings parameters: - in: path name: id description: 'The ID of the booking' example: 01ARZ3NDEKTSV4RRFFQ69G5FAV required: true schema: type: string '/v1/bookings/{id}/send-reminder': post: summary: 'Send booking reminder email.' operationId: sendBookingReminderEmail description: 'Sends a reminder email before the booking starts with all access codes.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: message: 'Reminder notification queued successfully' recipients: - email: customer@example.com phone: '+44 1234 567890' properties: message: type: string example: 'Reminder notification queued successfully' recipients: type: array example: - email: customer@example.com phone: '+44 1234 567890' items: type: object properties: email: type: string example: customer@example.com phone: type: string example: '+44 1234 567890' 400: description: '' content: application/json: schema: type: object example: message: 'No customer contact information available' properties: message: type: string example: 'No customer contact information available' 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 403: description: '' content: application/json: schema: type: object example: message: 'This action is unauthorised.' properties: message: type: string example: 'This action is unauthorised.' 404: description: '' content: application/json: schema: type: object example: message: 'Booking not found' properties: message: type: string example: 'Booking not found' tags: - Bookings parameters: - in: path name: id description: 'The ID of the booking' example: 01ARZ3NDEKTSV4RRFFQ69G5FAV required: true schema: type: string '/v1/bookings/{id}/send-expiry-reminder': post: summary: 'Send expiry reminder email.' operationId: sendExpiryReminderEmail description: 'Sends a reminder email before the booking expires.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: message: 'Expiry reminder notification queued successfully' recipients: - email: customer@example.com phone: '+44 1234 567890' properties: message: type: string example: 'Expiry reminder notification queued successfully' recipients: type: array example: - email: customer@example.com phone: '+44 1234 567890' items: type: object properties: email: type: string example: customer@example.com phone: type: string example: '+44 1234 567890' 400: description: '' content: application/json: schema: type: object example: message: 'No customer contact information available' properties: message: type: string example: 'No customer contact information available' 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 403: description: '' content: application/json: schema: type: object example: message: 'This action is unauthorised.' properties: message: type: string example: 'This action is unauthorised.' 404: description: '' content: application/json: schema: type: object example: message: 'Booking not found' properties: message: type: string example: 'Booking not found' tags: - Bookings parameters: - in: path name: id description: 'The ID of the booking' example: 01ARZ3NDEKTSV4RRFFQ69G5FAV required: true schema: type: string '/v1/bookings/{id}/send-cancellation-notice': post: summary: 'Send cancellation notice email.' operationId: sendCancellationNoticeEmail description: 'Sends a cancellation notice when a booking is cancelled.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: message: 'Cancellation notice queued successfully' recipients: - email: customer@example.com phone: '+44 1234 567890' properties: message: type: string example: 'Cancellation notice queued successfully' recipients: type: array example: - email: customer@example.com phone: '+44 1234 567890' items: type: object properties: email: type: string example: customer@example.com phone: type: string example: '+44 1234 567890' 400: description: '' content: application/json: schema: type: object example: message: 'No customer contact information available' properties: message: type: string example: 'No customer contact information available' 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 403: description: '' content: application/json: schema: type: object example: message: 'This action is unauthorised.' properties: message: type: string example: 'This action is unauthorised.' 404: description: '' content: application/json: schema: type: object example: message: 'Booking not found' properties: message: type: string example: 'Booking not found' tags: - Bookings requestBody: required: false content: application/json: schema: type: object properties: cancellation_reason: type: string description: 'Reason for cancellation' example: 'Customer request' parameters: - in: path name: id description: 'The ID of the booking' example: 01ARZ3NDEKTSV4RRFFQ69G5FAV required: true schema: type: string '/v1/bookings/{id}/labels': get: summary: 'Get labels by booking ID.' operationId: getLabelsByBookingID description: "Returns concatenated label data for all labels in a booking.\nCurrently only ZPL concatenation is supported." parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Bookings requestBody: required: false content: application/json: schema: type: object properties: format: type: string description: '' example: architecto enum: - zpl - pdf - png nullable: true parameters: - in: path name: id description: 'The ID of the booking' example: 01ARZ3NDEKTSV4RRFFQ69G5FAV required: true schema: type: string '/v1/bookings/{id}/authorisation': post: summary: 'Add or update booking authorisations.' operationId: addOrUpdateBookingAuthorisations description: "Adds or extends authorisation groups and locker users for an existing booking.\nThe booking must belong to the current account context." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: message: 'Authorisations updated' properties: message: type: string example: 'Authorisations updated' 400: description: '' content: application/json: schema: type: object example: message: 'No account context set' properties: message: type: string example: 'No account context set' 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 404: description: '' content: application/json: schema: type: object example: message: 'Booking not found' properties: message: type: string example: 'Booking not found' 422: description: '' content: application/json: schema: type: object example: message: 'The given data was invalid.' errors: authorisation_group_ids.0: - 'The selected authorisation group ids.0 is invalid.' properties: message: type: string example: 'The given data was invalid.' errors: type: object properties: authorisation_group_ids.0: type: array example: - 'The selected authorisation group ids.0 is invalid.' items: type: string tags: - Bookings requestBody: required: false content: application/json: schema: type: object properties: authorisation_group_ids: type: array description: 'Array of authorisation group IDs to add' example: - 01ARZ3NDEKTSV4RRFFQ69G5FAY items: type: string locker_user_ids: type: array description: 'Array of locker user IDs to add' example: - 01ARZ3NDEKTSV4RRFFQ69G5FAZ items: type: string parameters: - in: path name: id description: 'The ID of the booking' example: 01ARZ3NDEKTSV4RRFFQ69G5FAV required: true schema: type: string '/v1/bookings/{id}/generate-codes': post: summary: 'Generate lock codes for booking lockers.' operationId: generateLockCodesForBookingLockers description: "Generates access codes for all lockers associated with a booking.\nThe booking must belong to the current account context." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: message: 'Lock codes generated' codes: - locker_id: 01ARZ3NDEKTSV4RRFFQ69G5FAC code: '1234' properties: message: type: string example: 'Lock codes generated' codes: type: array example: - locker_id: 01ARZ3NDEKTSV4RRFFQ69G5FAC code: '1234' items: type: object properties: locker_id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAC code: type: string example: '1234' 400: description: '' content: application/json: schema: type: object example: message: 'No account context set' properties: message: type: string example: 'No account context set' 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 403: description: '' content: application/json: schema: type: object example: message: 'This action is unauthorised.' properties: message: type: string example: 'This action is unauthorised.' 404: description: '' content: application/json: schema: type: object example: message: 'Booking not found' properties: message: type: string example: 'Booking not found' tags: - Bookings parameters: - in: path name: id description: 'The ID of the booking' example: 01ARZ3NDEKTSV4RRFFQ69G5FAV required: true schema: type: string /v1/cabinets: get: summary: 'Display a listing of cabinets.' operationId: displayAListingOfCabinets description: 'Returns a list of cabinets with optional filtering by status or location.' parameters: - in: query name: status description: 'Filter by cabinet status name' example: active required: false schema: type: string description: 'Filter by cabinet status name' example: active - in: query name: latitude description: 'Latitude for location-based search (must include longitude and radius)' example: 51.5074 required: false schema: type: number description: 'Latitude for location-based search (must include longitude and radius)' example: 51.5074 - in: query name: longitude description: 'Longitude for location-based search (must include latitude and radius)' example: -0.1278 required: false schema: type: number description: 'Longitude for location-based search (must include latitude and radius)' example: -0.1278 - in: query name: radius description: 'Radius in kilometers for location-based search (must include latitude and longitude)' example: 10 required: false schema: type: number description: 'Radius in kilometers for location-based search (must include latitude and longitude)' example: 10 responses: 200: description: '' content: application/json: schema: type: object example: data: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAA name: 'Cabinet A1' status: active total_active_lockers: 10 total_available_lockers: 5 active_locker_ids: - 01ARZ3NDEKTSV4RRFFQ69G5FC1 - 01ARZ3NDEKTSV4RRFFQ69G5FC2 properties: data: type: array example: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAA name: 'Cabinet A1' status: active total_active_lockers: 10 total_available_lockers: 5 active_locker_ids: - 01ARZ3NDEKTSV4RRFFQ69G5FC1 - 01ARZ3NDEKTSV4RRFFQ69G5FC2 items: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAA name: type: string example: 'Cabinet A1' status: type: string example: active total_active_lockers: type: integer example: 10 total_available_lockers: type: integer example: 5 active_locker_ids: type: array example: - 01ARZ3NDEKTSV4RRFFQ69G5FC1 - 01ARZ3NDEKTSV4RRFFQ69G5FC2 items: type: string 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 403: description: '' content: application/json: schema: type: object example: message: 'This action is unauthorised.' properties: message: type: string example: 'This action is unauthorised.' tags: - Cabinets '/v1/cabinets/{id}': get: summary: 'Display the specified cabinet.' operationId: displayTheSpecifiedCabinet description: 'Returns detailed information about a specific cabinet.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: id: 01ARZ3NDEKTSV4RRFFQ69G5FAA name: 'Cabinet A1' status: active total_active_lockers: 10 total_available_lockers: 5 active_locker_ids: - 01ARZ3NDEKTSV4RRFFQ69G5FC1 - 01ARZ3NDEKTSV4RRFFQ69G5FC2 properties: data: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAA name: type: string example: 'Cabinet A1' status: type: string example: active total_active_lockers: type: integer example: 10 total_available_lockers: type: integer example: 5 active_locker_ids: type: array example: - 01ARZ3NDEKTSV4RRFFQ69G5FC1 - 01ARZ3NDEKTSV4RRFFQ69G5FC2 items: type: string 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 403: description: '' content: application/json: schema: type: object example: message: 'This action is unauthorised.' properties: message: type: string example: 'This action is unauthorised.' 404: description: '' content: application/json: schema: type: object example: message: 'Cabinet not found' properties: message: type: string example: 'Cabinet not found' tags: - Cabinets parameters: - in: path name: id description: 'The ID of the cabinet' example: 01ARZ3NDEKTSV4RRFFQ69G5FAA required: true schema: type: string '/v1/despatch-centres/{despatchCentreId}/collection-schedules': get: summary: 'Display a listing of collection schedules for a despatch centre.' operationId: displayAListingOfCollectionSchedulesForADespatchCentre description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAW despatch_centre_id: 01ARZ3NDEKTSV4RRFFQ69G5FAX name: 'Weekday Morning Collection' description: 'Standard weekday collection window' collection_start_time: '08:00:00' collection_end_time: '10:00:00' days_of_week: - 0 - 1 - 2 - 3 - 4 is_active: true properties: data: type: array example: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAW despatch_centre_id: 01ARZ3NDEKTSV4RRFFQ69G5FAX name: 'Weekday Morning Collection' description: 'Standard weekday collection window' collection_start_time: '08:00:00' collection_end_time: '10:00:00' days_of_week: - 0 - 1 - 2 - 3 - 4 is_active: true items: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAW despatch_centre_id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAX name: type: string example: 'Weekday Morning Collection' description: type: string example: 'Standard weekday collection window' collection_start_time: type: string example: '08:00:00' collection_end_time: type: string example: '10:00:00' days_of_week: type: array example: - 0 - 1 - 2 - 3 - 4 items: type: integer is_active: type: boolean example: true 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 403: description: '' content: application/json: schema: type: object example: message: 'This action is unauthorised.' properties: message: type: string example: 'This action is unauthorised.' 404: description: '' content: application/json: schema: type: object example: message: 'Despatch centre not found or does not belong to your account' properties: message: type: string example: 'Despatch centre not found or does not belong to your account' tags: - 'Collection Schedules' parameters: - in: path name: despatchCentreId description: 'The ID of the despatch centre' example: 01ARZ3NDEKTSV4RRFFQ69G5FAW required: true schema: type: string '/v1/despatch-centres/{despatchCentreId}/collection-schedules/{collectionScheduleId}': get: summary: 'Display the specified collection schedule.' operationId: displayTheSpecifiedCollectionSchedule description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: id: 01ARZ3NDEKTSV4RRFFQ69G5FAX despatch_centre_id: 01ARZ3NDEKTSV4RRFFQ69G5FAW name: 'Weekday Morning Collection' description: 'Standard weekday collection window' collection_start_time: '08:00:00' collection_end_time: '10:00:00' days_of_week: - 0 - 1 - 2 - 3 - 4 effective_from: '2025-01-01T00:00:00Z' effective_until: null is_active: true properties: data: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAX despatch_centre_id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAW name: type: string example: 'Weekday Morning Collection' description: type: string example: 'Standard weekday collection window' collection_start_time: type: string example: '08:00:00' collection_end_time: type: string example: '10:00:00' days_of_week: type: array example: - 0 - 1 - 2 - 3 - 4 items: type: integer effective_from: type: string example: '2025-01-01T00:00:00Z' effective_until: type: string example: null nullable: true is_active: type: boolean example: true 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 403: description: '' content: application/json: schema: type: object example: message: 'This action is unauthorised.' properties: message: type: string example: 'This action is unauthorised.' 404: description: '' content: application/json: schema: type: object example: message: 'Collection schedule not found' properties: message: type: string example: 'Collection schedule not found' tags: - 'Collection Schedules' parameters: - in: path name: despatchCentreId description: 'The ID of the despatch centre' example: 01ARZ3NDEKTSV4RRFFQ69G5FAW required: true schema: type: string - in: path name: collectionScheduleId description: 'The ID of the collection schedule' example: 01ARZ3NDEKTSV4RRFFQ69G5FAX required: true schema: type: string /v1/despatch-centres: get: summary: 'Display a listing of despatch centres.' operationId: displayAListingOfDespatchCentres description: 'Returns a paginated list of despatch centres for the current account.' parameters: - in: query name: per_page description: 'Number of items per page (max 100)' example: 20 required: false schema: type: integer description: 'Number of items per page (max 100)' example: 20 - in: query name: page description: 'Page number' example: 1 required: false schema: type: integer description: 'Page number' example: 1 responses: 200: description: '' content: application/json: schema: type: object example: data: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAW account_id: 01ARZ3NDEKTSV4RRFFQ69G5FAX name: 'Main Warehouse' description: 'Primary despatch centre' address_id: 01ARZ3NDEKTSV4RRFFQ69G5FAY address: id: 01ARZ3NDEKTSV4RRFFQ69G5FAY line_1: '123 Industrial Way' line_2: null city: London postcode: 'SW1A 1AA' latitude: 51.5074 longitude: -0.1278 access_instructions: 'Enter through main gate' special_instructions: null contact_phone: '+44 20 1234 5678' contact_email: warehouse@example.com is_active: true pagination: current_page: 1 per_page: 50 total: 10 last_page: 1 properties: data: type: array example: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAW account_id: 01ARZ3NDEKTSV4RRFFQ69G5FAX name: 'Main Warehouse' description: 'Primary despatch centre' address_id: 01ARZ3NDEKTSV4RRFFQ69G5FAY address: id: 01ARZ3NDEKTSV4RRFFQ69G5FAY line_1: '123 Industrial Way' line_2: null city: London postcode: 'SW1A 1AA' latitude: 51.5074 longitude: -0.1278 access_instructions: 'Enter through main gate' special_instructions: null contact_phone: '+44 20 1234 5678' contact_email: warehouse@example.com is_active: true items: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAW account_id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAX name: type: string example: 'Main Warehouse' description: type: string example: 'Primary despatch centre' address_id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAY address: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAY line_1: type: string example: '123 Industrial Way' line_2: type: string example: null nullable: true city: type: string example: London postcode: type: string example: 'SW1A 1AA' latitude: type: number example: 51.5074 longitude: type: number example: -0.1278 access_instructions: type: string example: 'Enter through main gate' special_instructions: type: string example: null nullable: true contact_phone: type: string example: '+44 20 1234 5678' contact_email: type: string example: warehouse@example.com is_active: type: boolean example: true pagination: type: object properties: current_page: type: integer example: 1 per_page: type: integer example: 50 total: type: integer example: 10 last_page: type: integer example: 1 400: description: '' content: application/json: schema: type: object example: message: 'No account context set' properties: message: type: string example: 'No account context set' 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 403: description: '' content: application/json: schema: type: object example: message: 'This action is unauthorised.' properties: message: type: string example: 'This action is unauthorised.' tags: - 'Despatch Centres' '/v1/despatch-centres/{id}': get: summary: 'Display the specified despatch centre.' operationId: displayTheSpecifiedDespatchCentre description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: id: 01ARZ3NDEKTSV4RRFFQ69G5FAW account_id: 01ARZ3NDEKTSV4RRFFQ69G5FAX name: 'Main Warehouse' description: 'Primary despatch centre' address_id: 01ARZ3NDEKTSV4RRFFQ69G5FAY address: id: 01ARZ3NDEKTSV4RRFFQ69G5FAY line_1: '123 Industrial Way' line_2: null city: London postcode: 'SW1A 1AA' latitude: 51.5074 longitude: -0.1278 access_instructions: 'Enter through main gate' is_active: true properties: data: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAW account_id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAX name: type: string example: 'Main Warehouse' description: type: string example: 'Primary despatch centre' address_id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAY address: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAY line_1: type: string example: '123 Industrial Way' line_2: type: string example: null nullable: true city: type: string example: London postcode: type: string example: 'SW1A 1AA' latitude: type: number example: 51.5074 longitude: type: number example: -0.1278 access_instructions: type: string example: 'Enter through main gate' is_active: type: boolean example: true 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 403: description: '' content: application/json: schema: type: object example: message: 'This action is unauthorised.' properties: message: type: string example: 'This action is unauthorised.' 404: description: '' content: application/json: schema: type: object example: message: 'Despatch centre not found' properties: message: type: string example: 'Despatch centre not found' tags: - 'Despatch Centres' parameters: - in: path name: id description: 'The ID of the despatch centre' example: 01ARZ3NDEKTSV4RRFFQ69G5FAW required: true schema: type: string '/v1/labels/{id}/zpl': get: summary: 'Get ZPL label data by label ID.' operationId: getZPLLabelDataByLabelID description: "Returns the ZPL (Zebra Programming Language) data for a specific label.\nThe label must belong to a booking in the current account context." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: label: '^XA^FO50,50^FDTest ZPL Label^FS^XZ' properties: label: type: string example: '^XA^FO50,50^FDTest ZPL Label^FS^XZ' 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 403: description: '' content: application/json: schema: type: object example: message: 'This action is unauthorised.' properties: message: type: string example: 'This action is unauthorised.' 404: description: '' content: application/json: schema: oneOf: - description: '' type: object example: message: 'Label not found' properties: message: type: string example: 'Label not found' - description: '' type: object example: message: 'ZPL data not available for this label' properties: message: type: string example: 'ZPL data not available for this label' tags: - Labels parameters: - in: path name: id description: 'The ID of the label' example: '1111111119' required: true schema: type: string '/v1/labels/{id}/pdf': get: summary: 'Get PDF label data by label ID.' operationId: getPDFLabelDataByLabelID description: "Returns the PDF binary data for a specific label.\nThe label must belong to a booking in the current account context." parameters: [] responses: 200: description: 'PDF binary data with Content-Type: application/pdf' content: application/json: schema: type: object nullable: true 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 403: description: '' content: application/json: schema: type: object example: message: 'This action is unauthorised.' properties: message: type: string example: 'This action is unauthorised.' 404: description: '' content: application/json: schema: oneOf: - description: '' type: object example: message: 'Label not found' properties: message: type: string example: 'Label not found' - description: '' type: object example: message: 'PDF data not available for this label' properties: message: type: string example: 'PDF data not available for this label' tags: - Labels parameters: - in: path name: id description: 'The ID of the label' example: '1111111119' required: true schema: type: string '/v1/labels/{id}/png': get: summary: 'Get PNG label data by label ID.' operationId: getPNGLabelDataByLabelID description: "Returns the PNG binary data for a specific label.\nThe label must belong to a booking in the current account context." parameters: [] responses: 200: description: 'PNG binary data with Content-Type: image/png' content: application/json: schema: type: object nullable: true 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 403: description: '' content: application/json: schema: type: object example: message: 'This action is unauthorised.' properties: message: type: string example: 'This action is unauthorised.' 404: description: '' content: application/json: schema: oneOf: - description: '' type: object example: message: 'Label not found' properties: message: type: string example: 'Label not found' - description: '' type: object example: message: 'PNG data not available for this label' properties: message: type: string example: 'PNG data not available for this label' tags: - Labels parameters: - in: path name: id description: 'The ID of the label' example: '1111111119' required: true schema: type: string /v1/reverse-flows: get: summary: 'Display a listing of reverse flow strategies.' operationId: displayAListingOfReverseFlowStrategies description: "Returns a paginated list of reverse flow strategies available to the current account context.\nReverse flow strategies define how items should be handled when they cannot be delivered\nor collected from lockers." parameters: - in: query name: per_page description: 'Number of items per page (max 100)' example: 20 required: false schema: type: integer description: 'Number of items per page (max 100)' example: 20 - in: query name: page description: 'Page number' example: 1 required: false schema: type: integer description: 'Page number' example: 1 responses: 200: description: '' content: application/json: schema: type: object example: data: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAX name: return_to_sender description: 'Return to Sender' is_active: true is_default: true - id: 01ARZ3NDEKTSV4RRFFQ69G5FAY name: hold_at_sort description: 'Hold at Sort Centre' is_active: true is_default: false - id: 01ARZ3NDEKTSV4RRFFQ69G5FAZ name: allow_redelivery description: 'Allow Redelivery' is_active: true is_default: false pagination: current_page: 1 per_page: 20 total: 3 last_page: 1 from: 1 to: 3 has_more_pages: false links: first: 'http://example.com/api/v1/reverse-flows?page=1' last: 'http://example.com/api/v1/reverse-flows?page=1' prev: null next: null properties: data: type: array example: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAX name: return_to_sender description: 'Return to Sender' is_active: true is_default: true - id: 01ARZ3NDEKTSV4RRFFQ69G5FAY name: hold_at_sort description: 'Hold at Sort Centre' is_active: true is_default: false - id: 01ARZ3NDEKTSV4RRFFQ69G5FAZ name: allow_redelivery description: 'Allow Redelivery' is_active: true is_default: false items: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAX name: type: string example: return_to_sender description: type: string example: 'Return to Sender' is_active: type: boolean example: true is_default: type: boolean example: true pagination: type: object properties: current_page: type: integer example: 1 per_page: type: integer example: 20 total: type: integer example: 3 last_page: type: integer example: 1 from: type: integer example: 1 to: type: integer example: 3 has_more_pages: type: boolean example: false links: type: object properties: first: type: string example: 'http://example.com/api/v1/reverse-flows?page=1' last: type: string example: 'http://example.com/api/v1/reverse-flows?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true 400: description: '' content: application/json: schema: type: object example: message: 'No account context set' properties: message: type: string example: 'No account context set' 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 403: description: '' content: application/json: schema: type: object example: message: 'This action is unauthorised.' properties: message: type: string example: 'This action is unauthorised.' tags: - 'Reverse Flows' /v1/service-products: get: summary: 'Display a listing of service products.' operationId: displayAListingOfServiceProducts description: "Returns a paginated list of service products available to the current account context.\nService products define the types of booking services that can be used." parameters: - in: query name: per_page description: 'Number of items per page (max 100)' example: 20 required: false schema: type: integer description: 'Number of items per page (max 100)' example: 20 - in: query name: page description: 'Page number' example: 1 required: false schema: type: integer description: 'Page number' example: 1 responses: 200: description: '' content: application/json: schema: type: object example: data: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAZ name: direct_locker_delivery description: 'Bookings are collected from a despatch centre and delivered directly to a locker' requires_collection: true requires_delivery: true requires_locker: true requires_sorting_hub: false is_active: true is_default: true - id: 01ARZ3NDEKTSV4RRFFQ69G5FAY name: sorted_locker_delivery description: 'Bookings are collected from a despatch centre, taken to our sort centre and then delivered to a locker optimally' requires_collection: true requires_delivery: true requires_locker: true requires_sorting_hub: true is_active: true is_default: false pagination: current_page: 1 per_page: 20 total: 2 last_page: 1 from: 1 to: 2 has_more_pages: false links: first: 'http://example.com/api/v1/service-products?page=1' last: 'http://example.com/api/v1/service-products?page=1' prev: null next: null properties: data: type: array example: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAZ name: direct_locker_delivery description: 'Bookings are collected from a despatch centre and delivered directly to a locker' requires_collection: true requires_delivery: true requires_locker: true requires_sorting_hub: false is_active: true is_default: true - id: 01ARZ3NDEKTSV4RRFFQ69G5FAY name: sorted_locker_delivery description: 'Bookings are collected from a despatch centre, taken to our sort centre and then delivered to a locker optimally' requires_collection: true requires_delivery: true requires_locker: true requires_sorting_hub: true is_active: true is_default: false items: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAZ name: type: string example: direct_locker_delivery description: type: string example: 'Bookings are collected from a despatch centre and delivered directly to a locker' requires_collection: type: boolean example: true requires_delivery: type: boolean example: true requires_locker: type: boolean example: true requires_sorting_hub: type: boolean example: false is_active: type: boolean example: true is_default: type: boolean example: true pagination: type: object properties: current_page: type: integer example: 1 per_page: type: integer example: 20 total: type: integer example: 2 last_page: type: integer example: 1 from: type: integer example: 1 to: type: integer example: 2 has_more_pages: type: boolean example: false links: type: object properties: first: type: string example: 'http://example.com/api/v1/service-products?page=1' last: type: string example: 'http://example.com/api/v1/service-products?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true 400: description: '' content: application/json: schema: type: object example: message: 'No account context set' properties: message: type: string example: 'No account context set' 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 403: description: '' content: application/json: schema: type: object example: message: 'This action is unauthorised.' properties: message: type: string example: 'This action is unauthorised.' tags: - 'Service Products' /v1/serviceable-postcodes: get: summary: 'List all serviceable postcode prefixes.' operationId: listAllServiceablePostcodePrefixes description: 'Returns a unique list of postcode prefixes mapped to active zones.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: - E1 - N1 - SW1 - SE1 properties: data: type: array example: - E1 - N1 - SW1 - SE1 items: type: string 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Serviceability /v1/sites: get: summary: 'Display a listing of sites with search and pagination.' operationId: displayAListingOfSitesWithSearchAndPagination description: "Returns a paginated list of active sites. Supports location-based filtering\nto find sites within a specified radius of coordinates." parameters: - in: query name: latitude description: 'Latitude for location-based search (must include longitude and radius)' example: 51.5074 required: false schema: type: number description: 'Latitude for location-based search (must include longitude and radius)' example: 51.5074 - in: query name: longitude description: 'Longitude for location-based search (must include latitude and radius)' example: -0.1278 required: false schema: type: number description: 'Longitude for location-based search (must include latitude and radius)' example: -0.1278 - in: query name: radius description: 'Radius in kilometers for location-based search (must include latitude and longitude, or postcode when enabled)' example: 10 required: false schema: type: number description: 'Radius in kilometers for location-based search (must include latitude and longitude, or postcode when enabled)' example: 10 - in: query name: postcode description: 'Postcode for location-based search (this may incur extra usage fees when enabled)' example: 'SW1A 1AA' required: false schema: type: string description: 'Postcode for location-based search (this may incur extra usage fees when enabled)' example: 'SW1A 1AA' - in: query name: per_page description: 'Number of items per page (max 100)' example: 20 required: false schema: type: integer description: 'Number of items per page (max 100)' example: 20 - in: query name: page description: 'Page number' example: 1 required: false schema: type: integer description: 'Page number' example: 1 responses: 200: description: '' content: application/json: schema: type: object example: data: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAW name: 'Downtown Location' address: recipient: null line_1: '123 Main St' line_2: null line_3: 'Greater London' city: London postcode: 'SW1A 1AA' country: 'United Kingdom' contact_phone: null contact_email: null special_instructions: null latitude: 51.5074 longitude: -0.1278 latitude: 51.5074 longitude: -0.1278 access_instructions: 'Enter through main entrance' height_restriction: 2.5 is_active: true distance: km: 2.5 mi: 1.55 site_access_codes: - name: 'Customer access code 1' code: AB12CD34 pagination: current_page: 1 per_page: 50 total: 25 last_page: 1 from: 1 to: 25 has_more_pages: false links: first: 'http://example.com/api/v1/sites?page=1' last: 'http://example.com/api/v1/sites?page=1' prev: null next: null properties: data: type: array example: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAW name: 'Downtown Location' address: recipient: null line_1: '123 Main St' line_2: null line_3: 'Greater London' city: London postcode: 'SW1A 1AA' country: 'United Kingdom' contact_phone: null contact_email: null special_instructions: null latitude: 51.5074 longitude: -0.1278 latitude: 51.5074 longitude: -0.1278 access_instructions: 'Enter through main entrance' height_restriction: 2.5 is_active: true distance: km: 2.5 mi: 1.55 site_access_codes: - name: 'Customer access code 1' code: AB12CD34 items: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAW name: type: string example: 'Downtown Location' address: type: object properties: recipient: type: string example: null nullable: true line_1: type: string example: '123 Main St' line_2: type: string example: null nullable: true line_3: type: string example: 'Greater London' city: type: string example: London postcode: type: string example: 'SW1A 1AA' country: type: string example: 'United Kingdom' contact_phone: type: string example: null nullable: true contact_email: type: string example: null nullable: true special_instructions: type: string example: null nullable: true latitude: type: number example: 51.5074 longitude: type: number example: -0.1278 latitude: type: number example: 51.5074 longitude: type: number example: -0.1278 access_instructions: type: string example: 'Enter through main entrance' height_restriction: type: number example: 2.5 is_active: type: boolean example: true distance: type: object properties: km: type: number example: 2.5 mi: type: number example: 1.55 site_access_codes: type: array example: - name: 'Customer access code 1' code: AB12CD34 items: type: object properties: name: type: string example: 'Customer access code 1' code: type: string example: AB12CD34 pagination: type: object properties: current_page: type: integer example: 1 per_page: type: integer example: 50 total: type: integer example: 25 last_page: type: integer example: 1 from: type: integer example: 1 to: type: integer example: 25 has_more_pages: type: boolean example: false links: type: object properties: first: type: string example: 'http://example.com/api/v1/sites?page=1' last: type: string example: 'http://example.com/api/v1/sites?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 403: description: '' content: application/json: schema: type: object example: message: 'This action is unauthorised.' properties: message: type: string example: 'This action is unauthorised.' tags: - Sites '/v1/sites/{id}': get: summary: 'Display the specified site.' operationId: displayTheSpecifiedSite description: 'Returns detailed information about a specific site.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: id: 01ARZ3NDEKTSV4RRFFQ69G5FAW name: 'Downtown Location' address: recipient: null line_1: '123 Main St' line_2: null line_3: 'Greater London' city: London postcode: 'SW1A 1AA' country: 'United Kingdom' contact_phone: null contact_email: null email: null special_instructions: null latitude: 51.5074 longitude: -0.1278 latitude: 51.5074 longitude: -0.1278 access_instructions: 'Enter through main entrance' height_restriction: 2.5 is_active: true site_access_codes: - name: 'Customer access code 1' code: AB12CD34 properties: data: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAW name: type: string example: 'Downtown Location' address: type: object properties: recipient: type: string example: null nullable: true line_1: type: string example: '123 Main St' line_2: type: string example: null nullable: true line_3: type: string example: 'Greater London' city: type: string example: London postcode: type: string example: 'SW1A 1AA' country: type: string example: 'United Kingdom' contact_phone: type: string example: null nullable: true contact_email: type: string example: null nullable: true email: type: string example: null nullable: true special_instructions: type: string example: null nullable: true latitude: type: number example: 51.5074 longitude: type: number example: -0.1278 latitude: type: number example: 51.5074 longitude: type: number example: -0.1278 access_instructions: type: string example: 'Enter through main entrance' height_restriction: type: number example: 2.5 is_active: type: boolean example: true site_access_codes: type: array example: - name: 'Customer access code 1' code: AB12CD34 items: type: object properties: name: type: string example: 'Customer access code 1' code: type: string example: AB12CD34 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 403: description: '' content: application/json: schema: type: object example: message: 'This action is unauthorised.' properties: message: type: string example: 'This action is unauthorised.' 404: description: '' content: application/json: schema: type: object example: message: 'Site not found' properties: message: type: string example: 'Site not found' tags: - Sites parameters: - in: path name: id description: 'The ID of the site' example: 01ARZ3NDEKTSV4RRFFQ69G5FAW required: true schema: type: string /v1/tokens/generate: post: summary: 'Generate API token for account.' operationId: generateAPITokenForAccount description: "Creates a new API token for the authenticated user in the current account context.\nRequires Admin or Owner role in the current account." parameters: [] responses: 201: description: '' content: application/json: schema: type: object example: token: 1|abcdefghijklmnopqrstuvwxyz1234567890 token_name: 'Production API Token' account_id: 01ARZ3NDEKTSV4RRFFQ69G5FAW abilities: - '*' expires_at: '2025-12-31T23:59:59.000000Z' created_at: '2025-01-01T00:00:00.000000Z' message: 'API token generated successfully' properties: token: type: string example: 1|abcdefghijklmnopqrstuvwxyz1234567890 token_name: type: string example: 'Production API Token' account_id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAW abilities: type: array example: - '*' items: type: string expires_at: type: string example: '2025-12-31T23:59:59.000000Z' created_at: type: string example: '2025-01-01T00:00:00.000000Z' message: type: string example: 'API token generated successfully' 400: description: '' content: application/json: schema: type: object example: message: 'No account context set' properties: message: type: string example: 'No account context set' 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 403: description: '' content: application/json: schema: type: object example: message: 'This action is unauthorised.' properties: message: type: string example: 'This action is unauthorised.' 422: description: '' content: application/json: schema: type: object example: message: 'The given data was invalid.' errors: token_name: - 'The token name field is required.' expires_at: - 'The expires at must be a date after now.' properties: message: type: string example: 'The given data was invalid.' errors: type: object properties: token_name: type: array example: - 'The token name field is required.' items: type: string expires_at: type: array example: - 'The expires at must be a date after now.' items: type: string tags: - 'Token Management' requestBody: required: true content: application/json: schema: type: object properties: token_name: type: string description: 'Name for the token' example: 'Production API Token' expires_at: type: string description: 'Expiration date and time (ISO 8601). Must be in the future' example: '2025-12-31T23:59:59Z' required: - token_name /v1/tokens: get: summary: 'List API tokens for account.' operationId: listAPITokensForAccount description: "Returns all API tokens for the authenticated user in the current account context.\nRequires Admin or Owner role in the current account." parameters: - in: query name: search description: 'Search tokens by name' example: Production required: false schema: type: string description: 'Search tokens by name' example: Production responses: 200: description: '' content: application/json: schema: type: object example: tokens: - id: 1 name: 'Production API Token' abilities: - '*' last_used_at: '2025-01-15T10:30:00.000000Z' created_at: '2025-01-01T00:00:00.000000Z' expires_at: '2025-12-31T23:59:59.000000Z' account_id: 01ARZ3NDEKTSV4RRFFQ69G5FAW total: 1 properties: tokens: type: array example: - id: 1 name: 'Production API Token' abilities: - '*' last_used_at: '2025-01-15T10:30:00.000000Z' created_at: '2025-01-01T00:00:00.000000Z' expires_at: '2025-12-31T23:59:59.000000Z' items: type: object properties: id: type: integer example: 1 name: type: string example: 'Production API Token' abilities: type: array example: - '*' items: type: string last_used_at: type: string example: '2025-01-15T10:30:00.000000Z' created_at: type: string example: '2025-01-01T00:00:00.000000Z' expires_at: type: string example: '2025-12-31T23:59:59.000000Z' account_id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAW total: type: integer example: 1 400: description: '' content: application/json: schema: type: object example: message: 'No account context set' properties: message: type: string example: 'No account context set' 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 403: description: '' content: application/json: schema: type: object example: message: 'This action is unauthorised.' properties: message: type: string example: 'This action is unauthorised.' tags: - 'Token Management' delete: summary: 'Revoke all API tokens for account.' operationId: revokeAllAPITokensForAccount description: "Revokes all API tokens for the authenticated user in the current account context.\nRequires Admin or Owner role in the current account." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: message: 'All API tokens revoked successfully' deleted_count: 5 properties: message: type: string example: 'All API tokens revoked successfully' deleted_count: type: integer example: 5 400: description: '' content: application/json: schema: type: object example: message: 'No account context set' properties: message: type: string example: 'No account context set' 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 403: description: '' content: application/json: schema: type: object example: message: 'This action is unauthorised.' properties: message: type: string example: 'This action is unauthorised.' tags: - 'Token Management' '/v1/tokens/{tokenId}': delete: summary: 'Revoke a specific API token.' operationId: revokeASpecificAPIToken description: 'Revokes a single API token by ID. Requires Admin or Owner role in the current account.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: message: 'API token revoked successfully' properties: message: type: string example: 'API token revoked successfully' 400: description: '' content: application/json: schema: type: object example: message: 'No account context set' properties: message: type: string example: 'No account context set' 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 403: description: '' content: application/json: schema: type: object example: message: 'This action is unauthorised.' properties: message: type: string example: 'This action is unauthorised.' 404: description: '' content: application/json: schema: type: object example: message: 'Token not found' properties: message: type: string example: 'Token not found' tags: - 'Token Management' parameters: - in: path name: tokenId description: 'The ID of the token to revoke' example: '1' required: true schema: type: string /v1/webhooks: get: summary: 'Display a listing of webhooks.' operationId: displayAListingOfWebhooks description: "Returns all webhooks for the authenticated user's account." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAW account_id: 01ARZ3NDEKTSV4RRFFQ69G5FAX name: 'Production Webhook' description: 'Webhook for production events' url: 'https://example.com/webhook' secret: whsec_... event_types: - booking.created - booking.cancelled is_active: true created_at: '2024-01-01T00:00:00.000000Z' updated_at: '2024-01-01T00:00:00.000000Z' properties: data: type: array example: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAW account_id: 01ARZ3NDEKTSV4RRFFQ69G5FAX name: 'Production Webhook' description: 'Webhook for production events' url: 'https://example.com/webhook' secret: whsec_... event_types: - booking.created - booking.cancelled is_active: true created_at: '2024-01-01T00:00:00.000000Z' updated_at: '2024-01-01T00:00:00.000000Z' items: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAW account_id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAX name: type: string example: 'Production Webhook' description: type: string example: 'Webhook for production events' url: type: string example: 'https://example.com/webhook' secret: type: string example: whsec_... event_types: type: array example: - booking.created - booking.cancelled items: type: string is_active: type: boolean example: true created_at: type: string example: '2024-01-01T00:00:00.000000Z' updated_at: type: string example: '2024-01-01T00:00:00.000000Z' 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 403: description: '' content: application/json: schema: type: object example: message: 'This action is unauthorised.' properties: message: type: string example: 'This action is unauthorised.' tags: - Webhooks post: summary: 'Create a new webhook.' operationId: createANewWebhook description: "Creates a webhook for the authenticated user's account. A unique secret will be generated automatically." parameters: [] responses: 201: description: '' content: application/json: schema: type: object example: data: id: 01ARZ3NDEKTSV4RRFFQ69G5FAW account_id: 01ARZ3NDEKTSV4RRFFQ69G5FAX name: 'Production Webhook' description: 'Webhook for production events' url: 'https://example.com/webhook' secret: whsec_... event_types: - booking.created - booking.cancelled is_active: true created_at: '2024-01-01T00:00:00.000000Z' updated_at: '2024-01-01T00:00:00.000000Z' properties: data: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAW account_id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAX name: type: string example: 'Production Webhook' description: type: string example: 'Webhook for production events' url: type: string example: 'https://example.com/webhook' secret: type: string example: whsec_... event_types: type: array example: - booking.created - booking.cancelled items: type: string is_active: type: boolean example: true created_at: type: string example: '2024-01-01T00:00:00.000000Z' updated_at: type: string example: '2024-01-01T00:00:00.000000Z' 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 403: description: '' content: application/json: schema: type: object example: message: 'This action is unauthorised.' properties: message: type: string example: 'This action is unauthorised.' 422: description: '' content: application/json: schema: type: object example: message: 'The given data was invalid.' properties: message: type: string example: 'The given data was invalid.' tags: - Webhooks requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'Name of the webhook' example: 'Production Webhook' description: type: string description: 'Description of the webhook' example: 'Webhook for production events' url: type: string description: 'URL to send webhook events' example: 'https://example.com/webhook' event_types: type: array description: 'Array of event types to subscribe to' example: - booking.created - booking.cancelled items: type: string headers: type: array description: 'Optional custom HTTP headers sent with each delivery' example: - name: Authorization value: 'Bearer sk_live_abc123' items: type: string is_active: type: boolean description: '' example: true nullable: true required: - name - url - event_types '/v1/webhooks/{id}': get: summary: 'Display the specified webhook.' operationId: displayTheSpecifiedWebhook description: 'Returns detailed information about a specific webhook.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: id: 01ARZ3NDEKTSV4RRFFQ69G5FAW account_id: 01ARZ3NDEKTSV4RRFFQ69G5FAX name: 'Production Webhook' description: 'Webhook for production events' url: 'https://example.com/webhook' secret: whsec_... event_types: - booking.created - booking.cancelled is_active: true created_at: '2024-01-01T00:00:00.000000Z' updated_at: '2024-01-01T00:00:00.000000Z' properties: data: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAW account_id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAX name: type: string example: 'Production Webhook' description: type: string example: 'Webhook for production events' url: type: string example: 'https://example.com/webhook' secret: type: string example: whsec_... event_types: type: array example: - booking.created - booking.cancelled items: type: string is_active: type: boolean example: true created_at: type: string example: '2024-01-01T00:00:00.000000Z' updated_at: type: string example: '2024-01-01T00:00:00.000000Z' 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 403: description: '' content: application/json: schema: type: object example: message: 'This action is unauthorised.' properties: message: type: string example: 'This action is unauthorised.' 404: description: '' content: application/json: schema: type: object example: message: 'Webhook not found' properties: message: type: string example: 'Webhook not found' tags: - Webhooks put: summary: 'Update the specified webhook.' operationId: updateTheSpecifiedWebhook description: "Updates a webhook's details." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: id: 01ARZ3NDEKTSV4RRFFQ69G5FAW account_id: 01ARZ3NDEKTSV4RRFFQ69G5FAX name: 'Updated Webhook' description: 'Updated description' url: 'https://example.com/webhook' secret: whsec_... event_types: - booking.created is_active: true created_at: '2024-01-01T00:00:00.000000Z' updated_at: '2024-01-01T00:00:00.000000Z' properties: data: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAW account_id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAX name: type: string example: 'Updated Webhook' description: type: string example: 'Updated description' url: type: string example: 'https://example.com/webhook' secret: type: string example: whsec_... event_types: type: array example: - booking.created items: type: string is_active: type: boolean example: true created_at: type: string example: '2024-01-01T00:00:00.000000Z' updated_at: type: string example: '2024-01-01T00:00:00.000000Z' 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 403: description: '' content: application/json: schema: type: object example: message: 'This action is unauthorised.' properties: message: type: string example: 'This action is unauthorised.' 404: description: '' content: application/json: schema: type: object example: message: 'Webhook not found' properties: message: type: string example: 'Webhook not found' 422: description: '' content: application/json: schema: type: object example: message: 'The given data was invalid.' properties: message: type: string example: 'The given data was invalid.' tags: - Webhooks requestBody: required: false content: application/json: schema: type: object properties: name: type: string description: 'Name of the webhook' example: 'Updated Webhook' description: type: string description: 'Description of the webhook' example: 'Updated description' url: type: string description: 'URL to send webhook events' example: 'https://example.com/webhook' event_types: type: array description: 'Array of event types to subscribe to' example: - booking.created items: type: string headers: type: array description: 'Custom HTTP headers sent with each delivery' example: - name: X-API-Key value: my-key items: type: string is_active: type: boolean description: 'Whether the webhook is active' example: true delete: summary: 'Delete the specified webhook.' operationId: deleteTheSpecifiedWebhook description: 'Permanently deletes a webhook.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: message: 'Webhook deleted successfully' properties: message: type: string example: 'Webhook deleted successfully' 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 403: description: '' content: application/json: schema: type: object example: message: 'This action is unauthorised.' properties: message: type: string example: 'This action is unauthorised.' 404: description: '' content: application/json: schema: type: object example: message: 'Webhook not found' properties: message: type: string example: 'Webhook not found' tags: - Webhooks parameters: - in: path name: id description: 'The ID of the webhook.' example: architecto required: true schema: type: string - in: path name: webhook description: 'The ID of the webhook' example: 01ARZ3NDEKTSV4RRFFQ69G5FAW required: true schema: type: string