Skip to main content

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.
MethodPathDescription
GET/workspaces/{workspaceId}/incidents/{source}/{incidentId}Get the full incident detail, including alerts, entities, investigation details, and evidence.
GET/workspaces/{workspaceId}/incidents/{source}/{incidentId}/evidenceGet the evidence table for an incident.
GET/workspaces/{workspaceId}/incidents/{source}/{incidentId}/last-gamebookGet the last gamebook run for an incident, or 404 if none has run.
GET/workspaces/{workspaceId}/incidents/{source}/{incidentId}/commentsList comments on an incident.
GET/workspaces/{workspaceId}/incidents/{source}/by-entityFind incidents in this source related to a specific entity.
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.
ScopeMethodPathDescription
incidents:readPOST/incidents/across-workspacesList incidents across all visible workspaces.
gamebooks:readGET/gamebooks/across-workspaces/historyList gamebook history across visible workspaces. Supports ?workspaces=, ?statuses=, ?currentPage=, ?query=.
datasources:readPOST/datasources/across-workspaces/anomaliesList data connector anomalies across visible workspaces.
datasources:readGET/datasources/across-workspacesGroup 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.
Read (webhooks:read):
MethodPathDescription
GET/webhooksList all webhook configurations.
GET/webhooks/{id}Get a webhook by ID.
GET/webhooks/{id}/delivery-logsList 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):
MethodPathDescription
POST/webhooksCreate a webhook configuration.
PUT/webhooks/{id}Update a webhook configuration.
DELETE/webhooks/{id}Delete a webhook configuration.
POST/webhooks/{id}/pausePause delivery.
POST/webhooks/{id}/resumeResume a paused webhook.
POST/webhooks/{id}/enableRe-enable a webhook auto-disabled by repeated delivery failures.
POST/webhooks/{id}/credentialsUpdate webhook authentication credentials.
POST/webhooks/{id}/testSend a test event.
POST/webhooks/{id}/delivery-logs/{logId}/redeliver?createdAt=Redeliver a previously failed event.

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.