SupportOS
Sign in

API Reference

Complete reference for the SupportOS REST API. Base URL: https://api.supportos.io

Authentication

All API requests must be authenticated. There are two authentication methods: **JWT Bearer Tokens** — Used by the dashboard and programmatic clients. Obtain a token via the /auth/token endpoint. Include it in the Authorization header: `Authorization: Bearer <token>`. Tokens are tenant-scoped, RS256-signed, and expire after 1 hour. **API Keys** — Used for webhook ingestion and server-to-server calls. API keys are created in Settings > API Keys and are scoped to a single tenant. Include the key in the `X-API-Key` header. API keys do not expire but can be revoked at any time. All requests must include a `Content-Type: application/json` header. Rate limits apply: 100 requests/minute for standard endpoints, 500/minute for webhook ingestion.

Webhooks

Ingest events from external platforms. All webhook payloads must be signed with HMAC-SHA256. Compute the signature over the raw request body using your webhook secret and include it in the `X-Signature-256` header. Events are processed idempotently based on `event_id`.

POST/api/v1/webhooks/eventsX-API-Key + X-Signature-256 (HMAC-SHA256)

Receive an event from an external platform. Supported event types: user_reported, message_flagged, csam_hash_match, account_suspended, content_removed, user_blocked, appeal_submitted. Each event is deduplicated by event_id.

Body Parameters

NameTypeRequiredDescription
event_idstring (UUID)requiredUnique identifier for this event — used for idempotency.
event_typestringrequiredOne of: user_reported, message_flagged, csam_hash_match, account_suspended, content_removed, user_blocked, appeal_submitted.
timestampstring (ISO 8601)requiredWhen the event occurred on the source platform.
sourcestringrequiredIdentifier for the source platform (e.g. 'dating-frame').
payloadobjectrequiredEvent-specific data. Schema varies by event_type.
payload.reporter_idstringoptionalID of the reporting user (user_reported events).
payload.reported_user_idstringoptionalID of the reported user.
payload.reasonstringoptionalReason for the report.
payload.contentobjectoptionalContent associated with the event (messages, images, etc.).
payload.hash_valuestringoptionalHash value for csam_hash_match events.
payload.hash_algorithmstringoptionalHash algorithm used (e.g. 'photodna', 'md5').

Example Request

curl -X POST https://api.supportos.io/api/v1/webhooks/events \
  -H "Content-Type: application/json" \
  -H "X-API-Key: sk_live_abc123def456" \
  -H "X-Signature-256: sha256=a1b2c3d4e5f6..." \
  -d '{
    "event_id": "evt_9f8e7d6c-5b4a-3c2d-1e0f-a1b2c3d4e5f6",
    "event_type": "user_reported",
    "timestamp": "2026-04-02T14:30:00.000Z",
    "source": "dating-frame",
    "payload": {
      "reporter_id": "usr_a1b2c3d4",
      "reported_user_id": "usr_e5f6g7h8",
      "reason": "inappropriate_content",
      "content": {
        "type": "message",
        "text": "Reported message content here",
        "message_id": "msg_x1y2z3"
      }
    }
  }'

Example Response

{
  "id": "tkt_3a2b1c0d-9e8f-7a6b-5c4d-3e2f1a0b9c8d",
  "event_id": "evt_9f8e7d6c-5b4a-3c2d-1e0f-a1b2c3d4e5f6",
  "status": "received",
  "created_at": "2026-04-02T14:30:01.123Z"
}

Error Responses

StatusDescription
400Invalid payload — missing required fields or unknown event_type.
401Missing or invalid API key.
403HMAC signature verification failed.
409Event with this event_id has already been processed (idempotent — safe to retry).
429Rate limit exceeded. Retry after the duration in the Retry-After header.

Tickets

Manage support tickets created from webhooks, user reports, or manual entry. Tickets are classified by AI and can have AI-generated draft responses.

GET/api/v1/ticketsBearer JWT

List tickets for the current tenant. Results are cursor-paginated and sorted by creation date descending.

Query Parameters

NameTypeRequiredDescription
statusstringoptionalFilter by status: open, in_progress, waiting, resolved, closed.
prioritystringoptionalFilter by priority: low, medium, high, critical.
categorystringoptionalFilter by AI-assigned category.
cursorstringoptionalCursor for pagination. Omit for the first page.
limitnumberoptionalNumber of results per page (1–100, default 25).

Example Request

curl https://api.supportos.io/api/v1/tickets?status=open&priority=high&limit=10 \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..."

Example Response

{
  "data": [
    {
      "id": "tkt_3a2b1c0d-9e8f-7a6b-5c4d-3e2f1a0b9c8d",
      "tenant_id": "ten_f1e2d3c4-b5a6-9788-7c6d-5e4f3a2b1c0d",
      "status": "open",
      "priority": "high",
      "category": "harassment",
      "subject": "User report: inappropriate messages",
      "source": "webhook",
      "ai_confidence": 0.92,
      "assigned_to": null,
      "created_at": "2026-04-02T14:30:01.123Z",
      "updated_at": "2026-04-02T14:30:01.123Z"
    }
  ],
  "pagination": {
    "cursor": "eyJpZCI6InRrdF8zYTJiMWMwZCJ9",
    "has_more": true,
    "total": 47
  }
}

Error Responses

StatusDescription
401Missing or invalid JWT.
400Invalid query parameters.
429Rate limit exceeded.
GET/api/v1/tickets/:idBearer JWT

Get full details for a single ticket including AI classification, timeline events, and linked safety cases.

Path Parameters

NameTypeRequiredDescription
idstring (UUID)requiredTicket ID.

Example Request

