# SiberMate API Reference

> Static Markdown API reference for crawlers, AI agents, SDK generators, and clients that cannot render the interactive API UI.

Last updated: 2026-06-15

Base URL: `https://api.sibermate.com/v1`

Authentication: send a SiberMate tenant API key as `Authorization: Bearer <API_KEY>`.

Successful responses return a JSON object with a top-level `data` property. Error responses return a top-level `error` object with a stable `code` and client-safe `message`.

Machine-readable OpenAPI JSON: https://api.sibermate.com/v1/openapi.json

## System

Operational checks and machine-readable API metadata.

### GET /health

Check API availability.

Returns a lightweight status response that can be used by uptime checks and deployment monitors.

Endpoint: `GET https://api.sibermate.com/v1/health`

Responses:

| Status | Description |
| --- | --- |
| 200 | The API is reachable. |
| 500 | Health check could not be completed. |

Success example:

```json
{
  "data": {
    "status": "ok",
    "service": "sibermate-api",
    "timestamp": "2026-06-12T09:00:00.000Z"
  }
}
```

### GET /openapi.json

Retrieve the OpenAPI document.

Returns this OpenAPI document for tooling, SDK generation, and documentation workflows.

Endpoint: `GET https://api.sibermate.com/v1/openapi.json`

Responses:

| Status | Description |
| --- | --- |
| 200 | OpenAPI document. |

### GET /ready

Check deployment readiness.

Returns whether the API is configured for serving traffic. This check does not validate tenant API keys, organization data access, or external service connectivity.

Endpoint: `GET https://api.sibermate.com/v1/ready`

Responses:

| Status | Description |
| --- | --- |
| 200 | The API is ready to serve traffic. |
| 503 | Service is not ready. |

Success example:

```json
{
  "data": {
    "status": "ready",
    "service": "sibermate-api",
    "checks": {
      "rateLimit": "enabled"
    },
    "timestamp": "2026-06-12T09:00:00.000Z"
  }
}
```

## Company

Organization profile, plan summary, and enabled SiberMate modules.

### GET /companies

List child tenant companies (MSP/Distributor only).

Returns the child tenant companies managed by the authenticated MSP or Distributor account. Non-MSP API keys receive 403. Use the returned company id as the companyId query parameter on other read endpoints to access a specific tenant's data. This endpoint returns data for the organization associated with the authenticated API key.

Endpoint: `GET https://api.sibermate.com/v1/companies`

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": []
}
```

### GET /company

Retrieve organization profile.

Returns the authenticated organization profile, plan summary, and enabled SiberMate modules. This endpoint returns data for the organization associated with the authenticated API key.

Endpoint: `GET https://api.sibermate.com/v1/company`

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {
    "id": "company_123",
    "name": "Acme Security",
    "accountType": "tenant",
    "plan": {
      "name": "Premium",
      "learnerCount": 42,
      "learnerLimit": 500,
      "domainLock": true,
      "domain": "acme.example"
    },
    "features": {
      "smlearn": true,
      "smphish": true,
      "smpolicy": true,
      "smbreachproenabled": true,
      "smbreachprodomains": [
        "acme.example"
      ]
    }
  }
}
```

### GET /company/features

Retrieve enabled SiberMate modules.

Returns enabled SiberMate modules and Breach Pro monitored-domain settings. This endpoint returns data for the organization associated with the authenticated API key.

Endpoint: `GET https://api.sibermate.com/v1/company/features`

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {
    "smlearn": true,
    "smphish": true,
    "smpolicy": true,
    "smbreachproenabled": true,
    "smbreachprodomains": [
      "acme.example"
    ]
  }
}
```

## Learners

Learner records, lifecycle actions, group membership, and learner-level outcomes.

### GET /learners

List learners.

Returns learner records for the authenticated organization. Use this endpoint to sync learner rosters, status, group membership, and risk-level indicators into client systems. This endpoint returns data for the organization associated with the authenticated API key.

Endpoint: `GET https://api.sibermate.com/v1/learners`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `companyId` | query | no | `string` | MSP/Distributor only: scope this read to a child tenant by its SiberMate company ID (from GET /companies). Omit to use your own organization; non-MSP keys passing a foreign companyId receive 403. |

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": [
    {
      "id": "learner_123",
      "email": "learner@example.com",
      "externalLearnerId": "EMP-001",
      "name": "Ari Pratama",
      "inactive": false
    }
  ]
}
```

### POST /learners

Create a learner.

Creates one learner in the authenticated organization. Email is required, free-email providers are rejected, and when domain lock is enabled the email must be on the company domain. Include group IDs when the learner should be added to existing learner groups during creation. Email-less ("User ID") learners — for people without an email who use the User ID Access Portal — cannot be created through this API and must be added via the dashboard. This endpoint changes organization data and requires an authorized bearer token.

Endpoint: `POST https://api.sibermate.com/v1/learners`

Request body:

| Field | Required | Type | Description |
| --- | --- | --- | --- |
| `email` | yes | `string` |  |
| `firstName` | yes | `string` |  |
| `lastName` | yes | `string` |  |
| `groupIds` | no | `array<string>` |  |
| `externalLearnerId` | no | `string` | External learner identifier from the source HR or employee system. |
| `locale` | no | `string` |  |
| `excludedFromAutoEnrol` | no | `boolean` |  |

Request example:

```json
{
  "email": "learner@example.com",
  "firstName": "Ari",
  "lastName": "Pratama",
  "externalLearnerId": "EMP-001"
}
```

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {}
}
```

### DELETE /learners/{learnerId}

Delete a learner.

Deletes a learner from the authenticated organization. Use this only when the learner should be permanently removed from SiberMate workflows. This endpoint changes organization data and should be called only from trusted server-side systems.

Endpoint: `DELETE https://api.sibermate.com/v1/learners/{learnerId}`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `learnerId` | path | yes | `string` |  |

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": true
}
```

### GET /learners/{learnerId}

Retrieve learner details.

Returns a single learner record, including profile fields, active status, locale, group membership, and available risk-level indicators. This endpoint returns data for the organization associated with the authenticated API key.

Endpoint: `GET https://api.sibermate.com/v1/learners/{learnerId}`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `learnerId` | path | yes | `string` |  |
| `companyId` | query | no | `string` | MSP/Distributor only: scope this read to a child tenant by its SiberMate company ID (from GET /companies). Omit to use your own organization; non-MSP keys passing a foreign companyId receive 403. |

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {
    "id": "learner_123",
    "email": "learner@example.com",
    "externalLearnerId": "EMP-001",
    "name": "Ari Pratama",
    "firstName": "Ari",
    "lastName": "Pratama",
    "createdAt": "2026-01-15T10:00:00.000Z",
    "updatedAt": "2026-01-20T10:00:00.000Z",
    "inactive": false,
    "isManager": false,
    "locale": "en",
    "riskScoreLevel": "medium",
    "groups": [
      {
        "id": "group_123",
        "name": "Finance"
      }
    ],
    "manager": null
  }
}
```

### PATCH /learners/{learnerId}

Update a learner.

Updates learner profile fields and optional group membership. Use this endpoint for HRIS or identity-driven learner profile synchronization. This endpoint changes organization data and requires an authorized bearer token.

Endpoint: `PATCH https://api.sibermate.com/v1/learners/{learnerId}`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `learnerId` | path | yes | `string` |  |

Request body:

| Field | Required | Type | Description |
| --- | --- | --- | --- |
| `email` | no | `string` |  |
| `firstName` | yes | `string` |  |
| `lastName` | yes | `string` |  |
| `groupIds` | no | `array<string>` |  |
| `externalLearnerId` | no | `string` | External learner identifier from the source HR or employee system. |
| `locale` | no | `string` |  |
| `excludedFromAutoEnrol` | no | `boolean` |  |

Request example:

```json
{
  "email": "learner@example.com",
  "firstName": "Ari",
  "lastName": "Pratama",
  "externalLearnerId": "EMP-001",
  "groupIds": [
    "group_123"
  ]
}
```

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {}
}
```

### GET /learners/{learnerId}/breaches

Retrieve learner breach exposure.

Returns breach exposure linked to a single learner when breach monitoring data is available. This endpoint returns data for the organization associated with the authenticated API key.

Endpoint: `GET https://api.sibermate.com/v1/learners/{learnerId}/breaches`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `learnerId` | path | yes | `string` |  |
| `companyId` | query | no | `string` | MSP/Distributor only: scope this read to a child tenant by its SiberMate company ID (from GET /companies). Omit to use your own organization; non-MSP keys passing a foreign companyId receive 403. |

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": [
    {
      "id": "breach_service_123",
      "name": "Example Service",
      "breachDate": "2024-03-01",
      "category": "technology",
      "dataClassNames": [
        "Email addresses",
        "Passwords"
      ]
    }
  ]
}
```

### GET /learners/{learnerId}/course-results

Retrieve learner course results.

Returns course-level training results for a learner, including enrolment, start, completion, score, and grade fields when available. This endpoint returns data for the organization associated with the authenticated API key.

Endpoint: `GET https://api.sibermate.com/v1/learners/{learnerId}/course-results`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `learnerId` | path | yes | `string` |  |
| `companyId` | query | no | `string` | MSP/Distributor only: scope this read to a child tenant by its SiberMate company ID (from GET /companies). Omit to use your own organization; non-MSP keys passing a foreign companyId receive 403. |

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": [
    {
      "learnerId": "learner_123",
      "courseId": "course_123",
      "enrollDate": "2026-01-15",
      "startDate": "2026-01-16",
      "finishDate": "2026-01-20",
      "score": 92,
      "grade": "A",
      "course": {
        "id": "course_123",
        "name": "Security Awareness Essentials",
        "difficulty": 2
      }
    }
  ]
}
```

### GET /learners/{learnerId}/gap-analysis-results

Retrieve learner gap analysis results.

Returns gap analysis results for a learner so client systems can inspect assessment progress and outcomes. This endpoint returns data for the organization associated with the authenticated API key.

Endpoint: `GET https://api.sibermate.com/v1/learners/{learnerId}/gap-analysis-results`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `learnerId` | path | yes | `string` |  |
| `companyId` | query | no | `string` | MSP/Distributor only: scope this read to a child tenant by its SiberMate company ID (from GET /companies). Omit to use your own organization; non-MSP keys passing a foreign companyId receive 403. |

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": [
    {
      "learnerId": "learner_123",
      "courseId": "course_123",
      "enrollDate": "2026-01-15",
      "startDate": "2026-01-16",
      "finishDate": "2026-01-20",
      "score": 92,
      "grade": "A",
      "course": {
        "id": "course_123",
        "name": "Gap Analysis",
        "difficulty": 2
      }
    }
  ]
}
```

### PUT /learners/{learnerId}/groups

Replace learner group membership.

Replaces the full set of groups assigned to a learner. Send the complete desired group list, not only the groups being added. This endpoint changes organization data and requires an authorized bearer token.

Endpoint: `PUT https://api.sibermate.com/v1/learners/{learnerId}/groups`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `learnerId` | path | yes | `string` |  |

Request body:

| Field | Required | Type | Description |
| --- | --- | --- | --- |
| `groupIds` | yes | `array<string>` |  |

Request example:

