API reference
Custom fields
Fields of your own on every person, each with a visibility tier.
3 actions · base URL https://api.bizisy.com/v1 · generated from the same definitions as the API.
List custom fields#
POST/v1/org/fields.listRead
Lists the organization's custom person fields (key, label, type, options for select, tier, archived). Values live on each person (org_people_get → custom) and are set with org_people_update_profile or org_people_hire via custom: { <key>: value }. Tier decides who sees a field: public (everyone in the org), job (the person, their managers and HR) or private (the person and HR).
- Who can call it
- Manage key any Manage role
Me key anyone - MCP tool
org_fields_liston My Workplace, HR Assistant- Method
POSTwith a JSON body, orGETwith the input as query parameters
Input
include_archivedboolean
Returns
An array of objects with 9 fields
An array of objects:
idstringrequiredkeystringrequiredlabelstringrequiredtype"text" | "number" | "date" | "select" | "boolean" | "file"requiredoptionsstring[]requiredtier"public" | "job" | "private"requiredarchivedbooleanrequiredpositionintegerrequiredfileobject | nullrequiredType file only; null for other types.
3 fields
kinds"pdf" | "image" | "office"[]requiredpdf (PDF), image (PNG, JPEG, WebP, HEIC), office (DOCX, XLSX, ODT, ODS).
max_mbinteger | nullrequiredThe field's largest file in MB; null = the company's limit. The smaller of the two applies.
self_uploadbooleanrequiredPeople upload their own file in Bizisy Me (it counts toward their monthly self-upload limit).
Errors
validation_failed unauthenticated forbidden not_found rate_limited internal
curl https://api.bizisy.com/v1/org/fields.list \
-H "Authorization: Bearer $BIZISY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"include_archived":true}'const res = await fetch('https://api.bizisy.com/v1/org/fields.list', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.BIZISY_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"include_archived": true
}),
});
const body = await res.json();
if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
console.log(body.data);import os
import requests
res = requests.post(
"https://api.bizisy.com/v1/org/fields.list",
headers={"Authorization": f"Bearer {os.environ['BIZISY_API_KEY']}"},
json={
"include_archived": True,
},
)
body = res.json()
if not res.ok:
raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
print(body["data"]){
"data": [
{
"id": "f1",
"key": "t_shirt_size",
"label": "T-shirt size",
"type": "select",
"options": [
"S",
"M",
"L"
],
"tier": "public",
"archived": false,
"position": 1,
"file": null
},
{
"id": "f2",
"key": "driving_licence",
"label": "Driving licence",
"type": "file",
"options": [],
"tier": "private",
"archived": false,
"position": 2,
"file": {
"kinds": [
"pdf",
"image"
],
"max_mb": 10,
"self_upload": true
}
}
]
}Add a custom field#
POST/v1/org/fields.createWrite
Adds a custom person field. label (shown in the app), type (text, number, date, select, boolean, file), options (2–50, select only), tier (public, job or private; default private). key defaults to the label in snake_case and never changes. File fields hold one file per person (a document: it also shows in the person's Documents, from the field) and take file: { kinds (pdf, image, office; default all), max_mb (1–100 or null for the company's largest-file limit; the smaller applies), self_upload (default false: people upload their own in Bizisy Me, counted toward their monthly self-upload limit) }; their files follow the field's tier. At most 30 active fields.
- Who can call it
- Manage key owner admin hr
- MCP tool
org_fields_createon HR Assistant- Preview
?dry_run=trueruns every check and saves nothing- Retries
- An Idempotency-Key replays the first result
Input
labelstringrequired1–60 characters.
type"text" | "number" | "date" | "select" | "boolean" | "file"requiredoptionsstring[]1–80 characters. 2–50 items.
tier"public" | "job" | "private"Default
"private".keystringPattern
^[a-z][a-z0-9_]{0,39}$.fileobject3 fields
kinds"pdf" | "image" | "office"[]1–10 items.
max_mbinteger | nullFrom 1 to 100.
self_uploadboolean
Returns
9 fields
idstringrequiredkeystringrequiredlabelstringrequiredtype"text" | "number" | "date" | "select" | "boolean" | "file"requiredoptionsstring[]requiredtier"public" | "job" | "private"requiredarchivedbooleanrequiredpositionintegerrequiredfileobject | nullrequiredType file only; null for other types.
3 fields
kinds"pdf" | "image" | "office"[]requiredpdf (PDF), image (PNG, JPEG, WebP, HEIC), office (DOCX, XLSX, ODT, ODS).
max_mbinteger | nullrequiredThe field's largest file in MB; null = the company's limit. The smaller of the two applies.
self_uploadbooleanrequiredPeople upload their own file in Bizisy Me (it counts toward their monthly self-upload limit).
Errors
validation_failed unauthenticated forbidden not_found conflict rate_limited internal
curl https://api.bizisy.com/v1/org/fields.create \
-H "Authorization: Bearer $BIZISY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"label": "Driving licence",
"type": "file",
"file": {
"kinds": [
"pdf",
"image"
],
"max_mb": 10,
"self_upload": true
}
}'const res = await fetch('https://api.bizisy.com/v1/org/fields.create', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.BIZISY_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({
"label": "Driving licence",
"type": "file",
"file": {
"kinds": [
"pdf",
"image"
],
"max_mb": 10,
"self_upload": true
}
}),
});
const body = await res.json();
if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
console.log(body.data);import os, uuid
import requests
res = requests.post(
"https://api.bizisy.com/v1/org/fields.create",
headers={"Authorization": f"Bearer {os.environ['BIZISY_API_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"label": "Driving licence",
"type": "file",
"file": {
"kinds": [
"pdf",
"image",
],
"max_mb": 10,
"self_upload": True,
},
},
)
body = res.json()
if not res.ok:
raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
print(body["data"]){
"data": {
"id": "f1",
"key": "t_shirt_size",
"label": "Driving licence",
"type": "file",
"options": [
"S",
"M",
"L"
],
"tier": "public",
"archived": false,
"position": 1,
"file": null
}
}Change a custom field#
POST/v1/org/fields.updateWrite
Changes a custom field: label, tier, options (select only; removing an option some people still have is refused), file options (file only: kinds, max_mb, self_upload; they apply to new uploads, files already attached stay), position, or archived (archived fields are hidden from forms; their values are kept and included in personal-data exports, not in the people CSV). The key and type never change. Widening the tier (private to job or public, job to public) while people have values would show those values to more people: it is refused unless confirm_expose_existing is true, which is accepted only in the app, after the user confirmed.
- Who can call it
- Manage key owner admin hr
- Keys and apps
- confirm_expose_existing (widening a tier while people have values) is refused.
- MCP tool
org_fields_updateon HR Assistant- Preview
?dry_run=trueruns every check and saves nothing- Retries
- An Idempotency-Key replays the first result
Input
field_idstringrequiredlabelstring1–60 characters.
tier"public" | "job" | "private"optionsstring[]1–80 characters. 2–50 items.
positionintegerFrom 0 to 1000.
archivedbooleanfileobject3 fields
kinds"pdf" | "image" | "office"[]1–10 items.
max_mbinteger | nullFrom 1 to 100.
self_uploadboolean
confirm_expose_existingboolean
Returns
10 fields
idstringrequiredkeystringrequiredlabelstringrequiredtype"text" | "number" | "date" | "select" | "boolean" | "file"requiredoptionsstring[]requiredtier"public" | "job" | "private"requiredarchivedbooleanrequiredpositionintegerrequiredfileobject | nullrequiredType file only; null for other types.
3 fields
kinds"pdf" | "image" | "office"[]requiredpdf (PDF), image (PNG, JPEG, WebP, HEIC), office (DOCX, XLSX, ODT, ODS).
max_mbinteger | nullrequiredThe field's largest file in MB; null = the company's limit. The smaller of the two applies.
self_uploadbooleanrequiredPeople upload their own file in Bizisy Me (it counts toward their monthly self-upload limit).
previous_tier"public" | "job" | "private"required
Errors
validation_failed unauthenticated forbidden not_found conflict rate_limited internal
curl https://api.bizisy.com/v1/org/fields.update \
-H "Authorization: Bearer $BIZISY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"field_id": "f1",
"tier": "job",
"options": [
"S",
"M",
"L",
"XL"
],
"position": 2,
"archived": true
}'const res = await fetch('https://api.bizisy.com/v1/org/fields.update', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.BIZISY_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({
"field_id": "f1",
"tier": "job",
"options": [
"S",
"M",
"L",
"XL"
],
"position": 2,
"archived": true
}),
});
const body = await res.json();
if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
console.log(body.data);import os, uuid
import requests
res = requests.post(
"https://api.bizisy.com/v1/org/fields.update",
headers={"Authorization": f"Bearer {os.environ['BIZISY_API_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"field_id": "f1",
"tier": "job",
"options": [
"S",
"M",
"L",
"XL",
],
"position": 2,
"archived": True,
},
)
body = res.json()
if not res.ok:
raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
print(body["data"]){
"data": {
"id": "f1",
"key": "t_shirt_size",
"label": "T-shirt size",
"type": "select",
"options": [
"S",
"M",
"L"
],
"tier": "job",
"archived": true,
"position": 2,
"file": null,
"previous_tier": "private"
}
}Something missing or wrong on this page? Write to hello@bizisy.com.