praetoid
Get Started

API Quickstart

First moderation in minutes.

This guide walks you through your first moderation request. You will create a checkout session, submit content, and get a moderation case back. The whole flow takes three API calls.

Your Praetoid account comes with everything you need out of the box: a default Praetor, a development environment, and a sandbox API key. Find your API key in Settings > API Keys. It starts with sk_test_.

Install the SDK

npm install @praetoid/node
# mix.exs
defp deps do
  [{:praetoid_client, "~> 0.0.2"}]
end

No installation needed. All examples use curl.

Create a Checkout

A checkout is a short-lived session that authorizes content submission. Your server creates it using your API key and gets back a signed URL containing a JWT token. Your client uses that URL to submit content directly. The API key never leaves your server.

import { Praetoid } from '@praetoid/node'

const praetoid = new Praetoid('sk_test_your_api_key')
const praetor = praetoid.praetor('default')

const checkout = await praetor.checkouts.create({
  client_id: 'user_123'
})
client = Praetoid.Client.new!(
  api_key: "sk_test_your_api_key",
  praetor: "default"
)

{:ok, checkout} = Praetoid.Checkouts.create(client,
  client_id: "user_123"
)
curl -X POST https://api.praetoid.com/api/checkouts \
  -H "Authorization: Bearer sk_test_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "praetor": "default",
    "client_id": "user_123"
  }'

The response includes a signed_url and a token that you will use to submit content.

{
  "checkout_id": "ch_abc123",
  "token": "eyJhbG...",
  "signed_url": "https://api.praetoid.com/api/checkouts/eyJhbG...",
  "expires_in": 900,
  "expires_at": "2026-04-09T12:30:00Z",
  "status": "open"
}

Checkouts expire after 15 minutes by default. You can set expires_in between 300 and 3600 seconds.

Submit Content

Use the token from the previous step to submit content for moderation. Send text, images, or both. Each checkout accepts exactly one submission. Once content is submitted, the checkout closes.

Sync vs Async

Pass sync: true to wait for the moderation result before the response returns (up to 60 seconds). Without it, the response returns immediately and results are delivered through webhooks.

const result = await praetor.checkouts.submit(checkout.token, {
  input: [
    { type: 'text', text: 'This is a message to moderate' }
  ]
})
{:ok, result} = Praetoid.Checkouts.submit(client, checkout.token,
  texts: ["This is a message to moderate"],
  sync: true
)
curl -X POST "https://api.praetoid.com/api/checkouts/eyJhbG...?sync=true" \
  -F "texts[]=This is a message to moderate"

The response confirms the submission and returns the created case.

{
  "checkout_id": "ch_abc123",
  "checkout_status": "closed",
  "case_id": "case_def456",
  "case_status": "completed",
  "case_items": [
    {
      "id": "ci_ghi789",
      "case_id": "case_def456",
      "type": "text",
      "path": "texts/0.txt",
      "inserted_at": "2026-04-09T12:15:30Z"
    }
  ],
  "submitted_at": "2026-04-09T12:15:30Z"
}

Check the Result

When case_status returns "completed", your content has been evaluated against every policy in your Praetor. The case_id is your handle for this moderation decision. Use it to look up the full verdict, including which policies were violated, which content items triggered them, and what enforcement actions were produced.

You can inspect the case in your Praetoid dashboard under Cases, or retrieve it programmatically through the API.

What Happens Next

Behind the scenes, Praetoid runs a trial against your case. Each content item is evaluated against the policies in your Praetor. When violations are found, enforcement actions are collected into a sentence that you can review, approve, or override.

On this page