curl https://api.supportos.io/api/v1/tickets/tkt_3a2b1c0d-9e8f-7a6b-5c4d-3e2f1a0b9c8d \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..."

Example Response

{
  "id": "tkt_3a2b1c0d-9e8f-7a6b-5c4d-3e2f1a0b9c8d",
  "tenant_id": "ten_f1e2d3c4-b5a6-9788-7c6d-5e4f3a2b1c0d",
  "status": "open",
  "priority": "high",
  "category": "harassment",
  "subject": "User report: inappropriate messages",
  "source": "webhook",
  "event_id": "evt_9f8e7d6c-5b4a-3c2d-1e0f-a1b2c3d4e5f6",
  "ai_classification": {
    "category": "harassment",
    "confidence": 0.92,
    "model": "claude-sonnet-4-20250514",
    "provider": "anthropic",
    "risk_indicators": ["threatening_language", "repeated_contact"]
  },
  "assigned_to": null,
  "safety_case_id": null,
  "timeline": [
    {
      "id": "evt_c1d2e3f4-a5b6-7c8d-9e0f-a1b2c3d4e5f6",
      "type": "ticket_created",
      "actor": "system",
      "timestamp": "2026-04-02T14:30:01.123Z",
      "details": { "source": "webhook" }
    },
    {
      "id": "evt_d2e3f4a5-b6c7-8d9e-0f1a-b2c3d4e5f6a7",
      "type": "ai_classified",
      "actor": "system",
      "timestamp": "2026-04-02T14:30:02.456Z",
      "details": { "category": "harassment", "confidence": 0.92 }
    }
  ],
  "created_at": "2026-04-02T14:30:01.123Z",
  "updated_at": "2026-04-02T14:30:02.456Z"
}

Error Responses

StatusDescription
401Missing or invalid JWT.
404Ticket not found or not accessible by this tenant.
POST/api/v1/tickets/:id/draftsBearer JWT

Generate an AI draft response for a ticket. The draft uses tenant-configured prompts and relevant knowledge base articles.

Path Parameters

NameTypeRequiredDescription
idstring (UUID)requiredTicket ID.

Body Parameters

NameTypeRequiredDescription
tonestringoptionalTone override: professional, empathetic, firm. Defaults to tenant config.
instructionsstringoptionalAdditional instructions for the AI when generating the draft.

Example Request

curl -X POST https://api.supportos.io/api/v1/tickets/tkt_3a2b1c0d-9e8f-7a6b-5c4d-3e2f1a0b9c8d/drafts \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{
    "tone": "empathetic",
    "instructions": "Reference our community guidelines"
  }'

Example Response

{
  "id": "drf_a1b2c3d4-e5f6-7a8b-9c0d-e1f2a3b4c5d6",
  "ticket_id": "tkt_3a2b1c0d-9e8f-7a6b-5c4d-3e2f1a0b9c8d",
  "content": "Hi there,\n\nThank you for reaching out to us about this. We take reports of harassment very seriously and I want you to know we are looking into this.\n\nOur Community Guidelines clearly state that threatening or intimidating behaviour is not tolerated. We have flagged the reported user for review by our safety team.\n\nWe will update you once our investigation is complete. In the meantime, you can block this user from your settings.\n\nBest regards,\nDating Frame Support",
  "confidence": 0.88,
  "model": "claude-sonnet-4-20250514",
  "provider": "anthropic",
  "tokens_used": 342,
  "knowledge_articles_used": [
    { "id": "ka_b1c2d3e4", "title": "Community Guidelines — Harassment Policy" }
  ],
  "status": "pending_approval",
  "created_at": "2026-04-02T14:35:12.789Z"
}

Error Responses

StatusDescription
401Missing or invalid JWT.
404Ticket not found.
422Ticket is closed or already has a pending draft.
429Rate limit exceeded.
POST/api/v1/tickets/:id/drafts/:draftId/approveBearer JWT

Approve an AI-generated draft response. The response is sent to the user and the ticket status is updated.

Path Parameters

NameTypeRequiredDescription
idstring (UUID)requiredTicket ID.
draftIdstring (UUID)requiredDraft ID.

Body Parameters

NameTypeRequiredDescription
editsstringoptionalEdited content to use instead of the original draft. If omitted, the original draft is sent as-is.

Example Request

curl -X POST https://api.supportos.io/api/v1/tickets/tkt_3a2b1c0d-9e8f-7a6b-5c4d-3e2f1a0b9c8d/drafts/drf_a1b2c3d4-e5f6-7a8b-9c0d-e1f2a3b4c5d6/approve \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{}'

Example Response

{
  "id": "drf_a1b2c3d4-e5f6-7a8b-9c0d-e1f2a3b4c5d6",
  "status": "approved",
  "approved_by": "usr_c4d5e6f7-a8b9-0c1d-2e3f-4a5b6c7d8e9f",
  "approved_at": "2026-04-02T14:40:05.321Z",
  "ticket_status": "resolved"
}

Error Responses

StatusDescription
401Missing or invalid JWT.
404Ticket or draft not found.
409Draft has already been approved or rejected.

Safety Cases

Safety cases track safety investigations including CSEA, harassment, threats, and other priority offences. Cases follow a strict status workflow and may trigger mandatory NCA referrals.

GET/api/v1/casesBearer JWT

List safety cases for the current tenant. Supports filtering by status and case type.

Query Parameters

NameTypeRequiredDescription
statusstringoptionalFilter by status: open, investigating, escalated, referred, closed.
caseTypestringoptionalFilter by type: csea, harassment, threats, fraud, self_harm, other.
cursorstringoptionalCursor for pagination.
limitnumberoptionalResults per page (1–100, default 25).

