API reference
File fields
Files in custom fields of type file, for a person or yourself.
5 actions · base URL https://api.bizisy.com/v1 · generated from the same definitions as the API.
Start a file upload for a person's file field#
POST/v1/documents/field_file.startWrite
Puts a file in a custom field of type file (org_fields_list: type file) for a person, in two calls and one upload: (1) this call with person_id, field_key and the file's name, size, content_type and sha256; (2) PUT the bytes to the returned signed URL within 15 minutes with exactly the returned headers; (3) documents_field_file_finish with the document id. The field keeps one file: finishing replaces the one it had (deleted). Accepted: the field's kinds (pdf, image, office) up to the smaller of the field's max_mb and the company's largest file; archived fields are refused. The file is a person document (listed in their Documents, from the field) and follows the field's tier: private = the person and HR, job = also their managers, public = everyone in the company; API keys and AI assistants never get other people's files. Owners, admins and HR.
- Who can call it
- Manage key owner admin hr
- Keys and apps
- Other people's files are never returned.
- MCP tool
documents_field_file_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
person_idstringrequiredfield_keystringrequiredThe file field's key (
org_fields_list, type file).1–40 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/field_file.start \
-H "Authorization: Bearer $BIZISY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"person_id": "p1",
"field_key": "driving_licence",
"file": {
"name": "Contract 2026.pdf",
"size": 182000,
"content_type": "application/pdf",
"sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
}
}'const res = await fetch('https://api.bizisy.com/v1/documents/field_file.start', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.BIZISY_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({
"person_id": "p1",
"field_key": "driving_licence",
"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/field_file.start",
headers={"Authorization": f"Bearer {os.environ['BIZISY_API_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"person_id": "p1",
"field_key": "driving_licence",
"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": "d5",
"title": "Licence",
"category": "Driving licence",
"subject": {
"kind": "person",
"person": {
"id": "p1",
"name": "Ana Ferreira"
}
},
"visibility": "hr_person",
"uploaded_by": "hr",
"field": {
"key": "driving_licence",
"label": "Driving licence"
},
"expires_on": null,
"notes": null,
"file": {
"name": "Licence.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"
},
"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 person's file field upload#
POST/v1/documents/field_file.finishWrite
Finishes an upload started with documents_field_file_start, after the bytes were uploaded: Bizisy checks the size, SHA-256 and type from the bytes, the field now holds the file, and the file it held before is deleted. 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_field_file_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/field_file.finish \
-H "Authorization: Bearer $BIZISY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"document_id":"d5"}'const res = await fetch('https://api.bizisy.com/v1/documents/field_file.finish', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.BIZISY_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({
"document_id": "d5"
}),
});
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/field_file.finish",
headers={"Authorization": f"Bearer {os.environ['BIZISY_API_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"document_id": "d5",
},
)
body = res.json()
if not res.ok:
raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
print(body["data"]){
"data": {
"id": "d5",
"title": "Licence",
"category": "Driving licence",
"subject": {
"kind": "person",
"person": {
"id": "p1",
"name": "Ana Ferreira"
}
},
"visibility": "hr_person",
"uploaded_by": "hr",
"field": {
"key": "driving_licence",
"label": "Driving licence"
},
"expires_on": null,
"notes": null,
"file": {
"name": "Licence.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"
}
}Start uploading my file for a field#
POST/v1/documents/me.field_file.startWrite
Puts your own file in one of your custom fields of type file that your company lets people fill in (org_fields_list: type file, file.self_upload true), like documents_me_upload_start: this call with field_key and the file's name, size, content_type and sha256; PUT the bytes to the signed URL within 15 minutes with exactly the returned headers; then documents_me_field_file_finish. It replaces the file the field had. Accepted: the field's kinds up to its largest size. It counts toward your monthly self-upload limit (see documents_me_list self_upload), and your HR team is emailed when it arrives. Who sees it follows the field.
- Who can call it
- Me key anyone
- MCP tool
documents_me_field_file_starton My Workplace- 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
field_keystringrequiredThe file field's key (
org_fields_list, type file).1–40 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/me.field_file.start \
-H "Authorization: Bearer $BIZISY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"field_key": "driving_licence",
"file": {
"name": "Contract 2026.pdf",
"size": 182000,
"content_type": "application/pdf",
"sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
}
}'const res = await fetch('https://api.bizisy.com/v1/documents/me.field_file.start', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.BIZISY_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({
"field_key": "driving_licence",
"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/me.field_file.start",
headers={"Authorization": f"Bearer {os.environ['BIZISY_API_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"field_key": "driving_licence",
"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": "d5",
"title": "Licence",
"category": "Driving licence",
"subject": {
"kind": "person",
"person": {
"id": "p1",
"name": "Ana Ferreira"
}
},
"visibility": "hr_person",
"uploaded_by": "self",
"field": {
"key": "driving_licence",
"label": "Driving licence"
},
"expires_on": null,
"notes": null,
"file": {
"name": "Licence.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"
},
"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 uploading my file for a field#
POST/v1/documents/me.field_file.finishWrite
Finishes your field upload after the bytes were uploaded: Bizisy checks the file (size, SHA-256, type from the bytes) and your monthly limits, the field now holds it (the file it held before is deleted), and your HR team is emailed (never with the file name). Finishing twice returns the document.
- Who can call it
- Me key anyone
- MCP tool
documents_me_field_file_finishon My Workplace- 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/me.field_file.finish \
-H "Authorization: Bearer $BIZISY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"document_id":"d5"}'const res = await fetch('https://api.bizisy.com/v1/documents/me.field_file.finish', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.BIZISY_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({
"document_id": "d5"
}),
});
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/me.field_file.finish",
headers={"Authorization": f"Bearer {os.environ['BIZISY_API_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"document_id": "d5",
},
)
body = res.json()
if not res.ok:
raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
print(body["data"]){
"data": {
"id": "d5",
"title": "Licence",
"category": "Driving licence",
"subject": {
"kind": "person",
"person": {
"id": "p1",
"name": "Ana Ferreira"
}
},
"visibility": "hr_person",
"uploaded_by": "self",
"field": {
"key": "driving_licence",
"label": "Driving licence"
},
"expires_on": null,
"notes": null,
"file": {
"name": "Licence.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"
}
}Remove my file from a field#
POST/v1/documents/me.field_file.removeDestructive
Removes your file from one of your custom fields that your company lets people fill in (file.self_upload true): the file is deleted for good and the field is empty again. Fields HR fills in are changed by HR. Use dry_run first and confirm with the user.
- Who can call it
- Me key anyone
- MCP tool
documents_me_field_file_removeon My Workplace- 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
field_keystringrequiredThe file field's key (
org_fields_list, type file).1–40 characters.
Returns
person_idstringrequiredfield_keystringrequiredlabelstringrequiredremovedtruerequired
Errors
validation_failed unauthenticated forbidden not_found conflict rate_limited internal
curl https://api.bizisy.com/v1/documents/me.field_file.remove \
-H "Authorization: Bearer $BIZISY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"field_key":"driving_licence"}'const res = await fetch('https://api.bizisy.com/v1/documents/me.field_file.remove', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.BIZISY_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({
"field_key": "driving_licence"
}),
});
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/me.field_file.remove",
headers={"Authorization": f"Bearer {os.environ['BIZISY_API_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"field_key": "driving_licence",
},
)
body = res.json()
if not res.ok:
raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
print(body["data"]){
"data": {
"person_id": "p1",
"field_key": "driving_licence",
"label": "Driving licence",
"removed": true
}
}Something missing or wrong on this page? Write to hello@bizisy.com.