List positions
Returns your organisation's positions by title, each with who holds it now. Filter by department, or by
status: vacant lists your vacancies.
Scope: people:read · Plan: Pro and Enterprise in live mode; every plan in test mode.
AuthorizationBearer <token>Send Authorization: Bearer <token> on every request. The token is one of:
| Prefix | What it is | Where it may be used |
|---|---|---|
agoo_sk_live_ | Secret key, live mode | Your servers only |
agoo_sk_test_ | Secret key, test mode | Your servers only |
agoo_pk_live_ | Publishable key, live mode | Browsers 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 mode | As 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: people:read
department_id?stringOnly positions in this department.
^dept_[0-7][0-9a-hjkmnp-tv-z]{25}$"dept_01kjsd2v80e5q7m3c9x4ht6wfa"status?stringOnly positions in this state.
"filled""vacant""frozen""closed"Your positions.
application/json- response
data*array<>next_cursor*|Pass this as cursor to get the next page. null on the last page.
"b3BhcXVlLWN1cnNvcg"has_more*booleancurl -X GET 'https://api.agoohq.com/v1/positions'{ "data": [ { "id": "pos_01m6h1a3c5e7g9j1k3m5n7p9qr", "object": "position", "title": "Head of Operations", "department_id": "dept_01kjsd2v80e5q7m3c9x4ht6wfb", "site_id": "site_01kjpt3yw0fz0v414608h9x65s", "reports_to_id": null, "grade": "G9", "fte": 1, "status": "filled", "budgeted": true, "holder_id": "person_01kjsf3c00ecxs9b3k1hw7wq2n", "held_since": "2024-02-01", "created_at": "2026-10-12T08:30:00Z", "updated_at": "2026-10-12T08:30:00Z" }, { "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": "vacant", "budgeted": true, "holder_id": null, "held_since": null, "created_at": "2026-10-12T08:40:00Z", "updated_at": "2026-10-12T08:40:00Z" } ], "next_cursor": null, "has_more": false}Update a department PATCH
Changes a department. Send only the fields you want to change; `null` clears an optional one. - Renaming a department renames it for everyone in it: their `department` changes with it. - `archived: true` archives a department nobody active is in, with no departments under it and no positions that aren't closed; otherwise it returns `invalid_state`. `archived: false` brings one back, unless another department now has its name (`conflict`). Its history stays either way. - Fires `department.updated`, with `previous_attributes.changed` naming what changed. **Scope:** `hr:write` · **Plan:** Pro and Enterprise in live mode; every plan in test mode.
Create a position POST
Makes a position: a seat in your organisation with its department, site, grade and the position it reports to. It's `vacant` until someone holds it, which happens with a job change that sets their `position_id` (`POST /people/{person_id}/job-changes`). Positions are part of Growth, Pro and Enterprise, so in test mode an organisation on another plan gets `plan_required`. - Fires `position.created`. **Scope:** `hr:write` · **Plan:** Pro and Enterprise in live mode; Growth, Pro and Enterprise in test mode.