Developer Documentation

TITAN AI Security API

A REST API and webhooks system designed for engineering teams who want findings in their own tooling. Integrate with any ticketing system, SIEM, or workflow tool. The customer's developers stay in control.

Contents

Design philosophy

TITAN AI does not write tickets into customer ticketing systems. There are too many of them, with too many compliance variants, and direct ticket writes create liability for both vendor and customer. Instead, TITAN AI exposes findings via a REST API and emits events to customer-registered webhook endpoints. The customer's engineering team writes a small adapter that translates TITAN AI findings into whatever ticketing, SIEM, or workflow system the customer already runs.

This is the same model used by every mature security vendor in the category. It is the model that scales across hundreds of customers with different toolchains, and it is the model that procurement teams expect when reviewing a security platform.

Three principles that govern the API:

Quick start

1

Get a license key

Sign up for a trial or contact sales. License keys are provisioned per tenant and scope all API access.

2

Pull findings

Make a GET request to /api/v1/findings with your license key. Findings return as JSON.

3

Register a webhook (optional)

POST your callback URL to /api/v1/webhooks. TITAN AI will fire events when finding state changes.

4

Build your adapter

Map TITAN AI findings to your ticket system, SIEM, or workflow tool. The customer's engineering team owns this layer.

Authentication

All API requests require a license key in the X-License-Key header. The same license key authorizes both REST API calls and webhook deliveries.

curl https://api.titanaisec.com/api/v1/findings \
  -H "X-License-Key: ttl_yourlicensekeyhere"
License keys are tenant-scoped. A leaked key exposes findings for that tenant only. Rotate keys via the dashboard if a key is suspected to be compromised. Keys can be revoked instantly.

Findings API

The Findings API exposes the current state of all findings across the customer's connected Azure subscriptions.

GET /api/v1/findings

Returns all current findings for the tenant. Findings are scoped by license key.

Query parameters

ParameterTypeDescription
severitystringFilter by severity. One of critical, high, medium, low, info
categorystringFilter by layer. Example: network, identity, storage, keyvault, compliance, cost
subscription_idstringFilter to a single Azure subscription
sinceISO 8601 timestampReturn only findings detected or updated after this time
limitintegerMax results per page. Default 100, max 500

Example request

curl "https://api.titanaisec.com/api/v1/findings?severity=critical&limit=10" \
  -H "X-License-Key: ttl_yourlicensekeyhere"

Example response

{
  "findings": [
    {
      "id": "azure-nsg-prod-vnet-rule1-abc123",
      "title": "NSG allows SSH/RDP from internet",
      "severity": "critical",
      "category": "network",
      "layer": "infrastructure",
      "subscription_id": "f623a36c-87b5-48e4-a3d4-1c6dc182eb43",
      "environment": "PROD",
      "resource_id": "/subscriptions/.../networkSecurityGroups/nsg-prod-web",
      "framework": "NIST 800-53 SC-7, CIS Azure 6.1",
      "description": "NSG rule allows inbound from 0.0.0.0/0 to port 22.",
      "recommendation": "Restrict source to corporate IPs or use Azure Bastion.",
      "detected_at": "2026-05-15T18:42:11Z",
      "state": "open"
    }
  ],
  "total": 47,
  "has_more": false
}
GET /api/v1/findings/{id}

Returns a single finding with full detail including resource metadata and remediation guidance.

GET /api/v1/findings/{id}/history

Returns the full audit trail for a finding: every state change, acceptance, resolution, and remediation request, with timestamps and user attribution.

Example response

{
  "finding_id": "azure-nsg-prod-vnet-rule1-abc123",
  "history": [
    { "action": "detected",     "timestamp": "2026-05-10T12:00:00Z", "by": "scanner" },
    { "action": "accept_risk",  "timestamp": "2026-05-11T09:15:22Z", "by": "[email protected]", "justification": "Approved exception, ticket #4521", "expires_at": "2026-08-11T00:00:00Z" },
    { "action": "expired",      "timestamp": "2026-08-11T00:00:01Z", "by": "system" },
    { "action": "redetected",   "timestamp": "2026-08-11T00:05:00Z", "by": "scanner" }
  ]
}

Findings Actions API

Three customer-controlled actions can be taken on any finding: accept risk, mark resolved, or request remediation. Every action is logged to the finding's history.

POST /api/v1/findings/{id}/accept

Accept the risk for this finding. The finding is hidden from default views until expiry or until the underlying issue changes. Requires a justification string. Optional expiry.

Request body

{
  "justification": "Compensating control X in place. Approved by security council 2026-05-14.",
  "expires_at": "2026-08-14T00:00:00Z",
  "user": "[email protected]"
}
POST /api/v1/findings/{id}/resolve

Mark a finding as resolved. The next scan will re-check the underlying resource. If the issue is still present, the finding is automatically reopened.

Request body

{
  "user": "[email protected]",
  "evidence": "PR #4521 merged, NSG rule removed."
}
POST /api/v1/findings/{id}/remediate Opt-in required

Request that TITAN AI auto-remediate a low or medium severity finding. Auto-remediation is disabled by default and must be explicitly enabled per tenant. Critical severity findings cannot be auto-remediated under any circumstances.

