Scopes
| Scope | Allows |
|---|---|
company_catalog:read | Read company profile, facilities, services, and company policies. |
locations:read | List and read company locations. |
locations:write | Create, update, and archive locations. |
Rate limits
All resource calls use the standard Public API Bearer-token rate limit. Responses include the current rate-limit headers when rate limiting is enabled:| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests in the current window. |
X-RateLimit-Remaining | Requests remaining in the current window. |
X-RateLimit-Reset | Reset time for the current window. |
Retry-After | Seconds to wait after a 429 response. |
Company profile
GET /public/v1/company-profile
Authorization: Bearer <access_token>
company_catalog:read
Response fields:
| Field | Type | Nullable | Description |
|---|---|---|---|
data.company.companyId | string | no | Company ID. |
data.company.name | string | no | Company display name. |
data.company.slug | string | no | Public slug when configured. |
data.company.logoUrl | string | no | Company logo URL when configured. |
data.company.imageUrl | string | no | Company image URL when configured. |
data.company.businessType | string | no | Business type label when configured. |
data.company.email | string | no | Public company email. |
data.company.phoneNumber | string | no | Public company phone number. |
data.company.about | string | no | Public company profile text. |
data.company.location.address | string | no | Full address string. |
data.company.location.addressLine1 | string | no | Address line 1. |
data.company.location.addressLine2 | string | no | Address line 2 or street number. |
data.company.location.zipCode | string | no | Postal code. |
data.company.location.city | string | no | City. |
data.company.location.country | string | no | Country. |
data.company.primaryLanguage | string | no | Primary language code. |
data.company.secondaryLanguage | string | no | Secondary language code. |
data.company.timeZone | string | no | IANA timezone. |
data.company.timeFormat | string | no | Company time display format. |
data.company.dateFormat | string | no | Company date display format. |
data.company.currency | string | no | ISO currency code when configured. |
data.company.profileVisibility | boolean | no | Whether the company profile is public. |
data.company.socialMedia.website | string | no | Website URL. |
data.company.socialMedia.instagram | string | no | Instagram URL or handle. |
data.company.socialMedia.facebook | string | no | Facebook URL or handle. |
data.company.socialMedia.linkedin | string | no | LinkedIn URL or handle. |
data.company.socialMedia.youtube | string | no | YouTube URL or handle. |
data.company.socialMedia.twitter | string | no | Twitter/X URL or handle. |
data.company.createdAt | string | yes | Creation timestamp. |
data.company.updatedAt | string | yes | Update timestamp. |
Facilities and services
GET /public/v1/facilities-services
Authorization: Bearer <access_token>
company_catalog:read
Response fields:
| Field | Type | Nullable | Description |
|---|---|---|---|
data.facilitiesAndServices.facilities[] | array | no | Selected facility keys. |
data.facilitiesAndServices.services[] | array | no | Selected service keys. |
data.facilitiesAndServices.source | string | no | embedded, legacy, or defaults depending on stored source. |
data.facilitiesAndServices.updatedAt | string | yes | Update timestamp for the selected source. |
Company policies
GET /public/v1/company-policies
Authorization: Bearer <access_token>
company_catalog:read
Response fields:
| Field | Type | Nullable | Description |
|---|---|---|---|
data.policies.privacy.defaultLanguage | string | yes | null until policy storage declares a source language. |
data.policies.privacy.content | object | no | Stored privacy policy text by language code, or {}. |
data.policies.privacy.updatedAt | object | no | Per-language update timestamps, each ISO UTC or null. |
data.policies.terms.defaultLanguage | string | yes | null until policy storage declares a source language. |
data.policies.terms.content | object | no | Stored terms text by language code, or {}. |
data.policies.terms.updatedAt | object | no | Per-language update timestamps, each ISO UTC or null. |
data.policies.updatedAt | string | yes | Policy document update timestamp. |
Locations
GET /public/v1/locations?page=1&limit=100
POST /public/v1/locations
GET /public/v1/locations/{locationId}
PATCH /public/v1/locations/{locationId}
POST /public/v1/locations/{locationId}/archive
locations:read for reads, locations:write for writes.
List responses include pagination fields:
| Field | Type | Nullable | Description |
|---|---|---|---|
data.page | integer | no | Current page. |
data.limit | integer | no | Page size after applying the maximum. |
data.total | integer | no | Total matching locations. |
data.totalPages | integer | no | Number of pages. |
data.hasNextPage | boolean | no | Whether another page exists. |
data.hasPrevPage | boolean | no | Whether a previous page exists. |
data.locations[] | array | no | Location DTOs. |
| Field | Type | Nullable | Description |
|---|---|---|---|
locationId | string | no | Location ID. |
name | string | no | Location name. |
alternateName | string | no | Optional alternate name. |
address | string | no | Address label. |
primary | boolean | no | Whether this is the primary company location. |
coordinates.longitude | number | yes | Longitude. |
coordinates.latitude | number | yes | Latitude. |
timeZone | string | no | IANA timezone. |
type | string | no | branch, outdoor, online, external, or temporary. |
allowsClientAssignment | boolean | no | Whether clients can be assigned to this location. |
accessZones[].key | string | no | Stable zone key. |
accessZones[].name | string | no | Zone display name. |
accessZones[].isActive | boolean | no | Zone active flag. |
facilitiesAndServices.mode | string | no | inherit or custom. |
facilitiesAndServices.facilities[] | array | no | Facility keys. |
facilitiesAndServices.services[] | array | no | Service keys. |
profile.visibility | string | no | Location profile visibility mode. |
profile.displayName | string | no | Public display name. |
profile.description | string | no | Public description. |
profile.website | string | no | Public website. |
profile.email | string | no | Public email. |
profile.phone | string | no | Public phone number. |
profile.socialMedia.instagram | string | no | Instagram URL or handle. |
profile.socialMedia.facebook | string | no | Facebook URL or handle. |
profile.socialMedia.linkedin | string | no | LinkedIn URL or handle. |
profile.socialMedia.youtube | string | no | YouTube URL or handle. |
profile.socialMedia.twitter | string | no | Twitter/X URL or handle. |
openingHours.mode | string | no | Opening-hours mode. |
openingHours.weeklyPattern[].dayOfWeek | integer | yes | Day number, 0 through 6. |
openingHours.weeklyPattern[].slots[].startTime | string | no | Local start time, HH:mm. |
openingHours.weeklyPattern[].slots[].endTime | string | no | Local end time, HH:mm. |
openingHours.exceptions[].date | string | yes | Exception date timestamp. |
openingHours.exceptions[].type | string | no | Exception type, such as closed. |
openingHours.exceptions[].slots[].startTime | string | no | Exception slot start time. |
openingHours.exceptions[].slots[].endTime | string | no | Exception slot end time. |
openingHours.exceptions[].reason | string | no | Public reason text when configured. |
archived | boolean | no | Whether the location is archived. |
createdAt | string | yes | Creation timestamp. |
updatedAt | string | yes | Update timestamp. |
| Input | Rule |
|---|---|
page | Integer, minimum 1. |
limit | Integer, default 100, maximum 100. |
locationId | Must be a valid MongoDB ObjectId. |
name | Required on create. |
type | Must be branch, outdoor, online, external, or temporary. |
coordinates | Must contain numeric longitude and latitude values. |
accessZones | Must be an array; entries without both key and name are ignored. |
facilitiesAndServices.mode | Must be inherit or custom. |
facilitiesAndServices.facilities[] | Unknown facility keys are ignored. |
facilitiesAndServices.services[] | Unknown service keys are ignored. |
List locations example
curl -H "Authorization: Bearer $FITSOCIETY_ACCESS_TOKEN" \
"https://api.fitsociety.io/public/v1/locations?page=1&limit=100"
const response = await fetch(
"https://api.fitsociety.io/public/v1/locations?page=1&limit=100",
{
headers: {
Authorization: `Bearer ${process.env.FITSOCIETY_ACCESS_TOKEN}`,
},
},
);
const body = await response.json();
console.log(body.data.total, body.data.locations);
import os
import requests
response = requests.get(
"https://api.fitsociety.io/public/v1/locations",
headers={"Authorization": f"Bearer {os.environ['FITSOCIETY_ACCESS_TOKEN']}"},
params={"page": 1, "limit": 100},
)
response.raise_for_status()
body = response.json()
print(body["data"]["total"], body["data"]["locations"])
{
"data": {
"page": 1,
"limit": 100,
"total": 1,
"totalPages": 1,
"hasNextPage": false,
"hasPrevPage": false,
"locations": [
{
"locationId": "64b64c0f2f5f4c00123456e5",
"name": "Amsterdam HQ",
"alternateName": "",
"address": "Main street 1, 1011AB Amsterdam",
"primary": true,
"coordinates": { "longitude": 4.9041, "latitude": 52.3676 },
"timeZone": "Europe/Amsterdam",
"type": "branch",
"allowsClientAssignment": true,
"archived": false,
"createdAt": "2026-01-05T09:00:00.000Z",
"updatedAt": "2026-07-01T09:00:00.000Z"
}
]
},
"meta": {
"requestId": "req_0123456789abcdef",
"rateLimit": { "limit": 10, "remaining": 9, "resetSeconds": 1 }
}
}
Create location example
curl -X POST "https://api.fitsociety.io/public/v1/locations" \
-H "Authorization: Bearer $FITSOCIETY_ACCESS_TOKEN" \
-H "Idempotency-Key: location-create-utrecht-studio-20260823" \
-H "Content-Type: application/json" \
-d '{
"name": "Utrecht studio",
"address": "Stationsplein 10, 3511ED Utrecht",
"type": "branch",
"timeZone": "Europe/Amsterdam",
"allowsClientAssignment": true,
"coordinates": { "longitude": 5.1101, "latitude": 52.0894 }
}'
const response = await fetch("https://api.fitsociety.io/public/v1/locations", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.FITSOCIETY_ACCESS_TOKEN}`,
"Idempotency-Key": "location-create-utrecht-studio-20260823",
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Utrecht studio",
address: "Stationsplein 10, 3511ED Utrecht",
type: "branch",
timeZone: "Europe/Amsterdam",
allowsClientAssignment: true,
coordinates: { longitude: 5.1101, latitude: 52.0894 },
}),
});
const body = await response.json();
if (response.status === 201) {
console.log("Created location", body.data.location.locationId);
}
import os
import requests
response = requests.post(
"https://api.fitsociety.io/public/v1/locations",
headers={
"Authorization": f"Bearer {os.environ['FITSOCIETY_ACCESS_TOKEN']}",
"Idempotency-Key": "location-create-utrecht-studio-20260823",
},
json={
"name": "Utrecht studio",
"address": "Stationsplein 10, 3511ED Utrecht",
"type": "branch",
"timeZone": "Europe/Amsterdam",
"allowsClientAssignment": True,
"coordinates": {"longitude": 5.1101, "latitude": 52.0894},
},
)
response.raise_for_status()
body = response.json()
if response.status_code == 201:
print("Created location", body["data"]["location"]["locationId"])
201 Created):
{
"data": {
"location": {
"locationId": "64b64c0f2f5f4c00123456e6",
"name": "Utrecht studio",
"alternateName": "",
"address": "Stationsplein 10, 3511ED Utrecht",
"primary": false,
"coordinates": { "longitude": 5.1101, "latitude": 52.0894 },
"timeZone": "Europe/Amsterdam",
"type": "branch",
"allowsClientAssignment": true,
"archived": false,
"createdAt": "2026-08-23T10:00:00.000Z",
"updatedAt": "2026-08-23T10:00:00.000Z"
}
},
"meta": {
"requestId": "req_0123456789abcdef",
"rateLimit": { "limit": 10, "remaining": 8, "resetSeconds": 1 }
}
}
Archive location example
Archive is an action route (POST .../archive), not a DELETE. Empty request
bodies are accepted; the Idempotency-Key header is still required.
curl -X POST "https://api.fitsociety.io/public/v1/locations/64b64c0f2f5f4c00123456e6/archive" \
-H "Authorization: Bearer $FITSOCIETY_ACCESS_TOKEN" \
-H "Idempotency-Key: location-archive-64b64c0f2f5f4c00123456e6"
const locationId = "64b64c0f2f5f4c00123456e6";
const response = await fetch(
`https://api.fitsociety.io/public/v1/locations/${locationId}/archive`,
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.FITSOCIETY_ACCESS_TOKEN}`,
"Idempotency-Key": `location-archive-${locationId}`,
},
},
);
const body = await response.json();
console.log(body.data.location.archived);
import os
import requests
location_id = "64b64c0f2f5f4c00123456e6"
response = requests.post(
f"https://api.fitsociety.io/public/v1/locations/{location_id}/archive",
headers={
"Authorization": f"Bearer {os.environ['FITSOCIETY_ACCESS_TOKEN']}",
"Idempotency-Key": f"location-archive-{location_id}",
},
)
response.raise_for_status()
body = response.json()
print(body["data"]["location"]["archived"])
{
"data": {
"location": {
"locationId": "64b64c0f2f5f4c00123456e6",
"name": "Utrecht studio",
"archived": true,
"updatedAt": "2026-08-23T10:05:00.000Z"
}
},
"meta": {
"requestId": "req_0123456789abcdef",
"rateLimit": { "limit": 10, "remaining": 7, "resetSeconds": 1 }
}
}