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

# Create a reservation

> Creates a reservation using the same booking side effects as the standard booking flow. Partner v1 create supports deposit inference only. Explicit prepayment or extra-product selection is not supported. `external_id`, when provided, must be unique per restaurant and duplicate values return a conflict response. `customer` may be set to `null` to create an anonymous reservation with no linked customer, such as a walk-in. `bypass_availability` is available only to credentials with the `RESERVATIONS_FORCE_INSERT` scope and force-inserts the reservation without capacity validation. The same `RESERVATIONS_FORCE_INSERT` scope is also required when `initial_status` is provided to override the normal create-time status derivation for trusted operational integrations such as POS walk-ins. `bypass_approval` is available only to credentials with the `RESERVATIONS_FORCE_CONFIRM` scope and bypasses manual staff approval for shifts that would normally create pending reservations.



## OpenAPI

````yaml https://app.eat-now.io/api/partner/v1/openapi.json post /api/partner/v1/reservations
openapi: 3.0.3
info:
  title: EatNow Partner API
  version: v1
  description: >-
    Version 1 of the EatNow partner API.


    This API is designed for trusted partner integrations that need
    restaurant-scoped access to availability, reservation management, and
    operational reference data.


    Authentication

    - Use `Authorization: Bearer <token>` with a partner API token created from
    the EatNow dashboard.

    - Access is controlled by credential scopes and each request is resolved to
    a single restaurant.


    Base URL

    - The server URL in this document is the canonical base URL for the current
    environment.


    Errors

    - Errors follow a consistent envelope with `error.code`, `error.message`,
    and `error.request_id`.

    - Validation, authentication, authorization, conflicts, and not-found cases
    all use the same top-level error shape.


    Rate limits

    - Partner API traffic is rate limited. Clients should treat `429` responses
    as retryable and back off accordingly.


    Public endpoints

    - `GET /api/partner/v1` and `GET /api/partner/v1/openapi.json` are public.

    - All business endpoints require Bearer authentication.
servers:
  - url: https://app.eat-now.io
security: []
tags:
  - name: Meta
    description: Platform metadata and schema endpoints
  - name: Authentication
    description: Credential validation and auth context endpoints
  - name: Availability
    description: Bookable slot search and exact slot validation
  - name: Catalog
    description: Reference data for restaurant tables, rooms, prescribers, and discounts
  - name: Reservations
    description: Reservation lookup, search, update, and cancellation
  - name: Missed Calls
    description: Report missed calls and trigger WhatsApp follow-up templates
paths:
  /api/partner/v1/reservations:
    post:
      tags:
        - Reservations
      summary: Create a reservation
      description: >-
        Creates a reservation using the same booking side effects as the
        standard booking flow. Partner v1 create supports deposit inference
        only. Explicit prepayment or extra-product selection is not supported.
        `external_id`, when provided, must be unique per restaurant and
        duplicate values return a conflict response. `customer` may be set to
        `null` to create an anonymous reservation with no linked customer, such
        as a walk-in. `bypass_availability` is available only to credentials
        with the `RESERVATIONS_FORCE_INSERT` scope and force-inserts the
        reservation without capacity validation. The same
        `RESERVATIONS_FORCE_INSERT` scope is also required when `initial_status`
        is provided to override the normal create-time status derivation for
        trusted operational integrations such as POS walk-ins. `bypass_approval`
        is available only to credentials with the `RESERVATIONS_FORCE_CONFIRM`
        scope and bypasses manual staff approval for shifts that would normally
        create pending reservations.
      operationId: createPartnerReservation
      requestBody:
        required: true
        description: >-
          Reservation creation payload for standard bookings, force inserts, or
          operational walk-ins.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PartnerApiReservationCreateRequest'
            examples:
              depositFlow:
                summary: Create with inferred deposit
                value:
                  customer:
                    name: Jane Doe
                    email: jane@example.com
                    phone_number: '+33612345678'
                    lang: FR
                  party_size: 4
                  start_at: '2026-04-08T19:15:00+01:00'
                  shift_id: shift_dinner
                  external_id: partner-booking-123
                  source: WEBSITE
                  tags:
                    - vip
                  allergies: Peanuts
                  custom_message: Seat near the window
                  total_amount_paid: 12000
                  bypass_payments: false
                  bypass_availability: false
                  bypass_approval: false
                  send_client_notifications: true
                  send_payment_link: true
              bypassPayments:
                summary: Create while bypassing payments and customer notifications
                value:
                  customer:
                    name: John Smith
                    email: john@example.com
                  party_size: 2
                  start_at: '2026-04-08T20:00:00+01:00'
                  external_id: partner-booking-456
                  bypass_payments: true
                  bypass_availability: true
                  bypass_approval: true
                  send_client_notifications: false
                  send_payment_link: false
              posWalkIn:
                summary: Create an anonymous POS walk-in directly as seated
                value:
                  customer: null
                  party_size: 2
                  start_at: '2026-04-08T20:00:00+01:00'
                  source: WALK_IN
                  bypass_payments: true
                  bypass_approval: true
                  initial_status: SEATED
                  send_client_notifications: false
                  send_payment_link: false
      responses:
        '201':
          description: Reservation created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerApiReservationCreateResponse'
        '400':
          description: Request validation failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerApiError'
        '401':
          description: Authentication failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerApiError'
        '403':
          description: >-
            Scope is insufficient, including when bypass_availability or
            initial_status is requested without the RESERVATIONS_FORCE_INSERT
            scope, or bypass_approval is requested without the
            RESERVATIONS_FORCE_CONFIRM scope.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerApiError'
        '409':
          description: >-
            Conflict. The provided external_id is already used by another
            reservation in the same restaurant.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerApiError'
              examples:
                duplicateExternalId:
                  summary: Duplicate external_id
                  value:
                    error:
                      code: RESOURCE_CONFLICT
                      message: >-
                        external_id must be unique per restaurant and is already
                        in use
                      request_id: 7d8e6350-b815-4ac9-bfc3-57c6d2e7d8fa
        '422':
          description: >-
            Business-rule validation failed, for example when the slot is not
            bookable or the shift requires unsupported mandatory prepayment.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerApiError'
      security:
        - PartnerBearerToken: []
