Add a document
Adds a standard document to a person's record. Send the file as the request body (a PDF, or a photo as JPEG,
PNG or WebP, up to 20 MB) and its type and details in the query. Agoo checks the file by its bytes, removes a
photo's camera details and location, encrypts it with a key of its own and scans it for viruses; the document
is checking until the scan passes. Send replaces to add the next version of a current document (a renewed
licence): the older one is kept as superseded.
- A type that expires needs
expires_on; Agoo reminds the person, their manager and HR before it expires, as the type says, and fireshr_document.expiring. - A copy of a Ghana Card is refused (L.I. 2523 forbids relying on a photocopy, scan or image of one to verify identity): record the Ghana Card PIN on the HR record instead.
- HEIC photos and Word files are refused: send a JPEG or a PDF.
Scope: documents:write · 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: documents:write
person_id*stringThe person's ID.
^person_[0-7][0-9a-hjkmnp-tv-z]{25}$"person_01kjsesxm0e4zbyvkr7bcfxbfg"type_id*stringThe document's type (its organisation's types are in the Console, under People, Documents).
^hrdoctype_[0-7][0-9a-hjkmnp-tv-z]{25}$"hrdoctype_01m6k1z8b0d2f4h6k8m0p2r4tw"title?stringThe type's name when left out.
length <= 160issued_on?string^[0-9]{4}-[0-9]{2}-[0-9]{2}$expires_on?stringRequired for a type that expires.
^[0-9]{4}-[0-9]{2}-[0-9]{2}$notes?stringlength <= 500replaces?stringThe current document this one replaces: it becomes the next version.
^hrdoc_[0-7][0-9a-hjkmnp-tv-z]{25}$"hrdoc_01m6k2a4c6e8g0j2r4n6q8s0tv"file_name?stringlength <= 160Idempotency-Key*stringA 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.
uuidbody*fileapplication/octet-streambinaryThe document, checking until its virus scan passes.
application/json- response
One version of a person's HR document, without the file (Download a document). Through the API, standard documents only: identity documents, disciplinary letters and health documents stay inside Agoo.
id*HrDocumentIdAn HR document ID (TypeID with the hrdoc prefix): one version of a document.
^hrdoc_[0-7][0-9a-hjkmnp-tv-z]{25}$"hrdoc_01m6k2a4c6e8g0j2r4n6q8s0tv"object*"hr_document""hr_document"person_id*PersonIdA person ID (TypeID with the person prefix).
^person_[0-7][0-9a-hjkmnp-tv-z]{25}$"person_01kjsesxm0e4zbyvkr7bcfxbfg"type*A document's type, as the document names it.
title*stringversion*integer1 <= valuesupersedes_id*|The version it replaced.
status*stringchecking until its virus scan passes; then current (or expired past its date); superseded once a newer version is in force; refused when the scan or the check of its bytes failed (its file was deleted).
"checking""current""expired""superseded""refused"visibility*"standard"Through the API, standard documents only.
"standard"issued_on*|dateexpires_on*|datecontent_type*string"application/pdf""image/jpeg""image/png""image/webp"byte_size*integersha256*stringHex SHA-256 of the file, so a copy proves itself.
created_at*stringdate-timeupdated_at*stringdate-timecurl -X POST 'https://api.agoohq.com/v1/people/person_01kjsesxm0e4zbyvkr7bcfxbfg/documents?type_id=hrdoctype_01m6k1z8b0d2f4h6k8m0p2r4tw' \ -H 'Idempotency-Key: 3f6b2a1e-8c4d-4f7a-9b2e-5d1c0a7e9f64' \ -H 'Content-Type: application/octet-stream' \ -d 'string'{ "id": "hrdoc_01m6k2a4c6e8g0j2r4n6q8s0tv", "object": "hr_document", "person_id": "person_01kjw4mg80efgb5aqbsqnxhtbh", "type": { "id": "hrdoctype_01m6k1z8b0d2f4h6k8m0p2r4tw", "name": "Professional licence", "category": "licence" }, "title": "Medical and Dental Council licence", "version": 2, "supersedes_id": "hrdoc_01m3f8c0e2g4j6r8n0q2s4v6wy", "status": "checking", "visibility": "standard", "issued_on": "2026-01-02", "expires_on": "2026-12-31", "content_type": "application/pdf", "byte_size": 176004, "sha256": "9f2c0b8e4d1a7c3e5b6f8a0d2c4e6f8a1b3d5f7a9c1e3b5d7f9a1c3e5b7d9f1a", "created_at": "2026-01-04T09:12:00Z", "updated_at": "2026-01-04T09:14:00Z"}List a person's documents GET
Returns a person's standard HR documents (contracts, letters, certificates, licences) as metadata, newest first: the latest version of each document, or every version with `versions=true`. A document is `checking` until its virus scan passes, then `current` (or `expired` past its date), and `superseded` once a newer version is in force. Identity documents, disciplinary letters and health documents (medical certificates, police reports) are never returned to an API key: they stay inside Agoo. **Scope:** `documents:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode.
Get a document GET
Returns one of a person's standard documents as metadata. **Scope:** `documents:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode.