API reference
Documents
Company and person documents: list, upload, change, download and delete; categories.
8 actions · base URL https://api.bizisy.com/v1 · generated from the same definitions as the API.
List documents#
POST/v1/documents/listRead
Lists documents you can see, newest first (or largest first with sort=largest): person documents (contracts, addenda, certificates, ID copies…) and company documents (handbook, policies…). Filters: person_id (one person's documents), scope (person, company or all), category, q (words in the title). Owners, admins and HR see every document; others see the company documents shared with them and their own. Person documents are private: through an API key or an AI assistant, other people's documents come as metadata only (title, category, date, size; access = metadata), never their contents.
- Who can call it
- Manage key any Manage role
- Keys and apps
- Other people's documents come as metadata only.
- MCP tool
documents_liston HR Assistant- Method
POSTwith a JSON body, orGETwith the input as query parameters
Input
person_idstringscope"person" | "company" | "all"Default all (person_id implies person).
categorystringUp to 60 characters.
qstringWords that must all appear in the title (case-insensitive).
Up to 100 characters.
sort"newest" | "largest"limitintegerDefault 500.
From 1 to 500.
Returns
documentsobject[]required14 fields
idstringrequiredtitlestringrequiredcategorystringrequiredsubjectobjectrequired3 fields (one of several shapes)
Option 1
kind"person"requiredpersonobject | nullrequired2 fields
idstringrequirednamestringrequired
Option 2
kind"company"required
visibility"hr" | "hr_person" | "hr_person_manager" | "everyone" | "managers" | "hr"requireduploaded_by"hr" | "self"requiredself: the person added it themself ("From me", or a custom field they fill in).
fieldobject | nullrequiredA custom file field's file (
org_fields_list): its visibility follows the field's tier; replace or remove it through the field.2 fields
keystringrequiredlabelstringrequired
expires_onstring | nullrequirednotesstring | nullrequirednull when you only see metadata.
fileobjectrequired4 fields
namestring | nullrequiredThe original file name; null when you only see metadata.
sizeintegerrequiredcontent_typestringrequiredpreviewablebooleanrequiredThe web app can show it (PDF, PNG, JPEG, WebP).
access"full" | "metadata"requiredmetadata: title, category, date and size only (no notes, no download): API keys and AI assistants never get the contents of other people's documents.
status"pending" | "ready"requiredcreated_atstringrequiredupdated_atstringrequired
categoriesstring[]requiredEvery category in use for new documents: the starter list and your own.
max_file_bytesintegerrequiredThe largest file allowed (Settings → Storage).
Errors
validation_failed unauthenticated forbidden not_found rate_limited internal
curl https://api.bizisy.com/v1/documents/list \
-H "Authorization: Bearer $BIZISY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"person_id": "p1",
"category": "Contract",
"q": "contract",
"sort": "largest",
"limit": 5
}'const res = await fetch('https://api.bizisy.com/v1/documents/list', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.BIZISY_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"person_id": "p1",
"category": "Contract",
"q": "contract",
"sort": "largest",
"limit": 5
}),
});
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/documents/list",
headers={"Authorization": f"Bearer {os.environ['BIZISY_API_KEY']}"},
json={
"person_id": "p1",
"category": "Contract",
"q": "contract",
"sort": "largest",
"limit": 5,
},
)
body = res.json()
if not res.ok:
raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
print(body["data"]){
"data": {
"documents": [
{
"id": "d1",
"title": "Contract 2026",
"category": "Contract",
"subject": {
"kind": "person",
"person": {
"id": "p1",
"name": "Ana Ferreira"
}
},
"visibility": "hr_person",
"uploaded_by": "hr",
"field": null,
"expires_on": "2027-01-31",
"notes": "Signed copy",
"file": {
"name": "Contract 2026.pdf",
"size": 182000,
"content_type": "application/pdf",
"previewable": true
},
"access": "full",
"status": "ready",
"created_at": "2026-10-05T10:00:00.000Z",
"updated_at": "2026-10-05T10:00:00.000Z"
},
{
"id": "d2",
"title": "Contract 2026",
"category": "Contract",
"subject": {
"kind": "person",
"person": {
"id": "p1",
"name": "Ana Ferreira"
}
},
"visibility": "hr_person",
"uploaded_by": "hr",
"field": null,
"expires_on": "2027-01-31",
"notes": null,
"file": {
"name": null,
"size": 182000,
"content_type": "application/pdf",
"previewable": true
},
"access": "metadata",
"status": "ready",
"created_at": "2026-10-05T10:00:00.000Z",
"updated_at": "2026-10-05T10:00:00.000Z"
},
{
"id": "d3",
"title": "Employee handbook",
"category": "Handbook",
"subject": {
"kind": "company"
},
"visibility": "everyone",
"uploaded_by": "hr",
"field": null,
"expires_on": null,
"notes": null,
"file": {
"name": "Contract 2026.pdf",
"size": 182000,
"content_type": "application/pdf",
"previewable": true
},
"access": "full",
"status": "ready",
"created_at": "2026-10-05T10:00:00.000Z",
"updated_at": "2026-10-05T10:00:00.000Z"
}
],
"categories": [
"Contract",
"Addendum",
"Certificate",
"ID",
"Policy",
"Handbook",
"Other",
"Payslip"
],
"max_file_bytes": 25000000
}
}Start a document upload#
POST/v1/documents/upload.startWrite
Adds a document in two calls and one upload: (1) this call with the subject (a person, or the company), category, optional title (default: the file name), visibility, expires_on and notes, and the file's name, size, content_type and sha256; (2) PUT the file's bytes to the returned signed URL within 15 minutes, with exactly the returned headers (the size is part of them); (3) documents_upload_finish with the document id. Person document visibility: hr (owners, admins, HR), hr_person (default; also the person) or hr_person_manager (also their managers). Company: everyone (default), managers (people with reports and HR) or hr. Accepted: PDF, PNG, JPEG, WebP, HEIC, DOCX, XLSX, ODT, ODS, TXT, CSV (checked from the bytes; macros, archives and executables are refused); the largest file and the company's storage ceiling are set in Settings → Storage. Above 500 MB a company pays €1 per GB per month. Owners, admins and HR.
- Who can call it
- Manage key owner admin hr
- MCP tool
documents_upload_starton HR Assistant- Preview
?dry_run=trueruns every check and saves nothing- Retries
- An Idempotency-Key prevents a second run, but the result is never stored (it holds a secret or personal data): a retry gets a 409 that points to Activity
Input
subjectobjectrequired3 fields (one of several shapes)
Option 1
kind"person"requiredperson_idstringrequired
Option 2
kind"company"required
categorystringrequired1–40 characters.
titlestringUp to 200 characters.
visibility"hr" | "hr_person" | "hr_person_manager" | "everyone" | "managers" | "hr"expires_onstring | nullPattern
^\d{4}-\d{2}-\d{2}$.notesstring | nullUp to 2000 characters.
fileobjectrequired4 fields
namestringrequiredThe file name, e.g. "Contract 2026.pdf" (kept as metadata only).
1–500 characters.
sizeintegerrequiredBytes. Must equal what is uploaded.
At least 0.
content_typestringrequiredapplication/pdf, image/png, image/jpeg, image/webp, image/heic, DOCX, XLSX, ODT or ODS MIME type, text/plain or text/csv. Must match the bytes.
1–200 characters.
sha256stringrequiredLowercase hex SHA-256 of the file; checked against the upload.
Pattern
^[0-9a-f]{64}$.
Returns
documentobjectrequired14 fields
idstringrequiredtitlestringrequiredcategorystringrequiredsubjectobjectrequired3 fields (one of several shapes)
Option 1
kind"person"requiredpersonobject | nullrequired2 fields
idstringrequirednamestringrequired
Option 2
kind"company"required
visibility"hr" | "hr_person" | "hr_person_manager" | "everyone" | "managers" | "hr"requireduploaded_by"hr" | "self"requiredself: the person added it themself ("From me", or a custom field they fill in).
fieldobject | nullrequiredA custom file field's file (
org_fields_list): its visibility follows the field's tier; replace or remove it through the field.2 fields
keystringrequiredlabelstringrequired
expires_onstring | nullrequirednotesstring | nullrequirednull when you only see metadata.
fileobjectrequired4 fields
namestring | nullrequiredThe original file name; null when you only see metadata.
sizeintegerrequiredcontent_typestringrequiredpreviewablebooleanrequiredThe web app can show it (PDF, PNG, JPEG, WebP).
access"full" | "metadata"requiredmetadata: title, category, date and size only (no notes, no download): API keys and AI assistants never get the contents of other people's documents.
status"pending" | "ready"requiredcreated_atstringrequiredupdated_atstringrequired
uploadobject | nullrequirednull on a dry run.
4 fields
urlstringrequiredShort-lived signed URL (15 minutes). Never share it.
method"PUT"requiredheadersobjectrequiredSend exactly these headers (they include the exact file size: any other size is refused).
resumablefalserequiredAlways false: upload the whole file in one PUT.
upload_expires_atstringrequired
Errors
validation_failed unauthenticated forbidden not_found conflict rate_limited internal
curl https://api.bizisy.com/v1/documents/upload.start \
-H "Authorization: Bearer $BIZISY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"subject": {
"kind": "person",
"person_id": "p1"
},
"category": "Contract",
"title": "Contract 2026",
"visibility": "hr_person_manager",
"expires_on": "2027-01-31",
"notes": "Signed",
"file": {
"name": "Contract 2026.pdf",
"size": 182000,
"content_type": "application/pdf",
"sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
}
}'const res = await fetch('https://api.bizisy.com/v1/documents/upload.start', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.BIZISY_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({
"subject": {
"kind": "person",
"person_id": "p1"
},
"category": "Contract",
"title": "Contract 2026",
"visibility": "hr_person_manager",
"expires_on": "2027-01-31",
"notes": "Signed",
"file": {
"name": "Contract 2026.pdf",
"size": 182000,
"content_type": "application/pdf",
"sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
}
}),
});
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/documents/upload.start",
headers={"Authorization": f"Bearer {os.environ['BIZISY_API_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"subject": {
"kind": "person",
"person_id": "p1",
},
"category": "Contract",
"title": "Contract 2026",
"visibility": "hr_person_manager",
"expires_on": "2027-01-31",
"notes": "Signed",
"file": {
"name": "Contract 2026.pdf",
"size": 182000,
"content_type": "application/pdf",
"sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
},
},
)
body = res.json()
if not res.ok:
raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
print(body["data"]){
"data": {
"document": {
"id": "d1",
"title": "Contract 2026",
"category": "Contract",
"subject": {
"kind": "person",
"person": {
"id": "p1",
"name": "Ana Ferreira"
}
},
"visibility": "hr_person",
"uploaded_by": "hr",
"field": null,
"expires_on": "2027-01-31",
"notes": "Signed copy",
"file": {
"name": "Contract 2026.pdf",
"size": 182000,
"content_type": "application/pdf",
"previewable": true
},
"access": "full",
"status": "pending",
"created_at": "2026-10-05T10:00:00.000Z",
"updated_at": "2026-10-05T10:00:00.000Z"
},
"upload": {
"url": "https://storage.googleapis.com/b/uploads/o1/d1?X-Goog-Signature=x",
"method": "PUT",
"headers": {
"content-type": "application/pdf",
"x-goog-content-length-range": "182000,182000",
"x-goog-if-generation-match": "0"
},
"resumable": false
},
"upload_expires_at": "2026-10-05T10:15:00.000Z"
}
}Finish a document upload#
POST/v1/documents/upload.finishWrite
Finishes an upload started with documents_upload_start, after the bytes were uploaded: Bizisy checks the size, the SHA-256 and the type from the bytes, then the document appears for everyone its visibility allows. A file that does not match is deleted and refused (start again). Finishing twice returns the document. Owners, admins and HR.
- Who can call it
- Manage key owner admin hr
- MCP tool
documents_upload_finishon HR Assistant- Preview
?dry_run=trueruns every check and saves nothing- Retries
- An Idempotency-Key prevents a second run, but the result is never stored (it holds a secret or personal data): a retry gets a 409 that points to Activity
Input
document_idstringrequired
Returns
14 fields
idstringrequiredtitlestringrequiredcategorystringrequiredsubjectobjectrequired3 fields (one of several shapes)
Option 1
kind"person"requiredpersonobject | nullrequired2 fields
idstringrequirednamestringrequired
Option 2
kind"company"required
visibility"hr" | "hr_person" | "hr_person_manager" | "everyone" | "managers" | "hr"requireduploaded_by"hr" | "self"requiredself: the person added it themself ("From me", or a custom field they fill in).
fieldobject | nullrequiredA custom file field's file (
org_fields_list): its visibility follows the field's tier; replace or remove it through the field.2 fields
keystringrequiredlabelstringrequired
expires_onstring | nullrequirednotesstring | nullrequirednull when you only see metadata.
fileobjectrequired4 fields
namestring | nullrequiredThe original file name; null when you only see metadata.
sizeintegerrequiredcontent_typestringrequiredpreviewablebooleanrequiredThe web app can show it (PDF, PNG, JPEG, WebP).
access"full" | "metadata"requiredmetadata: title, category, date and size only (no notes, no download): API keys and AI assistants never get the contents of other people's documents.
status"pending" | "ready"requiredcreated_atstringrequiredupdated_atstringrequired
Errors
validation_failed unauthenticated forbidden not_found conflict rate_limited internal
curl https://api.bizisy.com/v1/documents/upload.finish \
-H "Authorization: Bearer $BIZISY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"document_id":"d1"}'const res = await fetch('https://api.bizisy.com/v1/documents/upload.finish', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.BIZISY_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({
"document_id": "d1"
}),
});
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/documents/upload.finish",
headers={"Authorization": f"Bearer {os.environ['BIZISY_API_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"document_id": "d1",
},
)
body = res.json()
if not res.ok:
raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
print(body["data"]){
"data": {
"id": "d1",
"title": "Contract 2026",
"category": "Contract",
"subject": {
"kind": "person",
"person": {
"id": "p1",
"name": "Ana Ferreira"
}
},
"visibility": "hr_person",
"uploaded_by": "hr",
"field": null,
"expires_on": "2027-01-31",
"notes": "Signed copy",
"file": {
"name": "Contract 2026.pdf",
"size": 182000,
"content_type": "application/pdf",
"previewable": true
},
"access": "full",
"status": "ready",
"created_at": "2026-10-05T10:00:00.000Z",
"updated_at": "2026-10-05T10:00:00.000Z"
}
}Change a document#
POST/v1/documents/updateWrite
Changes a document's title, category, visibility, expiry date (expires_on, YYYY-MM-DD or null) or notes. Send only what changes. The visibility of a person's own "From me" upload stays hr_person; a custom field's file (field set) keeps the field's visibility and category (change the field instead). Owners, admins and HR.
- Who can call it
- Manage key owner admin hr
- MCP tool
documents_updateon HR Assistant- Preview
?dry_run=trueruns every check and saves nothing- Retries
- An Idempotency-Key prevents a second run, but the result is never stored (it holds a secret or personal data): a retry gets a 409 that points to Activity
Input
document_idstringrequiredtitlestring1–200 characters.
categorystring1–40 characters.
visibility"hr" | "hr_person" | "hr_person_manager" | "everyone" | "managers" | "hr"expires_onstring | nullPattern
^\d{4}-\d{2}-\d{2}$.notesstring | nullUp to 2000 characters.
Returns
14 fields
idstringrequiredtitlestringrequiredcategorystringrequiredsubjectobjectrequired3 fields (one of several shapes)
Option 1
kind"person"requiredpersonobject | nullrequired2 fields
idstringrequirednamestringrequired
Option 2
kind"company"required
visibility"hr" | "hr_person" | "hr_person_manager" | "everyone" | "managers" | "hr"requireduploaded_by"hr" | "self"requiredself: the person added it themself ("From me", or a custom field they fill in).
fieldobject | nullrequiredA custom file field's file (
org_fields_list): its visibility follows the field's tier; replace or remove it through the field.2 fields
keystringrequiredlabelstringrequired
expires_onstring | nullrequirednotesstring | nullrequirednull when you only see metadata.
fileobjectrequired4 fields
namestring | nullrequiredThe original file name; null when you only see metadata.
sizeintegerrequiredcontent_typestringrequiredpreviewablebooleanrequiredThe web app can show it (PDF, PNG, JPEG, WebP).
access"full" | "metadata"requiredmetadata: title, category, date and size only (no notes, no download): API keys and AI assistants never get the contents of other people's documents.
status"pending" | "ready"requiredcreated_atstringrequiredupdated_atstringrequired
Errors
validation_failed unauthenticated forbidden not_found conflict rate_limited internal
curl https://api.bizisy.com/v1/documents/update \
-H "Authorization: Bearer $BIZISY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"document_id": "d1",
"category": "Addendum",
"visibility": "hr",
"expires_on": null,
"notes": null
}'const res = await fetch('https://api.bizisy.com/v1/documents/update', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.BIZISY_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({
"document_id": "d1",
"category": "Addendum",
"visibility": "hr",
"expires_on": null,
"notes": null
}),
});
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/documents/update",
headers={"Authorization": f"Bearer {os.environ['BIZISY_API_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"document_id": "d1",
"category": "Addendum",
"visibility": "hr",
"expires_on": None,
"notes": None,
},
)
body = res.json()
if not res.ok:
raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
print(body["data"]){
"data": {
"id": "d1",
"title": "Contract 2026",
"category": "Addendum",
"subject": {
"kind": "person",
"person": {
"id": "p1",
"name": "Ana Ferreira"
}
},
"visibility": "hr",
"uploaded_by": "hr",
"field": null,
"expires_on": null,
"notes": null,
"file": {
"name": "Contract 2026.pdf",
"size": 182000,
"content_type": "application/pdf",
"previewable": true
},
"access": "full",
"status": "ready",
"created_at": "2026-10-05T10:00:00.000Z",
"updated_at": "2026-10-05T10:00:00.000Z"
}
}Delete a document#
POST/v1/documents/deleteDestructive
Deletes a document and its file for good (no recycle bin; the storage it used is freed, though this month's billed peak does not go down). A custom field's file (field set) is removed from the field too. Owners, admins and HR.
- Who can call it
- Manage key owner admin hr
- MCP tool
documents_deleteon HR Assistant- Preview
?dry_run=trueruns every check and saves nothing- Retries
- An Idempotency-Key prevents a second run, but the result is never stored (it holds a secret or personal data): a retry gets a 409 that points to Activity
Input
document_idstringrequired
Returns
idstringrequireddeletedtruerequiredcategorystringrequiredperson_idstring | nullrequiredvisibilitystringrequired
Errors
validation_failed unauthenticated forbidden not_found conflict rate_limited internal
curl https://api.bizisy.com/v1/documents/delete \
-H "Authorization: Bearer $BIZISY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"document_id":"d1"}'const res = await fetch('https://api.bizisy.com/v1/documents/delete', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.BIZISY_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({
"document_id": "d1"
}),
});
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/documents/delete",
headers={"Authorization": f"Bearer {os.environ['BIZISY_API_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"document_id": "d1",
},
)
body = res.json()
if not res.ok:
raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
print(body["data"]){
"data": {
"id": "d1",
"deleted": true,
"category": "Contract",
"person_id": "p1",
"visibility": "hr_person"
}
}Download a document#
POST/v1/documents/downloadWrite
Returns a short-lived link (5 minutes) that downloads the document as a file. Downloading a person's document is recorded in Activity (company documents are not). Only for documents you can fully see: through an API key or an AI assistant, other people's documents never download. The link is never stored; ask again for a new one.
- Who can call it
- Manage key any Manage role
- Keys and apps
- Other people's documents never download.
- MCP tool
documents_downloadon HR Assistant- Preview
?dry_run=trueruns every check and saves nothing- Retries
- An Idempotency-Key prevents a second run, but the result is never stored (it holds a secret or personal data): a retry gets a 409 that points to Activity
Input
document_idstringrequired
Returns
8 fields
urlstring | nullrequiredSigned URL valid for 5 minutes, downloads as an attachment. null on a dry run. Never store or share it.
expires_atstring | nullrequiredfile_namestringrequiredcontent_typestringrequiredsizeintegerrequiredcategorystringrequiredperson_idstring | nullrequiredvisibilitystringrequired
Errors
validation_failed unauthenticated forbidden not_found conflict rate_limited internal
curl https://api.bizisy.com/v1/documents/download \
-H "Authorization: Bearer $BIZISY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"document_id":"d1"}'const res = await fetch('https://api.bizisy.com/v1/documents/download', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.BIZISY_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({
"document_id": "d1"
}),
});
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/documents/download",
headers={"Authorization": f"Bearer {os.environ['BIZISY_API_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"document_id": "d1",
},
)
body = res.json()
if not res.ok:
raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
print(body["data"]){
"data": {
"url": "https://storage.googleapis.com/b/orgs/o1/files/d1?X-Goog-Signature=x",
"expires_at": "2026-10-05T10:05:00.000Z",
"file_name": "Contract 2026.pdf",
"content_type": "application/pdf",
"size": 182000,
"category": "Contract",
"person_id": "p1",
"visibility": "hr_person"
}
}See document categories#
POST/v1/documents/categories.getRead
The document categories: the starter list (Contract, Addendum, Certificate, ID, Policy, Handbook, Other) and your own.
- Who can call it
- Manage key any Manage role
Me key anyone - MCP tool
documents_categories_geton HR Assistant, My Workplace- Method
POSTwith a JSON body, orGETwith the input as query parameters
Input
No input: send {}.
Returns
starterstring[]requiredcustomstring[]required
Errors
validation_failed unauthenticated forbidden not_found rate_limited internal
curl https://api.bizisy.com/v1/documents/categories.get \
-H "Authorization: Bearer $BIZISY_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'const res = await fetch('https://api.bizisy.com/v1/documents/categories.get', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.BIZISY_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({}),
});
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/documents/categories.get",
headers={"Authorization": f"Bearer {os.environ['BIZISY_API_KEY']}"},
json={},
)
body = res.json()
if not res.ok:
raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
print(body["data"]){
"data": {
"starter": [
"Contract",
"Addendum",
"Certificate",
"ID",
"Policy",
"Handbook",
"Other"
],
"custom": [
"Payslip"
]
}
}Change document categories#
POST/v1/documents/categories.setWrite
Replaces your own document categories (up to 30, each up to 40 characters) beside the starter list. Documents keep the category they have when one is removed. Owners, admins and HR.
- Who can call it
- Manage key owner admin hr
- MCP tool
documents_categories_seton HR Assistant- Preview
?dry_run=trueruns every check and saves nothing- Retries
- An Idempotency-Key replays the first result
Input
customstring[]required1–40 characters. Up to 30 items.
Returns
starterstring[]requiredcustomstring[]required
Errors
validation_failed unauthenticated forbidden not_found conflict rate_limited internal
curl https://api.bizisy.com/v1/documents/categories.set \
-H "Authorization: Bearer $BIZISY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"custom":["Payslip","Medical note"]}'const res = await fetch('https://api.bizisy.com/v1/documents/categories.set', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.BIZISY_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({
"custom": [
"Payslip",
"Medical note"
]
}),
});
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/documents/categories.set",
headers={"Authorization": f"Bearer {os.environ['BIZISY_API_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"custom": [
"Payslip",
"Medical note",
],
},
)
body = res.json()
if not res.ok:
raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
print(body["data"]){
"data": {
"starter": [
"Contract",
"Addendum",
"Certificate",
"ID",
"Policy",
"Handbook",
"Other"
],
"custom": [
"Payslip"
]
}
}Something missing or wrong on this page? Write to hello@bizisy.com.