Introduction
Welcome to the Shift Collect API - A RESTful API for managing locker bookings and account access.
This API allows you to manage bookings for lockers at various sites, switch between account contexts, and manage your API tokens.
This API uses Bearer token authentication. Generate API tokens using the POST /v1/tokens/generate endpoint (requires appropriate permissions) and then include the token in the Authorization header as: Bearer {your-token}.
As you scroll, you'll see code examples for working with the API in different programming languages in the dark area to the right (or as part of the content on mobile). You can switch the language used with the tabs at the top right (or from the nav menu at the top left on mobile).
Authenticating requests
To authenticate requests, include an Authorization header with the value "Bearer {YOUR_API_TOKEN}".
All authenticated endpoints are marked with a requires authentication badge in the documentation below.
Generate API tokens using the POST /v1/auth/token endpoint. See the Authentication section below for more information.
Accounts
List the accounts the authenticated user belongs to.
requires authentication
Returns every account that the authenticated user is a member of, including the membership status, join date, and their role assignments scoped to each account.
Example request:
curl --request GET \
--get "https://sandbox-api.shiftcollect.com/v1/accounts" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/accounts"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/accounts';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/accounts'
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (HTTP 200):
{
"data": [
{
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAW",
"name": "Acme Corp",
"slug": "acme-corp",
"role": "owner"
}
]
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get the current account context.
requires authentication
Returns detailed information about the currently active account, including collection strategies, locker assignment strategy, service products, and users.
Example request:
curl --request GET \
--get "https://sandbox-api.shiftcollect.com/v1/account" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/account"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/account';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/account'
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (HTTP 200):
{
"data": {
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAW",
"name": "Acme Corp",
"description": "A leading logistics company",
"website": "https://acme.example.com",
"phone": "+44 20 1234 5678",
"email": "[email protected]",
"address": "123 Business Street, London, SW1A 1AA",
"active": true,
"created_at": "2025-01-01T00:00:00.000000Z",
"updated_at": "2025-01-01T00:00:00.000000Z",
"collection_strategies": [
{
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAX",
"name": "Pre-planned Collection",
"description": "Daily scheduled collection from depot",
"active": true,
"is_default": true
}
],
"locker_assignment_strategy": {
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAY",
"name": "Just-in-time Assignment",
"description": "Assign lockers on day of delivery",
"active": true
},
"service_products": [
{
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAZ",
"name": "DC to Locker",
"description": "Direct delivery from despatch centre to locker",
"requires_collection": true,
"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",
"active": true,
"role": "owner"
}
]
}
}
Example response (HTTP 400):
{
"message": "No account context set"
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Authentication
Generate API token from credentials.
requires authentication
Authenticates a user with email and password and returns an API token. This is useful for programmatic access without needing to login via the SPA first. Requires Admin or Owner role in the specified account.
Example request:
curl --request POST \
"https://sandbox-api.shiftcollect.com/v1/auth/token" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"email\": \"[email protected]\",
\"password\": \"password123\",
\"account_id\": \"01ARZ3NDEKTSV4RRFFQ69G5FAW\",
\"token_name\": \"Production API Token\",
\"expires_at\": \"2025-12-31T23:59:59Z\"
}"
const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/auth/token"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"email": "[email protected]",
"password": "password123",
"account_id": "01ARZ3NDEKTSV4RRFFQ69G5FAW",
"token_name": "Production API Token",
"expires_at": "2025-12-31T23:59:59Z"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/auth/token';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'email' => '[email protected]',
'password' => 'password123',
'account_id' => '01ARZ3NDEKTSV4RRFFQ69G5FAW',
'token_name' => 'Production API Token',
'expires_at' => '2025-12-31T23:59:59Z',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/auth/token'
payload = {
"email": "[email protected]",
"password": "password123",
"account_id": "01ARZ3NDEKTSV4RRFFQ69G5FAW",
"token_name": "Production API Token",
"expires_at": "2025-12-31T23:59:59Z"
}
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()Example response (HTTP 200):
{
"token": "1|abcdefghijklmnopqrstuvwxyz1234567890",
"token_name": "Production API Token",
"account_id": "01ARZ3NDEKTSV4RRFFQ69G5FAW",
"user": {
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAW",
"name": "John Doe",
"email": "[email protected]"
},
"abilities": [
"*"
],
"expires_at": "2025-12-31T23:59:59.000000Z",
"created_at": "2025-01-01T00:00:00.000000Z",
"message": "API token generated successfully"
}
Example response (HTTP 403):
{
"message": "This action is unauthorized. Only admins and owners can generate API tokens."
}
Example response (HTTP 403):
{
"message": "User does not belong to the specified account."
}
Example response (HTTP 422):
{
"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."
]
}
}
Example response (HTTP 422):
{
"message": "The given data was invalid.",
"errors": {
"email": [
"These credentials do not match our records."
]
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Availability
Get site availability for a date range.
requires authentication
Returns all active sites with availability information for the requested time window. Sites are returned regardless of availability (sites with 0 available lockers are still included). Availability considers both confirmed reservations and estimated bookings for the requested period. Each site includes an array of available lockers with their dimensions and status. Note: Booking details are never included in the response to prevent data leakage between accounts.
Example request:
curl --request GET \
--get "https://sandbox-api.shiftcollect.com/v1/availability?from=2025-01-15T09%3A00%3A00Z&to=2025-01-20T17%3A00%3A00Z&site_id=01ARZ3NDEKTSV4RRFFQ69G5FAA&per_page=20&latitude=50.376289&longitude=-4.143841" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/availability"
);
const params = {
"from": "2025-01-15T09:00:00Z",
"to": "2025-01-20T17:00:00Z",
"site_id": "01ARZ3NDEKTSV4RRFFQ69G5FAA",
"per_page": "20",
"latitude": "50.376289",
"longitude": "-4.143841",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/availability';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'query' => [
'from' => '2025-01-15T09:00:00Z',
'to' => '2025-01-20T17:00:00Z',
'site_id' => '01ARZ3NDEKTSV4RRFFQ69G5FAA',
'per_page' => '20',
'latitude' => '50.376289',
'longitude' => '-4.143841',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/availability'
params = {
'from': '2025-01-15T09:00:00Z',
'to': '2025-01-20T17:00:00Z',
'site_id': '01ARZ3NDEKTSV4RRFFQ69G5FAA',
'per_page': '20',
'latitude': '50.376289',
'longitude': '-4.143841',
}
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (HTTP 200):
{
"data": [
{
"id": "01kehrxqpxaqarzefdmcbs4fsn",
"name": "Price Ltd Site",
"address": {
"recipient": null,
"line_1": "825 Reid Estates",
"line_2": null,
"line_3": null,
"city": "Richardsonmouth",
"postcode": "EX12 2WH",
"country": "United Kingdom",
"phone": "(0536) 813 4982",
"email": null,
"special_instructions": "Qui commodi incidunt iure odit. Et modi ipsum nostrum omnis autem et consequatur. Dolores enim non facere tempora.",
"latitude": "-55.526499",
"longitude": "-0.84108"
},
"latitude": -55.526499,
"longitude": -0.84108,
"access_instructions": "Praesentium quis adipisci molestias fugit. Distinctio eum doloremque id aut libero aliquam veniam corporis. Mollitia deleniti nemo odit quia officia. Dignissimos neque blanditiis odio.",
"height_restriction": null,
"reserved_lockers": 0,
"available_lockers": 0,
"distance": null,
"lockers": [
{
"name": "R23",
"cabinet": "Train Station",
"status": "active",
"dimensions": {
"height": 79.52,
"width": 64.45,
"depth": 54.68,
"volume": 280238.49952
}
}
]
},
{
"id": "01kehrxqspb02f56ay462fmbbk",
"name": "Khan Ltd Site",
"address": {
"recipient": null,
"line_1": "957 Griffiths Course",
"line_2": "887 Davies Passage",
"line_3": "Lake Lola",
"city": "Port Rosie",
"postcode": "CM16 6TT",
"country": "United Kingdom",
"phone": "04159 68209",
"email": "[email protected]",
"special_instructions": null,
"latitude": "-4.7052",
"longitude": "104.588688"
},
"latitude": -4.7052,
"longitude": 104.588688,
"access_instructions": "Repellendus ut eaque alias ratione dolores. Rem ea ut aut deserunt. Quis in quod id aspernatur.",
"height_restriction": null,
"reserved_lockers": 0,
"available_lockers": 0,
"distance": null,
"lockers": [
{
"name": "W72",
"cabinet": "Train Station",
"status": "out_of_order",
"dimensions": {
"height": 55.06,
"width": 62.88,
"depth": 47.14,
"volume": 163206.82579200002
}
}
]
}
],
"links": {
"first": "/?page=1",
"last": "/?page=1",
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 1,
"links": [
{
"url": null,
"label": "« Previous",
"page": null,
"active": false
},
{
"url": "/?page=1",
"label": "1",
"page": 1,
"active": true
},
{
"url": null,
"label": "Next »",
"page": null,
"active": false
}
],
"path": "/",
"per_page": 10,
"to": 2,
"total": 2
}
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 422):
{
"message": "The given data was invalid.",
"errors": {
"from": [
"The from field is required."
],
"to": [
"The to must be a date after from."
]
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Booking Tracking
Track a booking by reference ID (public endpoint).
requires authentication
Allows public users to track their booking using reference ID and email or phone verification. At least one of email or phone must be provided.
Example request:
curl --request POST \
"https://sandbox-api.shiftcollect.com/v1/tracking/booking" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"reference_id\": \"BK691B2516D28B2\",
\"email\": \"[email protected]\",
\"phone\": \"+447700900123\"
}"
const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/tracking/booking"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"reference_id": "BK691B2516D28B2",
"email": "[email protected]",
"phone": "+447700900123"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/tracking/booking';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'reference_id' => 'BK691B2516D28B2',
'email' => '[email protected]',
'phone' => '+447700900123',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/tracking/booking'
payload = {
"reference_id": "BK691B2516D28B2",
"email": "[email protected]",
"phone": "+447700900123"
}
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()Example response (HTTP 200):
{
"data": {
"reference_id": "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
}
]
}
}
Example response (HTTP 404):
{
"message": "Booking not found"
}
Example response (HTTP 422):
{
"message": "The given data was invalid."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Track a booking by ID (authenticated endpoint).
requires authentication
Allows authenticated accounts to track their bookings.
Example request:
curl --request POST \
"https://sandbox-api.shiftcollect.com/v1/bookings/architecto/tracking" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/bookings/architecto/tracking"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/bookings/architecto/tracking';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/bookings/architecto/tracking'
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers)
response.json()Example response (HTTP 200):
{
"data": {
"reference_id": "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
}
]
}
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 404):
{
"message": "Booking not found"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Bookings
Display a listing of bookings.
requires authentication
Returns a paginated list of bookings for the current account context. Bookings can be filtered by status.
Example request:
curl --request GET \
--get "https://sandbox-api.shiftcollect.com/v1/bookings?status=confirmed&per_page=20&page=1" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/bookings"
);
const params = {
"status": "confirmed",
"per_page": "20",
"page": "1",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/bookings';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'query' => [
'status' => 'confirmed',
'per_page' => '20',
'page' => '1',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/bookings'
params = {
'status': 'confirmed',
'per_page': '20',
'page': '1',
}
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (HTTP 200):
{
"data": [
{
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAV",
"reference_id": "SC689PUY74F",
"account_id": "01ARZ3NDEKTSV4RRFFQ69G5FAZ",
"service_product_id": "01ARZ3NDEKTSV4RRFFQ69G5FAX",
"created_at": "2025-01-01T00:00:00.000000Z",
"updated_at": "2025-01-01T00:00:00.000000Z",
"status": {
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAX",
"name": "confirmed"
},
"user": {
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAY",
"name": "John Doe"
},
"account": {
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAZ",
"name": "Acme Corp"
},
"service_product": {
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAX",
"name": "DC to Locker"
},
"items": [],
"status_history": [],
"locker_assignments": [],
"collections": [],
"reservation_window": [],
"authorisations": [],
"contacts": [],
"returns": []
}
],
"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"
}
}
Example response (HTTP 400):
{
"message": "No account context set"
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 403):
{
"message": "This action is unauthorized."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Store a newly created booking.
requires authentication
Creates a new booking associated with the current account context and the authenticated user. The booking will be processed according to the specified service product.
Example request:
curl --request POST \
"https://sandbox-api.shiftcollect.com/v1/bookings" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"service_product_id\": \"01ARZ3NDEKTSV4RRFFQ69G5FAX\",
\"reference_id\": \"ORD-12345\",
\"collection\": {
\"site_id\": \"01ARZ3NDEKTSV4RRFFQ69G5FAY\",
\"despatch_centre_id\": \"01ARZ3NDEKTSV4RRFFQ69G5FAY\",
\"address\": {
\"recipient\": \"John Smith\",
\"line_1\": \"2 Hallerton Close\",
\"line_2\": \"Flat 3\",
\"line_3\": \"Building A\",
\"city\": \"Plymouth\",
\"postcode\": \"PL6 8NP\",
\"country\": \"United Kingdom\",
\"phone\": \"+44 1234 567890\",
\"email\": \"[email protected]\",
\"special_instructions\": \"Leave at side gate\",
\"latitude\": -89,
\"longitude\": -179
},
\"earliest_collection_time\": \"2052-02-03\",
\"latest_collection_time\": \"2052-02-02\"
},
\"delivery\": {
\"site_id\": \"01ARZ3NDEKTSV4RRFFQ69G5FAZ\",
\"despatch_centre_id\": \"01ARZ3NDEKTSV4RRFFQ69G5FAZ\",
\"address\": {
\"recipient\": \"John Smith\",
\"line_1\": \"2 Hallerton Close\",
\"line_2\": \"Flat 3\",
\"line_3\": \"Building A\",
\"city\": \"Plymouth\",
\"postcode\": \"PL6 8NP\",
\"country\": \"United Kingdom\",
\"phone\": \"+44 1234 567890\",
\"email\": \"[email protected]\",
\"special_instructions\": \"Leave at side gate\",
\"latitude\": -89,
\"longitude\": -179
}
},
\"locker_reservation_window\": {
\"site_id\": \"01ARZ3NDEKTSV4RRFFQ69G5FAZ\",
\"t_earliest_arrival\": \"2025-01-15T09:00:00Z\",
\"t_latest_collection\": \"2025-01-22T17:00:00Z\"
},
\"items\": [
{
\"name\": \"Box of documents\",
\"description\": \"Important business documents\",
\"quantity\": 1,
\"weight\": 5.5,
\"height\": 30,
\"width\": 40,
\"depth\": 50
}
],
\"authorisation_group_ids\": [
\"01ARZ3NDEKTSV4RRFFQ69G5FAY\"
],
\"locker_user_ids\": [
\"01ARZ3NDEKTSV4RRFFQ69G5FAZ\"
],
\"contacts\": [
{
\"name\": \"John Doe\",
\"email\": \"[email protected]\",
\"phone\": \"+447700900123\"
}
]
}"
const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/bookings"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"service_product_id": "01ARZ3NDEKTSV4RRFFQ69G5FAX",
"reference_id": "ORD-12345",
"collection": {
"site_id": "01ARZ3NDEKTSV4RRFFQ69G5FAY",
"despatch_centre_id": "01ARZ3NDEKTSV4RRFFQ69G5FAY",
"address": {
"recipient": "John Smith",
"line_1": "2 Hallerton Close",
"line_2": "Flat 3",
"line_3": "Building A",
"city": "Plymouth",
"postcode": "PL6 8NP",
"country": "United Kingdom",
"phone": "+44 1234 567890",
"email": "[email protected]",
"special_instructions": "Leave at side gate",
"latitude": -89,
"longitude": -179
},
"earliest_collection_time": "2052-02-03",
"latest_collection_time": "2052-02-02"
},
"delivery": {
"site_id": "01ARZ3NDEKTSV4RRFFQ69G5FAZ",
"despatch_centre_id": "01ARZ3NDEKTSV4RRFFQ69G5FAZ",
"address": {
"recipient": "John Smith",
"line_1": "2 Hallerton Close",
"line_2": "Flat 3",
"line_3": "Building A",
"city": "Plymouth",
"postcode": "PL6 8NP",
"country": "United Kingdom",
"phone": "+44 1234 567890",
"email": "[email protected]",
"special_instructions": "Leave at side gate",
"latitude": -89,
"longitude": -179
}
},
"locker_reservation_window": {
"site_id": "01ARZ3NDEKTSV4RRFFQ69G5FAZ",
"t_earliest_arrival": "2025-01-15T09:00:00Z",
"t_latest_collection": "2025-01-22T17:00:00Z"
},
"items": [
{
"name": "Box of documents",
"description": "Important business documents",
"quantity": 1,
"weight": 5.5,
"height": 30,
"width": 40,
"depth": 50
}
],
"authorisation_group_ids": [
"01ARZ3NDEKTSV4RRFFQ69G5FAY"
],
"locker_user_ids": [
"01ARZ3NDEKTSV4RRFFQ69G5FAZ"
],
"contacts": [
{
"name": "John Doe",
"email": "[email protected]",
"phone": "+447700900123"
}
]
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/bookings';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'service_product_id' => '01ARZ3NDEKTSV4RRFFQ69G5FAX',
'reference_id' => 'ORD-12345',
'collection' => [
'site_id' => '01ARZ3NDEKTSV4RRFFQ69G5FAY',
'despatch_centre_id' => '01ARZ3NDEKTSV4RRFFQ69G5FAY',
'address' => [
'recipient' => 'John Smith',
'line_1' => '2 Hallerton Close',
'line_2' => 'Flat 3',
'line_3' => 'Building A',
'city' => 'Plymouth',
'postcode' => 'PL6 8NP',
'country' => 'United Kingdom',
'phone' => '+44 1234 567890',
'email' => '[email protected]',
'special_instructions' => 'Leave at side gate',
'latitude' => -89,
'longitude' => -179,
],
'earliest_collection_time' => '2052-02-03',
'latest_collection_time' => '2052-02-02',
],
'delivery' => [
'site_id' => '01ARZ3NDEKTSV4RRFFQ69G5FAZ',
'despatch_centre_id' => '01ARZ3NDEKTSV4RRFFQ69G5FAZ',
'address' => [
'recipient' => 'John Smith',
'line_1' => '2 Hallerton Close',
'line_2' => 'Flat 3',
'line_3' => 'Building A',
'city' => 'Plymouth',
'postcode' => 'PL6 8NP',
'country' => 'United Kingdom',
'phone' => '+44 1234 567890',
'email' => '[email protected]',
'special_instructions' => 'Leave at side gate',
'latitude' => -89,
'longitude' => -179,
],
],
'locker_reservation_window' => [
'site_id' => '01ARZ3NDEKTSV4RRFFQ69G5FAZ',
't_earliest_arrival' => '2025-01-15T09:00:00Z',
't_latest_collection' => '2025-01-22T17:00:00Z',
],
'items' => [
[
'name' => 'Box of documents',
'description' => 'Important business documents',
'quantity' => 1,
'weight' => 5.5,
'height' => 30.0,
'width' => 40.0,
'depth' => 50.0,
],
],
'authorisation_group_ids' => [
'01ARZ3NDEKTSV4RRFFQ69G5FAY',
],
'locker_user_ids' => [
'01ARZ3NDEKTSV4RRFFQ69G5FAZ',
],
'contacts' => [
[
'name' => 'John Doe',
'email' => '[email protected]',
'phone' => '+447700900123',
],
],
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/bookings'
payload = {
"service_product_id": "01ARZ3NDEKTSV4RRFFQ69G5FAX",
"reference_id": "ORD-12345",
"collection": {
"site_id": "01ARZ3NDEKTSV4RRFFQ69G5FAY",
"despatch_centre_id": "01ARZ3NDEKTSV4RRFFQ69G5FAY",
"address": {
"recipient": "John Smith",
"line_1": "2 Hallerton Close",
"line_2": "Flat 3",
"line_3": "Building A",
"city": "Plymouth",
"postcode": "PL6 8NP",
"country": "United Kingdom",
"phone": "+44 1234 567890",
"email": "[email protected]",
"special_instructions": "Leave at side gate",
"latitude": -89,
"longitude": -179
},
"earliest_collection_time": "2052-02-03",
"latest_collection_time": "2052-02-02"
},
"delivery": {
"site_id": "01ARZ3NDEKTSV4RRFFQ69G5FAZ",
"despatch_centre_id": "01ARZ3NDEKTSV4RRFFQ69G5FAZ",
"address": {
"recipient": "John Smith",
"line_1": "2 Hallerton Close",
"line_2": "Flat 3",
"line_3": "Building A",
"city": "Plymouth",
"postcode": "PL6 8NP",
"country": "United Kingdom",
"phone": "+44 1234 567890",
"email": "[email protected]",
"special_instructions": "Leave at side gate",
"latitude": -89,
"longitude": -179
}
},
"locker_reservation_window": {
"site_id": "01ARZ3NDEKTSV4RRFFQ69G5FAZ",
"t_earliest_arrival": "2025-01-15T09:00:00Z",
"t_latest_collection": "2025-01-22T17:00:00Z"
},
"items": [
{
"name": "Box of documents",
"description": "Important business documents",
"quantity": 1,
"weight": 5.5,
"height": 30,
"width": 40,
"depth": 50
}
],
"authorisation_group_ids": [
"01ARZ3NDEKTSV4RRFFQ69G5FAY"
],
"locker_user_ids": [
"01ARZ3NDEKTSV4RRFFQ69G5FAZ"
],
"contacts": [
{
"name": "John Doe",
"email": "[email protected]",
"phone": "+447700900123"
}
]
}
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()Example response (HTTP 201):
{
"message": "Booking created successfully",
"booking_id": "01ARZ3NDEKTSV4RRFFQ69G5FAV",
"reference_id": "BK-2025-001",
"service": "DC to Locker",
"label_ids": [
"1111111119",
"1111111120"
]
}
Example response (HTTP 400):
{
"message": "No account context set"
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 403):
{
"message": "This action is unauthorized."
}
Example response (HTTP 422):
{
"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."
]
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Display the specified booking.
requires authentication
Returns detailed information about a specific booking. The booking must belong to the current account context.
Example request:
curl --request GET \
--get "https://sandbox-api.shiftcollect.com/v1/bookings/01ARZ3NDEKTSV4RRFFQ69G5FAV" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/bookings/01ARZ3NDEKTSV4RRFFQ69G5FAV"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/bookings/01ARZ3NDEKTSV4RRFFQ69G5FAV';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/bookings/01ARZ3NDEKTSV4RRFFQ69G5FAV'
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (HTTP 200):
{
"data": {
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAV",
"reference_id": "SC689PUY74F",
"account_id": "01ARZ3NDEKTSV4RRFFQ69G5FAZ",
"service_product_id": "01ARZ3NDEKTSV4RRFFQ69G5FAX",
"created_at": "2025-01-01T00:00:00.000000Z",
"updated_at": "2025-01-01T00:00:00.000000Z",
"status": {
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAX",
"name": "confirmed"
},
"user": {
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAY",
"name": "John Doe"
},
"account": {
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAZ",
"name": "Acme Corp"
},
"service_product": {
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAX",
"name": "DC to Locker"
},
"items": [
{
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAB",
"name": "Box of documents",
"description": "Important business documents",
"quantity": 1,
"weight": 5.5,
"height": 30,
"width": 40,
"depth": 50,
"volume": 60000,
"created_at": "2025-01-01T00:00:00.000000Z",
"updated_at": "2025-01-01T00:00:00.000000Z"
}
],
"status_history": [
{
"status": "confirmed",
"status_changed_at": "2025-01-01T00:00:00.000000Z"
}
],
"locker_assignments": [],
"collections": [],
"reservation_window": [],
"authorisations": [],
"contacts": [
{
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAC",
"name": "Jane Doe",
"email": "[email protected]",
"phone": "+447700900123"
}
],
"returns": []
}
}
Example response (HTTP 400):
{
"message": "No account context set"
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 404):
{
"message": "Booking not found"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Cancel the specified booking.
requires authentication
Cancels a booking, removing it from active status. The booking must belong to the current account context.
Example request:
curl --request DELETE \
"https://sandbox-api.shiftcollect.com/v1/bookings/01ARZ3NDEKTSV4RRFFQ69G5FAV" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/bookings/01ARZ3NDEKTSV4RRFFQ69G5FAV"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/bookings/01ARZ3NDEKTSV4RRFFQ69G5FAV';
$response = $client->delete(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/bookings/01ARZ3NDEKTSV4RRFFQ69G5FAV'
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('DELETE', url, headers=headers)
response.json()Example response (HTTP 200):
{
"message": "Booking cancelled",
"booking": {
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAV",
"reference_id": "BK-2025-001",
"created_at": "2025-01-01T00:00:00.000000Z",
"updated_at": "2025-01-01T00:00:00.000000Z",
"status": {
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAX",
"name": "cancelled"
},
"user": null,
"account": null,
"items": [],
"status_history": []
}
}
Example response (HTTP 400):
{
"message": "No account context set"
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 404):
{
"message": "Booking not found"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Send booking confirmation to customer.
requires authentication
Sends booking confirmation notification via email and SMS. This includes any access codes if the booking has locker assignments.
Example request:
curl --request POST \
"https://sandbox-api.shiftcollect.com/v1/bookings/01ARZ3NDEKTSV4RRFFQ69G5FAV/send-booking-confirmation" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/bookings/01ARZ3NDEKTSV4RRFFQ69G5FAV/send-booking-confirmation"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/bookings/01ARZ3NDEKTSV4RRFFQ69G5FAV/send-booking-confirmation';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/bookings/01ARZ3NDEKTSV4RRFFQ69G5FAV/send-booking-confirmation'
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers)
response.json()Example response (HTTP 200):
{
"message": "Booking confirmation notification queued successfully",
"recipients": [
{
"email": "[email protected]",
"phone": "+44 1234 567890"
}
]
}
Example response (HTTP 400):
{
"message": "No customer contact information available"
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 403):
{
"message": "This action is unauthorized."
}
Example response (HTTP 404):
{
"message": "Booking not found"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Send booking reminder email.
requires authentication
Sends a reminder email before the booking starts with all access codes.
Example request:
curl --request POST \
"https://sandbox-api.shiftcollect.com/v1/bookings/01ARZ3NDEKTSV4RRFFQ69G5FAV/send-reminder" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/bookings/01ARZ3NDEKTSV4RRFFQ69G5FAV/send-reminder"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/bookings/01ARZ3NDEKTSV4RRFFQ69G5FAV/send-reminder';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/bookings/01ARZ3NDEKTSV4RRFFQ69G5FAV/send-reminder'
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers)
response.json()Example response (HTTP 200):
{
"message": "Reminder notification queued successfully",
"recipients": [
{
"email": "[email protected]",
"phone": "+44 1234 567890"
}
]
}
Example response (HTTP 400):
{
"message": "No customer contact information available"
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 403):
{
"message": "This action is unauthorized."
}
Example response (HTTP 404):
{
"message": "Booking not found"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Send expiry reminder email.
requires authentication
Sends a reminder email before the booking expires.
Example request:
curl --request POST \
"https://sandbox-api.shiftcollect.com/v1/bookings/01ARZ3NDEKTSV4RRFFQ69G5FAV/send-expiry-reminder" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/bookings/01ARZ3NDEKTSV4RRFFQ69G5FAV/send-expiry-reminder"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/bookings/01ARZ3NDEKTSV4RRFFQ69G5FAV/send-expiry-reminder';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/bookings/01ARZ3NDEKTSV4RRFFQ69G5FAV/send-expiry-reminder'
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers)
response.json()Example response (HTTP 200):
{
"message": "Expiry reminder notification queued successfully",
"recipients": [
{
"email": "[email protected]",
"phone": "+44 1234 567890"
}
]
}
Example response (HTTP 400):
{
"message": "No customer contact information available"
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 403):
{
"message": "This action is unauthorized."
}
Example response (HTTP 404):
{
"message": "Booking not found"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Send cancellation notice email.
requires authentication
Sends a cancellation notice when a booking is cancelled.
Example request:
curl --request POST \
"https://sandbox-api.shiftcollect.com/v1/bookings/01ARZ3NDEKTSV4RRFFQ69G5FAV/send-cancellation-notice" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"cancellation_reason\": \"Customer request\"
}"
const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/bookings/01ARZ3NDEKTSV4RRFFQ69G5FAV/send-cancellation-notice"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"cancellation_reason": "Customer request"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/bookings/01ARZ3NDEKTSV4RRFFQ69G5FAV/send-cancellation-notice';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'cancellation_reason' => 'Customer request',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/bookings/01ARZ3NDEKTSV4RRFFQ69G5FAV/send-cancellation-notice'
payload = {
"cancellation_reason": "Customer request"
}
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()Example response (HTTP 200):
{
"message": "Cancellation notice queued successfully",
"recipients": [
{
"email": "[email protected]",
"phone": "+44 1234 567890"
}
]
}
Example response (HTTP 400):
{
"message": "No customer contact information available"
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 403):
{
"message": "This action is unauthorized."
}
Example response (HTTP 404):
{
"message": "Booking not found"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Add or update booking authorisations.
requires authentication
Adds or extends authorisation groups and locker users for an existing booking. The booking must belong to the current account context.
Generate lock codes for booking lockers.
requires authentication
Generates access codes for all lockers associated with a booking. The booking must belong to the current account context.
Example request:
curl --request POST \
"https://sandbox-api.shiftcollect.com/v1/bookings/01ARZ3NDEKTSV4RRFFQ69G5FAV/generate-codes" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/bookings/01ARZ3NDEKTSV4RRFFQ69G5FAV/generate-codes"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/bookings/01ARZ3NDEKTSV4RRFFQ69G5FAV/generate-codes';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/bookings/01ARZ3NDEKTSV4RRFFQ69G5FAV/generate-codes'
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers)
response.json()Example response (HTTP 200):
{
"message": "Lock codes generated",
"codes": [
{
"locker_id": "01ARZ3NDEKTSV4RRFFQ69G5FAC",
"code": "1234"
}
]
}
Example response (HTTP 400):
{
"message": "No account context set"
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 403):
{
"message": "This action is unauthorized."
}
Example response (HTTP 404):
{
"message": "Booking not found"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Cabinets
Display a listing of cabinets.
requires authentication
Returns a list of cabinets with optional filtering by status, version, layout, maintenance needs, or location. Cabinets include their lockers and arrangements.
Example request:
curl --request GET \
--get "https://sandbox-api.shiftcollect.com/v1/cabinets?status=active&version=v2.0&layout=standard&needs_maintenance=1&latitude=51.5074&longitude=-0.1278&radius=10" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/cabinets"
);
const params = {
"status": "active",
"version": "v2.0",
"layout": "standard",
"needs_maintenance": "1",
"latitude": "51.5074",
"longitude": "-0.1278",
"radius": "10",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/cabinets';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'query' => [
'status' => 'active',
'version' => 'v2.0',
'layout' => 'standard',
'needs_maintenance' => '1',
'latitude' => '51.5074',
'longitude' => '-0.1278',
'radius' => '10',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/cabinets'
params = {
'status': 'active',
'version': 'v2.0',
'layout': 'standard',
'needs_maintenance': '1',
'latitude': '51.5074',
'longitude': '-0.1278',
'radius': '10',
}
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (HTTP 200):
{
"data": [
{
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAA",
"name": "Cabinet A1",
"site_id": "01ARZ3NDEKTSV4RRFFQ69G5FAW",
"status": {
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAB",
"name": "active"
},
"version": {
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAC",
"version": "v2.0",
"layout": "standard"
},
"lockers": []
}
]
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 403):
{
"message": "This action is unauthorized."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Display the specified cabinet.
requires authentication
Returns detailed information about a specific cabinet, including its lockers and arrangements.
Example request:
curl --request GET \
--get "https://sandbox-api.shiftcollect.com/v1/cabinets/01ARZ3NDEKTSV4RRFFQ69G5FAA" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/cabinets/01ARZ3NDEKTSV4RRFFQ69G5FAA"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/cabinets/01ARZ3NDEKTSV4RRFFQ69G5FAA';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/cabinets/01ARZ3NDEKTSV4RRFFQ69G5FAA'
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (HTTP 200):
{
"data": {
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAA",
"name": "Cabinet A1",
"status": "active",
"total_active_lockers": 10,
"total_available_lockers": 5,
"site": {
"site_id": "01ARZ3NDEKTSV4RRFFQ69G5FAW",
"name": "Downtown Location"
},
"lockers": []
}
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 403):
{
"message": "This action is unauthorized."
}
Example response (HTTP 404):
{
"message": "Cabinet not found"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Collection Schedules
Store a newly created collection schedule.
requires authentication
Collection schedules are immutable - you cannot update or delete existing schedules. To change a schedule, create a new one with a future effective_from date. The system will automatically use the appropriate schedule based on the current date.
Example request:
curl --request POST \
"https://sandbox-api.shiftcollect.com/v1/despatch-centres/architecto/collection-schedules" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"despatch_centre_id\": \"01ARZ3NDEKTSV4RRFFQ69G5FAW\",
\"name\": \"Weekday Morning Collection\",
\"description\": \"Eius et animi quos velit et.\",
\"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\": \"2025-12-31T23:59:59Z\",
\"is_active\": true
}"
const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/despatch-centres/architecto/collection-schedules"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"despatch_centre_id": "01ARZ3NDEKTSV4RRFFQ69G5FAW",
"name": "Weekday Morning Collection",
"description": "Eius et animi quos velit et.",
"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": "2025-12-31T23:59:59Z",
"is_active": true
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/despatch-centres/architecto/collection-schedules';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'despatch_centre_id' => '01ARZ3NDEKTSV4RRFFQ69G5FAW',
'name' => 'Weekday Morning Collection',
'description' => 'Eius et animi quos velit et.',
'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' => '2025-12-31T23:59:59Z',
'is_active' => true,
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/despatch-centres/architecto/collection-schedules'
payload = {
"despatch_centre_id": "01ARZ3NDEKTSV4RRFFQ69G5FAW",
"name": "Weekday Morning Collection",
"description": "Eius et animi quos velit et.",
"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": "2025-12-31T23:59:59Z",
"is_active": true
}
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()Example response (HTTP 201):
{
"message": "Collection schedule created successfully",
"data": {
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAW",
"despatch_centre_id": "01ARZ3NDEKTSV4RRFFQ69G5FAX",
"name": "Weekday Morning Collection",
"collection_start_time": "08:00:00",
"collection_end_time": "10:00:00",
"days_of_week": [
0,
1,
2,
3,
4
],
"is_active": true
}
}
Example response (HTTP 400):
{
"message": "No account context set"
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 403):
{
"message": "This action is unauthorized."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Display a listing of collection schedules for a despatch centre.
requires authentication
Example request:
curl --request GET \
--get "https://sandbox-api.shiftcollect.com/v1/despatch-centres/01ARZ3NDEKTSV4RRFFQ69G5FAW/collection-schedules" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/despatch-centres/01ARZ3NDEKTSV4RRFFQ69G5FAW/collection-schedules"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/despatch-centres/01ARZ3NDEKTSV4RRFFQ69G5FAW/collection-schedules';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/despatch-centres/01ARZ3NDEKTSV4RRFFQ69G5FAW/collection-schedules'
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (HTTP 200):
{
"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
}
]
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 403):
{
"message": "This action is unauthorized."
}
Example response (HTTP 404):
{
"message": "Despatch centre not found or does not belong to your account"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Display the specified collection schedule.
requires authentication
Example request:
curl --request GET \
--get "https://sandbox-api.shiftcollect.com/v1/despatch-centres/01ARZ3NDEKTSV4RRFFQ69G5FAW/collection-schedules/01ARZ3NDEKTSV4RRFFQ69G5FAX" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/despatch-centres/01ARZ3NDEKTSV4RRFFQ69G5FAW/collection-schedules/01ARZ3NDEKTSV4RRFFQ69G5FAX"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/despatch-centres/01ARZ3NDEKTSV4RRFFQ69G5FAW/collection-schedules/01ARZ3NDEKTSV4RRFFQ69G5FAX';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/despatch-centres/01ARZ3NDEKTSV4RRFFQ69G5FAW/collection-schedules/01ARZ3NDEKTSV4RRFFQ69G5FAX'
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (HTTP 200):
{
"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
}
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 403):
{
"message": "This action is unauthorized."
}
Example response (HTTP 404):
{
"message": "Collection schedule not found"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Despatch Centres
Display a listing of despatch centres.
requires authentication
Returns a paginated list of despatch centres for the current account.
Example request:
curl --request GET \
--get "https://sandbox-api.shiftcollect.com/v1/despatch-centres?per_page=20&page=1" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/despatch-centres"
);
const params = {
"per_page": "20",
"page": "1",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/despatch-centres';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'query' => [
'per_page' => '20',
'page' => '1',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/despatch-centres'
params = {
'per_page': '20',
'page': '1',
}
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (HTTP 200):
{
"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": "[email protected]",
"is_active": true
}
],
"pagination": {
"current_page": 1,
"per_page": 50,
"total": 10,
"last_page": 1
}
}
Example response (HTTP 400):
{
"message": "No account context set"
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 403):
{
"message": "This action is unauthorized."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Display the specified despatch centre.
requires authentication
Example request:
curl --request GET \
--get "https://sandbox-api.shiftcollect.com/v1/despatch-centres/01ARZ3NDEKTSV4RRFFQ69G5FAW" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/despatch-centres/01ARZ3NDEKTSV4RRFFQ69G5FAW"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/despatch-centres/01ARZ3NDEKTSV4RRFFQ69G5FAW';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/despatch-centres/01ARZ3NDEKTSV4RRFFQ69G5FAW'
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (HTTP 200):
{
"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
}
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 403):
{
"message": "This action is unauthorized."
}
Example response (HTTP 404):
{
"message": "Despatch centre not found"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Store a newly created despatch centre.
requires authentication
Example request:
curl --request POST \
"https://sandbox-api.shiftcollect.com/v1/despatch-centres" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Main Warehouse\",
\"description\": \"Primary despatch centre\",
\"address_line_1\": \"123 Industrial Way\",
\"address_line_2\": \"Industrial Park\",
\"city\": \"London\",
\"postcode\": \"SW1A 1AA\",
\"county\": \"Greater London\",
\"country\": \"United Kingdom\",
\"latitude\": 51.5074,
\"longitude\": -0.1278,
\"access_instructions\": \"Enter through main gate\",
\"is_active\": true,
\"special_instructions\": \"Please park in the designated area\",
\"contact_phone\": \"+44 20 1234 5678\",
\"contact_email\": \"[email protected]\"
}"
const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/despatch-centres"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Main Warehouse",
"description": "Primary despatch centre",
"address_line_1": "123 Industrial Way",
"address_line_2": "Industrial Park",
"city": "London",
"postcode": "SW1A 1AA",
"county": "Greater London",
"country": "United Kingdom",
"latitude": 51.5074,
"longitude": -0.1278,
"access_instructions": "Enter through main gate",
"is_active": true,
"special_instructions": "Please park in the designated area",
"contact_phone": "+44 20 1234 5678",
"contact_email": "[email protected]"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/despatch-centres';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'name' => 'Main Warehouse',
'description' => 'Primary despatch centre',
'address_line_1' => '123 Industrial Way',
'address_line_2' => 'Industrial Park',
'city' => 'London',
'postcode' => 'SW1A 1AA',
'county' => 'Greater London',
'country' => 'United Kingdom',
'latitude' => 51.5074,
'longitude' => -0.1278,
'access_instructions' => 'Enter through main gate',
'is_active' => true,
'special_instructions' => 'Please park in the designated area',
'contact_phone' => '+44 20 1234 5678',
'contact_email' => '[email protected]',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/despatch-centres'
payload = {
"name": "Main Warehouse",
"description": "Primary despatch centre",
"address_line_1": "123 Industrial Way",
"address_line_2": "Industrial Park",
"city": "London",
"postcode": "SW1A 1AA",
"county": "Greater London",
"country": "United Kingdom",
"latitude": 51.5074,
"longitude": -0.1278,
"access_instructions": "Enter through main gate",
"is_active": true,
"special_instructions": "Please park in the designated area",
"contact_phone": "+44 20 1234 5678",
"contact_email": "[email protected]"
}
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()Example response (HTTP 201):
{
"message": "Despatch centre created successfully",
"data": {
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAW",
"name": "Main Warehouse"
}
}
Example response (HTTP 400):
{
"message": "No account context set"
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 403):
{
"message": "This action is unauthorized."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update the specified despatch centre.
requires authentication
Example request:
curl --request PUT \
"https://sandbox-api.shiftcollect.com/v1/despatch-centres/01ARZ3NDEKTSV4RRFFQ69G5FAW" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"b\",
\"description\": \"Et animi quos velit et fugiat.\",
\"address_line_1\": \"d\",
\"address_line_2\": \"l\",
\"city\": \"j\",
\"postcode\": \"nikhwaykcmyuwpwl\",
\"county\": \"v\",
\"country\": \"q\",
\"latitude\": -90,
\"longitude\": -179,
\"access_instructions\": \"s\",
\"is_active\": false
}"
const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/despatch-centres/01ARZ3NDEKTSV4RRFFQ69G5FAW"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "b",
"description": "Et animi quos velit et fugiat.",
"address_line_1": "d",
"address_line_2": "l",
"city": "j",
"postcode": "nikhwaykcmyuwpwl",
"county": "v",
"country": "q",
"latitude": -90,
"longitude": -179,
"access_instructions": "s",
"is_active": false
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/despatch-centres/01ARZ3NDEKTSV4RRFFQ69G5FAW';
$response = $client->put(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'name' => 'b',
'description' => 'Et animi quos velit et fugiat.',
'address_line_1' => 'd',
'address_line_2' => 'l',
'city' => 'j',
'postcode' => 'nikhwaykcmyuwpwl',
'county' => 'v',
'country' => 'q',
'latitude' => -90,
'longitude' => -179,
'access_instructions' => 's',
'is_active' => false,
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/despatch-centres/01ARZ3NDEKTSV4RRFFQ69G5FAW'
payload = {
"name": "b",
"description": "Et animi quos velit et fugiat.",
"address_line_1": "d",
"address_line_2": "l",
"city": "j",
"postcode": "nikhwaykcmyuwpwl",
"county": "v",
"country": "q",
"latitude": -90,
"longitude": -179,
"access_instructions": "s",
"is_active": false
}
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('PUT', url, headers=headers, json=payload)
response.json()Example response (HTTP 200):
{
"message": "Despatch centre updated successfully",
"data": {
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAW",
"name": "Main Warehouse"
}
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 403):
{
"message": "This action is unauthorized."
}
Example response (HTTP 404):
{
"message": "Despatch centre not found"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Remove the specified despatch centre.
requires authentication
Example request:
curl --request DELETE \
"https://sandbox-api.shiftcollect.com/v1/despatch-centres/01ARZ3NDEKTSV4RRFFQ69G5FAW" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/despatch-centres/01ARZ3NDEKTSV4RRFFQ69G5FAW"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/despatch-centres/01ARZ3NDEKTSV4RRFFQ69G5FAW';
$response = $client->delete(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/despatch-centres/01ARZ3NDEKTSV4RRFFQ69G5FAW'
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('DELETE', url, headers=headers)
response.json()Example response (HTTP 200):
{
"message": "Despatch centre deleted successfully"
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 403):
{
"message": "This action is unauthorized."
}
Example response (HTTP 404):
{
"message": "Despatch centre not found"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Labels
Get ZPL label data by label ID.
requires authentication
Returns the ZPL (Zebra Programming Language) data for a specific label. The label must belong to a booking in the current account context.
Example request:
curl --request GET \
--get "https://sandbox-api.shiftcollect.com/v1/labels/1111111119/zpl" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/labels/1111111119/zpl"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/labels/1111111119/zpl';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/labels/1111111119/zpl'
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (HTTP 200):
{
"label": "^XA^FO50,50^FDTest ZPL Label^FS^XZ"
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 403):
{
"message": "This action is unauthorized."
}
Example response (HTTP 404):
{
"message": "Label not found"
}
Example response (HTTP 404):
{
"message": "ZPL data not available for this label"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get PDF label data by label ID.
requires authentication
Returns the PDF binary data for a specific label. The label must belong to a booking in the current account context.
Example request:
curl --request GET \
--get "https://sandbox-api.shiftcollect.com/v1/labels/1111111119/pdf" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/labels/1111111119/pdf"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/labels/1111111119/pdf';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/labels/1111111119/pdf'
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (HTTP 200, PDF binary data with Content-Type: application/pdf):
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 403):
{
"message": "This action is unauthorized."
}
Example response (HTTP 404):
{
"message": "Label not found"
}
Example response (HTTP 404):
{
"message": "PDF data not available for this label"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get PNG label data by label ID.
requires authentication
Returns the PNG binary data for a specific label. The label must belong to a booking in the current account context.
Example request:
curl --request GET \
--get "https://sandbox-api.shiftcollect.com/v1/labels/1111111119/png" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/labels/1111111119/png"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/labels/1111111119/png';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/labels/1111111119/png'
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (HTTP 200, PNG binary data with Content-Type: image/png):
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 403):
{
"message": "This action is unauthorized."
}
Example response (HTTP 404):
{
"message": "Label not found"
}
Example response (HTTP 404):
{
"message": "PNG data not available for this label"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Sites
Display a listing of sites with search and pagination.
requires authentication
Returns a paginated list of active sites. Supports location-based filtering to find sites within a specified radius of coordinates.
Example request:
curl --request GET \
--get "https://sandbox-api.shiftcollect.com/v1/sites?latitude=51.5074&longitude=-0.1278&radius=10&per_page=20&page=1" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/sites"
);
const params = {
"latitude": "51.5074",
"longitude": "-0.1278",
"radius": "10",
"per_page": "20",
"page": "1",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/sites';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'query' => [
'latitude' => '51.5074',
'longitude' => '-0.1278',
'radius' => '10',
'per_page' => '20',
'page' => '1',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/sites'
params = {
'latitude': '51.5074',
'longitude': '-0.1278',
'radius': '10',
'per_page': '20',
'page': '1',
}
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (HTTP 200):
{
"data": [
{
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAW",
"name": "Downtown Location",
"address": {
"line_1": "123 Main St",
"line_2": null,
"line_3": "Greater London",
"city": "London",
"postcode": "SW1A 1AA",
"country": "United Kingdom"
},
"latitude": 51.5074,
"longitude": -0.1278,
"access_instructions": "Enter through main entrance",
"special_instructions": null,
"height_restriction": 2.5,
"contact_phone": "+44 20 1234 5678",
"contact_email": "[email protected]",
"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
}
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 403):
{
"message": "This action is unauthorized."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Display the specified site.
requires authentication
Returns detailed information about a specific site.
Example request:
curl --request GET \
--get "https://sandbox-api.shiftcollect.com/v1/sites/01ARZ3NDEKTSV4RRFFQ69G5FAW" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/sites/01ARZ3NDEKTSV4RRFFQ69G5FAW"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/sites/01ARZ3NDEKTSV4RRFFQ69G5FAW';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/sites/01ARZ3NDEKTSV4RRFFQ69G5FAW'
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (HTTP 200):
{
"data": {
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAW",
"name": "Downtown Location",
"address": {
"line_1": "123 Main St",
"line_2": null,
"line_3": "Greater London",
"city": "London",
"postcode": "SW1A 1AA",
"country": "United Kingdom"
},
"latitude": 51.5074,
"longitude": -0.1278,
"access_instructions": "Enter through main entrance",
"special_instructions": null,
"height_restriction": 2.5,
"contact_phone": "+44 20 1234 5678",
"contact_email": "[email protected]",
"is_active": true,
"site_access_codes": [
{
"id": "01ARZ3NDEKTSV4RRFFQ69G5FBA",
"name": "Customer access code 1",
"code": "AB12CD34",
"type": {
"id": "01ARZ3NDEKTSV4RRFFQ69G5FBB",
"name": "customer"
}
}
]
}
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 403):
{
"message": "This action is unauthorized."
}
Example response (HTTP 404):
{
"message": "Site not found"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Token Management
Generate API token for account.
requires authentication
Creates a new API token for the authenticated user in the current account context. Requires Admin or Owner role in the current account.
Example request:
curl --request POST \
"https://sandbox-api.shiftcollect.com/v1/tokens/generate" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"token_name\": \"Production API Token\",
\"expires_at\": \"2025-12-31T23:59:59Z\"
}"
const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/tokens/generate"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"token_name": "Production API Token",
"expires_at": "2025-12-31T23:59:59Z"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/tokens/generate';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'token_name' => 'Production API Token',
'expires_at' => '2025-12-31T23:59:59Z',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/tokens/generate'
payload = {
"token_name": "Production API Token",
"expires_at": "2025-12-31T23:59:59Z"
}
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()Example response (HTTP 201):
{
"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"
}
Example response (HTTP 400):
{
"message": "No account context set"
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 403):
{
"message": "This action is unauthorized."
}
Example response (HTTP 422):
{
"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."
]
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List API tokens for account.
requires authentication
Returns all API tokens for the authenticated user in the current account context. Requires Admin or Owner role in the current account.
Example request:
curl --request GET \
--get "https://sandbox-api.shiftcollect.com/v1/tokens?search=Production" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/tokens"
);
const params = {
"search": "Production",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/tokens';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'query' => [
'search' => 'Production',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/tokens'
params = {
'search': 'Production',
}
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (HTTP 200):
{
"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
}
Example response (HTTP 400):
{
"message": "No account context set"
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 403):
{
"message": "This action is unauthorized."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Revoke a specific API token.
requires authentication
Revokes a single API token by ID. Requires Admin or Owner role in the current account.
Example request:
curl --request DELETE \
"https://sandbox-api.shiftcollect.com/v1/tokens/1" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/tokens/1"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/tokens/1';
$response = $client->delete(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/tokens/1'
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('DELETE', url, headers=headers)
response.json()Example response (HTTP 200):
{
"message": "API token revoked successfully"
}
Example response (HTTP 400):
{
"message": "No account context set"
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 403):
{
"message": "This action is unauthorized."
}
Example response (HTTP 404):
{
"message": "Token not found"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Revoke all API tokens for account.
requires authentication
Revokes all API tokens for the authenticated user in the current account context. Requires Admin or Owner role in the current account.
Example request:
curl --request DELETE \
"https://sandbox-api.shiftcollect.com/v1/tokens" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/tokens"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/tokens';
$response = $client->delete(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/tokens'
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('DELETE', url, headers=headers)
response.json()Example response (HTTP 200):
{
"message": "All API tokens revoked successfully",
"deleted_count": 5
}
Example response (HTTP 400):
{
"message": "No account context set"
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 403):
{
"message": "This action is unauthorized."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
User Management
Get the current authenticated user
requires authentication
Returns information about the currently authenticated user, including all accounts they belong to, their roles in each account, and the current account context.
Example request:
curl --request GET \
--get "https://sandbox-api.shiftcollect.com/v1/user" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/user"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/user';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/user'
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (HTTP 200):
{
"data": {
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAV",
"name": "John Doe",
"email": "[email protected]",
"created_at": "2025-01-01T00:00:00.000000Z",
"is_active": true,
"accounts": [
{
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAW",
"name": "Acme Corp",
"slug": "acme-corp",
"is_active": true,
"joined_at": "2025-01-01T00:00:00.000000Z",
"role": "owner"
}
],
"current_account": {
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAW",
"name": "Acme Corp",
"slug": "acme-corp",
"role": "owner"
},
"role": "owner",
"permissions": [
"bookings.view",
"account.manage_users"
]
}
}
Example response (HTTP 401):
{
"message": "User not authenticated"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
string
The user's unique identifier (ID)
name
string
The user's full name
email
string
The user's email address
created_at
string
When the user account was created
is_active
boolean
Whether the user account is active
accounts
string[][]
Array of all accounts the user belongs to, with their roles
id
Account identifier (ID)
name
Account name
slug
Account URL slug
is_active
Whether the user is active in this account
joined_at
When the user joined this account
role
Role name for this account
current_account
object
The currently active account context
id
Account identifier (ID)
name
Account name
slug
Account URL slug
role
Role name for current account
role
string
Role name for the current account context
permissions
string[]
Array of permission names for the current account context
Webhooks
Display a listing of webhooks.
requires authentication
Returns all webhooks for the authenticated user's account.
Example request:
curl --request GET \
--get "https://sandbox-api.shiftcollect.com/v1/webhooks" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/webhooks"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/webhooks';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/webhooks'
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (HTTP 200):
{
"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"
}
]
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 403):
{
"message": "This action is unauthorized."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Create a new webhook.
requires authentication
Creates a webhook for the authenticated user's account. A unique secret will be generated automatically.
Example request:
curl --request POST \
"https://sandbox-api.shiftcollect.com/v1/webhooks" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Production Webhook\",
\"description\": \"Webhook for production events\",
\"url\": \"https:\\/\\/example.com\\/webhook\",
\"event_types\": [
\"booking.created\",
\"booking.cancelled\"
],
\"is_active\": false
}"
const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/webhooks"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Production Webhook",
"description": "Webhook for production events",
"url": "https:\/\/example.com\/webhook",
"event_types": [
"booking.created",
"booking.cancelled"
],
"is_active": false
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/webhooks';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'name' => 'Production Webhook',
'description' => 'Webhook for production events',
'url' => 'https://example.com/webhook',
'event_types' => [
'booking.created',
'booking.cancelled',
],
'is_active' => false,
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/webhooks'
payload = {
"name": "Production Webhook",
"description": "Webhook for production events",
"url": "https:\/\/example.com\/webhook",
"event_types": [
"booking.created",
"booking.cancelled"
],
"is_active": false
}
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()Example response (HTTP 201):
{
"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"
}
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 403):
{
"message": "This action is unauthorized."
}
Example response (HTTP 422):
{
"message": "The given data was invalid."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Display the specified webhook.
requires authentication
Returns detailed information about a specific webhook.
Example request:
curl --request GET \
--get "https://sandbox-api.shiftcollect.com/v1/webhooks/architecto" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/webhooks/architecto"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/webhooks/architecto';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/webhooks/architecto'
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (HTTP 200):
{
"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"
}
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 403):
{
"message": "This action is unauthorized."
}
Example response (HTTP 404):
{
"message": "Webhook not found"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update the specified webhook.
requires authentication
Updates a webhook's details.
Example request:
curl --request PUT \
"https://sandbox-api.shiftcollect.com/v1/webhooks/architecto" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Updated Webhook\",
\"description\": \"Updated description\",
\"url\": \"https:\\/\\/example.com\\/webhook\",
\"event_types\": [
\"booking.created\"
],
\"is_active\": true
}"
const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/webhooks/architecto"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Updated Webhook",
"description": "Updated description",
"url": "https:\/\/example.com\/webhook",
"event_types": [
"booking.created"
],
"is_active": true
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/webhooks/architecto';
$response = $client->put(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'name' => 'Updated Webhook',
'description' => 'Updated description',
'url' => 'https://example.com/webhook',
'event_types' => [
'booking.created',
],
'is_active' => true,
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/webhooks/architecto'
payload = {
"name": "Updated Webhook",
"description": "Updated description",
"url": "https:\/\/example.com\/webhook",
"event_types": [
"booking.created"
],
"is_active": true
}
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('PUT', url, headers=headers, json=payload)
response.json()Example response (HTTP 200):
{
"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"
}
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 403):
{
"message": "This action is unauthorized."
}
Example response (HTTP 404):
{
"message": "Webhook not found"
}
Example response (HTTP 422):
{
"message": "The given data was invalid."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Delete the specified webhook.
requires authentication
Permanently deletes a webhook.
Example request:
curl --request DELETE \
"https://sandbox-api.shiftcollect.com/v1/webhooks/architecto" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://sandbox-api.shiftcollect.com/v1/webhooks/architecto"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://sandbox-api.shiftcollect.com/v1/webhooks/architecto';
$response = $client->delete(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://sandbox-api.shiftcollect.com/v1/webhooks/architecto'
headers = {
'Authorization': 'Bearer {YOUR_API_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('DELETE', url, headers=headers)
response.json()Example response (HTTP 200):
{
"message": "Webhook deleted successfully"
}
Example response (HTTP 401):
{
"message": "Unauthenticated."
}
Example response (HTTP 403):
{
"message": "This action is unauthorized."
}
Example response (HTTP 404):
{
"message": "Webhook not found"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.