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_liston My Workplace, HR Assistant- Method
POSTwith a JSON body, orGETwith the input as query parameters
Input
statusstring (enum)One of:
active,draft,open,on_hold,filled,cancelled,closed,all. Default"active".unit_idstringreports_to_person_idstringlimitintegerFrom 1 to 200.
afterstring
Returns
An array of objects with 21 fields
An array of objects:
idstringrequiredtitlestringrequiredstatus"draft" | "open" | "on_hold" | "filled" | "cancelled"requiredreason"new" | "replacement"requiredunitobject | nullrequired2 fields
idstringrequirednamestringrequired
locationobject | nullrequired2 fields
idstringrequirednamestringrequired
legal_entityobject | nullrequired2 fields
idstringrequirednamestringrequired
reports_to_personobject | nullrequired4 fields
idstringrequirednamestringrequiredtitlestring | nullrequiredphoto_urlstring | nullrequired
reports_to_positionobject | nullrequired2 fields
idstringrequiredtitlestringrequired
contract_type"permanent" | "fixed_term" | "temporary" | "internship" | "freelance"requiredweekly_hoursnumber | nullrequiredpay_rangeobject | nullrequired4 fields
minnumberrequiredmaxnumberrequiredcurrencystringrequiredperiod"year" | "month" | "hour"required
pay_range_hiddenbooleanrequiredtarget_start_datestring | nullrequirednotesstring | nullrequiredreplacesobject | nullrequired4 fields
idstringrequirednamestringrequiredtitlestring | nullrequiredphoto_urlstring | nullrequired
filled_byobject | nullrequired4 fields
idstringrequirednamestringrequiredtitlestring | nullrequiredphoto_urlstring | nullrequired
filled_onstring | nullrequiredcan_reopenbooleanrequiredcreated_atstringrequiredupdated_atstringrequired
Errors
validation_failed unauthenticated forbidden not_found rate_limited internal
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"}'const res = await fetch('https://api.bizisy.com/v1/org/positions.list', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.BIZISY_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"status": "on_hold",
"unit_id": "u1",
"reports_to_person_id": "p1"
}),
});
const body = await res.json();
if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
console.log(body.data);import os
import requests
res = requests.post(
"https://api.bizisy.com/v1/org/positions.list",
headers={"Authorization": f"Bearer {os.environ['BIZISY_API_KEY']}"},
json={
"status": "on_hold",
"unit_id": "u1",
"reports_to_person_id": "p1",
},
)
body = res.json()
if not res.ok:
raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
print(body["data"]){
"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_geton My Workplace, HR Assistant- Method
POSTwith a JSON body, orGETwith the input as query parameters
Input
position_idstringrequired
Returns
21 fields
idstringrequiredtitlestringrequiredstatus"draft" | "open" | "on_hold" | "filled" | "cancelled"requiredreason"new" | "replacement"requiredunitobject | nullrequired2 fields
idstringrequirednamestringrequired
locationobject | nullrequired2 fields
idstringrequirednamestringrequired
legal_entityobject | nullrequired2 fields
idstringrequirednamestringrequired
reports_to_personobject | nullrequired4 fields
idstringrequirednamestringrequiredtitlestring | nullrequiredphoto_urlstring | nullrequired
reports_to_positionobject | nullrequired2 fields
idstringrequiredtitlestringrequired
contract_type"permanent" | "fixed_term" | "temporary" | "internship" | "freelance"requiredweekly_hoursnumber | nullrequiredpay_rangeobject | nullrequired4 fields
minnumberrequiredmaxnumberrequiredcurrencystringrequiredperiod"year" | "month" | "hour"required
pay_range_hiddenbooleanrequiredtarget_start_datestring | nullrequirednotesstring | nullrequiredreplacesobject | nullrequired4 fields
idstringrequirednamestringrequiredtitlestring | nullrequiredphoto_urlstring | nullrequired
filled_byobject | nullrequired4 fields
idstringrequirednamestringrequiredtitlestring | nullrequiredphoto_urlstring | nullrequired
filled_onstring | nullrequiredcan_reopenbooleanrequiredcreated_atstringrequiredupdated_atstringrequired
Errors
validation_failed unauthenticated forbidden not_found rate_limited internal
curl https://api.bizisy.com/v1/org/positions.get \
-H "Authorization: Bearer $BIZISY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"position_id":"pos1"}'const res = await fetch('https://api.bizisy.com/v1/org/positions.get', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.BIZISY_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"position_id": "pos1"
}),
});
const body = await res.json();
if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
console.log(body.data);import os
import requests
res = requests.post(
"https://api.bizisy.com/v1/org/positions.get",
headers={"Authorization": f"Bearer {os.environ['BIZISY_API_KEY']}"},
json={
"position_id": "pos1",
},
)
body = res.json()
if not res.ok:
raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
print(body["data"]){
"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_createon 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
titlestringrequired1–120 characters.
status"draft" | "open" | "on_hold"unit_idstring | nulllocation_idstring | nulllegal_entity_idstring | nullreports_to_person_idstring | nullreports_to_position_idstring | nullcontract_type"permanent" | "fixed_term" | "temporary" | "internship" | "freelance"weekly_hoursnumber | nullFrom 0 to 80.
pay_rangeobject | null4 fields
minnumberrequiredFrom 0 to 100000000.
maxnumberrequiredFrom 0 to 100000000.
currencyanyrequiredperiod"year" | "month" | "hour"required
target_start_datestring | nullnotesstring | nullUp to 1000 characters.
reason"new" | "replacement"replaces_person_idstring | null
Returns
21 fields
idstringrequiredtitlestringrequiredstatus"draft" | "open" | "on_hold" | "filled" | "cancelled"requiredreason"new" | "replacement"requiredunitobject | nullrequired2 fields
idstringrequirednamestringrequired
locationobject | nullrequired2 fields
idstringrequirednamestringrequired
legal_entityobject | nullrequired2 fields
idstringrequirednamestringrequired
reports_to_personobject | nullrequired4 fields
idstringrequirednamestringrequiredtitlestring | nullrequiredphoto_urlstring | nullrequired
reports_to_positionobject | nullrequired2 fields
idstringrequiredtitlestringrequired
contract_type"permanent" | "fixed_term" | "temporary" | "internship" | "freelance"requiredweekly_hoursnumber | nullrequiredpay_rangeobject | nullrequired4 fields
minnumberrequiredmaxnumberrequiredcurrencystringrequiredperiod"year" | "month" | "hour"required
pay_range_hiddenbooleanrequiredtarget_start_datestring | nullrequirednotesstring | nullrequiredreplacesobject | nullrequired4 fields
idstringrequirednamestringrequiredtitlestring | nullrequiredphoto_urlstring | nullrequired
filled_byobject | nullrequired4 fields
idstringrequirednamestringrequiredtitlestring | nullrequiredphoto_urlstring | nullrequired
filled_onstring | nullrequiredcan_reopenbooleanrequiredcreated_atstringrequiredupdated_atstringrequired
Errors
validation_failed unauthenticated forbidden not_found conflict rate_limited internal
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"
}'const res = await fetch('https://api.bizisy.com/v1/org/positions.create', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.BIZISY_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({
"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"
}),
});
const body = await res.json();
if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
console.log(body.data);import os, uuid
import requests
res = requests.post(
"https://api.bizisy.com/v1/org/positions.create",
headers={"Authorization": f"Bearer {os.environ['BIZISY_API_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"title": "Data Engineer",
"status": "draft",
"unit_id": "u2",
"location_id": None,
"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",
},
)
body = res.json()
if not res.ok:
raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
print(body["data"]){
"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_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
position_idstringrequiredtitlestring1–120 characters.
status"draft" | "open" | "on_hold" | "filled" | "cancelled"unit_idstring | nulllocation_idstring | nulllegal_entity_idstring | nullreports_to_person_idstring | nullreports_to_position_idstring | nullcontract_type"permanent" | "fixed_term" | "temporary" | "internship" | "freelance"weekly_hoursnumber | nullFrom 0 to 80.
pay_rangeobject | null4 fields
minnumberrequiredFrom 0 to 100000000.
maxnumberrequiredFrom 0 to 100000000.
currencyanyrequiredperiod"year" | "month" | "hour"required
target_start_datestring | nullnotesstring | nullUp to 1000 characters.
reason"new" | "replacement"replaces_person_idstring | null
Returns
21 fields
idstringrequiredtitlestringrequiredstatus"draft" | "open" | "on_hold" | "filled" | "cancelled"requiredreason"new" | "replacement"requiredunitobject | nullrequired2 fields
idstringrequirednamestringrequired
locationobject | nullrequired2 fields
idstringrequirednamestringrequired
legal_entityobject | nullrequired2 fields
idstringrequirednamestringrequired
reports_to_personobject | nullrequired4 fields
idstringrequirednamestringrequiredtitlestring | nullrequiredphoto_urlstring | nullrequired
reports_to_positionobject | nullrequired2 fields
idstringrequiredtitlestringrequired
contract_type"permanent" | "fixed_term" | "temporary" | "internship" | "freelance"requiredweekly_hoursnumber | nullrequiredpay_rangeobject | nullrequired4 fields
minnumberrequiredmaxnumberrequiredcurrencystringrequiredperiod"year" | "month" | "hour"required
pay_range_hiddenbooleanrequiredtarget_start_datestring | nullrequirednotesstring | nullrequiredreplacesobject | nullrequired4 fields
idstringrequirednamestringrequiredtitlestring | nullrequiredphoto_urlstring | nullrequired
filled_byobject | nullrequired4 fields
idstringrequirednamestringrequiredtitlestring | nullrequiredphoto_urlstring | nullrequired
filled_onstring | nullrequiredcan_reopenbooleanrequiredcreated_atstringrequiredupdated_atstringrequired
Errors
validation_failed unauthenticated forbidden not_found conflict rate_limited internal
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"
}'const res = await fetch('https://api.bizisy.com/v1/org/positions.update', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.BIZISY_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({
"position_id": "pos1",
"title": "Lead",
"reports_to_position_id": "pos2",
"reports_to_person_id": null,
"notes": null,
"reason": "new"
}),
});
const body = await res.json();
if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
console.log(body.data);import os, uuid
import requests
res = requests.post(
"https://api.bizisy.com/v1/org/positions.update",
headers={"Authorization": f"Bearer {os.environ['BIZISY_API_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"position_id": "pos1",
"title": "Lead",
"reports_to_position_id": "pos2",
"reports_to_person_id": None,
"notes": None,
"reason": "new",
},
)
body = res.json()
if not res.ok:
raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
print(body["data"]){
"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_reopenon HR Assistant- Preview
?dry_run=trueruns every check and saves nothing- Retries
- An Idempotency-Key replays the first result
Input
position_idstringrequired
Returns
21 fields
idstringrequiredtitlestringrequiredstatus"draft" | "open" | "on_hold" | "filled" | "cancelled"requiredreason"new" | "replacement"requiredunitobject | nullrequired2 fields
idstringrequirednamestringrequired
locationobject | nullrequired2 fields
idstringrequirednamestringrequired
legal_entityobject | nullrequired2 fields
idstringrequirednamestringrequired
reports_to_personobject | nullrequired4 fields
idstringrequirednamestringrequiredtitlestring | nullrequiredphoto_urlstring | nullrequired
reports_to_positionobject | nullrequired2 fields
idstringrequiredtitlestringrequired
contract_type"permanent" | "fixed_term" | "temporary" | "internship" | "freelance"requiredweekly_hoursnumber | nullrequiredpay_rangeobject | nullrequired4 fields
minnumberrequiredmaxnumberrequiredcurrencystringrequiredperiod"year" | "month" | "hour"required
pay_range_hiddenbooleanrequiredtarget_start_datestring | nullrequirednotesstring | nullrequiredreplacesobject | nullrequired4 fields
idstringrequirednamestringrequiredtitlestring | nullrequiredphoto_urlstring | nullrequired
filled_byobject | nullrequired4 fields
idstringrequirednamestringrequiredtitlestring | nullrequiredphoto_urlstring | nullrequired
filled_onstring | nullrequiredcan_reopenbooleanrequiredcreated_atstringrequiredupdated_atstringrequired
Errors
validation_failed unauthenticated forbidden not_found conflict rate_limited internal
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"}'const res = await fetch('https://api.bizisy.com/v1/org/positions.reopen', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.BIZISY_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({
"position_id": "pos1"
}),
});
const body = await res.json();
if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
console.log(body.data);import os, uuid
import requests
res = requests.post(
"https://api.bizisy.com/v1/org/positions.reopen",
headers={"Authorization": f"Bearer {os.environ['BIZISY_API_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"position_id": "pos1",
},
)
body = res.json()
if not res.ok:
raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
print(body["data"]){
"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.