```json
{}
```

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {}
}
```

### GET /learners/{learnerId}/policy-results

Retrieve learner policy results.

Returns policy acknowledgement results for a learner. Optionally filter by policyId for a single policy. This endpoint returns data for the organization associated with the authenticated API key.

Endpoint: `GET https://api.sibermate.com/v1/learners/{learnerId}/policy-results`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `learnerId` | path | yes | `string` |  |
| `policyId` | query | no | `string` | Optional policy ID filter. |
| `companyId` | query | no | `string` | MSP/Distributor only: scope this read to a child tenant by its SiberMate company ID (from GET /companies). Omit to use your own organization; non-MSP keys passing a foreign companyId receive 403. |

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": [
    {
      "id": "policy_result_123",
      "learnerId": "learner_123",
      "policyId": "policy_123",
      "visit": "2026-01-15T10:00:00.000Z",
      "signed": "2026-01-15T10:05:00.000Z",
      "signedOffline": false,
      "sentVersionId": "policy_version_123",
      "visitedVersionId": "policy_version_123",
      "signedVersionId": "policy_version_123"
    }
  ]
}
```

### GET /learners/{learnerId}/simulation-queue

Retrieve learner simulation queue.

Returns pending or queued phishing simulation activity for a learner when available. This endpoint returns data for the organization associated with the authenticated API key.

Endpoint: `GET https://api.sibermate.com/v1/learners/{learnerId}/simulation-queue`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `learnerId` | path | yes | `string` |  |
| `companyId` | query | no | `string` | MSP/Distributor only: scope this read to a child tenant by its SiberMate company ID (from GET /companies). Omit to use your own organization; non-MSP keys passing a foreign companyId receive 403. |

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": [
    {
      "id": "simulation_queue_123",
      "learnerId": "learner_123",
      "simulationId": "simulation_123",
      "scheduled": "2026-01-10T08:00:00.000Z",
      "simulation": {
        "id": "simulation_123",
        "name": "Quarterly Phishing Simulation",
        "status": "scheduled",
        "startDate": "2026-01-10T00:00:00.000Z",
        "endDate": "2026-01-20T00:00:00.000Z"
      }
    }
  ]
}
```

### GET /learners/{learnerId}/simulation-results

Retrieve learner simulation results.

Returns phishing simulation activity for a learner, suitable for learner-level security awareness reporting. This endpoint returns data for the organization associated with the authenticated API key.

Endpoint: `GET https://api.sibermate.com/v1/learners/{learnerId}/simulation-results`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `learnerId` | path | yes | `string` |  |
| `companyId` | query | no | `string` | MSP/Distributor only: scope this read to a child tenant by its SiberMate company ID (from GET /companies). Omit to use your own organization; non-MSP keys passing a foreign companyId receive 403. |

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": [
    {
      "id": "simulation_result_123",
      "learnerId": "learner_123",
      "simulationId": "simulation_123",
      "open": "2026-01-10T09:00:00.000Z",
      "visit": "2026-01-10T09:03:00.000Z",
      "compromise": null,
      "report": "2026-01-10T09:08:00.000Z",
      "createdAt": "2026-01-10T08:00:00.000Z",
      "deliveryMethod": "messageInjection",
      "simulation": {
        "id": "simulation_123",
        "name": "Quarterly Phishing Simulation",
        "status": "completed",
        "startDate": "2026-01-10T00:00:00.000Z",
        "endDate": "2026-01-20T00:00:00.000Z"
      }
    }
  ]
}
```

### POST /learners/activate

Activate learners.

Reactivates learners so they can receive training, policy, phishing simulation, and reporting workflows again. This endpoint changes organization data and requires an authorized bearer token.

Endpoint: `POST https://api.sibermate.com/v1/learners/activate`

Request body:

| Field | Required | Type | Description |
| --- | --- | --- | --- |
| `learnerIds` | yes | `array<string>` |  |

Request example:

```json
{}
```

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {}
}
```

### DELETE /learners/bulk

Delete learners in bulk.

Deletes multiple learners in a single request. Use this only for controlled offboarding or organization cleanup workflows. This endpoint changes organization data and should be called only from trusted server-side systems.

Endpoint: `DELETE https://api.sibermate.com/v1/learners/bulk`

Request body:

| Field | Required | Type | Description |
| --- | --- | --- | --- |
| `learnerIds` | yes | `array<string>` |  |

Request example:

```json
{}
```

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": true
}
```

### POST /learners/bulk

Create learners in bulk.

Creates one or more learners in a single request for roster import or bulk synchronization. Email is required for every learner (same rules as POST /learners). externalLearnerId is an optional HRIS/source identifier for emailed learners. Email-less ("User ID") learners cannot be created through this API — add them via the dashboard. This endpoint changes organization data and should be called only from trusted server-side systems.

Endpoint: `POST https://api.sibermate.com/v1/learners/bulk`

Request body:

| Field | Required | Type | Description |
| --- | --- | --- | --- |
| `learners` | yes | `array<object>` |  |
| `learners[].email` | yes | `string` | Required. Free-email providers are rejected, and with domain lock on the email must be on the company domain. Email-less (User ID) learners cannot be created via this API — use the dashboard. |
| `learners[].firstName` | yes | `string` |  |
| `learners[].lastName` | yes | `string` |  |
| `learners[].groupIds` | no | `array<string>` |  |
| `learners[].externalLearnerId` | no | `string` | External learner identifier from the source HR or employee system. |

Request example:

```json
{}
```

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {
    "success": true,
    "errors": []
  }
}
```

### POST /learners/deactivate

Deactivate learners.

Deactivates learners without deleting their historical results. Use this for temporary leave, offboarding holds, or staged cleanup workflows. This endpoint changes organization data and requires an authorized bearer token.

Endpoint: `POST https://api.sibermate.com/v1/learners/deactivate`

Request body:

| Field | Required | Type | Description |
| --- | --- | --- | --- |
| `learnerIds` | yes | `array<string>` |  |

Request example:

```json
{}
```

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {}
}
```

## Groups

Learner groups and group manager assignments.

### POST /group-membership/move

Move learners from one group to another.

Move learners from one group to another. This endpoint changes organization data and requires an authorized bearer token.

Endpoint: `POST https://api.sibermate.com/v1/group-membership/move`