Example Request

curl https://api.supportos.io/api/v1/cases?status=open&caseType=csea&limit=10 \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..."

Example Response

{
  "data": [
    {
      "id": "cas_e1f2a3b4-c5d6-7e8f-9a0b-c1d2e3f4a5b6",
      "tenant_id": "ten_f1e2d3c4-b5a6-9788-7c6d-5e4f3a2b1c0d",
      "case_type": "csea",
      "status": "open",
      "priority": "critical",
      "subject": "Potential CSEA — hash match detected",
      "ticket_ids": ["tkt_3a2b1c0d-9e8f-7a6b-5c4d-3e2f1a0b9c8d"],
      "assigned_to": "usr_c4d5e6f7-a8b9-0c1d-2e3f-4a5b6c7d8e9f",
      "sla_deadline": "2026-04-02T15:30:00.000Z",
      "evidence_count": 3,
      "referral_id": null,
      "created_at": "2026-04-02T14:30:05.000Z",
      "updated_at": "2026-04-02T14:30:05.000Z"
    }
  ],
  "pagination": {
    "cursor": "eyJpZCI6ImNhc19lMWYyYTNiNCJ9",
    "has_more": false,
    "total": 1
  }
}

Error Responses

StatusDescription
401Missing or invalid JWT.
400Invalid query parameters.
429Rate limit exceeded.
GET/api/v1/cases/:idBearer JWT

Get full details for a safety case including evidence, timeline, and referral status.

Path Parameters

NameTypeRequiredDescription
idstring (UUID)requiredSafety case ID.

Example Request

curl https://api.supportos.io/api/v1/cases/cas_e1f2a3b4-c5d6-7e8f-9a0b-c1d2e3f4a5b6 \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..."

Example Response

{
  "id": "cas_e1f2a3b4-c5d6-7e8f-9a0b-c1d2e3f4a5b6",
  "tenant_id": "ten_f1e2d3c4-b5a6-9788-7c6d-5e4f3a2b1c0d",
  "case_type": "csea",
  "status": "investigating",
  "priority": "critical",
  "subject": "Potential CSEA — hash match detected",
  "description": "PhotoDNA hash match on uploaded image. Automatic evidence preservation triggered.",
  "ticket_ids": ["tkt_3a2b1c0d-9e8f-7a6b-5c4d-3e2f1a0b9c8d"],
  "assigned_to": "usr_c4d5e6f7-a8b9-0c1d-2e3f-4a5b6c7d8e9f",
  "sla_deadline": "2026-04-02T15:30:00.000Z",
  "evidence": [
    {
      "id": "evi_f1a2b3c4-d5e6-7f8a-9b0c-d1e2f3a4b5c6",
      "type": "image_hash",
      "preserved_at": "2026-04-02T14:30:03.000Z",
      "s3_object_lock": true
    }
  ],
  "referral": null,
  "timeline": [
    {
      "type": "case_created",
      "actor": "system",
      "timestamp": "2026-04-02T14:30:05.000Z"
    },
    {
      "type": "evidence_preserved",
      "actor": "system",
      "timestamp": "2026-04-02T14:30:06.000Z"
    }
  ],
  "created_at": "2026-04-02T14:30:05.000Z",
  "updated_at": "2026-04-02T14:32:10.000Z"
}

Error Responses

StatusDescription
401Missing or invalid JWT.
404Case not found or not accessible by this tenant.
PATCH/api/v1/cases/:id/statusBearer JWT

Transition a safety case to a new status. Status transitions are validated — for example, CSEA cases cannot be closed without a referral.

Path Parameters

NameTypeRequiredDescription
idstring (UUID)requiredSafety case ID.

Body Parameters

NameTypeRequiredDescription
statusstringrequiredNew status: investigating, escalated, referred, closed.
reasonstringrequiredReason for the status change (logged to audit trail).

Example Request

curl -X PATCH https://api.supportos.io/api/v1/cases/cas_e1f2a3b4-c5d6-7e8f-9a0b-c1d2e3f4a5b6/status \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{
    "status": "escalated",
    "reason": "Confirmed CSEA material — escalating to safeguarding lead"
  }'

Example Response

{
  "id": "cas_e1f2a3b4-c5d6-7e8f-9a0b-c1d2e3f4a5b6",
  "status": "escalated",
  "previous_status": "investigating",
  "updated_at": "2026-04-02T14:45:00.000Z"
}

Error Responses

StatusDescription
401Missing or invalid JWT.
404Case not found.
422Invalid status transition (e.g. closing a CSEA case without referral).

Evidence

Evidence is immutable content preserved in S3 with Object Lock (Compliance Mode). Evidence cannot be modified or deleted. Every access is logged to the chain-of-custody audit trail.

GET/api/v1/evidenceBearer JWT

List evidence items. Must filter by case_id. Every call to this endpoint is logged to the evidence access audit trail.

Query Parameters

NameTypeRequiredDescription
case_idstring (UUID)requiredSafety case ID to list evidence for.
cursorstringoptionalCursor for pagination.
limitnumberoptionalResults per page (1–100, default 25).

Example Request

curl https://api.supportos.io/api/v1/evidence?case_id=cas_e1f2a3b4-c5d6-7e8f-9a0b-c1d2e3f4a5b6 \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..."

Example Response

