Skip to content

API reference

Open positions

Roles the company plans to fill: the headcount plan.

5 actions · base URL https://api.bizisy.com/v1 · generated from the same definitions as the API.

List open positions (headcount plan)#

POST/v1/org/positions.listRead

Lists open positions: roles the company plans to fill (title, team, location, legal entity, who it reports to — a person or another position —, contract type, weekly hours, target start date, status, reason "new" or "replacement" with the leaver it replaces, and who filled it). status: "active" (default: draft, open and on hold), one status (draft, open, on_hold, filled, cancelled), "closed" (filled and cancelled) or "all". Filled and cancelled positions come newest first, a page at a time: limit (default 50, at most 200) of them per call; for the next page pass after = the id of the last closed position you got (only with filled, cancelled, closed or all; with all the draft, open and on-hold ones come only on the first page). Filters: unit_id, reports_to_person_id. Who sees what: owners, admins and HR see every position; a manager sees only the open and on-hold positions that report to them or to someone below them (also when that person starts later or has left: the line they belong to); everyone else sees none (an empty list). notes are for owners, admins and HR only; pay_range (the budget) only for owners, admins and HR signed in to Bizisy, never over MCP or an API key (pay_range_hidden is then true); replaces is shown only when you may see that person's job details. can_reopen: a filled position whose hire did not start (org_positions_reopen).

Who can call it
Manage key any Manage role
Me key anyone
Keys and apps
pay_range (the budget) is never returned (pay_range_hidden is true).
MCP tool
org_positions_list on My Workplace, HR Assistant
Method
POST with a JSON body, or GET with the input as query parameters

Input

  • statusstring (enum)

    One of: active, draft, open, on_hold, filled, cancelled, closed, all. Default "active".

  • unit_idstring
  • reports_to_person_idstring
  • limitinteger

    From 1 to 200.

  • afterstring

Returns

An array of objects with 21 fields

An array of objects:

  • idstringrequired
  • titlestringrequired
  • status"draft" | "open" | "on_hold" | "filled" | "cancelled"required
  • reason"new" | "replacement"required
  • unitobject | nullrequired
    2 fields
    • idstringrequired
    • namestringrequired
  • locationobject | nullrequired
    2 fields
    • idstringrequired
    • namestringrequired
  • legal_entityobject | nullrequired
    2 fields
    • idstringrequired
    • namestringrequired
  • reports_to_personobject | nullrequired
    4 fields
    • idstringrequired
    • namestringrequired
    • titlestring | nullrequired
    • photo_urlstring | nullrequired
  • reports_to_positionobject | nullrequired
    2 fields
    • idstringrequired
    • titlestringrequired
  • contract_type"permanent" | "fixed_term" | "temporary" | "internship" | "freelance"required
  • weekly_hoursnumber | nullrequired
  • pay_rangeobject | nullrequired
    4 fields
    • minnumberrequired
    • maxnumberrequired
    • currencystringrequired
    • period"year" | "month" | "hour"required
  • pay_range_hiddenbooleanrequired
  • target_start_datestring | nullrequired
  • notesstring | nullrequired
  • replacesobject | nullrequired
    4 fields
    • idstringrequired
    • namestringrequired
    • titlestring | nullrequired
    • photo_urlstring | nullrequired
  • filled_byobject | nullrequired
    4 fields
    • idstringrequired
    • namestringrequired
    • titlestring | nullrequired
    • photo_urlstring | nullrequired
  • filled_onstring | nullrequired
  • can_reopenbooleanrequired
  • created_atstringrequired
  • updated_atstringrequired

Errors

validation_failed unauthenticated forbidden not_found rate_limited internal

curl
curl https://api.bizisy.com/v1/org/positions.list \
  -H "Authorization: Bearer $BIZISY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status":"on_hold","unit_id":"u1","reports_to_person_id":"p1"}'
