API Reference

Complete reference for the Filtyr API endpoints.

Data Ingestion

POST
/data/{organizationId}/{dataSourceId}
Submit content for moderation. The content will be processed according to your data source settings and assigned agents. You can find your data source URL in the Data Sources settings page.

Path Parameters

organizationIdYour organization ID
dataSourceIdThe ID of the data source

Request Body

1{
2 "data": {
3 // Your content to be moderated
4 // Structure depends on your data source configuration
5 },
6 "idempotencyKey": "optional-unique-key" // Optional
7}

Response Codes

202
Content accepted for processing
400
Bad request - The request body is invalid
401
Unauthorized - Invalid API key
402
Payment Required - No active plan or insufficient credits
404
Not Found - Data source not found or inactive
500
Internal Server Error

Example Requests

cURL
1curl -X POST https://filtyr.ai/api/data/123e4567-e89b-12d3-a456-426614174000/987fcdeb-51a2-43c7-9876-543210fedcba \
2 -H "Authorization: Bearer your-api-key" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "data": {
6 "content": "Hello, world!",
7 "metadata": {
8 "source": "chat",
9 "userId": "user123"
10 }
11 },
12 "idempotencyKey": "unique-request-id-123"
13 }'
Node.js
1const response = await fetch('https://filtyr.ai/api/data/123e4567-e89b-12d3-a456-426614174000/987fcdeb-51a2-43c7-9876-543210fedcba', {
2 method: 'POST',
3 headers: {
4 'Authorization': 'Bearer your-api-key',
5 'Content-Type': 'application/json',
6 },
7 body: JSON.stringify({
8 data: {
9 content: 'Hello, world!',
10 metadata: {
11 source: 'chat',
12 userId: 'user123'
13 }
14 },
15 idempotencyKey: 'unique-request-id-123'
16 })
17});
18
19const result = await response.json();
20// result: { status: 'accepted' }

Example Response (202 Accepted)

1{
2 "status": "accepted"
3}

Webhooks

POST
Webhook Deliveries
Webhook deliveries are sent to your configured endpoints when moderation decisions are made. Configure webhooks in the Agents dashboard under the Webhooks tab.

Request Headers

X-Filtyr-SecretThe webhook secret assigned to your webhook
X-Filtyr-TimestampISO 8601 timestamp of when the request was sent
User-AgentFiltyr-Webhook/1.0

Request Body

1{
2 "event_id": "evt_123abc", // Unique identifier for the moderation event
3 "agent_id": "agt_456def", // ID of the agent that performed the moderation
4 "data_source_id": "ds_789ghi", // ID of the data source that provided the content
5 "decision": {
6 "status": "approved", // The moderation decision status
7 "explanation": "Content meets community guidelines" // Detailed explanation
8 },
9 "data": {
10 // The original content that was moderated
11 "content": "Hello, world!",
12 "metadata": {
13 "source": "chat",
14 "userId": "user123"
15 }
16 },
17 "created_at": "2024-03-20T12:34:56Z", // ISO 8601 timestamp
18 "organization_id": "org_abc123", // Your organization's ID
19 "processing_type": "fast" // "fast" or "slow"
20}

Expected Response

Your webhook endpoint should return a 2xx status code to acknowledge receipt. We recommend responding quickly to prevent timeouts.

2xx
Success - Webhook received and processed
Other
Failed delivery - Will be logged and may be retried

Example Implementation

Node.js (Express)
1const express = require('express');
2const app = express();
3
4app.post('/webhook', express.json(), (req, res) => {
5 // 1. Verify the webhook secret
6 const secret = req.headers['x-filtyr-secret'];
7 if (secret !== process.env.WEBHOOK_SECRET) {
8 return res.status(401).json({ error: 'Invalid secret' });
9 }
10
11 // 2. Process the webhook payload
12 const { event_id, decision, data, processing_type } = req.body;
13
14 // 3. Implement idempotency using event_id
15 if (await hasProcessedEvent(event_id)) {
16 return res.status(200).json({ status: 'already_processed' });
17 }
18
19 // 4. Handle the moderation decision
20 await handleModerationDecision({
21 eventId: event_id,
22 decision,
23 content: data,
24 processingType: processing_type
25 });
26
27 // 5. Respond quickly to acknowledge receipt
28 res.status(200).json({ received: true });
29});

Best Practices

  • Implement idempotency using the event_id to prevent duplicate processing
  • Respond to webhooks quickly (within seconds) to prevent timeouts
  • Always validate the webhook secret in the X-Filtyr-Secret header
  • Store the webhook secret securely (e.g., in environment variables)
  • Implement proper error handling and logging for debugging
  • Consider using a queue for processing webhook payloads asynchronously