Combined Multi-Check Requests
You don't need one API call per check. A single POST /api/v2/check can run text, image, badword, and antivirus checks together over mixed content, and return one response with a result for each. This is the most efficient way to moderate a post that has a caption, an image, and an attachment all at once.
Why moderate everything in one call?
A user submission is usually a bundle: text plus media plus links. Calling the API separately for each part means more round trips, more latency, and more quota spent. One combined request runs the enabled checks in parallel and gives you a single verdict to act on.
How do I run several checks at once?
Put each kind of content in content, enable the checks you want in settings, and read the per-check results. Each enabled check runs against the matching content.
curl -X POST https://api.discuse.com/api/v2/check \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{
"content": {
"text": "Great deal, check my profile!",
"image_urls": ["https://example.com/post-image.jpg"],
"document_urls": ["https://example.com/attachment.pdf"]
},
"settings": {
"check_spam": true,
"check_sentiment": true,
"check_images": true,
"check_antivirus": true
}
}'
Response
{
"has_violations": true,
"cached": false,
"results": {
"hits": true,
"spamfinder": { "label": "spam", "confidence": 0.91, "is_spam": true, "hit": true },
"sentiment": { "is_negative": false, "is_toxic": false, "score": 0.1, "hit": false },
"images": { "status": "OK", "porn": 0.02, "sexual": 0.05, "neutral": 0.93, "hit": false },
"antivirus": { "status": "OK", "hit": false, "details": [] }
},
"usage": {
"api_requests_used": 530,
"api_requests_limit": 10000,
"api_requests_remaining": 9470
}
}
How do I read the combined result?
Use has_violations for the overall decision, then look at each results.<check>.hit to see which check fired and why:
| Field | Meaning |
|---|---|
has_violations |
True if any enabled check flagged the content — your one-line verdict |
results.hits |
The same overall signal inside the results object |
results.spamfinder.hit |
Spam fired (threshold-aware; gate on hit, not raw is_spam) |
results.sentiment.hit |
Toxic/negative sentiment over your thresholds |
results.images.hit |
An image was over your NSFW threshold |
results.antivirus.hit |
Malware found in a document |
results.badwords.hit |
A configured badword matched |
results.skipped_features |
Checks that were requested but not run (e.g. a feature whose quota is exhausted) |
Only the checks you enabled (and that had matching content) appear in results. A check with no content to act on — check_images with no image_urls — simply doesn't run.
Which content pairs with which check?
| Check | Content it reads |
|---|---|
check_sentiment, check_spam, check_badwords, check_language |
content.text |
check_images |
content.image_urls |
check_antivirus |
content.document_urls |
A single request can carry up to 10 image URLs, 5 document URLs, and text up to 10,000 characters. Send a submission's parts together rather than splitting them across calls.
What about partial failures?
If one check errors (say an image URL is unreachable) the others still return — you get the results that succeeded, and the failed check reports its error/empty result rather than failing the whole request. Decide per check: block on a confirmed hit, and choose whether an errored check should fail open or queue for review.
Best practices
Enable only what you need
Each enabled check adds work. Turn on the checks that match the content you actually receive — there's no benefit to running check_antivirus on text-only messages.
One verdict, then drill down
Branch on has_violations first for the fast path, then inspect results only when you need to know which check fired (for logging, appeals, or routing to the right reviewer).
const res = await check(content, settings);
if (!res.has_violations) return allow();
const r = res.results;
if (r.antivirus?.hit) return quarantine(); // most severe first
if (r.images?.hit) return blockMedia();
if (r.spamfinder?.hit || r.badwords?.hit) return shadowban();
return queueForReview(r);
Related
- Text Analysis — sentiment, spam, and the text result fields
- Image NSFW Detection — image scoring and thresholds
- File Antivirus Scanning — document malware checks
- Error and Response Codes — the response envelope and quota handling