Get started with the CalmLens API
CalmLens tells your app whether user content is safe to show. In this guide you moderate a comment, then an image, and learn how to read the decision. New to the concepts? Read How CalmLens works first.
Choose when to get the decision
You can moderate in place as part of your request, or queue moderation and receive an event when it finishes. This choice is separate from whether CalmLens stores and serves your content.
| Flow | Use | Get the result |
|---|---|---|
| Wait in the request | client.assets.moderate() (queue=false over HTTP) | The response contains the moderation decision. Useful when your app needs a decision before accepting a submission. |
| Queue and receive an event | client.assets.create() (queue=true over HTTP) | The response gives you an asset ID while moderation runs in the background. A webhook sends asset.classified when the decision is ready. |
Text and images support either flow. Audio and video always run asynchronously, even with queue=false. For queued content, keep it unpublished until approved, and handle asset.failed if processing fails. See Webhooks for setup and payloads.
1. Get an API key and your project ID
- In the portal, go to Portal › Developer › API Keys and create a key. Copy it now: it's only shown once.
- Copy the Project ID shown next to your new key and at the top of the API Keys page.
Store both on your server, for example as CALMLENS_API_KEY and CALMLENS_PROJECT_ID. Never put the key in browser or mobile app code.
Choose your language in the examples below. SDK guides cover JavaScript / TypeScript, Python, Go, Rust, Ruby and Java. Language selection stays in sync across examples.
npm install @calmlens/sdk
import { CalmLensClient } from "@calmlens/sdk";
const client = new CalmLensClient({
apiKey: process.env.CALMLENS_API_KEY!,
projectId: process.env.CALMLENS_PROJECT_ID!,
});
2. Moderate a comment
This example moderates in place: client.text.moderate() waits for the decision before your app continues. You can also queue text with client.assets.create() and receive the result by webhook.
const result = await client.text.moderate({ text: comment.body, externalId: `comment-${comment.id}` });
if (result.status === "approved") {
await publishComment(comment);
} else {
showError("Your comment wasn't posted because it may break our community guidelines.");
}
Use the SDK for your server language. It handles authentication, uploads and API errors. See the Assets API for the HTTP reference.
Try it without code
Paste a comment and see what CalmLens decides with your project's policy, and why. Each check is a normal upload, so it counts towards your usage and free uploads. The example above makes the same check from your server.
Sign in to try it here with your project's policy.
3. Read the decision
Your project's moderation policy turns each report into an action. Your app only needs two fields:
status | report.flagged | What your app should do |
|---|---|---|
| approved | false | Publish. |
| approved | true | Publish, and add it to a review queue. The policy action was alert. |
| rejected | true | Don't publish. Tell the author it wasn't posted. The action was hide or purge. |
| pending | N/A | Still being classified. Keep it unpublished and wait for a webhook. |
| error | N/A | Classification failed. Don't publish; retry or review manually. |
New projects use the General community policy, which suits most social apps and marketplaces. To see why something was flagged, read the six category scores in report.categories. A category with status not-evaluated is unknown, not safe. See Report format.
4. Moderate an image
This example uses the queued flow: client.assets.create() returns an asset ID while moderation runs. Keep the post hidden from other users until it's approved. Images also support waiting in the request with client.assets.moderate().
const asset = await client.assets.create({
name: file.name,
content: { data: file, type: file.type }, // a File or Blob; base64 and buffers also work
externalId: `post-${post.id}`,
});
// asset.status is "pending"; save asset.id with the post
For this queued upload, receive the result by webhook.
Receive the result by webhook
In Portal › Webhooks & connectors, subscribe your HTTPS endpoint to asset.classified. The event includes the decision in data.asset.status. Also subscribe to asset.failed so your app can handle processing failures. Save the returned asset ID to match the event to your submission.
The SDK chooses the appropriate upload mode. See upload modes for file limits and multipart uploads.
5. Try a rejection safely
Use test inputs to check your rejection flow without uploading real harmful content. For example, add <!calmlens-test XXXXXXXX harassment> to a comment, replacing XXXXXXXX with the last 8 characters of your project ID.
6. Serve approved images (optional)
To host approved files with CalmLens, follow Delivering assets. It covers retention, public and private access, signed URLs and image transforms.
AI assistants
Use the documentation index to discover published Markdown guides and the OpenAPI contract. Append .md to a documentation page URL to read its Markdown export.
Next steps
-
How CalmLens works: the concepts in one page.
-
Policies and actions: choose what gets hidden.
-
JavaScript SDK: every method, plus a mock client for unit tests.
-
Python SDK: synchronous calls, streamed uploads and local testing.
-
Go SDK: typed calls, context cancellation and local testing.
-
Rust SDK, Ruby SDK and Java SDK: installation, uploads and testing.