{
  "data": [
    {
      "id": "evi_f1a2b3c4-d5e6-7f8a-9b0c-d1e2f3a4b5c6",
      "case_id": "cas_e1f2a3b4-c5d6-7e8f-9a0b-c1d2e3f4a5b6",
      "type": "image_hash",
      "description": "PhotoDNA hash match — original image preserved",
      "content_type": "image/jpeg",
      "size_bytes": 245760,
      "hash_sha256": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2",
      "s3_key": "evidence/ten_f1e2d3c4/cas_e1f2a3b4/evi_f1a2b3c4.enc",
      "object_lock_mode": "COMPLIANCE",
      "object_lock_retain_until": "2033-04-02T14:30:03.000Z",
      "preserved_at": "2026-04-02T14:30:03.000Z",
      "preserved_by": "system",
      "created_at": "2026-04-02T14:30:03.000Z"
    }
  ],
  "pagination": {
    "cursor": null,
    "has_more": false,
    "total": 1
  }
}

Error Responses

StatusDescription
401Missing or invalid JWT.
400Missing required case_id parameter.
404Case not found or not accessible by this tenant.

Referrals

NCA (National Crime Agency) referrals for CSEA and other priority offences. Referrals are generated from safety cases and follow a strict workflow. Once submitted, referrals cannot be modified.

GET/api/v1/referralsBearer JWT

List referrals for the current tenant.

Query Parameters

NameTypeRequiredDescription
statusstringoptionalFilter by status: draft, pending_review, submitted, acknowledged.
cursorstringoptionalCursor for pagination.
limitnumberoptionalResults per page (1–100, default 25).

Example Request

curl https://api.supportos.io/api/v1/referrals?status=submitted&limit=10 \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..."

Example Response

{
  "data": [
    {
      "id": "ref_b1c2d3e4-f5a6-7b8c-9d0e-f1a2b3c4d5e6",
      "case_id": "cas_e1f2a3b4-c5d6-7e8f-9a0b-c1d2e3f4a5b6",
      "type": "nca",
      "status": "submitted",
      "submitted_at": "2026-04-02T15:00:00.000Z",
      "submitted_by": "usr_c4d5e6f7-a8b9-0c1d-2e3f-4a5b6c7d8e9f",
      "reference_number": "NCA-2026-04-0042",
      "evidence_count": 3,
      "created_at": "2026-04-02T14:50:00.000Z"
    }
  ],
  "pagination": {
    "cursor": null,
    "has_more": false,
    "total": 1
  }
}

Error Responses

StatusDescription
401Missing or invalid JWT.
429Rate limit exceeded.
POST/api/v1/cases/:caseId/referralsBearer JWT

Create a referral from a safety case. For CSEA cases, the system auto-attaches all preserved evidence. The referral enters draft status and must be reviewed before submission.

Path Parameters

NameTypeRequiredDescription
caseIdstring (UUID)requiredSafety case ID.

Body Parameters

NameTypeRequiredDescription
typestringrequiredReferral type: nca, police, other.
urgencystringrequiredUrgency level: routine, urgent, emergency.
summarystringrequiredHuman-written summary of the referral.
contact_detailsobjectoptionalOverride contact details for the referral recipient.

Example Request

curl -X POST https://api.supportos.io/api/v1/cases/cas_e1f2a3b4-c5d6-7e8f-9a0b-c1d2e3f4a5b6/referrals \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{
    "type": "nca",
    "urgency": "urgent",
    "summary": "CSEA material detected via PhotoDNA hash match. User account suspended. Evidence preserved with full chain of custody."
  }'

Example Response

{
  "id": "ref_b1c2d3e4-f5a6-7b8c-9d0e-f1a2b3c4d5e6",
  "case_id": "cas_e1f2a3b4-c5d6-7e8f-9a0b-c1d2e3f4a5b6",
  "type": "nca",
  "status": "draft",
  "urgency": "urgent",
  "summary": "CSEA material detected via PhotoDNA hash match. User account suspended. Evidence preserved with full chain of custody.",
  "evidence_count": 3,
  "created_at": "2026-04-02T14:50:00.000Z"
}

Error Responses

StatusDescription
401Missing or invalid JWT.
404Case not found.
409Case already has an active referral.
422Case does not have sufficient evidence for a referral.

Compliance

Compliance endpoints provide an overview of your regulatory status and generate Ofcom transparency reports as required by the UK Online Safety Act.

GET/api/v1/compliance/summaryBearer JWT

Get a summary of compliance status including SLA adherence, open cases, pending referrals, and upcoming deadlines.

Example Request

curl https://api.supportos.io/api/v1/compliance/summary \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..."

Example Response

{
  "tenant_id": "ten_f1e2d3c4-b5a6-9788-7c6d-5e4f3a2b1c0d",
  "period": {
    "from": "2026-03-01T00:00:00.000Z",
    "to": "2026-04-02T23:59:59.999Z"
  },
  "sla_adherence": {
    "overall": 0.94,
    "csea_response": 1.0,
    "priority_offence": 0.97,
    "standard_ticket": 0.91
  },
  "open_cases": {
    "total": 4,
    "csea": 1,
    "priority_offence": 2,
    "other": 1
  },
  "pending_referrals": 1,
  "overdue_items": [
    {
      "type": "ticket",
      "id": "tkt_7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d",
      "sla_deadline": "2026-04-02T12:00:00.000Z",
      "overdue_by_minutes": 150
    }
  ],
  "next_transparency_report_due": "2026-06-30T23:59:59.999Z"
}

Error Responses

StatusDescription
401Missing or invalid JWT.
GET/api/v1/compliance/transparency-reportBearer JWT

Generate an Ofcom transparency report for the specified period. Returns structured report data.

Query Parameters

NameTypeRequiredDescription
fromstring (ISO 8601)requiredStart of reporting period.
tostring (ISO 8601)requiredEnd of reporting period.

Example Request

curl "https://api.supportos.io/api/v1/compliance/transparency-report?from=2026-01-01T00:00:00Z&to=2026-03-31T23:59:59Z" \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..."

Example Response

{
  "report_id": "rpt_a1b2c3d4-e5f6-7a8b-9c0d-e1f2a3b4c5d6",
  "tenant_id": "ten_f1e2d3c4-b5a6-9788-7c6d-5e4f3a2b1c0d",
  "period": {
    "from": "2026-01-01T00:00:00.000Z",
    "to": "2026-03-31T23:59:59.000Z"
  },
  "summary": {
    "total_reports_received": 1247,
    "total_actions_taken": 892,
    "total_cases_opened": 156,
    "total_referrals_made": 3,
    "average_response_time_hours": 2.4,
    "sla_adherence_rate": 0.94
  },
  "categories": {
    "csea": { "reports": 8, "cases": 5, "referrals": 3, "actions": 8 },
    "harassment": { "reports": 412, "cases": 67, "referrals": 0, "actions": 298 },
    "threats": { "reports": 89, "cases": 23, "referrals": 0, "actions": 64 },
    "fraud": { "reports": 201, "cases": 34, "referrals": 0, "actions": 178 },
    "self_harm": { "reports": 45, "cases": 12, "referrals": 0, "actions": 39 },
    "other": { "reports": 492, "cases": 15, "referrals": 0, "actions": 305 }
  },
  "generated_at": "2026-04-02T15:00:00.000Z"
}

Error Responses

StatusDescription
401Missing or invalid JWT.
400Invalid or missing date range parameters.
GET/api/v1/compliance/transparency-report/exportBearer JWT

Export a transparency report as JSON or CSV. Returns a download URL.

Query Parameters

NameTypeRequiredDescription
fromstring (ISO 8601)requiredStart of reporting period.
tostring (ISO 8601)requiredEnd of reporting period.
formatstringrequiredExport format: json or csv.

Example Request

curl "https://api.supportos.io/api/v1/compliance/transparency-report/export?from=2026-01-01T00:00:00Z&to=2026-03-31T23:59:59Z&format=csv" \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..."

Example Response

{
  "download_url": "https://supportos-exports.s3.eu-west-2.amazonaws.com/exports/ten_f1e2d3c4/rpt_a1b2c3d4.csv?X-Amz-Expires=3600&...",
  "format": "csv",
  "expires_at": "2026-04-02T16:00:00.000Z",
  "size_bytes": 15420
}

Error Responses

StatusDescription
401Missing or invalid JWT.
400Invalid date range or unsupported format.

Workflows

Configure automated workflows that trigger on specific conditions (e.g. ticket created with category X, safety case escalated). Workflows consist of trigger conditions and ordered steps.

GET/api/v1/workflowsBearer JWT

List all workflows for the current tenant.

Query Parameters

NameTypeRequiredDescription
activebooleanoptionalFilter by active/inactive status.
cursorstringoptionalCursor for pagination.
limitnumberoptionalResults per page (1–100, default 25).

Example Request

curl https://api.supportos.io/api/v1/workflows?active=true \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..."

Example Response

{
  "data": [
    {
      "id": "wfl_a1b2c3d4-e5f6-7a8b-9c0d-e1f2a3b4c5d6",
      "name": "Auto-escalate CSEA tickets",
      "description": "Automatically creates safety case and escalates when CSEA is detected",
      "active": true,
      "trigger": {
        "event": "ticket.classified",
        "conditions": { "category": "csea" }
      },
      "steps": [
        { "order": 1, "action": "create_safety_case", "config": { "case_type": "csea", "priority": "critical" } },
        { "order": 2, "action": "preserve_evidence", "config": {} },
        { "order": 3, "action": "assign_to_role", "config": { "role": "safeguarding_lead" } },
        { "order": 4, "action": "send_notification", "config": { "channel": "urgent", "template": "csea_alert" } }
      ],
      "executions_count": 5,
      "last_executed_at": "2026-04-01T09:15:00.000Z",
      "created_at": "2026-03-01T10:00:00.000Z",
      "updated_at": "2026-03-15T14:20:00.000Z"
    }
  ],
  "pagination": {
    "cursor": null,
    "has_more": false,
    "total": 1
  }
}

Error Responses

StatusDescription
401Missing or invalid JWT.
POST/api/v1/workflowsBearer JWT

Create a new workflow. CSEA mandatory workflows cannot be created or modified by tenants.

Body Parameters

NameTypeRequiredDescription
namestringrequiredWorkflow name.
descriptionstringoptionalWorkflow description.
triggerobjectrequiredTrigger configuration: { event: string, conditions: object }.
stepsarrayrequiredOrdered array of steps: [{ order: number, action: string, config: object }].
activebooleanoptionalWhether to activate immediately (default: false).

Example Request

curl -X POST https://api.supportos.io/api/v1/workflows \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "High-priority ticket assignment",
    "description": "Auto-assign high priority tickets to senior agents",
    "trigger": {
      "event": "ticket.classified",
      "conditions": { "priority": "high" }
    },
    "steps": [
      { "order": 1, "action": "assign_to_role", "config": { "role": "senior_agent" } },
      { "order": 2, "action": "send_notification", "config": { "channel": "slack", "template": "high_priority_ticket" } }
    ],
    "active": true
  }'

Example Response

{
  "id": "wfl_d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f9a",
  "name": "High-priority ticket assignment",
  "active": true,
  "trigger": {
    "event": "ticket.classified",
    "conditions": { "priority": "high" }
  },
  "steps": [
    { "order": 1, "action": "assign_to_role", "config": { "role": "senior_agent" } },
    { "order": 2, "action": "send_notification", "config": { "channel": "slack", "template": "high_priority_ticket" } }
  ],
  "created_at": "2026-04-02T15:10:00.000Z"
}

