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

# Update a contact

> Partially update a contact (person) by its ID. Only the fields provided in the body are modified; omitted fields are left unchanged.

The body follows the same contract as the response (English snake_case names). String fields are trimmed and limited to 255 characters; `optin_marketing` and `optin_general` are booleans; `email` must be a valid email address; `account_id` must reference an existing account within the contact's venue or venues group. Pass `null` on any field to clear it. The `country` field is stored verbatim. Custom fields (`custom_<uuid>`) configured for your venue can be set too (string or array of strings); an unknown custom field key is rejected with `400`. `id` and `created_at` are read-only and ignored.

Updating a contact automatically emits the `contact.updated` webhook when at least one exposed field changes.



## OpenAPI

````yaml /api-reference/bookingshake-openapi.json patch /contacts/{id}
openapi: 3.0.3
info:
  title: BookingShake API
  description: >-
    The BookingShake API allows you to programmatically create and manage
    events, bookings, and related resources. Integrate BookingShake with your
    applications to automate event creation, retrieve booking sources, spaces,
    statuses, and custom fields.


    **Rate Limiting:** All endpoints are rate limited per API key. POST
    /events/create allows 10 requests per minute, while GET endpoints allow 60
    requests per minute. Rate limit information is provided in response headers
    (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset).
  version: 1.0.0
  contact:
    name: BookingShake Support
    email: support@bookingshake.com
    url: https://bookingshake.com
servers:
  - url: https://api.bookingshake.io/api
    description: Production server
security:
  - bearerAuth: []
tags:
  - name: Events
    description: Create and manage events and bookings
  - name: Resources
    description: Retrieve booking sources, spaces, and statuses
  - name: Fields
    description: Retrieve available custom and default fields
  - name: Invoices
    description: Retrieve issued invoices
  - name: Payments
    description: Retrieve payments
  - name: Contacts
    description: Retrieve contacts (people)
  - name: Products
    description: Retrieve the venue product catalog
paths:
  /contacts/{id}:
    patch:
      tags:
        - Contacts
      summary: Update a contact
      description: >-
        Partially update a contact (person) by its ID. Only the fields provided
        in the body are modified; omitted fields are left unchanged.


        The body follows the same contract as the response (English snake_case
        names). String fields are trimmed and limited to 255 characters;
        `optin_marketing` and `optin_general` are booleans; `email` must be a
        valid email address; `account_id` must reference an existing account
        within the contact's venue or venues group. Pass `null` on any field to
        clear it. The `country` field is stored verbatim. Custom fields
        (`custom_<uuid>`) configured for your venue can be set too (string or
        array of strings); an unknown custom field key is rejected with `400`.
        `id` and `created_at` are read-only and ignored.


        Updating a contact automatically emits the `contact.updated` webhook
        when at least one exposed field changes.
      operationId: updateContact
      parameters:
        - name: id
          in: path
          required: true
          description: Contact ID (the `id` field carried by the contact.* webhooks).
          schema:
            type: string
          example: contact-456
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateContactRequest'
            example:
              position: Head of Operations
              phone: '+33611111111'
              optin_marketing: false
      responses:
        '200':
          description: >-
            Contact updated successfully. Returns the full contact in its
            post-update state.
          headers:
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum requests allowed per minute (30 for this endpoint)
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests remaining in the current window
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Unix timestamp when the rate limit resets
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: success
                  data:
                    $ref: '#/components/schemas/ContactResource'
              example:
                message: success
                data:
                  id: contact-456
                  first_name: John
                  last_name: Doe
                  email: john.doe@example.com
                  phone: '+33611111111'
                  landline_phone: '+33145678901'
                  title: CEO
                  position: Head of Operations
                  avatar: null
                  comments: null
                  account_id: account-123
                  optin_marketing: false
                  optin_general: false
                  address_line_1: 10 rue Example
                  address_line_2: null
                  postal_code: '75001'
                  city: Paris
                  country: France
                  created_at: 1731493800000
                  custom_u1v2w3x4y5: VIP
                  custom_z6a7b8c9d0: null
        '400':
          description: >-
            Bad request - invalid token, missing contact id, empty/invalid body,
            no updatable fields, a wrongly-typed value, a value over 255
            characters, an invalid email, an `account_id` outside the contact's
            scope, or an unknown custom field key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                message: no updatable fields provided
        '404':
          description: >-
            Contact not found. Returned when the contact does not exist, or
            belongs to another venue or venues group.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                message: not found
        '429':
          $ref: '#/components/responses/RateLimitExceeded'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                message: error
      security:
        - bearerAuth: []
