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:
- Generate a new API key
- Update your application to use the new key
- Verify everything works correctly
- 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
- Per-environment keys: Separate keys for dev, staging, and production
- Per-service keys: Different keys for different microservices
- Per-team keys: Isolate usage by team for internal billing
- 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
- Quick Start Guide - Make your first API call
- Text Analysis - Learn about sentiment detection
- Scaling Content Moderation - High-volume implementation patterns