Skip to main content
Documentation
Learning Center

Master content moderation with comprehensive guides, tutorials, and API documentation

Quick Links

Error and Response Codes

The Discuse API signals problems in two ways: an HTTP error status with a message, or a normal 200 response whose fields tell you what happened. This page lists every case so you can handle them correctly — and explains the one that trips people up: a billing-quota exhaustion is not an HTTP error.

What HTTP statuses does the API return?

Status When What to do
200 Success — including the "quota exhausted" case Inspect the response body; a 200 is not always a green light (see below)
400 Request validation failed — empty content, text over 10,000 characters, or too many media URLs Fix the request; do not retry unchanged
401 Missing or invalid API key Check the X-API-Key header; do not retry unchanged
429 Rate limit exceeded for the key Back off and retry after the one-minute window
500 A downstream/internal error Retry with backoff

Read the message on any non-2xx response. Authentication failures return 401, rate-limit failures return 429, and request-validation failures return 400; treat 5xx as transient and retry with backoff.

Why is "quota exhausted" a 200, not an error?

When a project uses up its monthly API-request allowance, POST /api/v2/check still returns 200 — with the content treated as having no violations, a message explaining the quota is exhausted, and a usage object showing zero remaining:

{
  "has_violations": false,
  "message": "API quota exceeded. Current: 10000, Limit: 10000",
  "usage": {
    "api_requests_used": 10000,
    "api_requests_limit": 10000,
    "api_requests_remaining": 0
  }
}

This is deliberate: a quota run-out should not look like a server failure or block your pipeline with an exception. Check usage.api_requests_remaining (and the message) instead of relying on the status code. If you fail open on a 200, an exhausted quota would silently let content through unchecked — so branch on these fields explicitly.

How should I read a successful response?

A 200 from /api/v2/check always carries has_violations and cached; the rest is optional:

Field Type Meaning
has_violations boolean True if any enabled check flagged the content
cached boolean True if served from a recent identical-request cache
message string Present on quota exhaustion (and similar non-error notices)
request_id string Echoed back if you sent one
processing_time_ms number Present when timing is enabled for the project
usage object api_requests_used, api_requests_limit, api_requests_remaining
results object Per-check detail (spamfinder, sentiment, images, …) and the top-level hits flag

Decide on has_violations for the overall verdict, then drill into results.<check>.hit for which check fired.

How does caching affect responses?

Identical requests for the same project are de-duplicated: a repeat returns cached: true with the same result. Caching is per project. Note that a cached request still counts against your API-request quota — it saves processing time, not quota.

You can attach a request_id to a request for your own correlation; it is echoed back in the response.

A minimal, correct client

async function check(content, settings) {
  const response = await fetch('https://api.discuse.com/api/v2/check', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-API-Key': process.env.DISCUSE_API_KEY
    },
    body: JSON.stringify({ content, settings })
  });

  // 400: bad request — fix it, don't retry. 5xx: transient/auth/rate-limit — retry with backoff.
  if (response.status === 400) {
    throw new Error('Invalid request: ' + (await response.text()));
  }
  if (!response.ok) {
    throw new Error(`Discuse error ${response.status}`); // retry upstream with backoff
  }

  const data = await response.json();

  // Quota exhausted is a 200 — never treat it as "checked and clean".
  if (data.usage && data.usage.api_requests_remaining === 0 && data.message) {
    throw new Error('Quota exhausted: ' + data.message);
  }

  return data; // inspect data.has_violations and data.results
}

Related

Written by the Discuse Team · Last updated June 2026

Related Articles

What is Content Moderation?

Understanding content moderation fundamentals and why it matters for your platform

Quick Start Guide

Get up and running with the Discuse API in under 5 minutes

Authentication and API Keys

How to authenticate requests and manage your API keys securely