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

fieldtyperequireddescription
contentstringyesThe text to analyze. Max 50,000 characters.
titlestringnoArticle title. Improves triage accuracy.
sourcestringnoPublisher name. Activates the trusted-source rule when applicable.
languagestringnoISO code, e.g. en or he. Defaults to en.
content_typestringnoDefaults to article. Free-form tag preserved in the audit record.
metadataobjectnoArbitrary 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

fieldtypedescription
idstringUnique detection ID (det_...).
statusstringclear, review, or flagged.
scoresobjectPer-category max confidence.
detectionsarrayOne entry per piece of evidence. See detection object below.
triageobjectStage 1 triage: whether content needed deep analysis.
verificationobjectStage 3: accepted vs rejected signal count.
calibrationobjectStage 4: signal counts + review_decision.
complianceobjectDSA Article 34/15 flags.
processing_msnumberWall-clock pipeline time.
audit_idstringLink to the persisted audit record.

Detection object

fieldtypedescription
categorystringantisemitism, anti_israel_bias, or context_omission.
subcategorystringSignal type, e.g. classic_trope_conspiracy_control.
confidencenumber0.0–1.0, after calibration.
severitystringlow, medium, high.
attributionstringpublisher_voice (1.0×), quote (0.6×), rebuttal (0.15×), unclear (0.5×).
dog_whistle_hitboolTrue if pre-scanner flagged this text.
flagged_segmentsarrayCharacter offsets into original content.
definitionobjectFramework, reference (e.g. IHRA-7), description.
rationalestringModel's explanation.
recommended_actionstringblock_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

statusreview_decisionmeaning
clearauto_acceptNo actionable signals found.
reviewhuman_reviewSignals present but ambiguous. Attribution may soften a strong signal.
flaggedauto_rejectHigh-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:

headervalue
X-RateLimit-LimitYour quota for the current period.
X-RateLimit-RemainingCalls remaining before cutoff.
X-RateLimit-ResetUnix timestamp of the next reset.

Errors

codeerrorwhen
400content_requiredMissing or empty content.
400invalid_jsonBody is not valid JSON.
401missing_api_keyNo x-api-key header.
401invalid_api_keyKey does not exist or was revoked.
413content_too_largeExceeds 50,000 characters.
429rate_limit_exceededMonthly quota consumed.
500detection_failedPipeline did not complete.