Docs
API referencePeople and H R

Update a position

Preview· P9
PATCH
/positions/{position_id}

Changes a position's title, department, site, grade, the position it reports to, its full-time equivalent or whether it's budgeted, or freezes, closes or reopens it. Send only the fields you want to change; null clears an optional one.

  • A position someone holds can't be frozen or closed (invalid_state): change their job first.
  • status: vacant reopens a frozen or closed position; it shows filled while someone holds it. Who holds a position is changed by a job change, never here.
  • Fires position.updated, with previous_attributes.changed naming what changed.

Scope: hr:write · Plan: Pro and Enterprise in live mode; Growth, Pro and Enterprise in test mode.

Authorization

headerAuthorizationBearer <token>

Send Authorization: Bearer <token> on every request. The token is one of:

PrefixWhat it isWhere it may be used
agoo_sk_live_Secret key, live modeYour servers only
agoo_sk_test_Secret key, test modeYour servers only
agoo_pk_live_Publishable key, live modeBrowsers and apps: create pre-registrations and bookings, read public booking types (with their intake questions) and their free slots, read the visit types open for pre-registration with their public forms. Never lists people.
agoo_pk_test_Publishable key, test modeAs above, in test mode

Admins create keys in Console → Developers → API keys and choose each key's scopes. A key is shown once. Never put a secret key in a URL, a browser or a mobile app.

Scope: hr:write

Path Parameters

position_id*string

The position's ID.

Match^pos_[0-7][0-9a-hjkmnp-tv-z]{25}$
Example"pos_01m6h2k4q8e7r9t1v3w5x7y9za"

Request Body

application/json
  1. body

The fields to change. Send null to clear an optional field.

title?string
Length1 <= length <= 120
department_id?|null
site_id?|null
reports_to_id?|null
grade?|
Lengthlength <= 60
fte?number
Range0.1 <= value <= 1
status?string

vacant reopens it (it shows filled while someone holds it). One somebody holds can't be frozen or closed.

Value in"vacant""frozen""closed"
budgeted?boolean

Response Body

The updated position.

application/json
  1. response

A seat in your organisation, with its department, site, grade, the position it reports to, and who holds it. Positions are part of Growth, Pro and Enterprise.

id*PositionId

A position ID (TypeID with the pos prefix).

Match^pos_[0-7][0-9a-hjkmnp-tv-z]{25}$
Example"pos_01m6h2k4q8e7r9t1v3w5x7y9za"
object*"position"
Value in"position"
title*string
Length1 <= length <= 120
Example"Senior operations officer"
department_id*|null
site_id*|null
reports_to_id*|

The position it reports to. null: none.

grade*|
Lengthlength <= 60
Example"G6"
fte*number

Full-time equivalent, from 0.1 to 1.

Range0.1 <= value <= 1
Example1
status*PositionStatus

filled: someone holds it now. vacant: nobody does, and it may be filled. frozen: nobody is to be hired for it now. closed: it no longer exists, and is kept for its history. filled and vacant follow who holds it; frozen and closed are chosen.

Value in"filled""vacant""frozen""closed"
budgeted*boolean

Whether it's in the budget.

holder_id*|

The person who holds it now. null: nobody.

held_since*|

Since when the holder has held it.

Formatdate
created_at*string
Formatdate-time
updated_at*string
Formatdate-time
curl -X PATCH 'https://api.agoohq.com/v1/positions/pos_01m6h2k4q8e7r9t1v3w5x7y9za' \  -H 'Content-Type: application/json' \  -d '{  "status": "frozen"}'
{  "id": "pos_01m6h2k4q8e7r9t1v3w5x7y9za",  "object": "position",  "title": "Senior operations officer",  "department_id": "dept_01kjsd2v80e5q7m3c9x4ht6wfb",  "site_id": "site_01kjpt3yw0fz0v414608h9x65s",  "reports_to_id": "pos_01m6h1a3c5e7g9j1k3m5n7p9qr",  "grade": "G6",  "fte": 1,  "status": "frozen",  "budgeted": true,  "holder_id": null,  "held_since": null,  "created_at": "2026-10-12T08:40:00Z",  "updated_at": "2026-10-19T10:20:00Z"}