Skip to content
StatusSupportDashboard
Backend Events

Backend Events

Send durable server-side product events to SafetyKit.

Beta.

SafetyKit uses backend events to understand meaningful product actions such as account creation, account updates, user-to-user contact, and content uploads. Send events from your backend after the action has happened in your system. Do not send backend events directly from a browser or mobile client.

Use the Events API reference for the full request schema, SDK examples, and response fields.

Send one event, or an ordered batch of events, to:

Terminal window
POST https://api.safetykit.com/v1/events
Authorization: Bearer <SAFETYKIT_API_KEY>
Content-Type: application/json

Single event:

{
"type": "user_contact",
"event_name": "message_sent",
"user_id": "user_123",
"target_user_id": "user_456",
"timestamp": "2026-05-21T00:15:15.000Z",
"content": [
{
"type": "text",
"key": "body",
"text": "Hey, is this still available?"
}
],
"metadata": {
"conversation_id": "conversation_789",
"channel": "marketplace_dm"
}
}

Response:

{
"status": "ok",
"event_id": "01KSR4C8JN1SA9X63T6P368K6W"
}

Batch event request:

[
{
"type": "update_account",
"event_name": "profile_updated",
"user_id": "user_123",
"timestamp": "2026-05-21T00:15:10.000Z",
"metadata": {
"changed_fields": ["bio"]
}
},
{
"type": "user_contact",
"event_name": "message_sent",
"user_id": "user_123",
"target_user_id": "user_456",
"timestamp": "2026-05-21T00:15:15.000Z"
}
]

Response:

{
"status": "ok",
"event_ids": ["01KSR4C8JN1SA9X63T6P368K6W", "01KSR4CB1MFVX1TAYM46YQXZ3E"]
}

SafetyKit ingests every event in a batch before returning a response.

Every event is a JSON object:

{
"type": "user_contact",
"event_name": "message_sent",
"user_id": "user_123",
"target_user_id": "user_456",
"timestamp": "2026-05-21T00:15:15.000Z",
"content": [],
"resources_used": [],
"metadata": {}
}

Required base fields:

  • type: one of user_contact, content_uploaded, create_account, or update_account
  • event_name: a stable, low-cardinality snake_case name for the product action
  • timestamp: the time the event occurred in your system, as an ISO 8601 datetime string
  • user_id: your canonical stable identifier for the user or account performing the action

Use stable event names like message_sent or profile_updated. Put dynamic values in typed fields, content, resources_used, or metadata.

Use when one user contacts, transacts with, or otherwise interacts with another user.

Required fields:

  • user_id
  • target_user_id

Recommended fields:

  • content, if the interaction includes a message or user-authored note
  • metadata, for conversation IDs, transaction IDs, channel names, or similar context

Example:

{
"type": "user_contact",
"event_name": "message_sent",
"user_id": "sender_123",
"target_user_id": "recipient_456",
"timestamp": "2026-05-21T00:15:15.000Z",
"metadata": {
"conversation_id": "conversation_789"
}
}

Use when a user creates an account.

Required fields:

  • user_id

Recommended fields:

  • resources_used, for signup emails, phones, names, addresses, URLs, or social handles
  • content, for public bio or profile text
  • metadata, for signup source, cohort, or other event-local context

Use when a user updates account or profile information.

Required fields:

  • user_id

Recommended fields:

  • resources_used, for changed emails, phones, social handles, addresses, URLs, or payment identifiers
  • content, for changed public bio or profile text
  • metadata, for changed field names, visibility state, or other event-local context

Use when a user posts, uploads, publishes, edits, or replaces content.

Required fields:

  • user_id
  • content

Recommended fields:

  • metadata, for listing IDs, post IDs, visibility state, category, or similar product context

Use content for user-authored or user-uploaded content SafetyKit should compare or analyze.

Text part:

{
"type": "text",
"key": "body",
"text": "Hey, is this still available?"
}

Image part:

{
"type": "image",
"key": "profile_photo",
"source": {
"type": "url",
"url": "https://cdn.example.com/images/profile.jpg"
}
}

Guidelines:

  • Split structured content into meaningful parts.
  • Use stable key values such as body, title, description, bio, or primary_photo.
  • Send original user-authored text rather than rendered HTML when possible.
  • Send canonical media URLs when available.

Use resources_used for reusable identifiers associated with the event.

[
{
"type": "email",
"value": "user@example.com"
},
{
"type": "phone",
"value": "+12069406843"
},
{
"type": "url",
"value": "https://example.com/profile/user_123"
}
]

Common resource types include email, phone, name, address, url, facebook, instagram, x, tiktok, youtube, linkedin, and payment_instrument.

Guidelines:

  • Send values exactly as your backend receives or stores them.
  • Prefer E.164 phone numbers if your system already has them.
  • Prefer canonical URLs if your system already has them.
  • Do not put multiple resources in one string.
  • Do not duplicate the same value in both resources_used and metadata.

Use metadata for freeform non-PII product context for filtering, segmentation, debugging, and investigation.

{
"conversation_id": "conversation_789",
"channel": "marketplace_dm",
"is_first_message": true,
"message_count_24h": 12
}

Metadata values may be strings, numbers, booleans, or arrays of strings, numbers, or booleans. Metadata keys should be stable snake_case strings.

Do not put raw PII, message bodies, bios, addresses, image URLs, or reusable identifiers in metadata. Use content or resources_used.

  • Send events after durable writes in your own system.
  • For high-volume systems, write events to your own outbox or queue and have a worker send them to SafetyKit.
  • Retry transient network errors and 5xx responses with exponential backoff.
  • Do not retry 4xx responses without changing the request.
  • Store your own source event identifier in metadata if you need replay or reconciliation.