For the complete documentation index, see llms.txt. This page is also available as Markdown.

Public API Reference

Complete reference for all AOH Sync Public API endpoints. Every endpoint under /v1/ (except /v1/health) requires the X-API-Key header.

Interactive reference

Health check

get
Responses
200

Service is healthy

application/json
statusstringOptionalExample: ok
get/v1/health
GET /v1/health HTTP/1.1
Host: YOUR-AOH-SYNC-HOST
Accept: */*
200

Service is healthy

{
  "status": "ok"
}

List identities

get
Authorizations
X-API-KeystringRequired
Query parameters
limitintegerOptionalDefault: 50
offsetintegerOptionalDefault: 0
statusstring · enumOptionalPossible values:
Responses
200

Paginated identity list

application/json
totalintegerOptional
limitintegerOptional
offsetintegerOptional
get/v1/identities
GET /v1/identities HTTP/1.1
Host: YOUR-AOH-SYNC-HOST
X-API-Key: YOUR_API_KEY
Accept: */*
{
  "data": [
    {
      "id": "text",
      "display_name": "text",
      "status": "text",
      "created_at": "2026-01-01T00:00:00.000Z",
      "updated_at": "2026-01-01T00:00:00.000Z",
      "attributes": [
        {
          "identity_id": "text",
          "field_name": "text",
          "field_value": "text",
          "source_type": "text",
          "source_id": "text",
          "priority": 1,
          "updated_at": "2026-01-01T00:00:00.000Z"
        }
      ],
      "users": [
        {
          "id": "text",
          "external_id": "text",
          "user_principal_name": "text",
          "display_name": "text",
          "email": "text",
          "job_title": "text",
          "first_name": "text",
          "last_name": "text",
          "status": "text",
          "tenant_id": "text",
          "hire_date": "2026-01-01T00:00:00.000Z",
          "created_at": "2026-01-01T00:00:00.000Z",
          "updated_at": "2026-01-01T00:00:00.000Z",
          "roles": [
            "text"
          ],
          "groups": [
            "text"
          ],
          "departments": [
            "text"
          ]
        }
      ],
      "accounts": [
        {
          "id": "text",
          "external_id": "text",
          "identifier": "text",
          "display_name": "text",
          "first_name": "text",
          "last_name": "text",
          "job_title": "text",
          "status": "text",
          "source_system_id": "text",
          "person_id": "text",
          "last_synced_at": "2026-01-01T00:00:00.000Z",
          "created_at": "2026-01-01T00:00:00.000Z",
          "updated_at": "2026-01-01T00:00:00.000Z"
        }
      ],
      "machine_identities": [
        {
          "id": "text",
          "account_id": "text",
          "display_name": "text",
          "classification": "text",
          "owned_by": "text",
          "manager_id": "text",
          "technical_inheritor": "text",
          "risk_score": 1,
          "status": "text",
          "created_at": "2026-01-01T00:00:00.000Z",
          "updated_at": "2026-01-01T00:00:00.000Z"
        }
      ]
    }
  ],
  "total": 1,
  "limit": 1,
  "offset": 1
}

Get identity by ID

get
Authorizations
X-API-KeystringRequired
Path parameters
idstringRequired
Responses
200

Identity

application/json
idstringOptional
display_namestringOptional
statusstringOptional
created_atstring · date-timeOptional
updated_atstring · date-timeOptional
get/v1/identities/{id}
GET /v1/identities/{id} HTTP/1.1
Host: YOUR-AOH-SYNC-HOST
X-API-Key: YOUR_API_KEY
Accept: */*
{
  "id": "text",
  "display_name": "text",
  "status": "text",
  "created_at": "2026-01-01T00:00:00.000Z",
  "updated_at": "2026-01-01T00:00:00.000Z",
  "attributes": [
    {
      "identity_id": "text",
      "field_name": "text",
      "field_value": "text",
      "source_type": "text",
      "source_id": "text",
      "priority": 1,
      "updated_at": "2026-01-01T00:00:00.000Z"
    }
  ],
  "users": [
    {
      "id": "text",
      "external_id": "text",
      "user_principal_name": "text",
      "display_name": "text",
      "email": "text",
      "job_title": "text",
      "first_name": "text",
      "last_name": "text",
      "status": "text",
      "tenant_id": "text",
      "hire_date": "2026-01-01T00:00:00.000Z",
      "created_at": "2026-01-01T00:00:00.000Z",
      "updated_at": "2026-01-01T00:00:00.000Z",
      "roles": [
        "text"
      ],
      "groups": [
        "text"
      ],
      "departments": [
        "text"
      ]
    }
  ],
  "accounts": [
    {
      "id": "text",
      "external_id": "text",
      "identifier": "text",
      "display_name": "text",
      "first_name": "text",
      "last_name": "text",
      "job_title": "text",
      "status": "text",
      "source_system_id": "text",
      "person_id": "text",
      "last_synced_at": "2026-01-01T00:00:00.000Z",
      "created_at": "2026-01-01T00:00:00.000Z",
      "updated_at": "2026-01-01T00:00:00.000Z"
    }
  ],
  "machine_identities": [
    {
      "id": "text",
      "account_id": "text",
      "display_name": "text",
      "classification": "text",
      "owned_by": "text",
      "manager_id": "text",
      "technical_inheritor": "text",
      "risk_score": 1,
      "status": "text",
      "created_at": "2026-01-01T00:00:00.000Z",
      "updated_at": "2026-01-01T00:00:00.000Z"
    }
  ]
}

Get lifecycle history for an identity

get
Authorizations
X-API-KeystringRequired
Path parameters
idstringRequired
Query parameters
limitintegerOptionalDefault: 50
offsetintegerOptionalDefault: 0
Responses
200

Lifecycle event list

application/json
totalintegerOptional
limitintegerOptional
offsetintegerOptional
get/v1/identities/{id}/history
GET /v1/identities/{id}/history HTTP/1.1
Host: YOUR-AOH-SYNC-HOST
X-API-Key: YOUR_API_KEY
Accept: */*
{
  "data": [
    {
      "id": "text",
      "event_type": "text",
      "occurred_at": "2026-01-01T00:00:00.000Z",
      "details": {}
    }
  ],
  "total": 1,
  "limit": 1,
  "offset": 1
}