Error Responses

StatusDescription
401Missing or invalid JWT.
400Invalid workflow definition — missing trigger or steps.
422Workflow conflicts with a mandatory system workflow.
PATCH/api/v1/workflows/:idBearer JWT

Update an existing workflow. Only non-mandatory workflows can be modified.

Path Parameters

NameTypeRequiredDescription
idstring (UUID)requiredWorkflow ID.

Body Parameters

NameTypeRequiredDescription
namestringoptionalUpdated name.
descriptionstringoptionalUpdated description.
triggerobjectoptionalUpdated trigger configuration.
stepsarrayoptionalUpdated steps array.
activebooleanoptionalEnable or disable the workflow.

Example Request

curl -X PATCH https://api.supportos.io/api/v1/workflows/wfl_d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f9a \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{
    "active": false
  }'

Example Response

{
  "id": "wfl_d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f9a",
  "name": "High-priority ticket assignment",
  "active": false,
  "updated_at": "2026-04-02T15:15:00.000Z"
}

Error Responses

StatusDescription
401Missing or invalid JWT.
404Workflow not found.
403Cannot modify a mandatory system workflow.
DELETE/api/v1/workflows/:idBearer JWT

Soft-delete a workflow. Mandatory system workflows cannot be deleted.

Path Parameters

NameTypeRequiredDescription
idstring (UUID)requiredWorkflow ID.

Example Request

curl -X DELETE https://api.supportos.io/api/v1/workflows/wfl_d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f9a \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..."

Example Response

{
  "id": "wfl_d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f9a",
  "deleted": true,
  "deleted_at": "2026-04-02T15:20:00.000Z"
}

Error Responses

StatusDescription
401Missing or invalid JWT.
404Workflow not found.
403Cannot delete a mandatory system workflow.

Connectors

Connectors integrate external platforms (email providers, chat systems, CRMs) with SupportOS. Each connector has inbound mappings (how external data maps to SupportOS entities) and outbound actions (what actions SupportOS can push back to the external platform).

GET/api/v1/connectorsBearer JWT

List all connectors for the current tenant.

Query Parameters

NameTypeRequiredDescription
statusstringoptionalFilter by status: active, inactive, error.
cursorstringoptionalCursor for pagination.
limitnumberoptionalResults per page (1–100, default 25).

Example Request

curl https://api.supportos.io/api/v1/connectors \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..."

Example Response

{
  "data": [
    {
      "id": "con_a1b2c3d4-e5f6-7a8b-9c0d-e1f2a3b4c5d6",
      "name": "Dating Frame Production",
      "type": "webhook",
      "status": "active",
      "config": {
        "webhook_url": "https://api.supportos.io/api/v1/webhooks/events",
        "signing_secret_last4": "f6a7"
      },
      "inbound_mappings_count": 3,
      "outbound_actions_count": 2,
      "last_event_at": "2026-04-02T14:30:01.000Z",
      "created_at": "2026-03-01T10:00:00.000Z"
    }
  ],
  "pagination": {
    "cursor": null,
    "has_more": false,
    "total": 1
  }
}

Error Responses

StatusDescription
401Missing or invalid JWT.
POST/api/v1/connectorsBearer JWT

Create a new connector. A webhook signing secret is generated and returned once — store it securely.

Body Parameters

NameTypeRequiredDescription
namestringrequiredDisplay name for the connector.
typestringrequiredConnector type: webhook, email, api.
configobjectoptionalType-specific configuration (e.g. SMTP settings for email).

Example Request

curl -X POST https://api.supportos.io/api/v1/connectors \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Dating Frame Staging",
    "type": "webhook"
  }'

Example Response

{
  "id": "con_e5f6a7b8-c9d0-1e2f-3a4b-5c6d7e8f9a0b",
  "name": "Dating Frame Staging",
  "type": "webhook",
  "status": "active",
  "config": {
    "webhook_url": "https://api.supportos.io/api/v1/webhooks/events",
    "signing_secret": "whsec_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"
  },
  "created_at": "2026-04-02T15:25:00.000Z"
}

Error Responses

StatusDescription
401Missing or invalid JWT.
400Invalid connector configuration.
POST/api/v1/connectors/:id/mappingsBearer JWT

Create an inbound field mapping for a connector. Maps external event fields to SupportOS ticket fields.

Path Parameters

NameTypeRequiredDescription
idstring (UUID)requiredConnector ID.

Body Parameters

NameTypeRequiredDescription
event_typestringrequiredExternal event type this mapping applies to.
field_mappingsarrayrequiredArray of { source: string, target: string, transform?: string } mappings.

Example Request

curl -X POST https://api.supportos.io/api/v1/connectors/con_a1b2c3d4-e5f6-7a8b-9c0d-e1f2a3b4c5d6/mappings \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{
    "event_type": "user_reported",
    "field_mappings": [
      { "source": "payload.reporter_id", "target": "reporter_external_id" },
      { "source": "payload.reported_user_id", "target": "subject_external_id" },
      { "source": "payload.reason", "target": "category", "transform": "map_category" }
    ]
  }'

Example Response

{
  "id": "map_c1d2e3f4-a5b6-7c8d-9e0f-a1b2c3d4e5f6",
  "connector_id": "con_a1b2c3d4-e5f6-7a8b-9c0d-e1f2a3b4c5d6",
  "event_type": "user_reported",
  "field_mappings": [
    { "source": "payload.reporter_id", "target": "reporter_external_id" },
    { "source": "payload.reported_user_id", "target": "subject_external_id" },
    { "source": "payload.reason", "target": "category", "transform": "map_category" }
  ],
  "created_at": "2026-04-02T15:30:00.000Z"
}

