Clearhead API Documentation

Use the Eligibility Upload API to programmatically upload member data from external systems such as HRIS platforms.

Authentication

All API requests must include your API key in the Authorization header using Bearer token format.
Authorization: Bearer ch_your_api_key_here
API keys can be created and managed in Settings → API Keys. Ask your HR Manager with Clearhead access if you do not have access to that page. Keys are shown only once on creation — store them securely.
API requests are rate limited to 60 requests per minute per API key.

Update Members

PUThttps://your-domain.com/api/public/members
Update specific members by their unique ID. Only the fields you include will be changed — omitted fields are left as-is. Accepts a single object or an array of objects. If a uniqueId does not match an existing active member, a new member is created with the provided fields.
Request fields
FieldRequiredDescription
uniqueIdYesThe member identifier to look up (email or employee ID)
firstNameNoFirst name. Set to null to remove.
lastNameNoLast name. Set to null to remove.
departmentNoDepartment or team. Set to null to remove.
locationNoOffice or work location. Set to null to remove.
roleNoJob title or role. Set to null to remove.
subcompanyNoSubsidiary or business unit. Set to null to remove.
endDateNoEnd date for access (format: YYYY-MM-DD). Set to null to remove.
Examples
curl -X PUT https://your-domain.com/api/public/members \
  -H "Authorization: Bearer ch_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "uniqueId": "EMP001",
    "department": "Product",
    "location": "Wellington"
  }'
Response
{
  "total": 2,
  "updated": 1,
  "created": 1,
  "noChanges": 0,
  "results": [
    { "uniqueId": "EMP001", "status": "updated" },
    { "uniqueId": "EMP999", "status": "created" }
  ]
}

Upload Endpoint

POSThttps://your-domain.com/api/public/upload
Upload eligibility data as either JSON or CSV. The API validates the data, detects changes against existing members, and automatically applies them.
Accepted content types
Content-TypeDescription
application/jsonRows sent as a JSON array
multipart/form-dataCSV file upload
Request parameters
FieldRequiredDescription
modeYesfull or partial. Bulk deactivation of members not in the file applies only when eligibility is email or id. See Upload modes below.
rowsYes (JSON only)Array of member rows. For multipart/form-data requests, send the CSV as a file field instead. See Row fields below.
fileNameNoDescriptive name for the upload session. Defaults to api-upload.json for JSON or the uploaded file's name for CSV.
autoApproveNoAutomatically approve and apply changes after detection. Defaults to true. Set to false to review changes in the portal before applying.
Upload modes
The mode field determines how uploaded data is compared against existing members.
ModeDescription
fullFull sync: adds and updates from the file. Deactivating members not listed in the file runs only when the tenant's eligibility type is email or id. For other eligibility types, omitted members are left unchanged.
partialOnly add new members. Existing members are left unchanged.
Row fields
FieldRequiredDescription
uniqueIdYesUnique employee identifier (email or employee ID)
firstNameNoFirst name
lastNameNoLast name
departmentNoDepartment or team
locationNoOffice or work location
roleNoJob title or role
subcompanyNoSubsidiary or business unit
endDateNoEnd date for access (format: YYYY-MM-DD)
For CSV uploads, use these same names as column headers in your CSV file.
Examples
curl -X POST https://your-domain.com/api/public/upload \
  -H "Authorization: Bearer ch_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "full",
    "fileName": "monthly-sync.json",
    "rows": [
      {
        "uniqueId": "EMP001",
        "firstName": "John",
        "lastName": "Doe",
        "department": "Engineering",
        "location": "Auckland",
        "role": "Developer"
      },
      {
        "uniqueId": "EMP002",
        "firstName": "Jane",
        "lastName": "Smith",
        "department": "Marketing",
        "location": "Wellington",
        "role": "Manager",
        "endDate": "2026-12-31"
      }
    ]
  }'
Response
The API returns immediately after accepting the upload. Processing (change detection and applying) continues in the background.
{
  "sessionId": 123,
  "status": "AwaitingProcessing",
  "totalRows": 500
}
Use the session ID to check progress with the Session endpoints. Once detection completes, changes are automatically approved and applied if autoApprove is true (default).
Errors
StatusMeaning
400Invalid request — missing required fields, invalid mode, or missing uniqueId on rows
401Invalid, missing, or revoked API key
429Rate limit exceeded (60 requests per minute per API key)
415Unsupported content type (must be application/json or multipart/form-data)
500Server error processing the upload
Error responses include a JSON body:
{ "error": "Description of what went wrong" }

List All Sessions

After uploading, use the session endpoints to poll the status of your upload session.
GEThttps://your-domain.com/api/public/sessions
List upload sessions for your organisation, ordered by most recent first. Supports pagination via limit (default 20, max 100) and offset query parameters.
Example
curl "https://your-domain.com/api/public/sessions?limit=10&offset=0" \
  -H "Authorization: Bearer ch_your_api_key_here"

Details of a single Session

GEThttps://your-domain.com/api/public/sessions/:id
Get details for a specific session by ID. Use this to poll until status reaches Complete or Error.
Example
curl https://your-domain.com/api/public/sessions/123 \
  -H "Authorization: Bearer ch_your_api_key_here"
Response
{
  "id": 123,
  "fileName": "monthly-sync.json",
  "mode": "full",
  "status": "Complete",
  "totalRows": 500,
  "rowsProcessed": 500,
  "newCount": 12,
  "updateCount": 45,
  "deactivateCount": 3,
  "unchangedCount": 440,
  "errorCount": 0,
  "errorReason": null,
  "autoApprove": true,
  "dateCreated": "2026-03-04T10:00:00.000Z",
  "dateCompleted": "2026-03-04T10:01:30.000Z"
}
Status values
StatusDescription
UploadingRows are being received
AwaitingProcessingQueued for change detection
ProcessingDetecting changes against existing members
ReadyForUploadChanges detected, awaiting manual review (when autoApprove is false)
ReadyToApplyApproved, queued for applying
ApplyingChanges are being written to member records
CompleteAll changes applied successfully
ErrorProcessing failed — see errorReason
CancelledSession was superseded by a new upload

Approve Session

When a session is uploaded with autoApprove: false, it will reach ReadyForUpload status after change detection completes. Use this endpoint to approve the session and proceed to apply the changes.
POSThttps://your-domain.com/api/public/sessions/:id/approve
Approve a session that is in ReadyForUpload status. This transitions the session to ReadyToApply, queuing it for the background process to apply the detected changes to member records.
Example
curl -X POST https://your-domain.com/api/public/sessions/123/approve \
  -H "Authorization: Bearer ch_your_api_key_here"
Response
{
  "status": "ReadyToApply"
}
Errors
StatusMeaning
400Session is not in ReadyForUpload status
404Session not found
401Invalid or missing API key
500Server error
Management Portal