components:
  schemas:
    PartnerApiReservationCreateRequest:
      type: object
      properties:
        customer:
          type: object
          nullable: true
          properties:
            name:
              type: string
              minLength: 1
            email:
              type: string
              nullable: true
              format: email
              default: null
            phone_number:
              type: string
              nullable: true
              default: null
            lang:
              type: string
              enum:
                - FR
                - EN
                - IT
                - ES
                - DE
                - PT
            newsletter_consent:
              type: boolean
          required:
            - name
          additionalProperties: false
          description: >-
            Customer payload for the reservation. Use `null` to create an
            anonymous reservation with no linked customer, such as a walk-in.
        party_size:
          type: integer
          minimum: 1
        start_at:
          type: string
          format: date-time
          description: >-
            Reservation start datetime in the restaurant timezone, including
            offset.
        shift_id:
          type: string
          minLength: 1
          description: >-
            Optional shift identifier. When omitted, the system resolves the
            shift from `start_at`.
        room_id:
          type: string
          minLength: 1
          description: Optional room identifier to target during booking.
        table_ids:
          type: array
          items:
            type: string
            minLength: 1
          description: Optional table identifiers to assign at creation.
        waiter_id:
          type: string
          minLength: 1
        external_id:
          type: string
          minLength: 1
          description: >-
            Optional partner reference. When provided, it must be unique per
            restaurant.
        source:
          type: string
          enum:
            - WALK_IN
            - WEBSITE
            - PHONE
            - EMAIL
            - RESERVE_WITH_GOOGLE
            - TRAVEL_AGENCIES
            - OTHER
            - INSTAGRAM
            - FACEBOOK
            - TIKTOK
            - SNAPCHAT
            - WHATSAPP
            - TRIPADVISOR
            - PRIVATIZATION
            - MISSED_CALL
          description: Optional reservation source. Defaults to `WEBSITE`.
        prescriber_id:
          type: string
          minLength: 1
        discount_id:
          type: string
          minLength: 1
        tags:
          type: array
          items:
            type: string
        attached_files:
          type: array
          items:
            type: string
        metadata:
          type: object
          nullable: true
          additionalProperties:
            $ref: '#/components/schemas/PartnerApiMetadataField'
        allergies:
          type: string
          nullable: true
          description: Guest-facing note, such as allergies or special requests.
        custom_message:
          type: string
          nullable: true
          description: Internal staff note stored on the reservation.
        total_amount_paid:
          type: integer
          nullable: true
          minimum: 0
          description: >-
            Optional total amount already paid for the reservation, expressed in
            the smallest currency unit used by the restaurant, for example
            cents.
        bypass_payments:
          type: boolean
          default: false
          description: >-
            When true, no payment rows are created, even if the selected shift
            normally requires a deposit or mandatory prepayment.
        bypass_availability:
          type: boolean
          default: false
          description: >-
            When true, skips availability and capacity validation. This requires
            the `RESERVATIONS_FORCE_INSERT` scope and marks the reservation as
            force inserted.
        bypass_approval:
          type: boolean
          default: false
          description: >-
            When true, bypasses manual staff approval for shifts that normally
            create pending reservations. This requires the
            `RESERVATIONS_FORCE_CONFIRM` scope.
        initial_status:
          type: string
          enum:
            - PENDING
            - CONFIRMED
            - CONFIRMED_PENDING_PAYMENT
            - SHOWED_UP
            - SEATED
            - PARTIALLY_SEATED
            - SEATED_FOR_DRINKS
          description: >-
            Optional privileged create-time status override. When provided, this
            requires the `RESERVATIONS_FORCE_INSERT` scope and is validated
            against payment and manual-approval rules.
        send_client_notifications:
          type: boolean
          default: true
          description: >-
            When false, customer email and WhatsApp notifications are
            suppressed. Restaurant-side notifications still run.
        send_payment_link:
          type: boolean
          default: true
          description: >-
            Controls delayed payment-link delivery for created deposits. Ignored
            when payments are bypassed or no deposit is created.
      required:
        - customer
        - party_size
        - start_at
      additionalProperties: false
    PartnerApiReservationCreateResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/PartnerApiReservationDetail'
      required:
        - data
    PartnerApiError:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              $ref: '#/components/schemas/PartnerApiErrorCode'
            message:
              type: string
            request_id:
              type: string
            details:
              type: object
              additionalProperties:
                nullable: true
          required:
            - code
            - message
            - request_id
      required:
        - error
    PartnerApiMetadataField:
      type: object
      properties:
        name:
          type: string
        value:
          anyOf:
            - type: string
            - type: number
            - type: boolean
            - nullable: true
            - type: array
              items:
                type: string
      required:
        - name
        - value
    PartnerApiReservationDetail:
      type: object
      properties:
        id:
          type: string
        external_id:
          type: string
          nullable: true
        status:
          type: string
          enum:
            - PENDING
            - PENDING_PAYMENT
            - CANCELED_BY_USER
            - CONFIRMED
            - CONFIRMED_PENDING_PAYMENT
            - MANUALLY_CONFIRMED
            - DOUBLE_CONFIRMED
            - REJECTED
            - CANCELED_BY_RESTAURANT
            - SHOWED_UP
            - NO_SHOW
            - SEATED
            - PARTIALLY_SEATED
            - DONE
            - SEATED_FOR_DRINKS
        start_at:
          type: string
          format: date-time
        party_size:
          type: integer
          minimum: 1
        source:
          type: string
          enum:
            - WALK_IN
            - WEBSITE
            - PHONE
            - EMAIL
            - RESERVE_WITH_GOOGLE
            - TRAVEL_AGENCIES
            - OTHER
            - INSTAGRAM
            - FACEBOOK
            - TIKTOK
            - SNAPCHAT
            - WHATSAPP
            - TRIPADVISOR
            - PRIVATIZATION
            - MISSED_CALL
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        customer:
          $ref: '#/components/schemas/PartnerApiCustomer'
        room:
          $ref: '#/components/schemas/PartnerApiRoom'
        tables:
          type: array
          items:
            $ref: '#/components/schemas/PartnerApiTable'
        waiter:
          $ref: '#/components/schemas/PartnerApiWaiter'
        shift:
          $ref: '#/components/schemas/PartnerApiShift'
        discount:
          $ref: '#/components/schemas/PartnerApiDiscount'
        prescriber:
          $ref: '#/components/schemas/PartnerApiPrescriber'
        custom_message:
          type: string
          nullable: true
        allergies:
          type: string
          nullable: true
        metadata:
          type: object
          nullable: true
          additionalProperties:
            $ref: '#/components/schemas/PartnerApiMetadataField'
        feedback:
          $ref: '#/components/schemas/PartnerApiFeedback'
        cancellation_reason:
          type: string
          nullable: true
        attached_files:
          type: array
          items:
            type: string
        tags:
          type: array
          items:
            type: string
        send_followup_email:
          type: boolean
        is_table_definitive:
          type: boolean
        is_force_inserted:
          type: boolean
        total_amount_paid:
          type: integer
          nullable: true
        payment_summary:
          $ref: '#/components/schemas/PartnerApiPaymentSummary'
        payments:
          type: array
          nullable: true
          items:
            $ref: '#/components/schemas/PartnerApiPayment'
        seated_at:
          type: string
          nullable: true
          format: date-time
        left_at:
          type: string
          nullable: true
          format: date-time
        sensitive_data_included:
          type: boolean
      required:
        - id
        - external_id
        - status
        - start_at
        - party_size
        - source
        - created_at
        - updated_at
        - customer
        - room
        - tables
        - waiter
        - shift
        - discount
        - prescriber
        - custom_message
        - allergies
        - metadata
        - feedback
        - cancellation_reason
        - attached_files
        - tags
        - send_followup_email
        - is_table_definitive
        - is_force_inserted
        - total_amount_paid
        - payment_summary
        - payments
        - seated_at
        - left_at
        - sensitive_data_included
    PartnerApiErrorCode:
      type: string
      enum:
        - AUTHENTICATION_REQUIRED
        - INVALID_AUTHENTICATION
        - INSUFFICIENT_SCOPE
        - VALIDATION_ERROR
        - RESOURCE_NOT_FOUND
        - RESOURCE_CONFLICT
        - RATE_LIMITED
        - INTERNAL_ERROR
    PartnerApiCustomer:
      type: object
      nullable: true
      properties:
        id:
          type: string
          nullable: true
        name:
          type: string
          nullable: true
        email:
          type: string
          nullable: true
          format: email
        phone_number:
          type: string
          nullable: true
        lang:
          type: string
          nullable: true
          enum:
            - FR
            - EN
            - IT
            - ES
            - DE
            - PT
            - null
      required:
        - id
        - name
        - email
        - phone_number
        - lang
    PartnerApiRoom:
      type: object
      nullable: true
      properties:
        id:
          type: string
        name:
          type: string
      required:
        - id
        - name
    PartnerApiTable:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        min_pax:
          type: integer
        max_pax:
          type: integer
      required:
        - id
        - name
        - min_pax
        - max_pax
    PartnerApiWaiter:
      type: object
      nullable: true
      properties:
        id:
          type: string
        name:
          type: string
      required:
        - id
        - name
    PartnerApiShift:
      type: object
      nullable: true
      properties:
        id:
          type: string
        name:
          type: string
        start_time:
          type: string
          nullable: true
        end_time:
          type: string
          nullable: true
      required:
        - id
        - name
        - start_time
        - end_time
    PartnerApiDiscount:
      type: object
      nullable: true
      properties:
        id:
          type: string
        value:
          type: number
        message:
          type: string
          nullable: true
      required:
        - id
        - value
        - message
    PartnerApiPrescriber:
      type: object
      nullable: true
      properties:
        id:
          type: string
        name:
          type: string
        phone_number:
          type: string
          nullable: true
      required:
        - id
        - name
        - phone_number
    PartnerApiFeedback:
      type: object
      nullable: true
      properties:
        rating:
          type: integer
        comment:
          type: string
          nullable: true
        answer:
          type: string
          nullable: true
        created_at:
          type: string
          format: date-time
        answered_at:
          type: string
          nullable: true
          format: date-time
      required:
        - rating
        - comment
        - answer
        - created_at
        - answered_at
    PartnerApiPaymentSummary:
      type: object
      properties:
        currency:
          type: string
          nullable: true
          enum:
            - MAD
            - EUR
            - USD
            - XOF
            - null
        total_amount:
          type: integer
        paid_amount:
          type: integer
        authorized_amount:
          type: integer
        pending_amount:
          type: integer
        refunded_amount:
          type: integer
        statuses:
          type: array
          items:
            type: string
            enum:
              - FREE
              - PENDING
              - PAID
              - EXPIRED
              - REFUNDED
              - CANCELED
              - AUTHORIZED
              - CAPTURED
              - CAPTURE_FAILED
              - VOIDED
              - DECLINED
      required:
        - currency
        - total_amount
        - paid_amount
        - authorized_amount
        - pending_amount
        - refunded_amount
        - statuses
    PartnerApiPayment:
      type: object
      properties:
        id:
          type: string
        provider_id:
          type: string
          nullable: true
        payment_type:
          type: string
          enum:
            - DEPOSIT
            - PREPAYMENT
            - EXTRA
        payment_mode:
          type: string
          enum:
            - SOFT_PREAUTH
            - PREAUTH
            - POSTAUTH
        provider:
          type: string
          enum:
            - PAYZONE
            - CMI
            - STRIPE
            - CASH
            - WIRE_TRANSFER
            - DEBTOR
            - CREDIT_CARD
        status:
          type: string
          enum:
            - FREE
            - PENDING
            - PAID
            - EXPIRED
            - REFUNDED
            - CANCELED
            - AUTHORIZED
            - CAPTURED
            - CAPTURE_FAILED
            - VOIDED
            - DECLINED
        amount:
          type: integer
        quantity:
          type: integer
        unit_price:
          type: integer
        percent_of_total:
          type: number
        currency:
          type: string
          enum:
            - MAD
            - EUR
            - USD
            - XOF
        is_refundable:
          type: boolean
        expiration_date:
          type: string
          nullable: true
          format: date-time
        max_cancellation_date:
          type: string
          nullable: true
          format: date-time
        authorized_at:
          type: string
          nullable: true
          format: date-time
        capture_deadline:
          type: string
          nullable: true
          format: date-time
        captured_at:
          type: string
          nullable: true
          format: date-time
        voided_at:
          type: string
          nullable: true
          format: date-time
        linked_product:
          $ref: '#/components/schemas/PartnerApiPaymentProduct'
        linked_variant:
          $ref: '#/components/schemas/PartnerApiPaymentProduct'
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - provider_id
        - payment_type
        - payment_mode
        - provider
        - status
        - amount
        - quantity
        - unit_price
        - percent_of_total
        - currency
        - is_refundable
        - expiration_date
        - max_cancellation_date
        - authorized_at
        - capture_deadline
        - captured_at
        - voided_at
        - linked_product
        - linked_variant
        - created_at
        - updated_at
    PartnerApiPaymentProduct:
      type: object
      nullable: true
      properties:
        id:
          type: string
        name:
          type: string
      required:
        - id
        - name
  securitySchemes:
    PartnerBearerToken:
      type: http
      scheme: bearer
      bearerFormat: API Token
      description: >-
        Restaurant-scoped partner API token passed as `Authorization: Bearer
        <token>`.
      x-default: your_token_here

````