List users for the caller's tenant

get
Authorizations
X-API-KeystringRequired
Query parameters
limitintegerOptionalDefault: 50
offsetintegerOptionalDefault: 0
Responses
200

Paginated user list

application/json
totalintegerOptional
limitintegerOptional
offsetintegerOptional
get/v1/users
GET /v1/users HTTP/1.1
Host: YOUR-AOH-SYNC-HOST
X-API-Key: YOUR_API_KEY
Accept: */*
{
  "data": [
    {
      "id": "text",
      "external_id": "text",
      "user_principal_name": "text",
      "display_name": "text",
      "email": "text",
      "job_title": "text",
      "first_name": "text",
      "last_name": "text",
      "status": "text",
      "tenant_id": "text",
      "hire_date": "2026-01-01T00:00:00.000Z",
      "created_at": "2026-01-01T00:00:00.000Z",
      "updated_at": "2026-01-01T00:00:00.000Z",
      "roles": [
        "text"
      ],
      "groups": [
        "text"
      ],
      "departments": [
        "text"
      ]
    }
  ],
  "total": 1,
  "limit": 1,
  "offset": 1
}

Get user by ID

get
Authorizations
X-API-KeystringRequired
Path parameters
idstringRequired
Responses
200

User

application/json
idstringOptional
external_idstringOptional
user_principal_namestringOptional
display_namestringOptional
emailstringOptional
job_titlestringOptional
first_namestringOptional
last_namestringOptional
statusstringOptional
tenant_idstringOptional
hire_datestring · date-timeOptional
created_atstring · date-timeOptional
updated_atstring · date-timeOptional
rolesstring[]Optional
groupsstring[]Optional
departmentsstring[]Optional
get/v1/users/{id}
GET /v1/users/{id} HTTP/1.1
Host: YOUR-AOH-SYNC-HOST
X-API-Key: YOUR_API_KEY
Accept: */*
{
  "id": "text",
  "external_id": "text",
  "user_principal_name": "text",
  "display_name": "text",
  "email": "text",
  "job_title": "text",
  "first_name": "text",
  "last_name": "text",
  "status": "text",
  "tenant_id": "text",
  "hire_date": "2026-01-01T00:00:00.000Z",
  "created_at": "2026-01-01T00:00:00.000Z",
  "updated_at": "2026-01-01T00:00:00.000Z",
  "roles": [
    "text"
  ],
  "groups": [
    "text"
  ],
  "departments": [
    "text"
  ]
}

Trigger a sync job for a connector

post
Authorizations
X-API-KeystringRequired
Body
connector_idstringRequired
idempotency_keystringOptional
Responses
202

Job accepted

application/json
job_idstringOptional
statusstringOptional
post/v1/sync/trigger
POST /v1/sync/trigger HTTP/1.1
Host: YOUR-AOH-SYNC-HOST
X-API-Key: YOUR_API_KEY
Content-Type: application/json
Accept: */*
Content-Length: 48

{
  "connector_id": "text",
  "idempotency_key": "text"
}
{
  "job_id": "text",
  "status": "text"
}

Get sync job status

get
Authorizations
X-API-KeystringRequired
Path parameters
idstringRequired
Responses
200

Sync job status

application/json
job_idstringOptional
statusstringOptional
progress_pctintegerOptional
started_atstring · date-timeOptional
completed_atstring · date-timeOptional
error_messagestringOptional
batches_processedintegerOptional
batches_totalintegerOptional
get/v1/sync/jobs/{id}
GET /v1/sync/jobs/{id} HTTP/1.1
Host: YOUR-AOH-SYNC-HOST
X-API-Key: YOUR_API_KEY
Accept: */*
{
  "job_id": "text",
  "status": "text",
  "progress_pct": 1,
  "started_at": "2026-01-01T00:00:00.000Z",
  "completed_at": "2026-01-01T00:00:00.000Z",
  "error_message": "text",
  "batches_processed": 1,
  "batches_total": 1
}

