Skip to main content
Documentation
Learning Center

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

Quick Links

Authentication and API Keys

The Discuse API authenticates every request with an API key. Send it in the X-API-Key request header (or as an api_key field in the JSON body). Keys begin with the disc_ prefix, are tied to a single project, and are shown in full only once at creation. This guide covers how to obtain, use, secure, and rotate them.

How does Discuse authentication work?

Every API call must include a valid API key. Discuse uses it to:

  • Track usage against your project's quota
  • Apply per-key rate limiting to prevent abuse
  • Tie requests to the right project and its settings
  • Control access to your account's resources

Obtaining Your API Key

Step 1: Create an Account

If you haven't already, sign up for a Discuse account at discuse.com. You can start on the free Basic plan, which includes a monthly allowance of API requests plus access to text, spam, language, and image checks. See the pricing page for the current per-plan limits.

Step 2: Access the Dashboard

After logging in, navigate to your dashboard. Look for the "API Keys" or "Developer" section in the navigation menu.

Step 3: Generate a New Key

Click "Create New API Key" and optionally provide a name or description for the key. This helps you identify the purpose of each key if you create multiple ones.

Your new API key will be displayed only once. Copy it immediately and store it securely - you won't be able to view the full key again.

Using Your API Key

Include your API key in the X-API-Key header of every request:

curl -X POST https://api.discuse.com/api/v2/check \
  -H "Content-Type: application/json" \
  -H "X-API-Key: disc_aB3dEf6GhIjKlMnOpQrStUvWxYz012345" \
  -d '{
    "content": {
      "text": "Content to analyze"
    }
  }'

You can alternatively pass the key as an api_key field inside the JSON body instead of the header — the header is preferred so the key never lands in request-body logs.

JavaScript Example

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: { text: 'Content to analyze' }
  })
});

Python Example

import requests
import os

response = requests.post(
    'https://api.discuse.com/api/v2/check',
    headers={
        'Content-Type': 'application/json',
        'X-API-Key': os.environ['DISCUSE_API_KEY']
    },
    json={
        'content': {'text': 'Content to analyze'}
    }
)

API Key Security Best Practices

Never Expose Keys in Client-Side Code

API keys should never be included in JavaScript that runs in the browser. Client-side code is visible to anyone who views your page source.

// WRONG - Don't do this!
const API_KEY = 'disc_aB3dEf6...'; // Exposed in browser

// CORRECT - Use a backend proxy
const response = await fetch('/api/moderate', {
  method: 'POST',
  body: JSON.stringify({ text: userInput })
});

Use Environment Variables

Store API keys in environment variables, not in your codebase:

# .env file (add to .gitignore!)
DISCUSE_API_KEY=disc_aB3dEf6GhIjKlMnOpQrStUvWxYz012345
// Access in Node.js
const apiKey = process.env.DISCUSE_API_KEY;

Rotate Keys Regularly

Periodically rotate your API keys, especially if you suspect they may have been compromised:

  1. Generate a new API key
  2. Update your application to use the new key
  3. Verify everything works correctly
  4. Revoke the old key

Note: a revoked key can stay usable for up to about 5 minutes because validated keys are cached. Plan rotations with that short overlap in mind rather than expecting instant cutover.

Use Separate Keys for Different Environments

Create different API keys for development, staging, and production:

Environment Key Purpose
Development Testing and local development
Staging Pre-production testing
Production Live application traffic

This allows you to revoke a compromised key without affecting other environments.

How does rate limiting work?

Rate limiting is per API key, not per plan. Each key has a requests-per-minute (RPM) limit set when the key is created; if you don't specify one, it defaults to 60 requests per minute. Different keys on the same account can carry different limits, so you can give a high-throughput service a higher RPM than a one-off integration.

When a key exceeds its RPM limit, the request fails with an HTTP 429 Too Many Requests status whose message states that the rate limit was exceeded. Rate-limit counters reset on a rolling one-minute window.

Handling rate limits

Back off and retry on a 429 (and on transient 5xx). Because the window is one minute, exponential backoff that starts around a second and grows works well:

async function checkWithRetry(content, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    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 })
    });

    if (response.status === 429 || response.status >= 500) {
      const delay = 1000 * Math.pow(2, attempt); // 1s, 2s, 4s
      await new Promise(resolve => setTimeout(resolve, delay));
      continue;
    }

    return response.json();
  }
  throw new Error('Max retries exceeded');
}

What error responses can I get?

Situation HTTP status
Malformed request (empty content, text over 10,000 chars, too many URLs) 400 request validation
Missing or invalid API key 401
Rate limit exceeded for the key 429
Billing-period quota exhausted 200 with a message and usage (not an error status)

Quota exhaustion is intentionally not an HTTP error: the /api/v2/check response still returns 200 with has_violations: false, a message describing the exhausted quota, and a usage object showing api_requests_remaining: 0. Inspect those fields rather than relying on a status code. Authentication failures return 401, rate limits 429, and request-validation failures 400. See the Error and Response Codes reference for the full list.

Managing Multiple Keys

For larger teams or complex applications, you may need multiple API keys:

Use Cases for Multiple Keys

  1. Per-environment keys: Separate keys for dev, staging, and production
  2. Per-service keys: Different keys for different microservices
  3. Per-team keys: Isolate usage by team for internal billing
  4. Temporary keys: Short-lived keys for contractors or integrations

Key Management Best Practices

  • Name keys descriptively: "Production - User Service", "Staging - Backend"
  • Document key usage: Maintain records of which key is used where
  • Set up alerts: Monitor for unusual usage patterns
  • Regular audits: Review and clean up unused keys quarterly

Next Steps

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

Error and Response Codes

HTTP statuses, the quota-exhausted 200 response, and how to handle API errors correctly