openapi: 3.1.0
info:
description: "Adaptive API for external integrations.\n\n## \uD83D\uDCCA API Overview\n\nThe Adaptive API enables organizations to build comprehensive reporting and analytics around their security awareness training programs. This RESTful API provides programmatic access to track employee training progress, monitor compliance, and generate insights about your organization's security training effectiveness.\n\n### Purpose & Use Cases\n\nThis API is designed for:\n- **Compliance Reporting**: Track training completion rates and identify employees with overdue trainings\n- **Progress Monitoring**: Get real-time visibility into individual and team training progress\n- **Data Integration**: Sync training data with your HRIS, BI tools, or custom dashboards\n- **Automated Workflows**: Build alerts and notifications for training milestones or compliance deadlines\n\n### Technical Design\n\nThe API follows REST principles with:\n- Resource-oriented URLs that clearly represent your data\n- Standard HTTP methods (GET for reading data)\n- JSON responses for easy parsing and integration\n- Consistent error handling with detailed error messages\n- Token-based authentication for secure access\n\n### Available Resources\n\n| Resource | Purpose | Common Use Cases |\n|----------|---------|------------------|\n| **Users** | Access employee directory data | • Export user lists for reporting
• Track user status changes
• Map users to departments |\n| **Training** | Monitor training campaigns and progress | • Track campaign completion rates
• Identify at-risk employees
• Generate compliance reports |\n\n## \uD83D\uDE80 Quick Start Guide\n\nGet started with the Adaptive API in just 3 steps:\n\n### Step 1: Get Your API Token\nSee [Authentication](#section/Authentication) for more details on how to generate and use API tokens.\n\n### Step 2: Make Your First API Call\n```bash\ncurl -X GET https://api.adaptivesecurity.com/v2/users \\\n -H \"Authorization: Bearer YOUR_API_TOKEN\"\n```\n\n### Step 3: Handle the Response\n```json\n{\n \"users\": [\n {\n \"id\": \"123e4567-e89b-12d3-a456-426614174000\",\n \"email\": \"john.smith@example.com\",\n \"first_name\": \"John\",\n \"last_name\": \"Smith\",\n \"status\": \"ACTIVE\"\n }\n ],\n \"page_after\": \"123e4567-e89b-12d3-a456-426614174000\"\n}\n```\n\n## \uD83D\uDD10 Authentication\n\nAll API endpoints require authentication using an API token:\n\n```http\nAuthorization: Bearer YOUR_API_TOKEN\n```\n\n**Token Management:**\n- Tokens are generated in the Admin portal under **Settings → API**\n- Tokens have a user-set expiration but can be revoked at any time\n- Store tokens securely - treat them like passwords\n## \uD83C\uDF10 Base URL\n\nAll API endpoints are relative to:\n```\nhttps://api.adaptivesecurity.com\n```\n\n## \uD83D\uDEA8 Error Handling\n\nAll API errors follow a consistent JSON structure:\n\n### Standard Error Response\n```json\n{\n \"error_code\": \"RESOURCE_NOT_FOUND\",\n \"message\": \"The requested user was not found\",\n \"status_code\": 404,\n \"request_id\": \"3e502c09-4fd3-42d3-8b3a-4e2f08de0bbf\"\n}\n```\n\n### Validation Error Response\n```json\n{\n \"error_code\": \"VALIDATION_ERROR\",\n \"message\": \"Request validation failed\",\n \"status_code\": 400,\n \"request_id\": \"1d7c1712-2b8e-43f4-90c6-1185e249bdf0\",\n \"details\": [\n {\n \"field\": \"page\",\n \"message\": \"Page must be a non-negative integer\"\n }\n ]\n}\n```\n\n### Error Code Reference\n| Code | Status | Description | Action |\n|------|--------|-------------|--------|\n| `INVALID_TOKEN` | 401 | Token is invalid or expired | Check token validity |\n| `RESOURCE_NOT_FOUND` | 404 | Resource doesn't exist | Verify resource ID |\n| `VALIDATION_ERROR` | 400 | Request validation failed | Check field errors |\n| `INTERNAL_SERVER_ERROR` | 500 | Server error | Contact support |\n\n## \uD83D\uDCCB Request & Response Headers\n\n### Required Request Headers\n```http\nAuthorization: Bearer YOUR_API_TOKEN\n```\n\n### Optional Request Headers\n```http\nAccept: application/json\nContent-Type: application/json # Required for POST/PUT\n```\n\n### Response Headers\n```http\nX-Request-ID: 6acb3ce1-672a-4a49-8fa1-f1a994eef9fd\nContent-Type: application/json\n```\n\n## \uD83D\uDCC4 Pagination\n\nList endpoints return paginated results for optimal performance:\n\n- **Page cursor**: `page_after` field in the response to get the next page\n- **Default sorting**: By creation date (newest first)\n\n### Pagination Example\n```bash\n# Get the next page of users\ncurl -X GET \"https://api.adaptivesecurity.com/v2/users?page_after=5a6dce1e-8d0f-46b1-b263-50b6adca62da\" \\\n -H \"Authorization: Bearer YOUR_API_TOKEN\"\n```\n\n### Pagination Response\n```json\n{\n \"users\": [...],\n \"page_after\": \"123e4567-e89b-12d3-a456-426614174000\"\n}\n```\n\n## \uD83D\uDD50 Timestamps\n\nAll timestamps use ISO 8601 format in UTC:\n```\n2024-12-10T15:30:45.402Z\n```"
title: Adaptive Audit Logs Training API
version: v2
servers:
- url: https://api.adaptivesecurity.com
description: Production API
security:
- bearer-token: []
tags:
- description: 'BETATraining campaign and activity endpoints'
name: Training
paths:
/v2/training/campaigns:
get:
description: 'BETARetrieve a paginated list of training campaigns'
operationId: listTrainingCampaigns
parameters:
- description: Page cursor
example: 6e8e3c89-1122-4db2-ae91-f2c6bc0d5639
in: query
name: page_after
required: false
schema:
type: string
- description: Page size
example: 100
in: query
name: page_size
required: false
schema:
type: integer
default: 100
responses:
'200':
content:
application/json:
examples:
Success Response:
description: Success Response
value:
campaigns:
- id: 2db2730a-3a9d-4b3d-87b4-1d16e1e66a88
name: Engineering Annual Training
audience_type: GROUPS
groups:
- id: f95d3d85-284b-4f94-98fe-23914c805b88
name: Engineering Team
mode: SCHEDULED
status: IN_PROGRESS
created_at: '2025-01-01T13:19:13.402Z'
start_date: '2025-01-10T13:19:13.402Z'
end_date: '2025-04-10T13:19:13.402Z'
employee_title: 2024 Security Awareness Training
- id: 6e8e3c89-1122-4db2-ae91-f2c6bc0d5639
name: New Employee Onboarding
audience_type: ALL_USERS
groups: []
mode: TRIGGERED
status: IN_PROGRESS
created_at: '2025-06-15T08:00:00Z'
start_date: '2025-06-15T08:00:00Z'
end_date: null
employee_title: null
page_after: 6e8e3c89-1122-4db2-ae91-f2c6bc0d5639
schema:
$ref: '#/components/schemas/TrainingCampaignListResponseDto'
description: Successfully retrieved training campaigns
'400':
content:
application/json:
examples:
Validation Error:
description: Validation Error
value:
error_code: VALIDATION_ERROR
message: Request validation failed
status_code: 400
request_id: 2f6f683d-c3e3-44c3-8ee2-b06b5687f255
details:
- field: page_after
message: page_after must be a string
schema:
$ref: '#/components/schemas/ValidationErrorResponseDto'
description: Bad request - Invalid parameters
'401':
content:
application/json:
examples:
Unauthorized Error:
description: Unauthorized Error
value:
error_code: INVALID_TOKEN
message: The provided authentication token is invalid or expired
status_code: 401
request_id: 74fc4c18-2c80-4394-b2e2-2f137b237b92
schema:
$ref: '#/components/schemas/ErrorResponseDto'
description: Unauthorized - Invalid or missing authentication token
'429':
content:
application/json:
examples:
Rate Limit Error:
description: Rate Limit Error
value:
error_code: RATE_LIMIT_EXCEEDED
message: API rate limit exceeded. Please retry after some time
status_code: 429
request_id: 0d47b5d3-884b-42c5-a20a-04e47011ebf4
schema:
$ref: '#/components/schemas/ErrorResponseDto'
description: Too many requests - Rate limit exceeded
'500':
content:
application/json:
examples:
Internal Server Error:
description: Internal Server Error
value:
error_code: INTERNAL_SERVER_ERROR
message: An unexpected error occurred. Please try again later
status_code: 500
request_id: f7e20a42-3c64-4f45-8a87-76113a1ce2f0
schema:
$ref: '#/components/schemas/ErrorResponseDto'
description: Internal server error
summary: List training campaigns
tags:
- Training
/v2/training/campaigns/enrollments:
get:
description: 'BETARetrieve details about training enrollments with campaign and user filters'
operationId: getTrainingCampaignEnrollments
parameters:
- description: User ID
example: 123e4567-e89b-12d3-a456-426614174000
in: query
name: user_id
required: false
schema:
type: string
- description: Training campaign ID
example: c143c964-d39b-4f0f-b3d3-07bb3aaae71e
in: query
name: campaign_id
required: false
schema:
type: string
- description: Page cursor
example: f248c6c3-9c93-4d62-a41b-9843de18f56b
in: query
name: page_after
required: false
schema:
type: string
- description: Number of enrollments to return per page (max 1000)
example: 100
in: query
name: page_size
required: false
schema:
type: integer
default: 100
responses:
'200':
content:
application/json:
examples:
Success Response:
description: Success Response
value:
enrollments:
- id: 5a6dce1e-8d0f-46b1-b263-50b6adca62da
user:
id: 123e4567-e89b-12d3-a456-426614174000
email: john.smith@example.com
campaign:
id: e7f89a36-4b8f-4865-b11a-b0f280ae6a34
name: Q4 Security Training
employee_title: 2024 Security Awareness Training
status: IN_PROGRESS
enrolled_at: '2024-10-05T09:15:00Z'
due_at: '2024-10-12T09:20:00Z'
started_at: '2024-10-05T09:20:00Z'
unenrolled_at: null
completed_at: null
has_acknowledged_policy: false
page_after: 5a6dce1e-8d0f-46b1-b263-50b6adca62da
schema:
$ref: '#/components/schemas/UserTrainingCampaignEnrollmentListDto'
description: Successfully retrieved campaign enrollment details
'401':
content:
application/json:
examples:
Unauthorized Error:
description: Unauthorized Error
value:
error_code: INVALID_TOKEN
message: The provided authentication token is invalid or expired
status_code: 401
request_id: 5a7384c9-b5de-4aa1-a144-faa0de243ab0
schema:
$ref: '#/components/schemas/ErrorResponseDto'
description: Unauthorized - Invalid or missing authentication token
'429':
content:
application/json:
examples:
Rate Limit Error:
description: Rate Limit Error
value:
error_code: RATE_LIMIT_EXCEEDED
message: API rate limit exceeded. Please retry after some time
status_code: 429
request_id: 6e9d2fb1-95e2-49e2-ae36-9de6e6f51c25
schema:
$ref: '#/components/schemas/ErrorResponseDto'
description: Too many requests - Rate limit exceeded
'500':
content:
application/json:
examples:
Internal Server Error:
description: Internal Server Error
value:
error_code: INTERNAL_SERVER_ERROR
message: An unexpected error occurred. Please try again later
status_code: 500
request_id: a0a7b8e0-fc0b-46b1-8dbb-0d04872f9678
schema:
$ref: '#/components/schemas/ErrorResponseDto'
description: Internal server error
summary: Get training campaign enrollments details
tags:
- Training
/v2/training/campaigns/{campaignId}:
get:
description: 'BETARetrieve detailed information about a specific training campaign'
operationId: getTrainingCampaign
parameters:
- description: Campaign ID
example: e7f89a36-4b8f-4865-b11a-b0f280ae6a34
in: path
name: campaignId
required: true
schema:
type: string
responses:
'200':
content:
application/json:
examples:
Success Response:
description: Success Response
value:
id: 88479a0e-6ef4-4bc9-9af1-d57bae0f1234
name: Engineering Annual Training
audience_type: GROUPS
groups:
- id: 12345654-4321-1234-9abc-def012345678
name: Engineers
mode: SCHEDULED
status: IN_PROGRESS
created_at: '2025-06-01T13:19:13.402Z'
start_date: '2025-06-10T13:19:13.402Z'
end_date: '2025-08-10T13:19:13.402Z'
employee_title: 2024 Security Awareness Training
schema:
$ref: '#/components/schemas/TrainingCampaignDto'
description: Successfully retrieved training campaign details
'401':
content:
application/json:
examples:
Unauthorized Error:
description: Unauthorized Error
value:
error_code: INVALID_TOKEN
message: The provided authentication token is invalid or expired
status_code: 401
request_id: dcaf9f7e-6c47-4c93-bb41-0e2d8d9bb0de
schema:
$ref: '#/components/schemas/ErrorResponseDto'
description: Unauthorized - Invalid or missing authentication token
'404':
content:
application/json:
examples:
Not Found Error:
description: Not Found Error
value:
error_code: RESOURCE_NOT_FOUND
message: The requested training campaign was not found
status_code: 404
request_id: 2a3b4c5d-6e7f-8a9b-0c1d-2e3f4a5b6c7d
schema:
$ref: '#/components/schemas/ErrorResponseDto'
description: Training campaign not found
'500':
content:
application/json:
examples:
Internal Server Error:
description: Internal Server Error
value:
error_code: INTERNAL_SERVER_ERROR
message: An unexpected error occurred. Please try again later
status_code: 500
request_id: f351ac3c-cd5e-4ec7-89dc-191fc40a83f2
schema:
$ref: '#/components/schemas/ErrorResponseDto'
description: Internal server error
summary: Get training campaign details
tags:
- Training
components:
schemas:
TrainingCampaignListResponseDto:
type: object
description: Paginated list of training campaigns
properties:
campaigns:
type: array
items:
$ref: '#/components/schemas/TrainingCampaignDto'
page_after:
type: string
example: 123e4567-e89b-12d3-a456-426614174000
CampaignGroupDto:
type: object
properties:
id:
type: string
description: Unique identifier for the group
example: e7f89a36-4b8f-4865-b11a-b0f280ae6a34
name:
type: string
description: The name of the group
example: Finance Team
UserTrainingCampaignEnrollmentListDto:
type: object
properties:
enrollments:
type: array
items:
$ref: '#/components/schemas/UserTrainingCampaignEnrollmentDto'
page_after:
type: string
example: 3b495a63-23f2-4284-82d0-3aa5b5c0c753
TrainingCampaignSummaryDto:
type: object
description: Training campaign information
properties:
id:
type: string
description: Unique identifier for the campaign
example: e7f89a36-4b8f-4865-b11a-b0f280ae6a34
name:
type: string
description: Name of the training campaign
example: Engineering Annual Training
employee_title:
type:
- string
- 'null'
description: Employee-facing title for the campaign. Null if no employee-facing title is set.
example: 2024 Annual Security Training
UserTrainingCampaignEnrollmentDto:
type: object
description: User's enrollment details for a training campaign
properties:
campaign:
$ref: '#/components/schemas/TrainingCampaignSummaryDto'
completed_at:
type: string
format: date-time
example: '2025-01-01T13:19:13.402Z'
due_at:
type: string
format: date-time
description: Date when the user's training completion is due
example: '2025-01-08T13:19:13.402Z'
enrolled_at:
type: string
format: date-time
example: '2025-01-01T13:19:13.402Z'
has_acknowledged_policy:
type: boolean
example: false
id:
type: string
description: Unique identifier for the enrollment
example: 6a10d54c-f1bf-4d1d-8864-64bfac9a0c13
started_at:
type: string
format: date-time
description: Date when user started the training
example: '2025-01-01T13:19:13.402Z'
status:
type: string
description: User's enrollment status in the training campaign
enum:
- IN_PROGRESS
- COMPLETED
- INCOMPLETE
- OVERDUE
- UNENROLLED
example: IN_PROGRESS
unenrolled_at:
type: string
format: date-time
example: '2025-01-02T13:19:13.402Z'
user:
$ref: '#/components/schemas/UserSummaryDto'
ValidationErrorResponseDto:
type: object
description: Error response for validation failures with field-level details
properties:
details:
type: array
description: List of field-level validation error details
items:
$ref: '#/components/schemas/ErrorDetail'
error_code:
type: string
description: Machine-readable error code
example: VALIDATION_ERROR
message:
type: string
description: Human-readable error message
example: Request validation failed
request_id:
type: string
description: Unique request ID for debugging
example: 8f03bdf9-ac45-4279-8dbe-f28839c2fed3
status_code:
type: integer
format: int32
description: HTTP status code
example: 400
required:
- details
- error_code
- message
- request_id
- status_code
UserSummaryDto:
type: object
description: User summary information
properties:
email:
type: string
description: User's email address
example: john.smith@example.com
id:
type: string
description: Unique identifier for the user
example: 123e4567-e89b-12d3-a456-426614174000
ErrorDetail:
type: object
description: Field-level validation error details
properties:
field:
type: string
description: Field name that failed validation
example: email
message:
type: string
description: Validation error message for this field
example: Email address is not valid
required:
- field
- message
ErrorResponseDto:
type: object
description: Standard error response format for all API errors
properties:
error_code:
type: string
description: Machine-readable error code
example: RESOURCE_NOT_FOUND
message:
type: string
description: Human-readable error message
example: The requested user was not found
request_id:
type: string
description: Unique request ID for debugging
example: 8f03bdf9-ac45-4279-8dbe-f28839c2fed3
status_code:
type: integer
format: int32
description: HTTP status code
example: 404
required:
- error_code
- message
- request_id
- status_code
TrainingCampaignDto:
type: object
description: Training campaign information
properties:
audience_type:
type: string
description: Target audience type for the campaign
enum:
- GROUPS
- ALL_USERS
example: GROUPS
created_at:
type: string
format: date-time
description: Campaign's created date
example: '2025-01-01T13:19:13.402Z'
end_date:
type: string
format: date-time
description: End date for the campaign (null for TRIGGERED mode)
example: '2025-01-01T13:19:13.402Z'
groups:
type: array
description: Groups associated with the campaign
items:
$ref: '#/components/schemas/CampaignGroupDto'
id:
type: string
description: Unique identifier for the campaign
example: e7f89a36-4b8f-4865-b11a-b0f280ae6a34
mode:
type: string
description: Campaign mode
enum:
- SCHEDULED
- TRIGGERED
example: SCHEDULED
name:
type: string
description: Name of the training campaign
example: Engineering Annual Training
start_date:
type: string
format: date-time
description: Start date for the campaign
example: '2025-01-01T13:19:13.402Z'
status:
type: string
description: Current status of the campaign
enum:
- DRAFT
- SCHEDULED
- IN_PROGRESS
- COMPLETED
- OVERDUE
example: IN_PROGRESS
employee_title:
type:
- string
- 'null'
description: Employee-facing title for the campaign. Null if no employee-facing title is set.
example: 2024 Annual Security Training
securitySchemes:
bearer-token:
description: 'API authentication token obtained from the Adaptive Admin portal (Settings → API Tokens). Include the token in the Authorization header as: Bearer YOUR_TOKEN'
scheme: bearer
type: http