Documentation Index
Fetch the complete documentation index at: https://docs.contraforce.com/llms.txt
Use this file to discover all available pages before exploring further.
The v2 API is REST + JSON over HTTPS. Every request authenticates with a service account using HTTP Basic, every response is wrapped in a standard envelope, and every error is RFC 7807 ProblemDetails.
Base URL
https://portal.contraforce.com/api/v2
Authentication
Authorization: Basic <base64(clientId:clientSecret)>
Conventions
Content-Type: application/json (or multipart/form-data for SOP uploads)
- Property names are camelCase; enum values are PascalCase (
Sentinel, High, TwentyFourHours)
- Workspace IDs and most other identifiers are GUIDs
- Source segment values:
Sentinel, DefenderXDR, CrowdStrike, QRadar, Splunk, SentinelOne
Endpoints marked Portal Only in the codebase are excluded from this reference — they are gated to browser sessions and are not reachable by service accounts.
Workspace-Scoped Endpoints
Path prefix: /workspaces/{workspaceId}/...
The workspace ID is a GUID and identifies the customer environment the request operates against. The credential’s service account must have a role on the target workspace, otherwise the request returns 403 INSUFFICIENT_WORKSPACE_ROLE.
Every incident is the child of one SIEM source — the source is encoded as a route segment, not a query parameter.| Method | Path | Description |
|---|
GET | /workspaces/{workspaceId}/incidents/{source}/{incidentId} | Get the full incident detail, including alerts, entities, investigation details, and evidence. |
GET | /workspaces/{workspaceId}/incidents/{source}/{incidentId}/evidence | Get the evidence table for an incident. |
GET | /workspaces/{workspaceId}/incidents/{source}/{incidentId}/last-gamebook | Get the last gamebook run for an incident, or 404 if none has run. |
GET | /workspaces/{workspaceId}/incidents/{source}/{incidentId}/comments | List comments on an incident. |
GET | /workspaces/{workspaceId}/incidents/{source}/by-entity | Find incidents in this source related to a specific entity. |
| Method | Path | Description |
|---|
GET | /workspaces/{workspaceId}/gamebooks/rules/{incidentTitle} | Get playbooks matching an incident title. |
GET | /workspaces/{workspaceId}/gamebooks/history | List gamebook execution history. Supports ?query= and ?pageToken=. |
GET | /workspaces/{workspaceId}/gamebooks/history/{gamebookId}/playbooks | Get the playbooks recorded against a specific gamebook run. |
GET | /workspaces/{workspaceId}/gamebooks/by-incident/{incidentId} | List all gamebooks that have run for an incident. |
| Method | Path | Description |
|---|
GET | /workspaces/{workspaceId}/datasources | List data sources connected to the workspace. |
Read (tickets:read):| Method | Path | Description |
|---|
GET | /workspaces/{workspaceId}/tickets/search | Search service tickets. Supports ?groupingId= and ?ticketNumber=. |
Manage (tickets:manage):| Method | Path | Description |
|---|
POST | /workspaces/{workspaceId}/tickets/link | Link a service ticket to an incident. |
POST | /workspaces/{workspaceId}/tickets/unlink | Unlink a service ticket from an incident. |
PUT | /workspaces/{workspaceId}/tickets/priority | Update ticket priority. |
| Method | Path | Description |
|---|
GET | /workspaces/{workspaceId}/investigation/users/signin-logs | List user sign-in logs. |
GET | /workspaces/{workspaceId}/investigation/users/directory-logs | List directory audit logs. |
Some incident operations that don’t yet thread an explicit SIEM source through their handlers (/{incidentId}/summary, /{incidentId}/entities, /{incidentId}/alert-rules, assign, status, bulk, comment create/update, /high) have been removed from the v2 surface. They will return once their handlers operate against an explicit source rather than implicitly defaulting to Sentinel.
Cross-Workspace Endpoints
These endpoints span every workspace your service account can see — no workspace ID in the path. The handlers filter results to the workspaces the credential has been mapped to.
| Scope | Method | Path | Description |
|---|
incidents:read | POST | /incidents/across-workspaces | List incidents across all visible workspaces. |
gamebooks:read | GET | /gamebooks/across-workspaces/history | List gamebook history across visible workspaces. Supports ?workspaces=, ?statuses=, ?currentPage=, ?query=. |
datasources:read | POST | /datasources/across-workspaces/anomalies | List data connector anomalies across visible workspaces. |
datasources:read | GET | /datasources/across-workspaces | Group connected data sources by workspace. Repeat ?workspaceIds= for each workspace ID. |
Paginating /incidents/across-workspaces
The cross-workspace incidents list uses opaque continuation tokens. The first request leaves the token map empty; every subsequent request echoes the previous response’s tokens back unchanged. Tokens are server-encrypted strings — treat them as a single blob the API gave you, never parse or construct one yourself.
First request:
POST /api/v2/incidents/across-workspaces
{
"isFirstCall": true,
"workspacePageTokens": [],
"sources": ["Sentinel"],
"timeFilterSelection": { "type": "TwentyFourHours" }
}
Response (truncated):
{
"data": {
"incidents": [ /* ...page of incidents... */ ],
"sourcePageTokens": [
{
"workspaceId": "6eca6a1f-b7d1-4bb8-a055-35ad6bb4b9b1",
"sourceTokens": {
"Sentinel": "Gd41DJgGnsDnbYHEdqbFaAKzlIbg6NVK...CQM8="
}
}
],
"moreIncidentsAvailable": true
}
}
Next-page request — set isFirstCall: false and pass sourcePageTokens back verbatim as workspacePageTokens:
POST /api/v2/incidents/across-workspaces
{
"isFirstCall": false,
"workspacePageTokens": [
{
"workspaceId": "6eca6a1f-b7d1-4bb8-a055-35ad6bb4b9b1",
"sourceTokens": {
"Sentinel": "Gd41DJgGnsDnbYHEdqbFaAKzlIbg6NVK...CQM8="
}
}
],
"sources": ["Sentinel"],
"timeFilterSelection": { "type": "TwentyFourHours" }
}
Iterate until the response returns moreIncidentsAvailable: false. A workspace that has finished paging drops out of sourcePageTokens on subsequent responses; do not synthesize entries for it. Page size is server-controlled.
A token that has been modified or hand-built returns 400 VALIDATION_ERROR with the message One or more pagination tokens are invalid. Use the tokens from the previous response unmodified. Recover by restarting from the first call with an empty workspacePageTokens array.
Organization-Scoped Endpoints
These endpoints operate on the organization (service provider). The credential’s service account must hold the relevant org-level scope; workspace mappings are not required.
webhooks:read / webhooks:manage
org:service-accounts:read / manage
org:users:read / manage / roles
org:azure:read / manage
Read (webhooks:read):| Method | Path | Description |
|---|
GET | /webhooks | List all webhook configurations. |
GET | /webhooks/{id} | Get a webhook by ID. |
GET | /webhooks/{id}/delivery-logs | List delivery logs. Supports ?from=, ?to=, ?pageSize=, ?continuationToken=. |
GET | /webhooks/{id}/delivery-logs/{logId}?createdAt= | Get a single delivery log entry. createdAt is the ISO-8601 partition key and is required. |
Manage (webhooks:manage):| Method | Path | Description |
|---|
POST | /webhooks | Create a webhook configuration. |
PUT | /webhooks/{id} | Update a webhook configuration. |
DELETE | /webhooks/{id} | Delete a webhook configuration. |
POST | /webhooks/{id}/pause | Pause delivery. |
POST | /webhooks/{id}/resume | Resume a paused webhook. |
POST | /webhooks/{id}/enable | Re-enable a webhook auto-disabled by repeated delivery failures. |
POST | /webhooks/{id}/credentials | Update webhook authentication credentials. |
POST | /webhooks/{id}/test | Send a test event. |
POST | /webhooks/{id}/delivery-logs/{logId}/redeliver?createdAt= | Redeliver a previously failed event. |
Read (org:service-accounts:read):| Method | Path | Description |
|---|
GET | /service-accounts | List service accounts. |
GET | /service-accounts/{id} | Get a service account by ID. |
Manage (org:service-accounts:manage):| Method | Path | Description |
|---|
POST | /service-accounts | Create a service account. |
PUT | /service-accounts/{id} | Update a service account. |
DELETE | /service-accounts/{id} | Delete a service account. |
POST | /service-accounts/{id}/disable | Disable a service account. |
POST | /service-accounts/{id}/enable | Re-enable a disabled service account. |
POST | /service-accounts/{id}/credentials | Issue a new credential. The clientSecret is returned once. |
POST | /service-accounts/{id}/credentials/{credentialId}/revoke | Revoke a credential. |
Read (org:users:read):| Method | Path | Description |
|---|
GET | /users | List organization users. |
GET | /users/{userId} | Get a user by ID. |
GET | /users/profile | Get the calling principal’s profile. |
POST | /users/workspace/users | Get users for a specific workspace. |
Manage (org:users:manage):| Method | Path | Description |
|---|
POST | /users | Add users to the organization. |
PUT | /users | Update a user. |
PUT | /users/profile | Update the calling principal’s profile. |
DELETE | /users/{id} | Remove a user from the organization. |
POST | /users/workspace | Assign users to a workspace with a role. |
Roles (org:users:roles):| Method | Path | Description |
|---|
PUT | /users/organization/role | Change a user’s organizational role. |
Read (org:azure:read):| Method | Path | Description |
|---|
GET | /azure-resources/subscriptions | List Azure subscriptions visible to the org’s tenant. |
GET | /azure-resources/subscriptions/is-owner?subscriptionId= | Check whether the calling principal is an Owner of the subscription. |
GET | /azure-resources/subscriptions/{subscriptionId}/network-security-groups | List NSGs in a subscription. |
GET | /azure-resources/subscriptions/{subscriptionId}/resource-groups | List resource groups in a subscription. |
GET | /azure-resources/subscriptions/{subscriptionId}/resource-groups/{resourceGroup}/workspaces | List Log Analytics workspaces in a resource group. |
GET | /azure-resources/subscriptions/{subscriptionId}/resource-groups/{resourceGroup}/sentinels | List Sentinel instances in a resource group. |
GET | /azure-resources/subscriptions/{subscriptionId}/resource-groups/{resourceGroup}/workspaces/{workspaceName}/validate | Validate a Sentinel-attached workspace. |
Manage (org:azure:manage):| Method | Path | Description |
|---|
PUT | /azure-resources/analytical-rules/{ruleId}?enabled=true | Enable or disable an analytical rule. |
What Comes Back
Every successful response is wrapped in the standard envelope:
{
"data": { /* … endpoint-specific payload … */ },
"meta": {
"requestId": "0HN8Q3V0001",
"timestamp": "2026-04-15T20:00:00.0000000+00:00"
}
}
List endpoints add a pagination block; see the object models page for shapes per endpoint family.
Error responses are RFC 7807 ProblemDetails (application/problem+json) with a stable code extension you can switch on — the error reference lists every code.