Checkstep Docs API integration Developer Documentation API Integration Guide Connect your platform to Checkstep - send content for analysis, receive moderation decisions via webhooks, and integrate transparency flows for your users.
Overview
Integrating with Checkstep involves three steps: send your content via API, receive decisions via webhooks, and optionally redirect users to Checkstep's transparency portal for removal notifications and appeals.
Authentication
The Checkstep API uses API keys with Bearer authentication over HTTPS.
View and manage your API keys in the Checkstep settings page for each provisioned platform. All requests must include the authorization header:
Authorization: Bearer ${CHECKSTEP_API_KEY} All API requests must be made over HTTPS - plain HTTP calls will fail. Keep your API keys secure and never share them publicly.
Key rotation
You can create a new API key with a later expiration using an existing key via the management endpoint . New keys may take up to one minute to become active across all APIs. Store new keys with a started_at field set to now + 1 minute and always pick the latest one matching started_at .
Structuring your content
Content in Checkstep is flexible - it can combine text, image, audio, and video fields to match your platform's data model. Each piece of content is identified by its type and a unique ID.
Complex types
Checkstep provides standard complex types: profile , post , comment , thread , chat , channel , product , review , reply , and fragment variants. You can also request custom types from the solutions team.
Choose your complex type based on your moderation lifecycle. If you enforce a post as a whole (removing the entire thing when one part violates), send it as a single post . If you enforce parts independently (removing an attachment but keeping the post), send attachments as post-fragment with a parent relationship.
Content fields
Each piece of content contains fields with a unique ID and a simple type ( text , image , audio , video , uri , file ). Fields can be nested - for example, an image gallery where each image has a text caption.
Relationships
Link content with parent-child relationships by including the parent's type and ID in your ingestion request. Relationships are visible in the moderation UI - when reviewing content, the parent and nearby siblings are displayed for context.
Authors
Always designate the author of content with a unique ID from your platform. This enables Checkstep to build author profiles, track repeated offences, and take action directly against users rather than just individual pieces of content.
Example: a user profile
{ "id": "009d8aa9-7d25-44ed-bbf5-8410528f96e1", "author": "82a277f5-4714-4a09-bdb1-6b8726418ad8", "type": "profile", "fields": [ { "id": "name", "type": "text", "src": "John Doe" }, { "id": "bio", "type": "text", "src": "Hello I am John" } ] } Asynchronous ingestion The recommended approach. Send content for analysis and receive results via webhook when processing is complete. You can generate a cURL snippet from the Checkstep UI .
See the full OpenAPI specification for all available fields.
Partial updates
You can send partial content when a field gets updated - just submit the changed fields. Content is aggregated by complex type + content ID. Fields and metadata merge based on their unique id ; you don't need to repeat fields like author .
To discard all previously submitted fields, use the reset_fields and reset_metadata flags.
Parent relationships
Express parent-child relationships by including a parent object with the parent's type and ID:
{ "id": "009d8aa9", "type": "comment", "fields": [ { "id": "body", "type": "text", "src": "Aha true, I never thought about that" } ], "parent": { "type": "thread", "id": "26c1bce6" } } Nested fields Group related fields using nesting - for example, an image with a caption:
{ "id": "009d8aa9", "type": "gallery", "fields": [ { "id": "image_1", "type": "image", "src": "https://example.com/photo.jpg", "fields": [ { "id": "caption", "type": "text", "src": "Nice view on the lake!" } ] } ] } External evaluations If you have your own classification or scoring, you can send evaluations alongside content. These appear in content cases, show in analytics widgets, and can be used in policy rules. Requires an external strategy configured on your account.
"evaluations": [ { "label": "similar", "field": "name", "score": 0.9, "strategy": "external-multilabels" } ] Metadata Attach additional information for moderators using metadata - key-value pairs like user plan, region, or account age. Metadata can be attached to the whole content or to specific fields. Metadata is forwarded back in webhook payloads, making it useful for passing internal identifiers through the pipeline.
Tags
Tag content for queue classification or search. Tags must start with # :
"tags": ["#featured", "#popular"] Bulk ingestion Send multiple pieces of content in a single request. Useful for bootstrapping your account with existing content, scanning for violations, and avoiding the round-trips of one-by-one ingestion.
Wrap your content array in a bulk payload with a unique bulk ID. Each item follows the same structure as async ingestion. See the OpenAPI specification .
{ "bulk": "2dd1fca2-e303-40de-9172-a7b710b64f99", "contents": [ { "id": "520f3f31", "author": "Hollis", "type": "post", "fields": [{ "id": "message", "type": "text", "src": "First post content" }] }, { "id": "75c3f62f", "author": "Marianna", "type": "post", "fields": [{ "id": "message", "type": "text", "src": "Second post content" }] } ] } Synchronous ingestion For real-time proactive moderation - send content and get policy violations back in the response. Essential for live chat where you need to block harmful content before other users see it.
See the OpenAPI specification for details.
```
analysed-content
```
Response with no violations:
{ "id": "34a8f82bbb", "author": "4c0789faff", "type": "chat", "violations": [] } Response with violations:
{ "id": "34a8f82bbb", "author": "4c0789faff", "type": "chat", "violations": [ { "policy": "VLC", "confidence": "check", "severity": "medium" }, { "policy": "HTE", "confidence": "trust", "severity": "low" } ] } Analysing with context For chat scenarios, enable contextual analysis by including context=true as a query parameter. You must also set parent and author . Content will be analysed alongside preceding messages with the same parent - preventing false positives where a message looks innocent alone but is harmful in context.
```
context=true
```
Access delegation
Checkstep needs access to your media assets (images, audio, video) for analysis and moderator review. Three options are available depending on your storage infrastructure.
AWS S3
Configure an IAM role with read access to your bucket and allow Checkstep to assume the role. Checkstep generates pre-signed URLs whenever access is needed. Enable S3 versioning to decouple asset hosting. Contact support with your bucket name, region, and role ARN.
Google Cloud Storage
Set up a Workload Identity Federation Pool with an AWS provider and grant a service account Storage Object Viewer access to your bucket. Contact support with the audience from your client library config and your bucket name.
Private token
For storage systems that support token-based access, Checkstep can include an Authorization: Bearer header when accessing your URLs. Contact support with your token and storage domain.
Webhooks
Webhooks notify your platform when events happen in Checkstep - content analysed, moderation decisions taken, incidents closed. Configure your webhook endpoint in the Checkstep settings.
All webhooks are JSON payloads with a timestamp and webhook_type . The type is also available as an HTTP header ( X-Webhook-Type ) for routing without parsing the body.
Webhook types
decision
Raised when a moderator or ModBot takes action on content. Check the decision field: act (take down), overturn (restore), uphold (keep down after appeal), dismiss (no violation), or escalate . Use content.type and content.id to identify the content to act on.
author-decision
Raised when a moderator takes action on an author. Check decision : act (suspend/terminate and remove content), hold (suspend/terminate but keep content), overturn (restore account). Use author to identify the account.
incident-closed
Raised when an incident is fully resolved - slightly delayed after the decision. Use this for user notifications. Check resolution : enforced , dismissed , overturned , upheld , or terminated . The reporters array lists users who filed community reports.
analysed-content
Raised shortly after content is ingested and scanned. Provides early insights into potential violations before a final decision. Use this for pre-publication holds - if violations are detected, hold the content until a decision webhook arrives.
Error handling and retries
Checkstep considers a webhook successful on any 2xx response. On 4xx or 5xx , the webhook retries a few minutes later, up to three attempts. Contact support if your system is down for an extended period to request additional retries.
Payload signing
Optionally verify webhook authenticity using HMAC signatures. When enabled, webhooks include x-auth-signature , x-auth-date , and x-auth-nonce headers. Compute the signature by hashing the body + date + nonce with SHA-256, then HMAC the hash with your signing key. During key rotation, two signatures are included for 24 hours.
Amazon SQS
All webhook events can also be delivered to an Amazon SQS queue as messages with the same payloads. Configure by providing your queue URL and role ARN. The webhook type is available in message attributes as X-Webhook-Type .
Transparency
When content is removed, regulations require that users are informed and given the right to appeal. Checkstep provides a hosted Transparency Portal and redirect endpoints to handle this flow.
Statement of reason and appeal
When an author's content is enforced, present them a "View more" or "More info" link. On click, call the redirect endpoint to get a unique authenticated URL, then redirect the user to the Transparency Portal. The portal shows the removed content, the violated policy, and an appeal form.
Community reports
Let users report content by calling the report redirect endpoint to get a link to the reporting form. You can prefill the reporter's email using the reporter query parameter.
Custom domain and translations
By default the portal is hosted under checkstep.com. Contact support to set up a custom domain. Add the lang query parameter to display the portal in a supported language: cz , de , dk , en , es , fr , hu , it , jp , se . Policy names and descriptions also display in translated form if translations are configured.
Headless integration
If you want to build your own UI for community reports, statements of reason, appeals, and moderation decisions - instead of using Checkstep's hosted flows - use these endpoints.
Community reports
Receive reports from community members via the report endpoint . Provide the content's type and ID, a reporter identifier, the reason, and potential policy violations. If the content was previously ingested, the report is associated with it automatically.
{ "id": "3e5cb4b2", "type": "post", "reporter": "john@doe.com", "reason": "Remove this hateful post please!", "potential_violations": [{ "policy": "HTE" }] } Statement of reason Call the case endpoint to get the current status of a content case. Statuses progress through: no-incident → enforced (with statement of reason) → appealed (pending review) → appeal-ruled (with ruling).
Appeals
Submit an appeal via the appeal endpoint with the content's type, ID, author, and the user's statement. Returns a 202 Accepted.
External decisions
If you make moderation decisions outside Checkstep, send them back to maintain transparency records. Supported decisions for content: act , dismiss , escalate , overturn , uphold . For authors: act , overturn , escalate , hold .
Inquiries
Open a new incident on content manually by creating an inquiry - useful when you want moderators to review content that wasn't flagged by automation.
Quick reference
Key endpoints and patterns at a glance.
```
/content
```
```
/content/bulk
```
```
/content/sync
```
```
/content/report
```
```
/content/appeal
```
```
/review/cases
```
```
/review/cases/decisions
```
```
/review/authors/decisions
```
```
/review/cases/inquiries
```
```
/review/redirect/my-case
```
```
/review/redirect/report
```
```
/api-keys
```
All endpoints are under https://api.checkstep.com/api/v2 . For full request/response schemas, see the interactive OpenAPI documentation ↗ .
