API reference
One endpoint. Send text, get back IHRA-grounded antisemitism, anti-Israel bias, and context-omission signals with per-snippet attribution.
Base URL
https://magendetect.com
Authentication
Every request must include an x-api-key header. Create and rotate keys at /dashboard/api-keys after signing in.
x-api-key: mk_live_...
POST /v1/detect
Score a single piece of content. Synchronous — returns the full pipeline result.
Request body
| field | type | required | description |
|---|---|---|---|
content | string | yes | The text to analyze. Max 50,000 characters. |
title | string | no | Article title. Improves triage accuracy. |
source | string | no | Publisher name. Activates the trusted-source rule when applicable. |
language | string | no | ISO code, e.g. en or he. Defaults to en. |
content_type | string | no | Defaults to article. Free-form tag preserved in the audit record. |
metadata | object | no | Arbitrary JSON persisted alongside the detection. |
Example request
curl -X POST https://magendetect.com/v1/detect \
-H "x-api-key: mk_live_..." \
-H "Content-Type: application/json" \
-d '{"title": "...", "source": "...", "content": "..."}' Response
| field | type | description |
|---|---|---|
id | string | Unique detection ID (det_...). |
status | string | clear, review, or flagged. |
scores | object | Per-category max confidence. |
detections | array | One entry per piece of evidence. See detection object below. |
triage | object | Stage 1 triage: whether content needed deep analysis. |
verification | object | Stage 3: accepted vs rejected signal count. |
calibration | object | Stage 4: signal counts + review_decision. |
compliance | object | DSA Article 34/15 flags. |
processing_ms | number | Wall-clock pipeline time. |
audit_id | string | Link to the persisted audit record. |
Detection object
| field | type | description |
|---|---|---|
category | string | antisemitism, anti_israel_bias, or context_omission. |
subcategory | string | Signal type, e.g. classic_trope_conspiracy_control. |
confidence | number | 0.0–1.0, after calibration. |
severity | string | low, medium, high. |
attribution | string | publisher_voice (1.0×), quote (0.6×), rebuttal (0.15×), unclear (0.5×). |
dog_whistle_hit | bool | True if pre-scanner flagged this text. |
flagged_segments | array | Character offsets into original content. |
definition | object | Framework, reference (e.g. IHRA-7), description. |
rationale | string | Model's explanation. |
recommended_action | string | block_or_review or editorial_review. |
Example response
{
"id": "det_8f3a1c44",
"status": "review",
"processing_ms": 5439,
"scores": { "antisemitism": 1.0, "anti_israel_bias": 0.05 },
"detections": [{
"category": "antisemitism",
"subcategory": "classic_trope_conspiracy_control",
"confidence": 1.0,
"severity": "high",
"attribution": "publisher_voice",
"dog_whistle_hit": true,
"definition": { "framework": "IHRA", "reference": "IHRA-7" },
"rationale": "Classic antisemitic tropes about Jewish control."
}],
"calibration": { "review_decision": "human_review" }
}Status legend
| status | review_decision | meaning |
|---|---|---|
clear | auto_accept | No actionable signals found. |
review | human_review | Signals present but ambiguous. Attribution may soften a strong signal. |
flagged | auto_reject | High-severity signal above threshold. Recommend review before publishing. |
Rate limits
Each key has a monthly quota (default 10,000 for Starter). Resets automatically on the first of each month, UTC.
When you hit the limit the API returns 429 rate_limit_exceeded.
Every authenticated response includes three headers:
| header | value |
|---|---|
X-RateLimit-Limit | Your quota for the current period. |
X-RateLimit-Remaining | Calls remaining before cutoff. |
X-RateLimit-Reset | Unix timestamp of the next reset. |
Errors
| code | error | when |
|---|---|---|
| 400 | content_required | Missing or empty content. |
| 400 | invalid_json | Body is not valid JSON. |
| 401 | missing_api_key | No x-api-key header. |
| 401 | invalid_api_key | Key does not exist or was revoked. |
| 413 | content_too_large | Exceeds 50,000 characters. |
| 429 | rate_limit_exceeded | Monthly quota consumed. |
| 500 | detection_failed | Pipeline did not complete. |