Docs

Record leave

Preview· P9
POST
/leave-requests

Records leave from another system (an HR system, a paper form), approved at once, by the rules HR follows in the Console: within the balance and the type's negative allowance, never on days the person already has leave, and with over_reason when it's more than a per-occasion type allows. Working days never count public holidays, closed days or days the person doesn't work (Labour Act s.22). Its days come off the balance and leave.approved fires.

Scope: attendance:manage · Plan: Pro and Enterprise in live mode; every plan 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: attendance:manage

Header Parameters

Idempotency-Key*string

A UUID you generate for this operation. If you retry with the same key within 24 hours, Agoo returns the original response instead of acting twice. While the first request is still running, a retry returns conflict. Reusing a key with a different request returns idempotency_key_reused. Responses with rate_limited, internal_error or unavailable aren't stored, so retry those with the same key.

Formatuuid

Request Body

application/json
  1. body
person_id*PersonId

A person ID (TypeID with the person prefix).

Match^person_[0-7][0-9a-hjkmnp-tv-z]{25}$
Example"person_01kjsesxm0e4zbyvkr7bcfxbfg"
type_id*LeaveTypeId

A leave type ID (TypeID with the ltype prefix).

Match^ltype_[0-7][0-9a-hjkmnp-tv-z]{25}$
Example"ltype_01m4y8r6t0e9k2b7c5d3f1g0hj"
starts_on*string
Formatdate
ends_on*string
Formatdate
half_day?boolean

A half day: one day, of a type taken in half days.

half_day_part?string
Value in"morning""afternoon"
reason?string
Lengthlength <= 500
extra?boolean

Maternity: an abnormal confinement or multiple births add the type's extra days (s.57(3)).

over_reason?string

Required when it's more than a per-occasion type allows.

Lengthlength <= 300

Response Body

The leave, approved.

application/json
  1. response

A leave request. A private type (sick and maternity by default) comes back as kind: away, without its type, reason or note.

id*LeaveRequestId

A leave request ID (TypeID with the leave prefix).

Match^leave_[0-7][0-9a-hjkmnp-tv-z]{25}$
Example"leave_01m4z0q2k8fv7tqz3x9c1nbe5d"
person_id*PersonId

A person ID (TypeID with the person prefix).

Match^person_[0-7][0-9a-hjkmnp-tv-z]{25}$
Example"person_01kjsesxm0e4zbyvkr7bcfxbfg"
type_id*|

null for a private type.

Match^ltype_[0-7][0-9a-hjkmnp-tv-z]{25}$
type_name*string
Example"Annual leave"
Example"Away"
kind*string
Value in"annual""sick""maternity""paternity""compassionate""study""unpaid""other""away"
private*boolean
status*string
Value in"pending""approved""declined""cancelled"
starts_on*string
Formatdate
ends_on*string

The last day of leave.

Formatdate
half_day*boolean
half_day_part*|
Value in"morning""afternoon"null
days*number

What it counts, in unit.

Example3
unit*string
Value in"working_days""calendar_days"
paid*boolean
reason*|

The person's note; null for a private type.

decision_note*|

The approver's note; null for a private type.

decided_at*|
Formatdate-time
decided_by*|

Who decided it; null when recorded, decided through the API or approved at once.

Match^person_[0-7][0-9a-hjkmnp-tv-z]{25}$
approval*|

The approval's state; null when it needed none.

cancelled_at*|
Formatdate-time
created_at*string
Formatdate-time
updated_at*string
Formatdate-time
curl -X POST 'https://api.agoo.ardent.africa/v1/leave-requests' \  -H 'Idempotency-Key: 3f6b2a1e-8c4d-4f7a-9b2e-5d1c0a7e9f64' \  -H 'Content-Type: application/json' \  -d '{  "person_id": "person_01kjw4mg80efgb5aqbsqnxhtbh",  "type_id": "ltype_01m4y8r6t0e9k2b7c5d3f1g0hj",  "starts_on": "2026-11-16",  "ends_on": "2026-11-18",  "reason": "Family visit in Ho"}'
{  "id": "leave_01m4z0q2k8fv7tqz3x9c1nbe5d",  "person_id": "person_01kjw4mg80efgb5aqbsqnxhtbh",  "type_id": "ltype_01m4y8r6t0e9k2b7c5d3f1g0hj",  "type_name": "Annual leave",  "kind": "annual",  "private": false,  "status": "approved",  "starts_on": "2026-11-16",  "ends_on": "2026-11-18",  "half_day": false,  "half_day_part": null,  "days": 3,  "unit": "working_days",  "paid": true,  "reason": "Family visit in Ho",  "decision_note": null,  "decided_at": "2026-10-14T09:12:00Z",  "decided_by": null,  "approval": null,  "cancelled_at": null,  "created_at": "2026-10-14T09:12:00Z",  "updated_at": "2026-10-14T09:12:00Z"}