components:
  schemas:
    UpdateContactRequest:
      type: object
      description: >-
        Fields that can be updated on a contact. All fields are optional
        (partial update): only the fields present in the body are modified. Same
        conventions as the response (English snake_case names). String fields
        are trimmed and limited to 255 characters; `email` must be a valid email
        address; `optin_marketing`/`optin_general` are booleans; `account_id`
        must reference an existing account within the contact's venue or venues
        group. Pass null on any field to clear it. The country field is stored
        verbatim. Custom fields (custom_<uuid>) configured for your venue can be
        set too (string or array of strings); an unknown custom field key is
        rejected with 400. `id` and `created_at` are read-only and ignored. At
        least one field must be provided.
      minProperties: 1
      properties:
        first_name:
          type: string
          maxLength: 255
          nullable: true
          description: First name
        last_name:
          type: string
          maxLength: 255
          nullable: true
          description: Last name
        email:
          type: string
          format: email
          maxLength: 255
          nullable: true
          description: Email address (validated; pass null to clear)
        phone:
          type: string
          maxLength: 255
          nullable: true
          description: Mobile phone number
        landline_phone:
          type: string
          maxLength: 255
          nullable: true
          description: Landline phone number
        title:
          type: string
          maxLength: 255
          nullable: true
          description: Contact's title
        position:
          type: string
          maxLength: 255
          nullable: true
          description: Job position
        avatar:
          type: string
          maxLength: 255
          nullable: true
          description: Avatar image URL
        comments:
          type: string
          maxLength: 255
          nullable: true
          description: Free-text notes about the contact
        account_id:
          type: string
          nullable: true
          description: >-
            ID of an existing account (company) to link the contact to; must be
            within the contact's venue or venues group. Pass null to unlink.
        optin_marketing:
          type: boolean
          nullable: true
          description: Marketing communications opt-in
        optin_general:
          type: boolean
          nullable: true
          description: General communications opt-in
        address_line_1:
          type: string
          maxLength: 255
          nullable: true
          description: Address
        address_line_2:
          type: string
          maxLength: 255
          nullable: true
          description: Address, line 2
        postal_code:
          type: string
          maxLength: 255
          nullable: true
          description: Postal code
        city:
          type: string
          maxLength: 255
          nullable: true
          description: City
        country:
          type: string
          maxLength: 255
          nullable: true
          description: Country, stored verbatim
      additionalProperties:
        description: >-
          Custom fields (custom_<uuid>) configured for your venue: a string or
          an array of strings. An unknown custom field key is rejected with 400.
    ContactResource:
      type: object
      description: >-
        A contact (person) attached to your venue, optionally linked to an
        account. Every field is present with an explicit `null` when unset. The
        `country` field is verbatim as entered. `account_id` is the raw ID of
        the linked account (or `null`). Custom fields (`custom_<uuid>`)
        configured for your venue are included, also with explicit `null` when
        unset.
      properties:
        id:
          type: string
          description: Unique contact ID
        first_name:
          type: string
          nullable: true
          description: First name
        last_name:
          type: string
          nullable: true
          description: Last name
        email:
          type: string
          nullable: true
          description: Email address
        phone:
          type: string
          nullable: true
          description: Mobile phone number
        landline_phone:
          type: string
          nullable: true
          description: Landline phone number
        title:
          type: string
          nullable: true
          description: Contact's title
        position:
          type: string
          nullable: true
          description: Job position
        avatar:
          type: string
          nullable: true
          description: Avatar image URL
        comments:
          type: string
          nullable: true
          description: Free-text notes about the contact
        account_id:
          type: string
          nullable: true
          description: ID of the account (company) this contact belongs to
        optin_marketing:
          type: boolean
          nullable: true
          description: Marketing communications opt-in
        optin_general:
          type: boolean
          nullable: true
          description: General communications opt-in
        address_line_1:
          type: string
          nullable: true
          description: Address
        address_line_2:
          type: string
          nullable: true
          description: Address, line 2
        postal_code:
          type: string
          nullable: true
          description: Postal code
        city:
          type: string
          nullable: true
          description: City
        country:
          type: string
          nullable: true
          description: Country, verbatim as entered
        created_at:
          type: integer
          format: int64
          nullable: true
          description: Creation timestamp, Unix milliseconds
      additionalProperties:
        description: >-
          Custom fields (custom_<uuid>) configured for your venue, with explicit
          null when unset
    ErrorResponse:
      type: object
      properties:
        message:
          type: string
          description: Error message describing what went wrong
          example: invalid token
    RateLimitResponse:
      type: object
      properties:
        message:
          type: string
          description: Error message
          example: Rate limit exceeded
        data:
          type: object
          properties:
            limit:
              type: integer
              description: Maximum requests allowed per window
              example: 10
            window:
              type: string
              description: Time window duration
              example: 60 seconds
            remaining:
              type: integer
              description: Requests remaining (always 0 on rate limit error)
              example: 0
            resetAt:
              type: string
              format: date-time
              description: ISO 8601 timestamp when the limit resets
              example: '2025-11-17T14:30:00.000Z'
            retryAfter:
              type: integer
              description: Seconds to wait before retrying
              example: 45
  responses:
    RateLimitExceeded:
      description: Rate limit exceeded - too many requests
      headers:
        X-RateLimit-Limit:
          schema:
            type: integer
          description: Maximum requests allowed per minute
        X-RateLimit-Remaining:
          schema:
            type: integer
          description: Requests remaining (always 0 on 429)
        X-RateLimit-Reset:
          schema:
            type: integer
          description: Unix timestamp when the rate limit resets
        Retry-After:
          schema:
            type: integer
          description: Seconds to wait before retrying
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/RateLimitResponse'
          example:
            message: Rate limit exceeded
            data:
              limit: 60
              window: 60 seconds
              remaining: 0
              resetAt: '2025-11-17T14:30:00.000Z'
              retryAfter: 45
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API Key
      description: >-
        Bearer authentication using your BookingShake API key. Retrieve your API
        key from Settings > Integrations in your BookingShake dashboard.

````