Error Responses

StatusDescription
401Missing or invalid JWT.
404Connector not found.
400Invalid field mapping — unknown target field or transform.
POST/api/v1/connectors/:id/actionsBearer JWT

Create an outbound action for a connector. Defines what actions SupportOS can push to the external platform.

Path Parameters

NameTypeRequiredDescription
idstring (UUID)requiredConnector ID.

Body Parameters

NameTypeRequiredDescription
action_typestringrequiredAction type: suspend_user, remove_content, send_warning, restore_content.
endpointstringrequiredURL to call when this action is triggered.
methodstringrequiredHTTP method: POST, PUT, PATCH, DELETE.
headersobjectoptionalAdditional headers to include in the request.
payload_templatestringrequiredJSON template with {{variable}} placeholders for the request body.

Example Request

curl -X POST https://api.supportos.io/api/v1/connectors/con_a1b2c3d4-e5f6-7a8b-9c0d-e1f2a3b4c5d6/actions \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{
    "action_type": "suspend_user",
    "endpoint": "https://api.datingframe.com/v2/users/{{user_id}}/suspend",
    "method": "POST",
    "headers": { "X-Service-Key": "{{service_key}}" },
    "payload_template": "{ \"reason\": \"{{reason}}\", \"duration\": \"{{duration}}\" }"
  }'

Example Response

{
  "id": "act_d1e2f3a4-b5c6-7d8e-9f0a-b1c2d3e4f5a6",
  "connector_id": "con_a1b2c3d4-e5f6-7a8b-9c0d-e1f2a3b4c5d6",
  "action_type": "suspend_user",
  "endpoint": "https://api.datingframe.com/v2/users/{{user_id}}/suspend",
  "method": "POST",
  "created_at": "2026-04-02T15:35:00.000Z"
}

Error Responses

StatusDescription
401Missing or invalid JWT.
404Connector not found.
400Invalid action configuration — missing endpoint or payload_template.

Knowledge Base

Manage knowledge base articles used by AI to generate accurate draft responses. Articles are embedded as vectors using pgvector for semantic search. Up to 5 relevant articles are injected into AI context per query.

GET/api/v1/knowledgeBearer JWT

List knowledge base articles for the current tenant.

Query Parameters

NameTypeRequiredDescription
categorystringoptionalFilter by category.
statusstringoptionalFilter by status: published, draft, archived.
cursorstringoptionalCursor for pagination.
limitnumberoptionalResults per page (1–100, default 25).

Example Request

curl https://api.supportos.io/api/v1/knowledge?status=published&limit=10 \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..."

Example Response

{
  "data": [
    {
      "id": "ka_b1c2d3e4-f5a6-7b8c-9d0e-f1a2b3c4d5e6",
      "title": "Community Guidelines — Harassment Policy",
      "category": "policies",
      "status": "published",
      "content_preview": "Our platform has a zero-tolerance policy for harassment...",
      "word_count": 1240,
      "embedding_status": "indexed",
      "last_used_at": "2026-04-02T14:35:12.000Z",
      "created_at": "2026-02-15T10:00:00.000Z",
      "updated_at": "2026-03-20T14:30:00.000Z"
    }
  ],
  "pagination": {
    "cursor": null,
    "has_more": false,
    "total": 1
  }
}

Error Responses

StatusDescription
401Missing or invalid JWT.
POST/api/v1/knowledgeBearer JWT

Create a new knowledge base article. The article is automatically embedded for semantic search after creation.

Body Parameters

NameTypeRequiredDescription
titlestringrequiredArticle title.
contentstringrequiredArticle content in plain text or Markdown.
categorystringrequiredArticle category (e.g. policies, procedures, faq).
tagsstring[]optionalTags for filtering and organisation.
statusstringoptionalInitial status: draft or published (default: draft).

Example Request

curl -X POST https://api.supportos.io/api/v1/knowledge \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Account Deletion Process",
    "content": "When a user requests account deletion, the following steps must be followed:\n\n1. Verify the user identity via email confirmation.\n2. Initiate a 30-day cooling-off period.\n3. After 30 days, permanently delete all personal data.\n4. Retain anonymised usage data for compliance purposes.",
    "category": "procedures",
    "tags": ["gdpr", "account", "deletion"],
    "status": "published"
  }'

Example Response

{
  "id": "ka_e5f6a7b8-c9d0-1e2f-3a4b-5c6d7e8f9a0b",
  "title": "Account Deletion Process",
  "category": "procedures",
  "status": "published",
  "tags": ["gdpr", "account", "deletion"],
  "word_count": 52,
  "embedding_status": "pending",
  "created_at": "2026-04-02T15:40:00.000Z"
}

Error Responses

StatusDescription
401Missing or invalid JWT.
400Missing required fields (title, content, or category).
POST/api/v1/knowledge/searchBearer JWT

Semantic search across knowledge base articles using pgvector. Returns the top matching articles ranked by relevance.

Body Parameters

NameTypeRequiredDescription
querystringrequiredNatural language search query.
limitnumberoptionalMax results to return (1–10, default 5).
categorystringoptionalRestrict search to a specific category.
thresholdnumberoptionalMinimum similarity score (0–1, default 0.5).

Example Request

curl -X POST https://api.supportos.io/api/v1/knowledge/search \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{
    "query": "What is our harassment policy?",
    "limit": 3
  }'

Example Response