Response
{
  "data": [
    {
      "id": "pos1",
      "title": "Data Engineer",
      "status": "open",
      "reason": "replacement",
      "unit": {
        "id": "u2",
        "name": "Engineering"
      },
      "location": {
        "id": "l1",
        "name": "Lisbon"
      },
      "legal_entity": {
        "id": "e1",
        "name": "Acme Lda"
      },
      "reports_to_person": {
        "id": "p1",
        "name": "Ana Ferreira",
        "title": "CTO",
        "photo_url": null
      },
      "reports_to_position": null,
      "contract_type": "permanent",
      "weekly_hours": 40,
      "pay_range": null,
      "pay_range_hidden": true,
      "target_start_date": "2026-12-01",
      "notes": "Budget approved in Q3",
      "replaces": {
        "id": "p3",
        "name": "Rui Costa",
        "title": "Data Engineer",
        "photo_url": null
      },
      "filled_by": null,
      "filled_on": null,
      "can_reopen": false,
      "created_at": "2026-10-04T10:00:00.000Z",
      "updated_at": "2026-10-04T10:00:00.000Z"
    },
    {
      "id": "pos2",
      "title": "Data Engineer",
      "status": "on_hold",
      "reason": "new",
      "unit": {
        "id": "u2",
        "name": "Engineering"
      },
      "location": {
        "id": "l1",
        "name": "Lisbon"
      },
      "legal_entity": {
        "id": "e1",
        "name": "Acme Lda"
      },
      "reports_to_person": null,
      "reports_to_position": {
        "id": "pos1",
        "title": "Data Engineer"
      },
      "contract_type": "permanent",
      "weekly_hours": 40,
      "pay_range": null,
      "pay_range_hidden": true,
      "target_start_date": "2026-12-01",
      "notes": null,
      "replaces": null,
      "filled_by": null,
      "filled_on": null,
      "can_reopen": false,
      "created_at": "2026-10-04T10:00:00.000Z",
      "updated_at": "2026-10-04T10:00:00.000Z"
    }
  ]
}

Get an open position#

POST/v1/org/positions.getRead

Returns one position with the same visibility as org_positions_list: owners, admins and HR any position (filled and cancelled ones too); a manager the open and on-hold positions in their line; otherwise not_found.

Who can call it
Manage key any Manage role
Me key anyone
MCP tool
org_positions_get on My Workplace, HR Assistant
Method
POST with a JSON body, or GET with the input as query parameters

Input

  • position_idstringrequired

Returns

21 fields
  • idstringrequired
  • titlestringrequired
  • status"draft" | "open" | "on_hold" | "filled" | "cancelled"required
  • reason"new" | "replacement"required
  • unitobject | nullrequired
    2 fields
    • idstringrequired
    • namestringrequired
  • locationobject | nullrequired
    2 fields
    • idstringrequired
    • namestringrequired
  • legal_entityobject | nullrequired
    2 fields
    • idstringrequired
    • namestringrequired
  • reports_to_personobject | nullrequired
    4 fields
    • idstringrequired
    • namestringrequired
    • titlestring | nullrequired
    • photo_urlstring | nullrequired
  • reports_to_positionobject | nullrequired
    2 fields
    • idstringrequired
    • titlestringrequired
  • contract_type"permanent" | "fixed_term" | "temporary" | "internship" | "freelance"required
  • weekly_hoursnumber | nullrequired
  • pay_rangeobject | nullrequired
    4 fields
    • minnumberrequired
    • maxnumberrequired
    • currencystringrequired
    • period"year" | "month" | "hour"required
  • pay_range_hiddenbooleanrequired
  • target_start_datestring | nullrequired
  • notesstring | nullrequired
  • replacesobject | nullrequired
    4 fields
    • idstringrequired
    • namestringrequired
    • titlestring | nullrequired
    • photo_urlstring | nullrequired
  • filled_byobject | nullrequired
    4 fields
    • idstringrequired
    • namestringrequired
    • titlestring | nullrequired
    • photo_urlstring | nullrequired
  • filled_onstring | nullrequired
  • can_reopenbooleanrequired
  • created_atstringrequired
  • updated_atstringrequired

Errors

validation_failed unauthenticated forbidden not_found rate_limited internal

curl
curl https://api.bizisy.com/v1/org/positions.get \
  -H "Authorization: Bearer $BIZISY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"position_id":"pos1"}'
Response
{
  "data": {
    "id": "pos1",
    "title": "Data Engineer",
    "status": "open",
    "reason": "replacement",
    "unit": {
      "id": "u2",
      "name": "Engineering"
    },
    "location": {
      "id": "l1",
      "name": "Lisbon"
    },
    "legal_entity": {
      "id": "e1",
      "name": "Acme Lda"
    },
    "reports_to_person": {
      "id": "p1",
      "name": "Ana Ferreira",
      "title": "CTO",
      "photo_url": null
    },
    "reports_to_position": null,
    "contract_type": "permanent",
    "weekly_hours": 40,
    "pay_range": null,
    "pay_range_hidden": true,
    "target_start_date": "2026-12-01",
    "notes": "Budget approved in Q3",
    "replaces": {
      "id": "p3",
      "name": "Rui Costa",
      "title": "Data Engineer",
      "photo_url": null
    },
    "filled_by": null,
    "filled_on": null,
    "can_reopen": false,
    "created_at": "2026-10-04T10:00:00.000Z",
    "updated_at": "2026-10-04T10:00:00.000Z"
  }
}