Request body:

| Field | Required | Type | Description |
| --- | --- | --- | --- |
| `fromGroupId` | yes | `string` |  |
| `toGroupId` | yes | `string` |  |
| `learnerIds` | no | `array<string>` |  |
| `preserveManagerRole` | no | `boolean` |  |

Request example:

```json
{
  "fromGroupId": "group_123",
  "toGroupId": "group_456",
  "preserveManagerRole": false
}
```

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {}
}
```

### GET /groups

List learner groups.

List learner groups. This endpoint returns data for the organization associated with the authenticated API key.

Endpoint: `GET https://api.sibermate.com/v1/groups`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `companyId` | query | no | `string` | MSP/Distributor only: scope this read to a child tenant by its SiberMate company ID (from GET /companies). Omit to use your own organization; non-MSP keys passing a foreign companyId receive 403. |

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": [
    {
      "id": "group_123",
      "name": "Finance",
      "learnerCount": 12,
      "managers": [
        {
          "id": "learner_456",
          "name": "Maya Tan",
          "email": "maya@example.com"
        }
      ]
    }
  ]
}
```

### POST /groups

Create a learner group.

Creates a learner group and optionally assigns group managers. This endpoint changes organization data and requires an authorized bearer token.

Endpoint: `POST https://api.sibermate.com/v1/groups`

Request body:

| Field | Required | Type | Description |
| --- | --- | --- | --- |
| `name` | yes | `string` |  |
| `managerIds` | no | `array<string>` |  |

Request example:

```json
{
  "name": "Finance"
}
```

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {}
}
```

### DELETE /groups/{groupId}

Delete a learner group.

Deletes a learner group from the organization. Confirm downstream automations no longer depend on the group before deletion. This endpoint changes organization data and should be called only from trusted server-side systems.

Endpoint: `DELETE https://api.sibermate.com/v1/groups/{groupId}`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `groupId` | path | yes | `string` |  |

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {}
}
```

### GET /groups/{groupId}

Retrieve group details.

Retrieve group details. This endpoint returns data for the organization associated with the authenticated API key.

Endpoint: `GET https://api.sibermate.com/v1/groups/{groupId}`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `groupId` | path | yes | `string` |  |
| `companyId` | query | no | `string` | MSP/Distributor only: scope this read to a child tenant by its SiberMate company ID (from GET /companies). Omit to use your own organization; non-MSP keys passing a foreign companyId receive 403. |

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {}
}
```

### POST /groups/{groupId}/learners/add

Add learners to a group, keeping their existing groups.

Add learners to a group, keeping their existing groups. This endpoint changes organization data and requires an authorized bearer token.

Endpoint: `POST https://api.sibermate.com/v1/groups/{groupId}/learners/add`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `groupId` | path | yes | `string` |  |

Request body:

| Field | Required | Type | Description |
| --- | --- | --- | --- |
| `learnerIds` | yes | `array<string>` |  |

Request example:

```json
{
  "learnerIds": [
    "learner_123",
    "learner_456"
  ]
}
```

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {}
}
```

### POST /groups/{groupId}/learners/remove

Remove learners from a group, keeping their other groups.

Remove learners from a group, keeping their other groups. This endpoint changes organization data and requires an authorized bearer token.

Endpoint: `POST https://api.sibermate.com/v1/groups/{groupId}/learners/remove`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `groupId` | path | yes | `string` |  |

Request body:

| Field | Required | Type | Description |
| --- | --- | --- | --- |
| `learnerIds` | yes | `array<string>` |  |

Request example:

```json
{
  "learnerIds": [
    "learner_123"
  ]
}
```

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {}
}
```

### PUT /groups/{groupId}/managers

Replace group managers.

Replaces the manager list for a learner group. Send the complete desired manager list. This endpoint changes organization data and requires an authorized bearer token.

Endpoint: `PUT https://api.sibermate.com/v1/groups/{groupId}/managers`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `groupId` | path | yes | `string` |  |

Request body:

| Field | Required | Type | Description |
| --- | --- | --- | --- |
| `managerIds` | yes | `array<string>` |  |

Request example:

```json
{}
```

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {}
}
```

## Courses

Training catalog, course assignments, reminders, unenrollments, and gap analysis actions.

### POST /course-enrollments

Assign courses to learners.

Assigns one or more courses to one or more learners. This endpoint changes organization data and requires an authorized bearer token.

Endpoint: `POST https://api.sibermate.com/v1/course-enrollments`

Request body:

| Field | Required | Type | Description |
| --- | --- | --- | --- |
| `courseIds` | yes | `array<string>` |  |
| `learnerIds` | yes | `array<string>` |  |

Request example:

```json
{
  "courseIds": [
    "course_123"
  ],
  "learnerIds": [
    "learner_123"
  ]
}
```

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {
    "success": true,
    "completed": [
      {
        "learnerId": "learner_123",
        "courseId": "course_123"
      }
    ],
    "failures": [],
    "errors": []
  }
}
```

### POST /course-reminders

Send course reminders.

Sends reminders to learners with outstanding course work. This is exposed separately from course assignment for clearer client automation. This endpoint changes organization data and requires an authorized bearer token.

Endpoint: `POST https://api.sibermate.com/v1/course-reminders`

Request body:

| Field | Required | Type | Description |
| --- | --- | --- | --- |
| `courseIds` | yes | `array<string>` |  |
| `learnerIds` | yes | `array<string>` |  |

Request example:

```json
{}
```

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {
    "success": true,
    "completed": [
      {
        "learnerId": "learner_123",
        "courseId": "course_123"
      }
    ],
    "failures": [],
    "errors": []
  }
}
```

### POST /course-unenrollments

Remove course assignments.

Removes course assignments from learners when they should no longer complete those courses. This endpoint changes organization data and requires an authorized bearer token.

Endpoint: `POST https://api.sibermate.com/v1/course-unenrollments`