Request body

{
  "user": "[email protected]",
  "approval_required": true
}

Webhooks (callbacks)

Instead of polling the Findings API, register a webhook URL and TITAN AI will fire events to it whenever a finding is detected, changes state, or is acted upon. This is the recommended pattern for production integrations.

POST /api/v1/webhooks

Register a new webhook endpoint. TITAN AI will send signed POST requests to this URL on finding events.

Request body

{
  "url": "https://your-app.example.com/titan-webhook",
  "events": ["finding.detected", "finding.resolved", "finding.accepted"],
  "secret": "your-shared-secret-for-signature-verification"
}

Response

{
  "webhook_id": "wh_abc123def456",
  "url": "https://your-app.example.com/titan-webhook",
  "events": ["finding.detected", "finding.resolved", "finding.accepted"],
  "created_at": "2026-05-15T19:00:00Z"
}
GET /api/v1/webhooks

List all registered webhooks for the tenant.

DELETE /api/v1/webhooks/{webhook_id}

Unregister a webhook. No more events will be delivered to this URL.

Webhook signature verification

Every webhook delivery includes an X-Titan-Signature header containing an HMAC-SHA256 signature of the request body. Compute the signature using the shared secret provided at registration time and compare. Reject any request whose signature does not match.

# Python example
import hmac, hashlib

def verify_webhook(body_bytes, signature_header, shared_secret):
    expected = hmac.new(
        shared_secret.encode(),
        body_bytes,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature_header)

Supported events

EventFires when
finding.detectedA new finding is discovered by any scanner
finding.updatedAn existing finding's details change (severity rescored, description updated)
finding.resolvedA finding is marked resolved or auto-confirmed resolved by a rescan
finding.acceptedRisk has been accepted for a finding
finding.expiredAn accepted-risk exception has reached its expiry timestamp
finding.remediatedAuto-remediation has been successfully applied
scan.completedA full scan cycle has completed across all subscriptions

Optional remediation

TITAN AI can apply remediations on the customer's behalf for low and medium severity findings, but only when the customer has explicitly opted in.

Auto-remediation is OFF by default. To enable, contact your account team or set allow_auto_remediate: true in tenant settings. Even with auto-remediation enabled, critical severity findings will never be auto-fixed. Remediation requires the customer's Service Principal to have appropriate write permissions (typically Contributor on the affected resource).

How it works

  1. Customer enables auto-remediation per tenant.
  2. Customer's engineering team or automation calls POST /api/v1/findings/{id}/remediate.
  3. TITAN AI validates the request (severity check, opt-in check, permission check).
  4. Remediation is queued and applied during the next scan cycle.
  5. A finding.remediated webhook event fires on success, or finding.remediation_failed on error.
  6. Full audit trail logged in finding history.

What can be auto-remediated

Auto-remediation is currently supported for the following finding categories, all at low or medium severity:

Event payload schemas

All webhook events follow a consistent envelope structure:

{
  "event_id": "evt_01H7XYZ...",
  "event_type": "finding.detected",
  "tenant_id": "tnt_abc123",
  "timestamp": "2026-05-15T19:42:11Z",
  "data": {
    "finding": {
      "id": "azure-storage-prod-stacct1-http",
      "title": "Storage account allows insecure HTTP",
      "severity": "high",
      "category": "storage",
      "subscription_id": "f623a36c-...",
      "environment": "PROD",
      "resource_id": "/subscriptions/.../storageAccounts/stacct1",
      "framework": "CIS Azure 3.1, PCI DSS 4.1",
      "description": "Data in transit can be intercepted.",
      "recommendation": "Enable secure transfer required.",
      "detected_at": "2026-05-15T19:42:11Z",
      "state": "open"
    }
  }
}

Error handling

The API uses standard HTTP status codes. Error responses are JSON with a consistent shape:

{
  "error": {
    "code": "invalid_license_key",
    "message": "The provided license key is invalid or has been revoked.",
    "request_id": "req_01H7XYZ..."
  }
}
StatusCodeMeaning
400invalid_requestRequired parameter missing or malformed
401invalid_license_keyLicense key missing, malformed, or revoked
403auto_remediate_disabledTenant has not enabled auto-remediation
403critical_remediation_blockedCannot auto-remediate critical severity findings
404finding_not_foundThe finding ID does not exist or is not visible to this tenant
429rate_limitedToo many requests. Back off and retry after the time given in the Retry-After header
500internal_errorUnexpected error. Include the request_id when contacting support

Rate limits

API requests are rate limited per license key:

Endpoint groupLimit
Read endpoints (GET /findings, GET /findings/*)120 requests per minute
Write endpoints (POST, DELETE)30 requests per minute
Webhook deliveries (outbound from TITAN AI to your endpoint)No customer-side limit; TITAN AI retries up to 5 times with exponential backoff on 5xx or timeout

Customers running into rate limits at scale should contact support to discuss higher tier limits.

Need help integrating? The TITAN AI engineering team is available to support customer-side integration work. Email [email protected] with the question and your tenant ID. Founding customers have direct engineering team access.