Events

Events record what happened in a project: uploads and moderation decisions, manual reviews, processing failures, usage limits, new members and failing connectors. The events feed returns them oldest first after a cursor: call it without after to get a cursor for the current time, pass the returned cursor back to receive only newer events, and request again straight away while hasMore is true.

Guide: Webhooks & Connectors, which push the same events to you as they happen.

Feed and webhook envelopes

SourceShape
Events APIEvent fields include severity, asset and facts directly on the event.
WebhookThe same fields are inside data; id, type, createdAt and projectId remain at the top level.

Use the event ID to deduplicate deliveries. The asset snapshot records the decision when the event happened.

Endpoints

EndpointDescription
GET /projects/:projectId/eventsList project events, oldest first, after a cursor.

The event object

Asset events include the asset decision snapshot, and each event's facts is typed by its type. A webhook connector delivers the same event wrapped as { id, type, createdAt, projectId, data }, where data holds severity, title, description, assetId, asset and facts.

FieldTypePresenceDescription
idstringRequiredUnique event ID
projectIdstringRequiredID of the project the event belongs to
userIdstringOptional, nullableID of the user who caused the event, if any
typestringRequiredEvent type. See Event types.
severity"low" | "high"RequiredDefault severity of the event type
titlestringRequiredShort human-readable summary
descriptionstringOptional, nullableLonger human-readable explanation
assetIdstringOptional, nullableID of the asset the event is about, for asset events
assetobjectOptional, nullableSnapshot of the asset's moderation decision when the event was created, for asset events
asset.idstringRequiredAsset ID
asset.externalIdstringOptional, nullableThe asset's externalId, if you set one
asset.status"uploading" | "pending" | "approved" | "rejected" | "error"RequiredAsset status when the event was created
asset.flaggedbooleanOptional, nullableThe report's flagged value; null until the asset has been classified
asset.moderationAction"ignore" | "alert" | "hide" | "purge"Optional, nullableModeration action applied to the asset, if any
factsobject[]RequiredRegistered event facts. See Event facts.
notifybooleanOptional, nullableWhether the event triggers in-app notifications
createdAtintegerRequiredWhen the event was created, in milliseconds since the Unix epoch
updatedAtintegerOptionalWhen the event was last updated, in milliseconds since the Unix epoch
readAtnumberOptional, nullableWhen the event was marked as read in the portal, in milliseconds since the Unix epoch

Event types

EventCategorySeverityMeaning
asset.uploadedAssetslowA new asset was uploaded to the project.
asset.classifiedAssetslowModeration finished and the asset has a decision.
asset.flaggedModerationhighAutomated moderation flagged the asset for a policy violation.
asset.approvedModerationlowA reviewer approved a rejected asset in the portal.
asset.rejectedModerationhighA reviewer rejected an asset in the portal.
asset.failedAssetshighThe asset could not be processed and is in the error state.
usage.limit-reachedUsagehighThe project owner used their free upload allowance; new uploads are blocked.
project.member-joinedTeamlowSomeone accepted an invitation and joined the project.
connector.failingConnectorshighDeliveries to a connector kept failing, so it was turned off.

Event facts

EventFacts
asset.uploadedasset-name: The asset's name when the event was created.
asset-type: The asset's type, such as image or video.
file-format: The uploaded file's format, such as jpg.
asset.classifiedasset-name: The asset's name when the event was created.
asset-type: The asset's type, such as image or video.
status: The asset's status after classification: approved, rejected or error.
moderation-action: The action applied to flagged content (alert, hide or purge), or null.
asset.flaggedasset-name: The asset's name when the event was created.
asset-type: The asset's type, such as image or video.
flagged-categories: The matched parent policy categories. Inspect the asset's moderation report for qualifier detail.
moderation-action: The action applied to the flagged content (alert, hide or purge).
asset.approvedasset-name: The asset's name when the event was created.
asset-type: The asset's type, such as image or video.
reviewer-user-id: ID of the user who made the decision, or null when an API key made it.
reviewer-name: Name or email of the user who made the decision, when known.
note: The reviewer's note, or null.
asset.rejectedasset-name: The asset's name when the event was created.
asset-type: The asset's type, such as image or video.
reviewer-user-id: ID of the user who made the decision, or null when an API key made it.
reviewer-name: Name or email of the user who made the decision, when known.
note: The reviewer's reason for rejecting the asset, or null.
asset.failedasset-name: The asset's name when the event was created.
asset-type: The asset's type, such as image or video.
previous-status: The asset's status before it failed, such as pending.
usage.limit-reachedlimit: Number of free uploads in the allowance.
used: Number of free uploads used.
owner-user-id: ID of the project owner whose allowance was used.
project.member-joinedmember-user-id: User ID of the new member.
member-name: The new member's name or email.
role: The member's role: admin, member, viewer or custom.
invited-by-user-id: User ID of the person who sent the invitation.
connector.failingconnector-id: ID of the failing connector.
connector-name: The connector's name.
connector-type: The connector's type, such as webhook, slack or email.
consecutive-failures: Number of deliveries in a row that failed after their retries.
last-error: Summary of the most recent failure, or null.

Endpoint details

List Events

List project events, oldest first, after a cursor. A webhook connector delivers each event as `{ id, type, createdAt, projectId, data }`, where `data` holds the remaining event fields. Each event's `facts` are `{ key, value, url? }` entries registered for its `type` (see the event types in the webhooks guide). Omit `after` to get a cursor for the current time without any events, then pass each response's `cursor` as `after` until `hasMore` is false. Polling receives new events without a public webhook URL, for example during local development.

OpenAPI YAML
GET
https://api.calmlens.com/v1/projects/
/events
import { CalmLensClient } from "@calmlens/sdk";

const client = new CalmLensClient({
  apiKey: "your-api-key",
  projectId: "your-project-id"
});

const response = await client.events.list({
  "limit": 50
});

Query Parameters

Edit any value to update the generated request examples.

numberRequired
Maximum number of events to return
string (optional)Optional
The cursor from a previous response. Omit it to get a cursor for the current time without any events.

Response

cursorstringRequired
hasMorebooleanRequired

Error Codes

401auth/missing-token
Authentication required. Send your project API key in the X-Api-Key header.
401auth/invalid-api-key
The API key is invalid, revoked or expired. Create a key under Developer → API Keys.
403auth/project-mismatch
This API key belongs to a different project. Use a key created for the project that owns this resource.
404project/not-found
Project not found
400events/invalid-cursor
The events cursor is invalid. Use the cursor from a previous response, or omit it to start from now.

Signing in

Signing out

Cookies on CalmLens

We use essential cookies to keep you signed in and the site secure. With your permission, we'll also use functional cookies to remember preferences such as your layout and documentation language, and to offer Google One Tap sign-in. We don't use analytics or advertising cookies. Manage cookies