Create an open position#

POST/v1/org/positions.createWrite

Plans a role to fill. Required: title. Optional: status (open by default, or draft or on_hold), unit_id, location_id and legal_entity_id (default to the only active one), reports_to_person_id (someone employed now or starting soon) or reports_to_position_id (another draft, open or on-hold position; never both), contract_type, weekly_hours, target_start_date (YYYY-MM-DD), notes (owners, admins and HR only; do not put personal data here), reason ("new", default, or "replacement" with an optional replaces_person_id: the leaver), and pay_range {min, max, currency, period: year, month or hour} — the budget, which can only be set by signing in to Bizisy (refused over MCP or an API key). At most 500 draft, open or on-hold positions per organization. Owners, admins and HR. Use dry_run first. To fill it, hire someone with org_people_hire and position_id.

Who can call it
Manage key owner admin hr
Keys and apps
pay_range is refused.
MCP tool
org_positions_create 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

  • titlestringrequired

    1–120 characters.

  • status"draft" | "open" | "on_hold"
  • unit_idstring | null
  • location_idstring | null
  • legal_entity_idstring | null
  • reports_to_person_idstring | null
  • reports_to_position_idstring | null
  • contract_type"permanent" | "fixed_term" | "temporary" | "internship" | "freelance"
  • weekly_hoursnumber | null

    From 0 to 80.

  • pay_rangeobject | null
    4 fields
    • minnumberrequired

      From 0 to 100000000.

    • maxnumberrequired

      From 0 to 100000000.

    • currencyanyrequired
    • period"year" | "month" | "hour"required
  • target_start_datestring | null
  • notesstring | null

    Up to 1000 characters.

  • reason"new" | "replacement"
  • replaces_person_idstring | null

Returns

21 fields
  • idstringrequired
  • titlestringrequired
  • status"draft" | "open" | "on_hold" | "filled" | "cancelled"required
  • reason"new" | "replacement"required
  • unitobject | nullrequired
    2 fields
    • idstringrequired
    • namestringrequired
  • locationobject | nullrequired
    2 fields
    • idstringrequired
    • namestringrequired
  • legal_entityobject | nullrequired
    2 fields
    • idstringrequired
    • namestringrequired
  • reports_to_personobject | nullrequired
    4 fields
    • idstringrequired
    • namestringrequired
    • titlestring | nullrequired
    • photo_urlstring | nullrequired
  • reports_to_positionobject | nullrequired
    2 fields
    • idstringrequired
    • titlestringrequired
  • contract_type"permanent" | "fixed_term" | "temporary" | "internship" | "freelance"required
  • weekly_hoursnumber | nullrequired
  • pay_rangeobject | nullrequired
    4 fields
    • minnumberrequired
    • maxnumberrequired
    • currencystringrequired
    • period"year" | "month" | "hour"required
  • pay_range_hiddenbooleanrequired
  • target_start_datestring | nullrequired
  • notesstring | nullrequired
  • replacesobject | nullrequired
    4 fields
    • idstringrequired
    • namestringrequired
    • titlestring | nullrequired
    • photo_urlstring | nullrequired
  • filled_byobject | nullrequired
    4 fields
    • idstringrequired
    • namestringrequired
    • titlestring | nullrequired
    • photo_urlstring | nullrequired
  • filled_onstring | nullrequired
  • can_reopenbooleanrequired
  • created_atstringrequired
  • updated_atstringrequired

Errors

validation_failed unauthenticated forbidden not_found conflict rate_limited internal

curl
curl https://api.bizisy.com/v1/org/positions.create \
  -H "Authorization: Bearer $BIZISY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "title": "Data Engineer",
  "status": "draft",
  "unit_id": "u2",
  "location_id": null,
  "legal_entity_id": "e1",
  "reports_to_person_id": "p1",
  "contract_type": "permanent",
  "weekly_hours": 40,
  "target_start_date": "2026-12-01",
  "notes": "n",
  "reason": "replacement",
  "replaces_person_id": "p3"
}'
Response
{
  "data": {
    "id": "pos1",
    "title": "Data Engineer",
    "status": "draft",
    "reason": "replacement",
    "unit": {
      "id": "u2",
      "name": "Engineering"
    },
    "location": {
      "id": "l1",
      "name": "Lisbon"
    },
    "legal_entity": {
      "id": "e1",
      "name": "Acme Lda"
    },
    "reports_to_person": {
      "id": "p1",
      "name": "Ana Ferreira",
      "title": "CTO",
      "photo_url": null
    },
    "reports_to_position": null,
    "contract_type": "permanent",
    "weekly_hours": 40,
    "pay_range": null,
    "pay_range_hidden": true,
    "target_start_date": "2026-12-01",
    "notes": "n",
    "replaces": {
      "id": "p3",
      "name": "Rui Costa",
      "title": "Data Engineer",
      "photo_url": null
    },
    "filled_by": null,
    "filled_on": null,
    "can_reopen": false,
    "created_at": "2026-10-04T10:00:00.000Z",
    "updated_at": "2026-10-04T10:00:00.000Z"
  }
}