Request body:

| Field | Required | Type | Description |
| --- | --- | --- | --- |
| `courseIds` | yes | `array<string>` |  |
| `learnerIds` | yes | `array<string>` |  |

Request example:

```json
{}
```

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {}
}
```

### GET /courses

List training courses.

Returns managed catalog courses and courses owned by the authenticated organization. Courses owned by other tenants are filtered out even if the upstream catalog endpoint returns them. Use source to separate managed catalog courses from organization-created courses, and type to separate standard training from gap analysis courses. This endpoint returns data for the organization associated with the authenticated API key.

Endpoint: `GET https://api.sibermate.com/v1/courses`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `type` | query | no | `"all" \| "training" \| "gap_analysis"` | Filter by course type. training returns standard training courses. gap_analysis returns gap analysis courses. |
| `source` | query | no | `"all" \| "managed" \| "custom"` | Filter by course source. managed returns SiberMate-managed catalog courses. custom returns courses created for the organization. |
| `excludeGapAnalysis` | query | no | `boolean` | Legacy boolean filter. Prefer type=training for new integrations. |

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": [
    {
      "id": "course_123",
      "name": "Security Awareness Essentials",
      "displayName": "Security Awareness Essentials",
      "difficulty": 2,
      "subject": "Security Awareness",
      "source": "managed",
      "type": "training"
    }
  ]
}
```

### GET /courses/{courseId}

Retrieve course details.

Returns a global catalog course or a course owned by the authenticated organization. Courses owned by another tenant return 404. This endpoint returns data for the organization associated with the authenticated API key.

Endpoint: `GET https://api.sibermate.com/v1/courses/{courseId}`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `courseId` | path | yes | `string` |  |

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {}
}
```

### POST /gap-analysis/enrollments

Assign gap analysis to learners.

Assigns gap analysis to learners. This endpoint changes organization data and requires an authorized bearer token.

Endpoint: `POST https://api.sibermate.com/v1/gap-analysis/enrollments`

Request body:

| Field | Required | Type | Description |
| --- | --- | --- | --- |
| `learnerIds` | yes | `array<string>` |  |

Request example:

```json
{}
```

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {}
}
```

### POST /gap-analysis/reminders

Send gap analysis reminders.

Sends reminders to learners with outstanding gap analysis work. This endpoint changes organization data and requires an authorized bearer token.

Endpoint: `POST https://api.sibermate.com/v1/gap-analysis/reminders`

Request body:

| Field | Required | Type | Description |
| --- | --- | --- | --- |
| `learnerIds` | yes | `array<string>` |  |

Request example:

```json
{}
```

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {}
}
```

### POST /gap-analysis/unenrollments

Remove gap analysis assignments.

Removes gap analysis assignments from learners. This endpoint changes organization data and requires an authorized bearer token.

Endpoint: `POST https://api.sibermate.com/v1/gap-analysis/unenrollments`

Request body:

| Field | Required | Type | Description |
| --- | --- | --- | --- |
| `learnerIds` | yes | `array<string>` |  |

Request example:

```json
{}
```

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {}
}
```

## Reports

Organization-level learning, participation, risk score, course result, and gap analysis reports.

### GET /reports/course-participation

Retrieve course participation report.

Retrieve course participation report. This endpoint returns data for the organization associated with the authenticated API key.

Endpoint: `GET https://api.sibermate.com/v1/reports/course-participation`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `companyId` | query | no | `string` | MSP/Distributor only: scope this read to a child tenant by its SiberMate company ID (from GET /companies). Omit to use your own organization; non-MSP keys passing a foreign companyId receive 403. |

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {
    "groupTree": {},
    "courses": [
      {
        "id": "course_123",
        "name": "Security Awareness Essentials",
        "subject": "Security Awareness",
        "difficulty": 2
      }
    ],
    "learners": [
      {
        "id": "learner_123",
        "name": "Ari Pratama",
        "groups": [],
        "courseResults": []
      }
    ]
  }
}
```

### GET /reports/course-results

Retrieve course results report.

Retrieve course results report. This endpoint returns data for the organization associated with the authenticated API key.

Endpoint: `GET https://api.sibermate.com/v1/reports/course-results`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `companyId` | query | no | `string` | MSP/Distributor only: scope this read to a child tenant by its SiberMate company ID (from GET /companies). Omit to use your own organization; non-MSP keys passing a foreign companyId receive 403. |

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": [
    {
      "learnerId": "learner_123",
      "courseId": "course_123",
      "enrollDate": "2026-01-15",
      "startDate": "2026-01-16",
      "finishDate": "2026-01-20",
      "score": 92,
      "grade": "A",
      "course": {
        "id": "course_123",
        "name": "Security Awareness Essentials",
        "difficulty": 2
      },
      "learner": {
        "id": "learner_123",
        "name": "Ari Pratama",
        "email": "learner@example.com",
        "externalLearnerId": "EMP-001"
      }
    }
  ]
}
```

### GET /reports/gap-analysis-results

Retrieve gap analysis results report.

Retrieve gap analysis results report. This endpoint returns data for the organization associated with the authenticated API key.

Endpoint: `GET https://api.sibermate.com/v1/reports/gap-analysis-results`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `companyId` | query | no | `string` | MSP/Distributor only: scope this read to a child tenant by its SiberMate company ID (from GET /companies). Omit to use your own organization; non-MSP keys passing a foreign companyId receive 403. |

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": [
    {
      "learnerId": "learner_123",
      "courseId": "course_123",
      "enrollDate": "2026-01-15",
      "startDate": "2026-01-16",
      "finishDate": "2026-01-20",
      "score": 92,
      "grade": "A",
      "course": {
        "id": "course_123",
        "name": "Gap Analysis",
        "difficulty": 2
      },
      "learner": {
        "id": "learner_123",
        "name": "Ari Pratama",
        "email": "learner@example.com",
        "externalLearnerId": "EMP-001"
      }
    }
  ]
}
```

### GET /reports/learning

Retrieve learning report.

Returns organization-level learning report data for executive dashboards, periodic exports, or internal compliance reporting. This endpoint returns data for the organization associated with the authenticated API key.

Endpoint: `GET https://api.sibermate.com/v1/reports/learning`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `learnerId` | query | no | `string` | Optional SiberMate learner ID filter. |
| `courseId` | query | no | `string` | Optional course ID filter. |
| `companyId` | query | no | `string` | MSP/Distributor only: scope this read to a child tenant by its SiberMate company ID (from GET /companies). Omit to use your own organization; non-MSP keys passing a foreign companyId receive 403. |

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {
    "generatedAt": "2026-01-31T00:00:00.000Z",
    "summary": {},
    "rows": []
  }
}
```

### GET /reports/risk-score-history

Retrieve risk score history.

Returns historical risk score data for the requested date range. This endpoint returns data for the organization associated with the authenticated API key.

Endpoint: `GET https://api.sibermate.com/v1/reports/risk-score-history`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `fromDate` | query | no | `string:date` | Start date for the risk score history window. |
| `toDate` | query | no | `string:date` | End date for the risk score history window. |
| `companyId` | query | no | `string` | MSP/Distributor only: scope this read to a child tenant by its SiberMate company ID (from GET /companies). Omit to use your own organization; non-MSP keys passing a foreign companyId receive 403. |

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {
    "fromDate": "2026-01-01",
    "toDate": "2026-01-31",
    "rows": []
  }
}
```

## Policies

Policy library, PDF upload, draft publishing, assignments, reminders, removals, and templates.

### GET /policies

List policies.

List policies. This endpoint returns data for the organization associated with the authenticated API key.

Endpoint: `GET https://api.sibermate.com/v1/policies`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `publishedOnly` | query | no | `boolean` | Return only published policies. |
| `pdfOnly` | query | no | `boolean` | Return only PDF policies. |
| `companyId` | query | no | `string` | MSP/Distributor only: scope this read to a child tenant by its SiberMate company ID (from GET /companies). Omit to use your own organization; non-MSP keys passing a foreign companyId receive 403. |

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": [
    {
      "id": "policy_123",
      "name": "Acceptable Use Policy",
      "type": "pdf",
      "isLive": true,
      "inDraft": false,
      "majorVersion": 1,
      "minorVersion": 0,
      "category": "compliance",
      "isPublic": false
    }
  ]
}
```

### POST /policies

Create a policy.

Creates a policy as a draft or live policy, depending on the submitted action. This endpoint changes organization data and requires an authorized bearer token.

Endpoint: `POST https://api.sibermate.com/v1/policies`