{
  "results": [
    {
      "id": "ka_b1c2d3e4-f5a6-7b8c-9d0e-f1a2b3c4d5e6",
      "title": "Community Guidelines — Harassment Policy",
      "category": "policies",
      "content_preview": "Our platform has a zero-tolerance policy for harassment...",
      "similarity": 0.94,
      "word_count": 1240
    },
    {
      "id": "ka_c2d3e4f5-a6b7-8c9d-0e1f-a2b3c4d5e6f7",
      "title": "Escalation Procedures for Repeat Offenders",
      "category": "procedures",
      "content_preview": "When a user has multiple harassment reports...",
      "similarity": 0.78,
      "word_count": 890
    }
  ],
  "query_embedding_tokens": 12
}

Error Responses

StatusDescription
401Missing or invalid JWT.
400Missing search query.

Patterns

AI-detected patterns across tickets and safety cases. Patterns surface recurring issues, emerging threats, and anomalies that may require attention. Patterns can be confirmed or dismissed by operators.

GET/api/v1/patternsBearer JWT

List detected patterns for the current tenant.

Query Parameters

NameTypeRequiredDescription
statusstringoptionalFilter by status: detected, confirmed, dismissed.
severitystringoptionalFilter by severity: low, medium, high, critical.
cursorstringoptionalCursor for pagination.
limitnumberoptionalResults per page (1–100, default 25).

Example Request

curl https://api.supportos.io/api/v1/patterns?status=detected&severity=high \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..."

Example Response

{
  "data": [
    {
      "id": "pat_a1b2c3d4-e5f6-7a8b-9c0d-e1f2a3b4c5d6",
      "title": "Surge in harassment reports from London region",
      "description": "42% increase in harassment reports originating from users in the London area over the past 7 days, compared to the 30-day average.",
      "severity": "high",
      "status": "detected",
      "category": "harassment",
      "affected_tickets": 23,
      "confidence": 0.87,
      "detected_at": "2026-04-02T06:00:00.000Z",
      "time_range": {
        "from": "2026-03-26T00:00:00.000Z",
        "to": "2026-04-02T00:00:00.000Z"
      },
      "created_at": "2026-04-02T06:00:00.000Z"
    }
  ],
  "pagination": {
    "cursor": null,
    "has_more": false,
    "total": 1
  }
}

Error Responses

StatusDescription
401Missing or invalid JWT.
PATCH/api/v1/patterns/:id/reviewBearer JWT

Confirm or dismiss a detected pattern. Confirmed patterns remain visible and may trigger workflows. Dismissed patterns are hidden from the default view.

Path Parameters

NameTypeRequiredDescription
idstring (UUID)requiredPattern ID.

Body Parameters

NameTypeRequiredDescription
actionstringrequiredReview action: confirm or dismiss.
notesstringoptionalOptional notes about the review decision.

Example Request

curl -X PATCH https://api.supportos.io/api/v1/patterns/pat_a1b2c3d4-e5f6-7a8b-9c0d-e1f2a3b4c5d6/review \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{
    "action": "confirm",
    "notes": "Correlates with a viral social media post targeting our users. Increasing moderation capacity."
  }'

Example Response

{
  "id": "pat_a1b2c3d4-e5f6-7a8b-9c0d-e1f2a3b4c5d6",
  "status": "confirmed",
  "reviewed_by": "usr_c4d5e6f7-a8b9-0c1d-2e3f-4a5b6c7d8e9f",
  "reviewed_at": "2026-04-02T15:50:00.000Z",
  "notes": "Correlates with a viral social media post targeting our users. Increasing moderation capacity."
}

Error Responses

StatusDescription
401Missing or invalid JWT.
404Pattern not found.
400Invalid action — must be 'confirm' or 'dismiss'.

User Reports

Public-facing endpoint for the user reporting widget. Allows end-users of tenant platforms to submit reports directly. Authenticated via the widget embed token, not a user JWT.

POST/api/v1/reportsWidget Embed Token (X-Widget-Token header)

Submit a user report from the embedded reporting widget. Creates a ticket in the tenant's queue. No user authentication required — the widget embed token identifies the tenant.

Body Parameters

NameTypeRequiredDescription
reporter_idstringoptionalExternal user ID of the reporter (optional — anonymous reports supported).
reported_user_idstringoptionalExternal user ID of the reported user (if applicable).
categorystringrequiredReport category: harassment, inappropriate_content, spam, scam, underage, csea_concern, self_harm, other.
descriptionstringrequiredFree-text description of the report.
content_idsstring[]optionalIDs of content items on the tenant platform related to this report.
metadataobjectoptionalAdditional metadata from the tenant platform (e.g. page URL, session info).

Example Request

curl -X POST https://api.supportos.io/api/v1/reports \
  -H "Content-Type: application/json" \
  -H "X-Widget-Token: wgt_a1b2c3d4e5f6g7h8i9j0" \
  -d '{
    "reporter_id": "usr_a1b2c3d4",
    "reported_user_id": "usr_e5f6g7h8",
    "category": "harassment",
    "description": "This user has been sending threatening messages repeatedly after I asked them to stop.",
    "content_ids": ["msg_x1y2z3", "msg_a4b5c6"],
    "metadata": {
      "page_url": "https://datingframe.com/messages/usr_e5f6g7h8",
      "platform": "ios_app"
    }
  }'

Example Response

{
  "id": "rpt_a1b2c3d4-e5f6-7a8b-9c0d-e1f2a3b4c5d6",
  "ticket_id": "tkt_f1e2d3c4-b5a6-7c8d-9e0f-a1b2c3d4e5f6",
  "status": "received",
  "message": "Thank you for your report. Our team will review it shortly.",
  "created_at": "2026-04-02T16:00:00.000Z"
}

Error Responses

StatusDescription
400Missing required fields (category or description).
401Missing or invalid widget embed token.
429Rate limit exceeded — max 10 reports per minute per IP.