Create a webhook subscription

post
Authorizations
X-API-KeystringRequired
Body
callback_urlstring · uriRequired
eventsstring[] · min: 1Required
Responses
201

Webhook created (signing_secret returned once only)

application/json
idstringOptional
callback_urlstring · uriOptional
eventsstring[]Optional
activebooleanOptional
created_atstring · date-timeOptional
signing_secretstringOptional
post/v1/webhooks
POST /v1/webhooks HTTP/1.1
Host: YOUR-AOH-SYNC-HOST
X-API-Key: YOUR_API_KEY
Content-Type: application/json
Accept: */*
Content-Length: 56

{
  "callback_url": "https://example.com",
  "events": [
    "text"
  ]
}
{
  "id": "text",
  "callback_url": "https://example.com",
  "events": [
    "text"
  ],
  "active": true,
  "created_at": "2026-01-01T00:00:00.000Z",
  "signing_secret": "text"
}

List webhook subscriptions for the caller's tenant

get
Authorizations
X-API-KeystringRequired
Responses
200

Webhook list

application/json
totalintegerOptional
get/v1/webhooks
GET /v1/webhooks HTTP/1.1
Host: YOUR-AOH-SYNC-HOST
X-API-Key: YOUR_API_KEY
Accept: */*
{
  "data": [
    {
      "id": "text",
      "callback_url": "https://example.com",
      "events": [
        "text"
      ],
      "active": true,
      "created_at": "2026-01-01T00:00:00.000Z"
    }
  ],
  "total": 1
}

Update a webhook subscription

patch
Authorizations
X-API-KeystringRequired
Path parameters
idstringRequired
Body
callback_urlstring · uriOptional
eventsstring[] · min: 1Optional
activebooleanOptional
Responses
200

Updated webhook

application/json
idstringOptional
callback_urlstring · uriOptional
eventsstring[]Optional
activebooleanOptional
created_atstring · date-timeOptional
patch/v1/webhooks/{id}
PATCH /v1/webhooks/{id} HTTP/1.1
Host: YOUR-AOH-SYNC-HOST
X-API-Key: YOUR_API_KEY
Content-Type: application/json
Accept: */*
Content-Length: 70

{
  "callback_url": "https://example.com",
  "events": [
    "text"
  ],
  "active": true
}
{
  "id": "text",
  "callback_url": "https://example.com",
  "events": [
    "text"
  ],
  "active": true,
  "created_at": "2026-01-01T00:00:00.000Z"
}

Delete a webhook subscription

delete
Authorizations
X-API-KeystringRequired
Path parameters
idstringRequired
Responses
204

Deleted

No content

delete/v1/webhooks/{id}
DELETE /v1/webhooks/{id} HTTP/1.1
Host: YOUR-AOH-SYNC-HOST
X-API-Key: YOUR_API_KEY
Accept: */*

No content

Rotate the signing secret for a webhook subscription

post
Authorizations
X-API-KeystringRequired
Path parameters
idstringRequired
Responses
200

New signing secret (returned once only)

application/json
signing_secretstringOptional
post/v1/webhooks/{id}/rotate-secret
POST /v1/webhooks/{id}/rotate-secret HTTP/1.1
Host: YOUR-AOH-SYNC-HOST
X-API-Key: YOUR_API_KEY
Accept: */*
{
  "signing_secret": "text"
}

Endpoint summary

The table below is always readable, regardless of how the interactive blocks are configured.

Method
Path
Summary
Auth required

GET

/v1/health

Health check

No

GET

/v1/identities

List identities (paginated)

Yes

GET

/v1/identities/{id}

Get a single identity by ID

Yes

GET

/v1/identities/{id}/history

Get lifecycle history for an identity

Yes

GET

/v1/users

List users for the caller's tenant

Yes

GET

/v1/users/{id}

Get a single user by ID

Yes

POST

/v1/sync/trigger

Trigger a sync job for a connector

Yes

GET

/v1/sync/jobs/{id}

Get sync job status

Yes

POST

/v1/webhooks

Create a webhook subscription

Yes

GET

/v1/webhooks

List webhook subscriptions

Yes

PATCH

/v1/webhooks/{id}

Update a webhook subscription

Yes

DELETE

/v1/webhooks/{id}

Delete a webhook subscription

Yes

POST

/v1/webhooks/{id}/rotate-secret

Rotate the signing secret for a webhook

Yes

Key schemas

Identity

An Identity is AOH Sync's unified representation of a person, combining attributes, linked user accounts, directory accounts, and machine identities.

User

A User is a directory record (e.g. from Microsoft Entra) linked to an Identity. Users belong to the caller's tenant.

SyncJob (trigger response)

SyncStatus (job status response)

Last updated