Request body:

| Field | Required | Type | Description |
| --- | --- | --- | --- |
| `name` | yes | `string` |  |
| `pdfFile` | yes | `string` |  |
| `action` | yes | `string` |  |
| `majorVersion` | no | `integer` |  |
| `minorVersion` | no | `integer` |  |
| `category` | no | `string` |  |
| `ownerName` | no | `string` |  |
| `ownerEmail` | no | `string` |  |
| `isPublic` | no | `boolean` |  |
| `signatureSettings` | no | `object` |  |
| `signatureSettings.type` | yes | `"fixed" \| "lastSignature" \| "newUsers" \| "none"` |  |
| `signatureSettings.startDate` | no | `string:date` |  |
| `signatureSettings.intervalLength` | no | `integer` |  |
| `signatureSettings.intervalUnit` | no | `"months" \| "years"` |  |
| `signatureSettings.useDefault` | no | `boolean` |  |
| `signatureSettings.setDefault` | no | `boolean` |  |

Request example:

```json
{
  "name": "Acceptable Use Policy",
  "pdfFile": "uploaded-policy-key",
  "action": "saveDraft",
  "category": "compliance",
  "isPublic": false
}
```

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {}
}
```

### GET /policies/{policyId}

Retrieve policy details.

Retrieve policy details. This endpoint returns data for the organization associated with the authenticated API key.

Endpoint: `GET https://api.sibermate.com/v1/policies/{policyId}`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `policyId` | path | yes | `string` |  |
| `companyId` | query | no | `string` | MSP/Distributor only: scope this read to a child tenant by its SiberMate company ID (from GET /companies). Omit to use your own organization; non-MSP keys passing a foreign companyId receive 403. |

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {}
}
```

### PATCH /policies/{policyId}

Update a policy.

Updates an existing policy. Use draft and publish endpoints when you need a controlled policy review workflow. This endpoint changes organization data and requires an authorized bearer token.

Endpoint: `PATCH https://api.sibermate.com/v1/policies/{policyId}`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `policyId` | path | yes | `string` |  |

Request body:

| Field | Required | Type | Description |
| --- | --- | --- | --- |
| `name` | no | `string` |  |
| `pdfFile` | no | `string` |  |
| `action` | yes | `string` |  |
| `major` | no | `boolean` |  |
| `category` | no | `string` |  |
| `ownerName` | no | `string` |  |
| `ownerEmail` | no | `string` |  |
| `isPublic` | no | `boolean` |  |
| `resend` | no | `boolean` |  |
| `signatureSettings` | no | `object` |  |
| `signatureSettings.type` | yes | `"fixed" \| "lastSignature" \| "newUsers" \| "none"` |  |
| `signatureSettings.startDate` | no | `string:date` |  |
| `signatureSettings.intervalLength` | no | `integer` |  |
| `signatureSettings.intervalUnit` | no | `"months" \| "years"` |  |
| `signatureSettings.useDefault` | no | `boolean` |  |
| `signatureSettings.setDefault` | no | `boolean` |  |

Request example:

```json
{}
```

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {}
}
```

### POST /policies/{policyId}/discard-draft

Discard a policy draft.

Discards the current draft version and keeps the existing live policy unchanged. This endpoint changes organization data and requires an authorized bearer token.

Endpoint: `POST https://api.sibermate.com/v1/policies/{policyId}/discard-draft`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `policyId` | path | yes | `string` |  |

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {}
}
```

### POST /policies/{policyId}/publish-draft

Publish a policy draft.

Publishes the current draft version of a policy. This endpoint changes organization data and requires an authorized bearer token.

Endpoint: `POST https://api.sibermate.com/v1/policies/{policyId}/publish-draft`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `policyId` | path | yes | `string` |  |

Request body:

| Field | Required | Type | Description |
| --- | --- | --- | --- |
| `major` | no | `boolean` |  |
| `resend` | no | `boolean` |  |

Request example:

```json
{
  "major": false,
  "resend": false
}
```

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {}
}
```

### DELETE /policies/bulk

Delete policies in bulk.

Delete policies in bulk. This endpoint changes organization data and should be called only from trusted server-side systems.

Endpoint: `DELETE https://api.sibermate.com/v1/policies/bulk`

Request body:

| Field | Required | Type | Description |
| --- | --- | --- | --- |
| `policyIds` | yes | `array<string>` |  |

Request example:

```json
{}
```

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {}
}
```

### POST /policies/from-template

Create a policy from a template.

Creates an organization policy from a SiberMate policy template. This endpoint changes organization data and requires an authorized bearer token.

Endpoint: `POST https://api.sibermate.com/v1/policies/from-template`

Request body:

| Field | Required | Type | Description |
| --- | --- | --- | --- |
| `policyTemplateId` | yes | `string` |  |
| `name` | no | `string` |  |
| `action` | yes | `string` |  |
| `majorVersion` | no | `integer` |  |
| `minorVersion` | no | `integer` |  |
| `category` | no | `string` |  |
| `ownerName` | no | `string` |  |
| `ownerEmail` | no | `string` |  |
| `isPublic` | no | `boolean` |  |
| `signatureSettings` | no | `object` |  |
| `signatureSettings.type` | yes | `"fixed" \| "lastSignature" \| "newUsers" \| "none"` |  |
| `signatureSettings.startDate` | no | `string:date` |  |
| `signatureSettings.intervalLength` | no | `integer` |  |
| `signatureSettings.intervalUnit` | no | `"months" \| "years"` |  |
| `signatureSettings.useDefault` | no | `boolean` |  |
| `signatureSettings.setDefault` | no | `boolean` |  |

Request example:

```json
{}
```

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {}
}
```

### POST /policies/upload

Upload a policy PDF.

Uploads a policy PDF and returns the file reference used when creating or updating policy records. This endpoint changes organization data and should be called only from trusted server-side systems.

Endpoint: `POST https://api.sibermate.com/v1/policies/upload`

Request body:

| Field | Required | Type | Description |
| --- | --- | --- | --- |
| `file` | yes | `string:binary` |  |

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 411 | Content-Length is required for policy uploads. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {}
}
```

### POST /policy-assignments

Assign policies to learners.

Assigns one or more policies to one or more learners. This endpoint changes organization data and requires an authorized bearer token.

Endpoint: `POST https://api.sibermate.com/v1/policy-assignments`

Request body:

| Field | Required | Type | Description |
| --- | --- | --- | --- |
| `policyIds` | yes | `array<string>` |  |
| `learnerIds` | yes | `array<string>` |  |

Request example:

```json
{
  "policyIds": [
    "policy_123"
  ],
  "learnerIds": [
    "learner_123"
  ]
}
```

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {
    "success": true,
    "completed": [
      {
        "learnerId": "learner_123",
        "policyId": "policy_123"
      }
    ],
    "failures": [],
    "errors": []
  }
}
```

### POST /policy-reminders

Send policy reminders.

Sends reminders to learners with outstanding policy acknowledgements. This endpoint changes organization data and requires an authorized bearer token.

Endpoint: `POST https://api.sibermate.com/v1/policy-reminders`

Request body:

| Field | Required | Type | Description |
| --- | --- | --- | --- |
| `policyIds` | yes | `array<string>` |  |
| `learnerIds` | yes | `array<string>` |  |

Request example:

```json
{
  "policyIds": [
    "policy_123"
  ],
  "learnerIds": [
    "learner_123"
  ]
}
```

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {
    "success": true,
    "completed": [
      {
        "learnerId": "learner_123",
        "policyId": "policy_123"
      }
    ],
    "failures": [],
    "errors": []
  }
}
```

### POST /policy-removals

Remove policy assignments.

Removes learners from one or more policy assignments. This endpoint changes organization data and requires an authorized bearer token.

Endpoint: `POST https://api.sibermate.com/v1/policy-removals`

Request body:

| Field | Required | Type | Description |
| --- | --- | --- | --- |
| `policyIds` | yes | `array<string>` |  |
| `learnerIds` | yes | `array<string>` |  |

Request example:

```json
{
  "policyIds": [
    "policy_123"
  ],
  "learnerIds": [
    "learner_123"
  ]
}
```

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {}
}
```

### GET /policy-templates

List policy templates.

Returns available policy templates that can be used to create organization policies. This endpoint returns data for the organization associated with the authenticated API key.

Endpoint: `GET https://api.sibermate.com/v1/policy-templates`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `restrictToOwn` | query | no | `boolean` | Restrict templates to organization-owned templates when supported. |
| `publishedOnly` | query | no | `boolean` | Return only published templates. |
| `pdfOnly` | query | no | `boolean` | Return only PDF templates. |
| `companyId` | query | no | `string` | MSP/Distributor only: scope this read to a child tenant by its SiberMate company ID (from GET /companies). Omit to use your own organization; non-MSP keys passing a foreign companyId receive 403. |

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": [
    {
      "id": "policy_template_123",
      "name": "Acceptable Use Policy Template",
      "type": "pdf",
      "source": "managed",
      "category": "compliance",
      "locales": [
        "en"
      ],
      "isEditable": false,
      "isLive": true
    }
  ]
}
```

### GET /policy-templates/{policyTemplateId}

Retrieve policy template details.

Retrieve policy template details. This endpoint returns data for the organization associated with the authenticated API key.

Endpoint: `GET https://api.sibermate.com/v1/policy-templates/{policyTemplateId}`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `policyTemplateId` | path | yes | `string` |  |
| `companyId` | query | no | `string` | MSP/Distributor only: scope this read to a child tenant by its SiberMate company ID (from GET /companies). Omit to use your own organization; non-MSP keys passing a foreign companyId receive 403. |

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {}
}
```

## Simulations

Phishing simulation campaigns, metrics, and learner-level simulation activity.

### GET /simulations

List phishing simulations.

List phishing simulations. This endpoint returns data for the organization associated with the authenticated API key.

Endpoint: `GET https://api.sibermate.com/v1/simulations`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `companyId` | query | no | `string` | MSP/Distributor only: scope this read to a child tenant by its SiberMate company ID (from GET /companies). Omit to use your own organization; non-MSP keys passing a foreign companyId receive 403. |

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": [
    {
      "id": "simulation_123",
      "name": "Quarterly Phishing Simulation",
      "status": "completed",
      "createdAt": "2026-01-01T00:00:00.000Z",
      "recipientCount": 120,
      "sentCount": 120,
      "openCount": 48,
      "visitCount": 12,
      "compromiseCount": 3,
      "reportCount": 30
    }
  ]
}
```

### GET /simulations/{simulationId}

Retrieve phishing simulation details.

Retrieve phishing simulation details. This endpoint returns data for the organization associated with the authenticated API key.

Endpoint: `GET https://api.sibermate.com/v1/simulations/{simulationId}`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `simulationId` | path | yes | `string` |  |
| `companyId` | query | no | `string` | MSP/Distributor only: scope this read to a child tenant by its SiberMate company ID (from GET /companies). Omit to use your own organization; non-MSP keys passing a foreign companyId receive 403. |

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {}
}
```

### GET /simulations/metrics

Retrieve phishing simulation metrics.

Returns aggregate phishing simulation metrics for organization-level reporting. This endpoint returns data for the organization associated with the authenticated API key.

Endpoint: `GET https://api.sibermate.com/v1/simulations/metrics`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `companyId` | query | no | `string` | MSP/Distributor only: scope this read to a child tenant by its SiberMate company ID (from GET /companies). Omit to use your own organization; non-MSP keys passing a foreign companyId receive 403. |

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": {
    "totalMetrics": {
      "opened": 48,
      "visited": 12,
      "compromised": 3,
      "reported": 30,
      "total": 120
    },
    "simulations": [
      {
        "id": "simulation_123",
        "name": "Quarterly Phishing Simulation",
        "status": "completed",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "recipientCount": 120,
        "sentCount": 120,
        "openCount": 48,
        "visitCount": 12,
        "compromiseCount": 3,
        "reportCount": 30
      }
    ]
  }
}
```

## Breaches

Breach exposure insights for monitored accounts and affected services.

### GET /breaches/accounts

List exposed accounts.

Returns exposed account data when breach monitoring data is available. This endpoint returns data for the organization associated with the authenticated API key.

Endpoint: `GET https://api.sibermate.com/v1/breaches/accounts`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `accountType` | query | no | `"activeLearner" \| "inactiveLearner" \| "nonLearner" \| "employee"` | Optional exposed account type filter. employee is treated as an active learner account. |
| `companyId` | query | no | `string` | MSP/Distributor only: scope this read to a child tenant by its SiberMate company ID (from GET /companies). Omit to use your own organization; non-MSP keys passing a foreign companyId receive 403. |

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": [
    {
      "email": "learner@example.com",
      "domain": "example.com",
      "externalLearnerId": "EMP-001",
      "accountType": "activeLearner",
      "breaches": [
        {
          "id": "breach_service_123",
          "name": "Example Service",
          "breachDate": "2024-03-01"
        }
      ]
    }
  ]
}
```

### GET /breaches/services

List breached services.

Returns breached services and affected-account counts when breach monitoring data is available. This endpoint returns data for the organization associated with the authenticated API key.

Endpoint: `GET https://api.sibermate.com/v1/breaches/services`

Parameters:

| Name | Location | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `hasAffectedAccounts` | query | no | `boolean` | Only return services with affected accounts. |
| `accountType` | query | no | `"activeLearner" \| "inactiveLearner" \| "nonLearner" \| "employee"` | Optional exposed account type filter. employee is treated as an active learner account. |
| `companyId` | query | no | `string` | MSP/Distributor only: scope this read to a child tenant by its SiberMate company ID (from GET /companies). Omit to use your own organization; non-MSP keys passing a foreign companyId receive 403. |

Responses:

| Status | Description |
| --- | --- |
| 200 | Request succeeded. |
| 400 | Request is invalid. |
| 401 | Bearer token is missing or invalid. |
| 403 | This action is not available for the current organization. |
| 404 | Resource was not found. |
| 413 | Request body is too large. |
| 429 | Rate limit exceeded. |
| 502 | Service is temporarily unavailable. |
| 503 | Breach data is temporarily unavailable for this organization. |
| 504 | Service timed out. |

Success example:

```json
{
  "data": [
    {
      "id": "breach_service_123",
      "name": "Example Service",
      "breachDate": "2024-03-01",
      "category": "technology",
      "accountCount": 3,
      "dataClassNames": [
        "Email addresses",
        "Passwords"
      ],
      "affectedAccounts": [
        {
          "email": "learner@example.com",
          "domain": "example.com",
          "externalLearnerId": "EMP-001",
          "accountType": "activeLearner"
        }
      ]
    }
  ]
}
```
