Skip to main content
Beta - Contact data is currently in beta. The payload structure may still evolve before general availability. Share your feedback at support@bookingshake.com.

Overview

PATCH /contacts/{id} updates a single contact (person) by its ID. It is a partial update: only the fields you include in the body are modified, everything else is left untouched. The request body uses the same conventions as the response - the English (snake_case) field names returned by GET /contacts/{id}. So you can read a contact, change a few fields, and send them straight back. Pass null on any field to clear it.
Updating a contact automatically emits the contact.updated webhook when at least one exposed field changes. The country field is stored verbatim as provided - no ISO normalization.

Authentication

All requests require a Bearer token (your BookingShake API key):
Authorization: Bearer YOUR_API_KEY

Path Parameters

id
string
required
The contact ID - the id field carried by the contact.* webhooks.

Body Parameters

All body fields are optional, but at least one must be provided. String fields are trimmed and limited to 255 characters. Pass null on any field to clear it. id and created_at are read-only and ignored.
first_name
string
First name.
last_name
string
Last name.
email
string
Email address. Must be a valid email when provided; pass null to clear it.
phone
string
Mobile phone number.
landline_phone
string
Landline phone number.
title
string
Contact’s title.
position
string
Job position.
avatar
string
Avatar image URL.
comments
string
Free-text notes about the contact.
account_id
string
ID of an existing account (company) to link the contact to. Must reference an account within the contact’s venue or venues group, otherwise the request is rejected with 400. Pass null to unlink.
optin_marketing
boolean
Marketing communications opt-in. Must be true, false, or null.
optin_general
boolean
General communications opt-in. Must be true, false, or null.
address_line_1
string
Address.
address_line_2
string
Address, line 2.
postal_code
string
Postal code.
city
string
City.
country
string
Country, stored verbatim.
custom_<uuid>
string | array
Custom fields configured for your venue. A single-value field takes a string; a multi-select field takes an array of strings. An unknown custom field key is rejected with 400.

Request

curl -X PATCH https://api.bookingshake.io/api/contacts/contact-456 \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "position": "Head of Operations", "phone": "+33611111111", "optin_marketing": false }'
const res = await fetch("https://api.bookingshake.io/api/contacts/contact-456", {
  method: "PATCH",
  headers: {
    Authorization: `Bearer ${process.env.BOOKINGSHAKE_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    position: "Head of Operations",
    phone: "+33611111111",
    optin_marketing: false,
  }),
});
const { data: contact } = await res.json();
import os, requests

res = requests.patch(
    "https://api.bookingshake.io/api/contacts/contact-456",
    headers={"Authorization": f"Bearer {os.environ['BOOKINGSHAKE_API_KEY']}"},
    json={"position": "Head of Operations", "phone": "+33611111111", "optin_marketing": False},
)
contact = res.json()["data"]
<?php
$ch = curl_init("https://api.bookingshake.io/api/contacts/contact-456");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PATCH");
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
    "position" => "Head of Operations",
    "phone" => "+33611111111",
    "optin_marketing" => false,
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Authorization: Bearer " . getenv("BOOKINGSHAKE_API_KEY"),
    "Content-Type: application/json",
]);
$contact = json_decode(curl_exec($ch), true)["data"];
curl_close($ch);

Response

The full contact is returned in its post-update state, wrapped in the standard { message, data } envelope - identical in shape to GET /contacts/{id}.
{
  "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
  }
}
See the Get a Contact reference for the full field descriptions.

Errors

StatusMeaning
400Missing/invalid token, missing contact id, empty/invalid body, no updatable fields, a wrongly-typed value (e.g. a non-string on a string field, a non-boolean opt-in), a value over 255 characters, an invalid email, an account_id outside the contact’s scope, or an unknown custom field key
404Contact not found - it does not exist, or belongs to another venue or venues group
429Rate limit exceeded (30 requests/minute)
500Internal server error
A 404 is returned uniformly whenever the contact is outside your scope, so the existence of another venue’s contact is never disclosed.

Next Steps

Get a Contact

Retrieve a contact before updating it

Contact Events

Receive contact changes in real time via the contact.* webhooks