1. Prepare your merchant account
Register or sign in to the workspace. New client access starts inactive and requires administrator activation. Check your current package allowance, request limits and image-source settings before integrating.
Private file uploads do not need a host allowlist. URL submissions must use permitted sources. Keep submitted image bytes unchanged until the result is applied.
Call the API from your own backend. Keep credentials out of browser and mobile bundles.
2. Create an integration API key
Sign in with your customer account to obtain a four-hour mvs_ session. Use that session to POST /api/v1/api-key/rotate. Copy the returned mv_ key once and store it in your trusted server environment as MODERALENS_API_KEY.
Rotation revokes the previous key immediately by default. An optional grace_seconds value of 0–3600 permits a controlled transition. Account and billing actions require a customer session, not an integration key.
3. Choose available checks
GET /api/v1/capabilities lists capability IDs and availability. Choose only the checks your service needs. Omitting checks requests the five default checks; ai_generated must be selected explicitly and is experimental, review-only.
For reusable rules, create an enabled workflow and submit workflow_id instead of checks. Each job captures the workflow version and thresholds at admission.
4. Submit a private image
POST /api/v1/jobs/upload with multipart fields reference, images[] and checks[] (or workflow_id). Allow the HTTP client to create the multipart boundary; do not manually set Content-Type.
Use a unique Idempotency-Key per logical submission: 16–128 ASCII letters, digits, underscores or hyphens. If the response is uncertain, retry the same key with identical content. Changing content under the same key returns 409.
Limits: 1–8 static JPEG/PNG/WebP images, up to 10 MiB each, 20 MiB total and 16 million pixels per image. A 202 response means admitted, not approved.
5. Retrieve the asynchronous result
Save data.job_id from the 202 response. GET /api/v1/jobs/{id} using the same client credential. Poll with backoff, for example 2 seconds increasing to 10. Respect Retry-After when supplied. Stop polling at completed or failed.
Do not resubmit the image merely because processing is still queued or processing. Missing, expired and foreign-client jobs return 404.
6. Apply your publishing policy
Inspect checked_categories, not_checked_categories and unsupported_categories alongside the decision. Scores are signals, not calibrated probability guarantees. Batch scores are maxima across images.
Use image_hashes to match the original bytes. Store reviewer and publishing decisions in your application; there is no public reviewer-decision write API. Age, content involving minors, self-harm, hate, harassment, threats, text, legality and document authenticity are not assessed.
- completed + block: a configured blocking threshold was reached; hold according to your policy.
- completed + review: route to a human reviewer and keep pending.
- completed + no_signal: no selected threshold was reached. This is not a universal safety guarantee.
- failed: result is null and error.decision is review. Keep for manual review; never publish as a safety pass.
7. Handle errors and ship deliberately
Use the API reference for exact parameters, credential type, cURL/Node.js/PHP requests and illustrative responses. Test completed, review, block, no_signal and failure cases before automating publishing.
Billing endpoints describe the installed Stripe integration. They do not imply checkout readiness; inspect checkout_ready and your billing state first.
- 401: refresh your credential or sign in again. 403: check activation and permission.
- 422: correct validation fields. 409: preserve the original idempotent request rather than changing content.
- 429: back off and respect request, UTC-day and pending-job limits. 503: retry after dependency recovery.
- A successful HTTP response can contain a failed job. Monitor processing state separately from HTTP errors.