Skip to content

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_list on HR Assistant
Method
POST with a JSON body, or GET with the input as query parameters

Input

  • person_idstring
  • scope"person" | "company" | "all"

    Default all (person_id implies person).

  • categorystring

    Up to 60 characters.

  • qstring

    Words that must all appear in the title (case-insensitive).

    Up to 100 characters.

  • sort"newest" | "largest"
  • limitinteger

    Default 500.

    From 1 to 500.

Returns

  • documentsobject[]required
    14 fields
    • idstringrequired
    • titlestringrequired
    • categorystringrequired
    • subjectobjectrequired
      3 fields (one of several shapes)

      Option 1

      • kind"person"required
      • personobject | nullrequired
        2 fields
        • idstringrequired
        • namestringrequired

      Option 2

      • kind"company"required
    • visibility"hr" | "hr_person" | "hr_person_manager" | "everyone" | "managers" | "hr"required
    • uploaded_by"hr" | "self"required

      self: the person added it themself ("From me", or a custom field they fill in).

    • fieldobject | nullrequired

      A custom file field's file (org_fields_list): its visibility follows the field's tier; replace or remove it through the field.

      2 fields
      • keystringrequired
      • labelstringrequired
    • expires_onstring | nullrequired
    • notesstring | nullrequired

      null when you only see metadata.

    • fileobjectrequired
      4 fields
      • namestring | nullrequired

        The original file name; null when you only see metadata.

      • sizeintegerrequired
      • content_typestringrequired
      • previewablebooleanrequired

        The web app can show it (PDF, PNG, JPEG, WebP).

    • access"full" | "metadata"required

      metadata: 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"required
    • created_atstringrequired
    • updated_atstringrequired
  • categoriesstring[]required

    Every category in use for new documents: the starter list and your own.

  • max_file_bytesintegerrequired

    The largest file allowed (Settings → Storage).

Errors

validation_failed unauthenticated forbidden not_found rate_limited internal