Change an open position#

POST/v1/org/positions.updateWrite

Changes a position: any field of org_positions_create (null clears one; setting reports_to_person_id clears reports_to_position_id and the other way round; reason "new" clears replaces_person_id) and status: draft → open, on_hold or cancelled; open ↔ on_hold; open or on hold → cancelled; cancelled → draft or open (reopen; who it reports to is checked again). Cancelling a position moves the positions that reported to it to whoever it reported to. "filled" is never set here: hire into the position with org_people_hire and position_id. A filled position only takes notes; if its hire did not start, reopen it with org_positions_reopen. pay_range can only be changed by signing in to Bizisy (refused over MCP or an API key; leave it out to keep it). Owners, admins and HR.

Who can call it
Manage key owner admin hr
Keys and apps
pay_range is refused.
MCP tool
org_positions_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

  • position_idstringrequired
  • titlestring

    1–120 characters.

  • status"draft" | "open" | "on_hold" | "filled" | "cancelled"
  • unit_idstring | null
  • location_idstring | null
  • legal_entity_idstring | null
  • reports_to_person_idstring | null
  • reports_to_position_idstring | null
  • contract_type"permanent" | "fixed_term" | "temporary" | "internship" | "freelance"
  • weekly_hoursnumber | null

    From 0 to 80.

  • pay_rangeobject | null
    4 fields
    • minnumberrequired

      From 0 to 100000000.

    • maxnumberrequired

      From 0 to 100000000.

    • currencyanyrequired
    • period"year" | "month" | "hour"required
  • target_start_datestring | null
  • notesstring | null

    Up to 1000 characters.

  • reason"new" | "replacement"
  • replaces_person_idstring | null

Returns

21 fields
  • idstringrequired
  • titlestringrequired
  • status"draft" | "open" | "on_hold" | "filled" | "cancelled"required
  • reason"new" | "replacement"required
  • unitobject | nullrequired
    2 fields
    • idstringrequired
    • namestringrequired
  • locationobject | nullrequired
    2 fields
    • idstringrequired
    • namestringrequired
  • legal_entityobject | nullrequired
    2 fields
    • idstringrequired
    • namestringrequired
  • reports_to_personobject | nullrequired
    4 fields
    • idstringrequired
    • namestringrequired
    • titlestring | nullrequired
    • photo_urlstring | nullrequired
  • reports_to_positionobject | nullrequired
    2 fields
    • idstringrequired
    • titlestringrequired
  • contract_type"permanent" | "fixed_term" | "temporary" | "internship" | "freelance"required
  • weekly_hoursnumber | nullrequired
  • pay_rangeobject | nullrequired
    4 fields
    • minnumberrequired
    • maxnumberrequired
    • currencystringrequired
    • period"year" | "month" | "hour"required
  • pay_range_hiddenbooleanrequired
  • target_start_datestring | nullrequired
  • notesstring | nullrequired
  • replacesobject | nullrequired
    4 fields
    • idstringrequired
    • namestringrequired
    • titlestring | nullrequired
    • photo_urlstring | nullrequired
  • filled_byobject | nullrequired
    4 fields
    • idstringrequired
    • namestringrequired
    • titlestring | nullrequired
    • photo_urlstring | nullrequired
  • filled_onstring | nullrequired
  • can_reopenbooleanrequired
  • created_atstringrequired
  • updated_atstringrequired

Errors

validation_failed unauthenticated forbidden not_found conflict rate_limited internal

