Stitchflow
Drata logo

Drata User Management API Guide

API workflow

How to automate user lifecycle operations through APIs with caveats that matter in production.

UpdatedMar 11, 2026

Summary and recommendation

Drata exposes a REST API at https://public-api.drata.com, authenticated via Bearer token (API key). API access is gated to the Advanced plan and above; Foundation plan customers have no programmatic access. Keys are displayed only once at generation time and are scoped per workspace - a key from one workspace cannot query another.

The personnel object is the primary identity primitive. Key fields include `id` (UUID), `email`, `employmentType` (enum: FULL_TIME, CONTRACTOR, PART_TIME), `isActive` (boolean), `complianceStatus` (computed enum: COMPLIANT, NON_COMPLIANT, PENDING), `externalId` (for HRIS correlation), and `managerId` for org-graph traversal. The `complianceStatus` and `trainingStatus` fields are server-computed and cannot be written via API.

Pagination is offset-based using `page` / `limit` params (default 25, max 100, 1-based index).

For teams building an identity graph across their stack, `externalId` is the recommended join key between Drata personnel records and upstream HRIS or IdP sources. Mapping `managerId` chains enables org-hierarchy resolution within the compliance dataset.

Stitchflow's MCP server with 60+ deep IT/identity integrations can consume these fields to maintain a unified identity graph without custom pipeline work.

API quick reference

Has user APIYes
Auth methodAPI Key (Bearer token in Authorization header)
Base URLOfficial docs
SCIM availableNo
SCIM plan requiredEnterprise

Authentication

Auth method: API Key (Bearer token in Authorization header)

Setup steps

  1. Log in to Drata as an Administrator.
  2. Navigate to Settings → API Keys.
  3. Click 'Generate API Key', assign a name and select desired scopes.
  4. Copy the generated key immediately (shown only once).
  5. Include the key in all requests as: Authorization: Bearer

Required scopes

Scope Description Required for
personnel:read Read personnel (user) records including profile and compliance status. List and retrieve personnel/users
personnel:write Create and update personnel records. Creating or updating user records
controls:read Read control data. Fetching control assignments linked to users
evidence:read Read evidence records. Retrieving evidence associated with personnel

User object / data model

Field Type Description On create On update Notes
id string (UUID) Unique Drata identifier for the personnel record. system-generated immutable Use this ID for all subsequent operations.
email string Primary email address of the personnel. required updatable Must be unique within the workspace.
firstName string First name of the personnel. required updatable
lastName string Last name of the personnel. required updatable
title string Job title of the personnel. optional updatable
department string Department the personnel belongs to. optional updatable
employmentType enum Type of employment (e.g., FULL_TIME, CONTRACTOR, PART_TIME). optional updatable Affects compliance task assignment logic.
startDate string (ISO 8601 date) Employment start date. optional updatable
endDate string (ISO 8601 date) Employment end date; set when offboarding. optional updatable Setting this value triggers offboarding workflows.
isActive boolean Whether the personnel record is active. defaults to true updatable Deactivating removes user from compliance task queues.
role enum Drata platform role (e.g., ADMIN, MEMBER, AUDITOR). optional updatable Controls access within the Drata platform.
managerId string (UUID) ID of the personnel's manager. optional updatable References another personnel record's id.
complianceStatus enum Computed compliance status (e.g., COMPLIANT, NON_COMPLIANT, PENDING). system-computed read-only Cannot be set directly via API.
trainingStatus object Summary of assigned training completion. system-computed read-only
externalId string Identifier from an external HR or IdP system. optional updatable Useful for correlating with HRIS or IdP records.

Core endpoints

List Personnel

  • Method: GET
  • URL: https://public-api.drata.com/public/personnel
  • Watch out for: Returns all personnel including inactive; filter with isActive=true if needed.

Request example

GET /public/personnel?page=1&limit=25
Authorization: Bearer <api_key>

Response example

{
  "data": [
    {"id":"uuid","email":"user@example.com","firstName":"Jane","lastName":"Doe","isActive":true}
  ],
  "total": 120,
  "page": 1,
  "limit": 25
}

Get Personnel by ID

  • Method: GET
  • URL: https://public-api.drata.com/public/personnel/{id}
  • Watch out for: Returns 404 if the personnel ID does not exist or belongs to a different workspace.

Request example

GET /public/personnel/uuid-1234
Authorization: Bearer <api_key>

Response example

{
  "id": "uuid-1234",
  "email": "user@example.com",
  "firstName": "Jane",
  "lastName": "Doe",
  "complianceStatus": "COMPLIANT"
}

