---
title: Best Practices
url: https://docs.kaltura.com/docs/events-collaboration/messaging-api/messaging-best-practices
---

## Best Practices

- **Use CAN-SPAM compliant unsubscribe groups.** Assign unsubscribe groups to all marketing/event emails and include `{unsubLink}` tokens — users who unsubscribe are automatically excluded from future sends.
- **Use dynamic tokens for personalization.** Leverage `{recipient.*}`, `{magicLink}`, `{qrCodeLink}`, and custom tokens to create engaging, per-recipient emails without manual string substitution.
- **Configure domain authentication.** Set up SPF and DKIM records for your sending domain to maximize deliverability and avoid spam filters.
- **Track delivery stats and follow up on failures.** Use `msg-history/getStats` and `msg-history/getFiltered` to monitor bounce rates, open rates, and re-send to failed recipients.
- **Use AppTokens for production access.** Generate KS via `appToken.startSession` with HMAC — keep admin secrets off application servers.
- **Use the Messaging Service for all email communications.** Prefer the Messaging API over custom SMTP integrations — it provides tracking, analytics, and compliance out of the box.

### Common Integration Patterns

#### Event Invitation Workflow

Complete flow from virtual event to personalized invitations:

```bash
# Prerequisites
# KALTURA_MESSAGING_URL="https://messaging.nvp1.ovp.kaltura.com/api/v1"
# KALTURA_APP_REGISTRY_URL="https://app-registry.nvp1.ovp.kaltura.com/api/v1"
# KALTURA_KS="<your admin KS>"

# Step 1: Get App GUID for your event
APP_GUID=$(curl -s -X POST "$KALTURA_APP_REGISTRY_URL/app-registry/list" \
  -H "Authorization: Bearer $KALTURA_KS" \
  -H "Content-Type: application/json" \
  -d "{\"filter\": {\"appCustomIdIn\": [\"$VIRTUAL_EVENT_ID\"]}}" \
  | jq -r '.objects[0].id')

# Step 2: Create an invitation template
TEMPLATE_ID=$(curl -s -X POST "$KALTURA_MESSAGING_URL/email-template/add" \
  -H "Authorization: Bearer $KALTURA_KS" \
  -H "Content-Type: application/json" \
  -d "{
    \"appGuid\": \"$APP_GUID\",
    \"name\": \"Event Invitation\",
    \"subject\": \"You're invited: {eventName}\",
    \"body\": \"<p>Hi {recipient.firstName},</p><p>Join us at {eventName}!</p><p><a href='{joinLink}'>Join Event</a></p>\",
    \"toAttributePath\": \"{recipient.email}\",
    \"msgParamsMap\": {
      \"recipient\": {\"type\": \"User\"},
      \"eventName\": {\"type\": \"String\"},
      \"joinLink\": {\"type\": \"MagicLink\"}
    }
  }" | jq -r '.id')

# Step 3: Send invitations
curl -X POST "$KALTURA_MESSAGING_URL/message/send" \
  -H "Authorization: Bearer $KALTURA_KS" \
  -H "Content-Type: application/json" \
  -d "{
    \"receiverType\": \"user\",
    \"userIds\": [\"attendee1@example.com\", \"attendee2@example.com\"],
    \"appGuid\": \"$APP_GUID\",
    \"templateId\": \"$TEMPLATE_ID\",
    \"type\": \"email\",
    \"msgParams\": {
      \"recipient\": {\"type\": \"User\", \"value\": \"Message.userId\"},
      \"eventName\": {\"type\": \"String\", \"value\": \"Annual Conference 2025\"},
      \"joinLink\": {\"type\": \"MagicLink\", \"value\": {\"baseURL\": \"https://events.example.com/join\", \"expiry\": 48, \"privileges\": \"actionslimit:2\"}}
    },
    \"session\": \"conference-2025-invitations\"
  }"
```

#### Delivery Tracking Dashboard

After sending, monitor delivery and engagement:

```bash
# Get overall delivery stats
curl -X POST "$KALTURA_MESSAGING_URL/message/stats" \
  -H "Authorization: Bearer $KALTURA_KS" \
  -H "Content-Type: application/json" \
  -d '{"session": "conference-2025-invitations"}'

# Find failed deliveries for follow-up
curl -X POST "$KALTURA_MESSAGING_URL/message/listDiscreteAggregateMessages" \
  -H "Authorization: Bearer $KALTURA_KS" \
  -H "Content-Type: application/json" \
  -d '{
    "filter": {
      "sessionIn": ["conference-2025-invitations"],
      "statusIn": ["bounce", "error", "dropped"]
    }
  }'
```

#### Unsubscribe-Aware Messaging

Set up templates with unsubscribe groups to respect user preferences:

```bash
# Step 1: Create unsubscribe URI for your app
URI_ID=$(curl -s -X POST "$KALTURA_MESSAGING_URL/unsubscribe-uri/add" \
  -H "Authorization: Bearer $KALTURA_KS" \
  -H "Content-Type: application/json" \
  -d "{
    \"appGuid\": \"$APP_GUID\",
    \"uri\": \"https://events.example.com/unsubscribe\"
  }" | jq -r '.id')

# Step 2: Create template with unsubscribe group
curl -X POST "$KALTURA_MESSAGING_URL/email-template/add" \
  -H "Authorization: Bearer $KALTURA_KS" \
  -H "Content-Type: application/json" \
  -d "{
    \"appGuid\": \"$APP_GUID\",
    \"name\": \"Event Updates\",
    \"subject\": \"Update: {eventName}\",
    \"body\": \"<p>{recipient.firstName}, here's an update.</p><p><a href='{unsubLink}'>Unsubscribe</a></p>\",
    \"toAttributePath\": \"{recipient.email}\",
    \"msgParamsMap\": {
      \"recipient\": {\"type\": \"User\"},
      \"eventName\": {\"type\": \"String\"},
      \"unsubLink\": {\"type\": \"UnsubscribeUri\"}
    },
    \"unsubscribeGroups\": [\"event-updates\"]
  }"
```

Users who unsubscribe from the `"event-updates"` group will be automatically excluded from future messages sent with that group.