curl
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
}'
Response
{
  "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_start on HR Assistant
Preview
?dry_run=true runs 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

  • subjectobjectrequired
    3 fields (one of several shapes)

    Option 1

    • kind"person"required
    • person_idstringrequired

    Option 2

    • kind"company"required
  • categorystringrequired

    1–40 characters.

  • titlestring

    Up to 200 characters.

  • visibility"hr" | "hr_person" | "hr_person_manager" | "everyone" | "managers" | "hr"
  • expires_onstring | null

    Pattern ^\d{4}-\d{2}-\d{2}$.

  • notesstring | null

    Up to 2000 characters.

  • fileobjectrequired
    4 fields
    • namestringrequired

      The file name, e.g. "Contract 2026.pdf" (kept as metadata only).

      1–500 characters.

    • sizeintegerrequired

      Bytes. Must equal what is uploaded.

      At least 0.

    • content_typestringrequired

      application/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.

    • sha256stringrequired

      Lowercase hex SHA-256 of the file; checked against the upload.

      Pattern ^[0-9a-f]{64}$.

Returns

  • documentobjectrequired
    14 fields
    • idstringrequired
    • titlestringrequired
    • categorystringrequired
    • subjectobjectrequired
      3 fields (one of several shapes)

      Option 1

      • kind"person"required
      • personobject | nullrequired
        2 fields
        • idstringrequired
        • namestringrequired

      Option 2

      • kind"company"required
    • visibility"hr" | "hr_person" | "hr_person_manager" | "everyone" | "managers" | "hr"required
    • uploaded_by"hr" | "self"required

      self: the person added it themself ("From me", or a custom field they fill in).

    • fieldobject | nullrequired

      A custom file field's file (org_fields_list): its visibility follows the field's tier; replace or remove it through the field.

      2 fields
      • keystringrequired
      • labelstringrequired
    • expires_onstring | nullrequired
    • notesstring | nullrequired

      null when you only see metadata.

    • fileobjectrequired
      4 fields
      • namestring | nullrequired

        The original file name; null when you only see metadata.

      • sizeintegerrequired
      • content_typestringrequired
      • previewablebooleanrequired

        The web app can show it (PDF, PNG, JPEG, WebP).

    • access"full" | "metadata"required

      metadata: 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"required
    • created_atstringrequired
    • updated_atstringrequired
  • uploadobject | nullrequired

    null on a dry run.

    4 fields
    • urlstringrequired

      Short-lived signed URL (15 minutes). Never share it.

    • method"PUT"required
    • headersobjectrequired

      Send exactly these headers (they include the exact file size: any other size is refused).

    • resumablefalserequired

      Always false: upload the whole file in one PUT.

  • upload_expires_atstringrequired

Errors

validation_failed unauthenticated forbidden not_found conflict rate_limited internal

curl
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"
  }
}'
Response
{
  "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_finish on HR Assistant
Preview
?dry_run=true runs 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
  • idstringrequired
  • titlestringrequired
  • categorystringrequired
  • subjectobjectrequired
    3 fields (one of several shapes)

    Option 1

    • kind"person"required
    • personobject | nullrequired
      2 fields
      • idstringrequired
      • namestringrequired

    Option 2

    • kind"company"required
  • visibility"hr" | "hr_person" | "hr_person_manager" | "everyone" | "managers" | "hr"required
  • uploaded_by"hr" | "self"required

    self: the person added it themself ("From me", or a custom field they fill in).

  • fieldobject | nullrequired

    A custom file field's file (org_fields_list): its visibility follows the field's tier; replace or remove it through the field.

    2 fields
    • keystringrequired
    • labelstringrequired
  • expires_onstring | nullrequired
  • notesstring | nullrequired

    null when you only see metadata.

  • fileobjectrequired
    4 fields
    • namestring | nullrequired

      The original file name; null when you only see metadata.

    • sizeintegerrequired
    • content_typestringrequired
    • previewablebooleanrequired

      The web app can show it (PDF, PNG, JPEG, WebP).

  • access"full" | "metadata"required

    metadata: 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"required
  • created_atstringrequired
  • updated_atstringrequired

Errors

validation_failed unauthenticated forbidden not_found conflict rate_limited internal

curl
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"}'
Response
{
  "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_update on HR Assistant
Preview
?dry_run=true runs 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
  • titlestring

    1–200 characters.

  • categorystring

    1–40 characters.

  • visibility"hr" | "hr_person" | "hr_person_manager" | "everyone" | "managers" | "hr"
  • expires_onstring | null

    Pattern ^\d{4}-\d{2}-\d{2}$.

  • notesstring | null

    Up to 2000 characters.

Returns

14 fields
  • idstringrequired
  • titlestringrequired
  • categorystringrequired
  • subjectobjectrequired
    3 fields (one of several shapes)

    Option 1

    • kind"person"required
    • personobject | nullrequired
      2 fields
      • idstringrequired
      • namestringrequired

    Option 2

    • kind"company"required
  • visibility"hr" | "hr_person" | "hr_person_manager" | "everyone" | "managers" | "hr"required
  • uploaded_by"hr" | "self"required

    self: the person added it themself ("From me", or a custom field they fill in).

  • fieldobject | nullrequired

    A custom file field's file (org_fields_list): its visibility follows the field's tier; replace or remove it through the field.

    2 fields
    • keystringrequired
    • labelstringrequired
  • expires_onstring | nullrequired
  • notesstring | nullrequired

    null when you only see metadata.

  • fileobjectrequired
    4 fields
    • namestring | nullrequired

      The original file name; null when you only see metadata.

    • sizeintegerrequired
    • content_typestringrequired
    • previewablebooleanrequired

      The web app can show it (PDF, PNG, JPEG, WebP).

  • access"full" | "metadata"required

    metadata: 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"required
  • created_atstringrequired
  • updated_atstringrequired

Errors

validation_failed unauthenticated forbidden not_found conflict rate_limited internal

curl
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
}'
Response
{
  "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_delete on HR Assistant
Preview
?dry_run=true runs 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

  • idstringrequired
  • deletedtruerequired
  • categorystringrequired
  • person_idstring | nullrequired
  • visibilitystringrequired

Errors

validation_failed unauthenticated forbidden not_found conflict rate_limited internal

curl
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"}'
Response
{
  "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_download on HR Assistant
Preview
?dry_run=true runs 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 | nullrequired

    Signed URL valid for 5 minutes, downloads as an attachment. null on a dry run. Never store or share it.

  • expires_atstring | nullrequired
  • file_namestringrequired
  • content_typestringrequired
  • sizeintegerrequired
  • categorystringrequired
  • person_idstring | nullrequired
  • visibilitystringrequired

Errors

validation_failed unauthenticated forbidden not_found conflict rate_limited internal

curl
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"}'
Response
{
  "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_get on HR Assistant, My Workplace
Method
POST with a JSON body, or GET with the input as query parameters

Input

No input: send {}.

Returns

  • starterstring[]required
  • customstring[]required

Errors

validation_failed unauthenticated forbidden not_found rate_limited internal

curl
curl https://api.bizisy.com/v1/documents/categories.get \
  -H "Authorization: Bearer $BIZISY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
Response
{
  "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_set on HR Assistant
Preview
?dry_run=true runs every check and saves nothing
Retries
An Idempotency-Key replays the first result

Input

  • customstring[]required

    1–40 characters. Up to 30 items.

Returns

  • starterstring[]required
  • customstring[]required

Errors

validation_failed unauthenticated forbidden not_found conflict rate_limited internal

curl
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"]}'
Response
{
  "data": {
    "starter": [
      "Contract",
      "Addendum",
      "Certificate",
      "ID",
      "Policy",
      "Handbook",
      "Other"
    ],
    "custom": [
      "Payslip"
    ]
  }
}

Something missing or wrong on this page? Write to hello@bizisy.com.

Developer docs