Create Personnel

  • Method: POST
  • URL: https://public-api.drata.com/public/personnel
  • Watch out for: Duplicate email addresses return a 409 conflict. Compliance tasks are auto-assigned based on employmentType.

Request example

POST /public/personnel
Authorization: Bearer <api_key>
Content-Type: application/json
{
  "email": "new@example.com",
  "firstName": "John",
  "lastName": "Smith",
  "employmentType": "FULL_TIME"
}

Response example

{
  "id": "uuid-5678",
  "email": "new@example.com",
  "firstName": "John",
  "lastName": "Smith",
  "isActive": true
}

Update Personnel

  • Method: PATCH
  • URL: https://public-api.drata.com/public/personnel/{id}
  • Watch out for: Only include fields to be changed; omitted fields are not cleared.

Request example

PATCH /public/personnel/uuid-5678
Authorization: Bearer <api_key>
Content-Type: application/json
{
  "title": "Senior Engineer",
  "department": "Engineering"
}

Response example

{
  "id": "uuid-5678",
  "title": "Senior Engineer",
  "department": "Engineering"
}

Deactivate Personnel

  • Method: PATCH
  • URL: https://public-api.drata.com/public/personnel/{id}
  • Watch out for: Deactivation does not delete the record; historical compliance data is retained. Offboarding tasks are triggered by endDate.

Request example

PATCH /public/personnel/uuid-5678
Authorization: Bearer <api_key>
Content-Type: application/json
{
  "isActive": false,
  "endDate": "2025-06-01"
}

Response example

{
  "id": "uuid-5678",
  "isActive": false,
  "endDate": "2025-06-01"
}

List Personnel Training Status

  • Method: GET
  • URL: https://public-api.drata.com/public/personnel/{id}/training
  • Watch out for: Training records are read-only via API; completion must occur within Drata or integrated LMS.

Request example

GET /public/personnel/uuid-1234/training
Authorization: Bearer <api_key>

Response example

{
  "personnelId": "uuid-1234",
  "trainings": [
    {"name":"Security Awareness","status":"COMPLETED","completedAt":"2025-01-15"}
  ]
}

List Personnel Background Checks

  • Method: GET
  • URL: https://public-api.drata.com/public/personnel/{id}/background-checks
  • Watch out for: Background check initiation is not supported via API; only status retrieval is available.

Request example

GET /public/personnel/uuid-1234/background-checks
Authorization: Bearer <api_key>

Response example

{
  "personnelId": "uuid-1234",
  "backgroundChecks": [
    {"status":"PASSED","completedAt":"2024-11-01"}
  ]
}

List Controls

  • Method: GET
  • URL: https://public-api.drata.com/public/controls
  • Watch out for: ownerId references a personnel ID; useful for mapping control ownership to users.

Request example

GET /public/controls?page=1&limit=25
Authorization: Bearer <api_key>

Response example

{
  "data": [
    {"id":"ctrl-uuid","name":"Access Control","status":"PASSING","ownerId":"uuid-1234"}
  ],
  "total": 80
}

Rate limits, pagination, and events

  • Rate limits: Drata enforces rate limits on the public API; exact per-plan limits are not publicly documented in detail.
  • Rate-limit headers: Yes
  • Retry-After header: Yes
  • Rate-limit notes: HTTP 429 is returned when limits are exceeded. Retry-After header is included. Exact request-per-minute figures are not published in official docs as of this research.
  • Pagination method: offset
  • Default page size: 25
  • Max page size: 100
  • Pagination pointer: page / limit
Plan Limit Concurrent
Advanced API access enabled; specific rate limit not publicly documented
Enterprise/Scale Higher limits available; contact Drata for specifics
  • Webhooks available: No
  • Webhook notes: Drata does not publicly document outbound webhook support for user/personnel events as of this research.
  • Alternative event strategy: Poll the /public/personnel endpoint on a schedule to detect changes, or use Drata's native integrations (e.g., Okta SCIM) for real-time provisioning events.

SCIM API status

  • SCIM available: No
  • SCIM version: Not documented
  • Plan required: Enterprise
  • Endpoint: Not documented

Limitations:

  • SCIM provisioning is not natively offered by Drata as a SCIM provider endpoint.
  • Drata acts as a SCIM consumer by connecting to IdPs (e.g., Okta) to ingest user data, not as a SCIM server.
  • Enterprise plan and SSO configuration are prerequisites for IdP-based user sync.
  • Automated provisioning into Drata from an IdP is handled via Okta integration, not a SCIM endpoint exposed by Drata.

Common scenarios

Onboarding: POST /public/personnel with email, firstName, lastName, employmentType, startDate, and externalId. Store the returned Drata id mapped to the HRIS record.

