> ## Documentation Index
> Fetch the complete documentation index at: https://docs.now-os.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a reservation

> One reservation, keyed by YOUR `externalId`. Re-creating an existing id is a 409 — updates go through PUT. A `seated` status with `tableIds` is a seat instruction: the till opens the order and you receive `table.seated` as confirmation (or `reservation.seat_rejected`).



## OpenAPI

````yaml /api-reference/openapi.json post /api/provider/v1/reservations
openapi: 3.1.0
info:
  title: NowOS Reservations Provider API
  version: 1.0.0
  description: >-
    Integration surface for reservation providers (EatNow is the reference
    implementation). Read the published floor plan, write reservations keyed by
    your own ids, push a one-shot floor plan import, and consume signed webhooks
    for table lifecycle and spend. Every error body is `{ "error": { "code",
    "message", "occupiedBy" } }` — branch on `code` only.
servers:
  - url: https://api.now-os.app
security:
  - providerApiKey: []
paths:
  /api/provider/v1/reservations:
    post:
      summary: Create a reservation
      description: >-
        One reservation, keyed by YOUR `externalId`. Re-creating an existing id
        is a 409 — updates go through PUT. A `seated` status with `tableIds` is
        a seat instruction: the till opens the order and you receive
        `table.seated` as confirmation (or `reservation.seat_rejected`).
      operationId: createReservation
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $schema: https://json-schema.org/draft/2020-12/schema
              type: object
              properties:
                externalId:
                  type: string
                  minLength: 1
                  maxLength: 128
                status:
                  type: string
                  enum:
                    - booked
                    - confirmed
                    - arrived
                    - seated
                    - finished
                    - no_show
                    - cancelled
                partyName:
                  default: null
                  anyOf:
                    - type: string
                      minLength: 1
                      maxLength: 120
                    - type: 'null'
                covers:
                  type: integer
                  exclusiveMinimum: 0
                  maximum: 2147483647
                startsAt:
                  type: string
                  format: date-time
                  pattern: >-
                    ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
                endsAt:
                  default: null
                  anyOf:
                    - type: string
                      format: date-time
                      pattern: >-
                        ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
                    - type: 'null'
                tableIds:
                  default: []
                  maxItems: 20
                  type: array
                  items:
                    type: string
                    minLength: 1
                guest:
                  default: null
                  anyOf:
                    - type: object
                      properties:
                        name:
                          default: null
                          anyOf:
                            - type: string
                              minLength: 1
                              maxLength: 120
                            - type: 'null'
                        phone:
                          default: null
                          anyOf:
                            - type: string
                              minLength: 1
                              maxLength: 40
                            - type: 'null'
                        email:
                          default: null
                          anyOf:
                            - type: string
                              minLength: 1
                              maxLength: 254
                            - type: 'null'
                        vip:
                          default: false
                          type: boolean
                        firstVisit:
                          default: false
                          type: boolean
                        visitCount:
                          default: null
                          anyOf:
                            - type: integer
                              minimum: 0
                              maximum: 2147483647
                            - type: 'null'
                        occasion:
                          default: null
                          anyOf:
                            - type: string
                              minLength: 1
                              maxLength: 120
                            - type: 'null'
                        allergies:
                          default: null
                          anyOf:
                            - type: string
                              minLength: 1
                              maxLength: 500
                            - type: 'null'
                        tags:
                          default: []
                          maxItems: 20
                          type: array
                          items:
                            type: string
                            minLength: 1
                            maxLength: 40
                        memberSince:
                          default: null
                          anyOf:
                            - type: string
                              format: date-time
                              pattern: >-
                                ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
                            - type: 'null'
                        averageSpendMinor:
                          default: null
                          anyOf:
                            - type: integer
                              minimum: 0
                              maximum: 2147483647
                            - type: 'null'
                        noShowCount:
                          default: null
                          anyOf:
                            - type: integer
                              minimum: 0
                              maximum: 2147483647
                            - type: 'null'
                        recentVisits:
                          default: []
                          maxItems: 20
                          type: array
                          items:
                            type: object
                            properties:
                              occurredAt:
                                type: string
                                format: date-time
                                pattern: >-
                                  ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
                              tableLabel:
                                default: null
                                anyOf:
                                  - type: string
                                    minLength: 1
                                    maxLength: 40
                                  - type: 'null'
                              covers:
                                default: null
                                anyOf:
                                  - type: integer
                                    exclusiveMinimum: 0
                                    maximum: 2147483647
                                  - type: 'null'
                              spendMinor:
                                default: null
                                anyOf:
                                  - type: integer
                                    minimum: 0
                                    maximum: 2147483647
                                  - type: 'null'
                              outcome:
                                type: string
                                enum:
                                  - completed
                                  - in_progress
                                  - no_show
                            required:
                              - occurredAt
                              - outcome
                    - type: 'null'
                internalNote:
                  default: null
                  anyOf:
                    - type: string
                      minLength: 1
                      maxLength: 500
                    - type: 'null'
                prepayment:
                  default: null
                  anyOf:
                    - type: object
                      properties:
                        prepaidMinor:
                          type: integer
                          minimum: 0
                          maximum: 2147483647
                        currency:
                          type: string
                          minLength: 3
                          maxLength: 3
                        items:
                          default: []
                          maxItems: 50
                          type: array
                          items:
                            type: object
                            properties:
                              label:
                                type: string
                                minLength: 1
                                maxLength: 120
                              amountMinor:
                                type: integer
                                minimum: 0
                                maximum: 2147483647
                            required:
                              - label
                              - amountMinor
                        imprint:
                          default: null
                          anyOf:
                            - type: object
                              properties:
                                amountMinor:
                                  type: integer
                                  exclusiveMinimum: 0
                                  maximum: 2147483647
                                status:
                                  type: string
                                  enum:
                                    - active
                                    - released
                                    - charged
                              required:
                                - amountMinor
                                - status
                            - type: 'null'
                      required:
                        - prepaidMinor
                        - currency
                    - type: 'null'
                updatedAt:
                  type: string
                  format: date-time
                  pattern: >-
                    ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
              required:
                - externalId
                - status
                - covers
                - startsAt
                - updatedAt
      responses:
        '201':
          description: Created.
          content:
            application/json:
              schema:
                $schema: https://json-schema.org/draft/2020-12/schema
                type: object
                properties:
                  outcome:
                    type: string
                    enum:
                      - applied
                      - stale
                  reservation:
                    type: object
                    properties:
                      externalId:
                        type: string
                        minLength: 1
                        maxLength: 128
                      status:
                        type: string
                        enum:
                          - booked
                          - confirmed
                          - arrived
                          - seated
                          - finished
                          - no_show
                          - cancelled
                      partyName:
                        default: null
                        anyOf:
                          - type: string
                            minLength: 1
                            maxLength: 120
                          - type: 'null'
                      covers:
                        type: integer
                        exclusiveMinimum: 0
                        maximum: 2147483647
                      startsAt:
                        type: string
                        format: date-time
                        pattern: >-
                          ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
                      endsAt:
                        default: null
                        anyOf:
                          - type: string
                            format: date-time
                            pattern: >-
                              ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
                          - type: 'null'
                      tableIds:
                        default: []
                        maxItems: 20
                        type: array
                        items:
                          type: string
                          minLength: 1
                      guest:
                        default: null
                        anyOf:
                          - type: object
                            properties:
                              name:
                                default: null
                                anyOf:
                                  - type: string
                                    minLength: 1
                                    maxLength: 120
                                  - type: 'null'
                              phone:
                                default: null
                                anyOf:
                                  - type: string
                                    minLength: 1
                                    maxLength: 40
                                  - type: 'null'
                              email:
                                default: null
                                anyOf:
                                  - type: string
                                    minLength: 1
                                    maxLength: 254
                                  - type: 'null'
                              vip:
                                default: false
                                type: boolean
                              firstVisit:
                                default: false
                                type: boolean
                              visitCount:
                                default: null
                                anyOf:
                                  - type: integer
                                    minimum: 0
                                    maximum: 2147483647
                                  - type: 'null'
                              occasion:
                                default: null
                                anyOf:
                                  - type: string
                                    minLength: 1
                                    maxLength: 120
                                  - type: 'null'
                              allergies:
                                default: null
                                anyOf:
                                  - type: string
                                    minLength: 1
                                    maxLength: 500
                                  - type: 'null'
                              tags:
                                default: []
                                maxItems: 20
                                type: array
                                items:
                                  type: string
                                  minLength: 1
                                  maxLength: 40
                              memberSince:
                                default: null
                                anyOf:
                                  - type: string
                                    format: date-time
                                    pattern: >-
                                      ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
                                  - type: 'null'
                              averageSpendMinor:
                                default: null
                                anyOf:
                                  - type: integer
                                    minimum: 0
                                    maximum: 2147483647
                                  - type: 'null'
                              noShowCount:
                                default: null
                                anyOf:
                                  - type: integer
                                    minimum: 0
                                    maximum: 2147483647
                                  - type: 'null'
                              recentVisits:
                                default: []
                                maxItems: 20
                                type: array
                                items:
                                  type: object
                                  properties:
                                    occurredAt:
                                      type: string
                                      format: date-time
                                      pattern: >-
                                        ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
                                    tableLabel:
                                      default: null
                                      anyOf:
                                        - type: string
                                          minLength: 1
                                          maxLength: 40
                                        - type: 'null'
                                    covers:
                                      default: null
                                      anyOf:
                                        - type: integer
                                          exclusiveMinimum: 0
                                          maximum: 2147483647
                                        - type: 'null'
                                    spendMinor:
                                      default: null
                                      anyOf:
                                        - type: integer
                                          minimum: 0
                                          maximum: 2147483647
                                        - type: 'null'
                                    outcome:
                                      type: string
                                      enum:
                                        - completed
                                        - in_progress
                                        - no_show
                                  required:
                                    - occurredAt
                                    - tableLabel
                                    - covers
                                    - spendMinor
                                    - outcome
                                  additionalProperties: false
                            required:
                              - name
                              - phone
                              - email
                              - vip
                              - firstVisit
                              - visitCount
                              - occasion
                              - allergies
                              - tags
                              - memberSince
                              - averageSpendMinor
                              - noShowCount
                              - recentVisits
                            additionalProperties: false
                          - type: 'null'
                      internalNote:
                        default: null
                        anyOf:
                          - type: string
                            minLength: 1
                            maxLength: 500
                          - type: 'null'
                      prepayment:
                        default: null
                        anyOf:
                          - type: object
                            properties:
                              prepaidMinor:
                                type: integer
                                minimum: 0
                                maximum: 2147483647
                              currency:
                                type: string
                                minLength: 3
                                maxLength: 3
                              items:
                                default: []
                                maxItems: 50
                                type: array
                                items:
                                  type: object
                                  properties:
                                    label:
                                      type: string
                                      minLength: 1
                                      maxLength: 120
                                    amountMinor:
                                      type: integer
                                      minimum: 0
                                      maximum: 2147483647
                                  required:
                                    - label
                                    - amountMinor
                                  additionalProperties: false
                              imprint:
                                default: null
                                anyOf:
                                  - type: object
                                    properties:
                                      amountMinor:
                                        type: integer
                                        exclusiveMinimum: 0
                                        maximum: 2147483647
                                      status:
                                        type: string
                                        enum:
                                          - active
                                          - released
                                          - charged
                                    required:
                                      - amountMinor
                                      - status
                                    additionalProperties: false
                                  - type: 'null'
                            required:
                              - prepaidMinor
                              - currency
                              - items
                              - imprint
                            additionalProperties: false
                          - type: 'null'
                      updatedAt:
                        type: string
                        format: date-time
                        pattern: >-
                          ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
                      id:
                        type: string
                        minLength: 1
                      linkedOrderId:
                        default: null
                        anyOf:
                          - type: string
                            minLength: 1
                          - type: 'null'
                      arrivedAt:
                        default: null
                        anyOf:
                          - type: string
                            format: date-time
                            pattern: >-
                              ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
                          - type: 'null'
                      receivedAt:
                        type: string
                        format: date-time
                        pattern: >-
                          ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
                    required:
                      - externalId
                      - status
                      - partyName
                      - covers
                      - startsAt
                      - endsAt
                      - tableIds
                      - guest
                      - internalNote
                      - prepayment
                      - updatedAt
                      - id
                      - linkedOrderId
                      - arrivedAt
                      - receivedAt
                    additionalProperties: false
                required:
                  - outcome
                  - reservation
                additionalProperties: false
        '409':
          description: >-
            `duplicate_reservation`, or `table_occupied` on a seat targeting a
            taken table (with `occupiedBy`).
          content:
            application/json:
              schema:
                $schema: https://json-schema.org/draft/2020-12/schema
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        enum:
                          - unauthorized
                          - unknown_reservation
                          - duplicate_reservation
                          - unknown_table_id
                          - table_occupied
                          - floorplan_not_published
                          - draft_not_empty
                          - validation_failed
                      message:
                        type: string
                        minLength: 1
                      occupiedBy:
                        default: null
                        anyOf:
                          - type: object
                            properties:
                              orderId:
                                anyOf:
                                  - type: string
                                    minLength: 1
                                  - type: 'null'
                              reservationExternalId:
                                anyOf:
                                  - type: string
                                    minLength: 1
                                  - type: 'null'
                            required:
                              - orderId
                              - reservationExternalId
                            additionalProperties: false
                          - type: 'null'
                    required:
                      - code
                      - message
                      - occupiedBy
                    additionalProperties: false
                required:
                  - error
                additionalProperties: false
        '422':
          description: '`unknown_table_id` — fix your pos_table_id mapping.'
          content:
            application/json:
              schema:
                $schema: https://json-schema.org/draft/2020-12/schema
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        enum:
                          - unauthorized
                          - unknown_reservation
                          - duplicate_reservation
                          - unknown_table_id
                          - table_occupied
                          - floorplan_not_published
                          - draft_not_empty
                          - validation_failed
                      message:
                        type: string
                        minLength: 1
                      occupiedBy:
                        default: null
                        anyOf:
                          - type: object
                            properties:
                              orderId:
                                anyOf:
                                  - type: string
                                    minLength: 1
                                  - type: 'null'
                              reservationExternalId:
                                anyOf:
                                  - type: string
                                    minLength: 1
                                  - type: 'null'
                            required:
                              - orderId
                              - reservationExternalId
                            additionalProperties: false
                          - type: 'null'
                    required:
                      - code
                      - message
                      - occupiedBy
                    additionalProperties: false
                required:
                  - error
                additionalProperties: false
      security:
        - providerApiKey: []
components:
  securitySchemes:
    providerApiKey:
      type: http
      scheme: bearer
      description: >-
        Location-scoped API key (`nowos_sk_live_…`), issued at registration. The
        key identifies the location — URLs carry no location id.

````