curl
curl https://api.bizisy.com/v1/org/positions.update \
  -H "Authorization: Bearer $BIZISY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "position_id": "pos1",
  "title": "Lead",
  "reports_to_position_id": "pos2",
  "reports_to_person_id": null,
  "notes": null,
  "reason": "new"
}'
Response
{
  "data": {
    "id": "pos1",
    "title": "Lead",
    "status": "filled",
    "reason": "new",
    "unit": {
      "id": "u2",
      "name": "Engineering"
    },
    "location": {
      "id": "l1",
      "name": "Lisbon"
    },
    "legal_entity": {
      "id": "e1",
      "name": "Acme Lda"
    },
    "reports_to_person": {
      "id": "p1",
      "name": "Ana Ferreira",
      "title": "CTO",
      "photo_url": null
    },
    "reports_to_position": null,
    "contract_type": "permanent",
    "weekly_hours": 40,
    "pay_range": null,
    "pay_range_hidden": true,
    "target_start_date": "2026-12-01",
    "notes": null,
    "replaces": {
      "id": "p3",
      "name": "Rui Costa",
      "title": "Data Engineer",
      "photo_url": null
    },
    "filled_by": {
      "id": "p9",
      "name": "Zoe Lima",
      "title": "Data Engineer",
      "photo_url": null
    },
    "filled_on": "2026-12-01",
    "can_reopen": true,
    "created_at": "2026-10-04T10:00:00.000Z",
    "updated_at": "2026-10-04T10:00:00.000Z"
  }
}

Reopen a filled position (the hire did not start)#

POST/v1/org/positions.reopenWrite

Puts a filled position back to open when its hire fell through: the person was terminated on or before their start date, or erased (can_reopen in org_positions_get). The positions that were moved under that person go back under this position, and their job no longer records it. Refused otherwise (conflict). Owners, admins and HR.

Who can call it
Manage key owner admin hr
MCP tool
org_positions_reopen on HR Assistant
Preview
?dry_run=true runs every check and saves nothing
Retries
An Idempotency-Key replays the first result

Input

  • position_idstringrequired

Returns

21 fields
  • idstringrequired
  • titlestringrequired
  • status"draft" | "open" | "on_hold" | "filled" | "cancelled"required
  • reason"new" | "replacement"required
  • unitobject | nullrequired
    2 fields
    • idstringrequired
    • namestringrequired
  • locationobject | nullrequired
    2 fields
    • idstringrequired
    • namestringrequired
  • legal_entityobject | nullrequired
    2 fields
    • idstringrequired
    • namestringrequired
  • reports_to_personobject | nullrequired
    4 fields
    • idstringrequired
    • namestringrequired
    • titlestring | nullrequired
    • photo_urlstring | nullrequired
  • reports_to_positionobject | nullrequired
    2 fields
    • idstringrequired
    • titlestringrequired
  • contract_type"permanent" | "fixed_term" | "temporary" | "internship" | "freelance"required
  • weekly_hoursnumber | nullrequired
  • pay_rangeobject | nullrequired
    4 fields
    • minnumberrequired
    • maxnumberrequired
    • currencystringrequired
    • period"year" | "month" | "hour"required
  • pay_range_hiddenbooleanrequired
  • target_start_datestring | nullrequired
  • notesstring | nullrequired
  • replacesobject | nullrequired
    4 fields
    • idstringrequired
    • namestringrequired
    • titlestring | nullrequired
    • photo_urlstring | nullrequired
  • filled_byobject | nullrequired
    4 fields
    • idstringrequired
    • namestringrequired
    • titlestring | nullrequired
    • photo_urlstring | nullrequired
  • filled_onstring | nullrequired
  • can_reopenbooleanrequired
  • created_atstringrequired
  • updated_atstringrequired

Errors

validation_failed unauthenticated forbidden not_found conflict rate_limited internal

curl
curl https://api.bizisy.com/v1/org/positions.reopen \
  -H "Authorization: Bearer $BIZISY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"position_id":"pos1"}'
Response
{
  "data": {
    "id": "pos1",
    "title": "Data Engineer",
    "status": "open",
    "reason": "replacement",
    "unit": {
      "id": "u2",
      "name": "Engineering"
    },
    "location": {
      "id": "l1",
      "name": "Lisbon"
    },
    "legal_entity": {
      "id": "e1",
      "name": "Acme Lda"
    },
    "reports_to_person": {
      "id": "p1",
      "name": "Ana Ferreira",
      "title": "CTO",
      "photo_url": null
    },
    "reports_to_position": null,
    "contract_type": "permanent",
    "weekly_hours": 40,
    "pay_range": null,
    "pay_range_hidden": true,
    "target_start_date": "2026-12-01",
    "notes": "Budget approved in Q3",
    "replaces": {
      "id": "p3",
      "name": "Rui Costa",
      "title": "Data Engineer",
      "photo_url": null
    },
    "filled_by": null,
    "filled_on": null,
    "can_reopen": false,
    "created_at": "2026-10-04T10:00:00.000Z",
    "updated_at": "2026-10-04T10:00:00.000Z"
  }
}

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

Developer docs