Drata auto-assigns compliance tasks based on employmentType. If the email already exists (e.

g. , from a prior IdP sync), the API returns HTTP 409 - resolve by PATCHing the existing record rather than retrying the POST.

Offboarding: PATCH /public/personnel/{id} with both isActive: false and endDate set to the last working day. Setting only isActive: false without endDate may not trigger all offboarding workflows. The record is retained for audit trail purposes; deletion is not supported via API.

Compliance status sync: GET /public/personnel?page=1&limit=100 and paginate using the total field. Extract id, email, complianceStatus, and trainingStatus per record and write to your data warehouse or dashboard. Schedule on a polling interval (hourly is a reasonable baseline) since Drata does not expose outbound webhooks for personnel events. Note that complianceStatus is computed asynchronously - newly created records may show PENDING for several minutes before all assigned controls are evaluated.

Onboard a new employee from HRIS

  1. POST /public/personnel with email, firstName, lastName, employmentType, startDate, and externalId (HRIS ID).
  2. Store the returned Drata personnel id mapped to the HRIS record.
  3. Drata auto-assigns compliance tasks (security training, background check acknowledgment) based on employmentType.
  4. Poll GET /public/personnel/{id}/training periodically to verify training completion.

Watch out for: If the email already exists in Drata (e.g., from a prior IdP sync), the POST returns 409. Resolve by PATCHing the existing record instead.

Offboard a departing employee

  1. PATCH /public/personnel/{id} with isActive: false and endDate set to the last working day.
  2. Verify the response confirms isActive is false.
  3. Drata will revoke pending compliance task assignments and flag the record as offboarded.
  4. Retain the record for audit trail purposes; do not attempt deletion.

Watch out for: Setting only isActive: false without endDate may not trigger all offboarding workflows; include both fields.

Sync personnel compliance status to an external dashboard

  1. GET /public/personnel?page=1&limit=100 and paginate through all pages using the total field.
  2. For each record, extract id, email, complianceStatus, and trainingStatus.
  3. Write results to your data warehouse or dashboard tool.
  4. Schedule this sync at a regular interval (e.g., hourly) since webhooks are not available.

Watch out for: complianceStatus is computed asynchronously; a newly created personnel record may show PENDING for several minutes before Drata evaluates all assigned controls.

Why building this yourself is a trap

The most significant API caveat is the plan gate: the public API is unavailable on the Foundation tier, meaning teams that start on the entry plan and build manual workflows cannot migrate to API-driven provisioning without an upgrade to Advanced (~$15,000/year) or higher. Budget this dependency explicitly.

Drata acts as a SCIM consumer (ingesting from IdPs like Okta), not a SCIM provider - it does not expose a SCIM endpoint for downstream systems to call. Automated provisioning into Drata from an IdP requires Enterprise tier plus SSO configuration; there is no SCIM server endpoint to target directly.

Rate limit specifics are not published in official documentation; implement exponential backoff on HTTP 429 responses and rely on the Retry-After header. The public API base URL (public-api.drata.com) is distinct from the app URL (app.drata.com) - mixing them in client configuration is a documented source of auth failures.

Automate Drata workflows without one-off scripts

Stitchflow builds and maintains end-to-end IT automation across your SaaS stack, including apps without APIs. Built for exactly how your company works, with human approvals where they matter.

Every app coverage, including apps without APIs
60+ app integrations plus browser automation for apps without APIs
IT graph reconciliation across apps and your IdP
Less than a week to launch, maintained as APIs and admin consoles change
SOC 2 Type II. ~2 hours of your team's time

UpdatedMar 11, 2026

* Details sourced from official product documentation and admin references.

Keep exploring

Related apps

Abnormal Security logo

Abnormal Security

API Only
AutomationAPI only
Last updatedMar 2026

Abnormal Security is an enterprise email security platform focused on detecting and investigating threats such as phishing, account takeover (ATO), and vendor email compromise. It does not support SCIM provisioning, which means every app in your stack

ActiveCampaign logo

ActiveCampaign

API Only
AutomationAPI only
Last updatedFeb 2026

ActiveCampaign uses a group-based permission model: every user belongs to exactly one group, and all feature-area access (Contacts, Campaigns, Automations, Deals, Reports, Templates) is configured at the group level, not per individual. The default Adm

ADP logo

ADP

API Only
AutomationAPI only
Last updatedFeb 2026

ADP Workforce Now is a mid-market to enterprise HCM platform that serves as the HR source of record for employee data — payroll, benefits, time, and talent. User access is governed by a hybrid permission model: predefined security roles (Security Maste