> ## Documentation Index
> Fetch the complete documentation index at: https://social-b97141fb-feat-user-history-moderation-detail.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Sending Messages

> Send text messages, query history, subscribe to real-time updates, and edit or delete messages in any channel.

> [!NOTE]
>
> **SDK v7.x** · Last verified March 2026 · iOS · Android · Web · Flutter

> **Speed run — just the code**
>
> ```typescript theme={null}
> // Send a text message
> await MessageRepository.createMessage({
>   subChannelId: channelId,
>   data: { text: 'Hello world!' },
>   dataType: 'text',
> });
>
> // Query 20 most recent messages
> const liveCollection = MessageRepository.getMessages({
>   subChannelId: channelId,
>   limit: 20,
> });
> liveCollection.on('dataUpdated', (messages) => renderMessages(messages));
>
> // Edit a message
> await MessageRepository.updateMessage(messageId, {
>   data: { text: 'Hello, corrected world!' },
> });
>
> // Delete
> await MessageRepository.deleteMessage(messageId);
> ```
>
> Full walkthrough below ↓

> [!TIP]
>
> **Platform note** — code samples below use TypeScript. Every method has an equivalent in the iOS (Swift), Android (Kotlin), and Flutter (Dart) SDKs — see the linked SDK reference in each step.

Messages are the core of every chat experience. This guide covers the full send-read-edit-delete lifecycle, plus real-time subscriptions so your UI stays in sync without polling.

```mermaid theme={null}
graph TD
    A[User types message] --> B[createMessage]
    B --> C{Optimistic render}
    C -->|Immediately| D[Show in UI]
    C -->|Background| E[Server processing]
    E -->|Success| F[Message confirmed]
    E -->|Failure| G[Mark as failed]
    F --> H[Live Collection notifies all subscribers]
    H --> I[Other users see message]
    D --> J{User edits?}
    J -->|Yes| K[updateMessage]
    J -->|Delete| L[deleteMessage]
    K & L --> M[Live Collection updates]

    classDef action fill:#e1f5fe,stroke:#0288d1,color:#01579b
    classDef decision fill:#fff8e1,stroke:#f9a825,color:#f57f17
    classDef process fill:#f3e5f5,stroke:#7b1fa2,color:#4a148c
    classDef outcome fill:#e8f5e9,stroke:#388e3c,color:#1b5e20

    class A action
    class C,J decision
    class B,E,K,L process
    class D,F,G,H,I,M outcome
```

> [!NOTE]
>
> **Prerequisites**: Channel created and user is a member → [Channels & Conversations](/use-cases/chat/channels-and-conversations)

## Limits at a Glance

| Property | Limit |
| - | - |
| Max text length | 20,000 characters |
| Max tags per message | 5 |
| Max metadata size | 100 KB JSON |
| Max mentions per message | 30 |
| Soft-delete behavior | Placeholder remains visible |

## Quick Start: Send and Receive Messages

```typescript theme={null}
import { MessageRepository } from '@amityco/ts-sdk';

try {
  // Send
  await MessageRepository.createMessage({
    subChannelId: channelId,
    data: { text: 'Hey everyone! 👋' },
    dataType: 'text',
  });
} catch (error) {
  console.error('Failed to send message:', error);
}

// Receive (Live Collection — no try/catch needed)
const feed = MessageRepository.getMessages({ subChannelId: channelId });
feed.on('dataUpdated', (msgs) => console.log(msgs.length, 'messages'));
```

## Step-by-Step Implementation

**1. Send a text message**

```typescript theme={null}
import { MessageRepository } from '@amityco/ts-sdk';

await MessageRepository.createMessage({
  subChannelId: channelId,   // Target channel
  data: { text: 'Hello from TypeScript!' },
  dataType: 'text',
  tags: ['greeting'],        // Optional tags for filtering
  metadata: { source: 'web' }, // Optional custom metadata
});
```

→ [Send Message](/social-plus-sdk/chat/messaging-features/message-creation/send-a-message)

**2. Query message history with pagination**

```typescript theme={null}
const liveCollection = MessageRepository.getMessages({
  subChannelId: channelId,
  limit: 20,           // Load 20 messages per page
  reverse: true,       // Newest first (typical chat layout)
});

// Initial render + any future updates
liveCollection.on('dataUpdated', (messages) => {
  setMessages(messages);
});

// Load older messages
if (liveCollection.hasPrevPage) {
  liveCollection.prevPage();
}
```

→ [Query Messages](/social-plus-sdk/chat/messaging-features/messages/query-and-filter-messages)

**3. Subscribe to real-time updates**

The Live Collection already handles real-time updates — new messages, edits, and deletions all trigger `dataUpdated`. No extra setup required.

Channel and message subscriptions keep documented SDK data current, but they do not expose typing-indicator state. Do not infer “typing” from user presence, a channel subscription, or message-collection activity.

→ [Real-time Events](/social-plus-sdk/core-concepts/realtime-communication/realtime-events)

**4. Edit and delete messages**

```typescript theme={null}
// Edit
await MessageRepository.updateMessage(messageId, {
  data: { text: 'Edited message text' },
});

// Soft delete (message placeholder remains, content removed)
await MessageRepository.deleteMessage(messageId);
```

> [!NOTE]
>
> Only the message author (or a moderator) can edit or delete a message.

→ [Edit & Delete Messages](/social-plus-sdk/chat/messaging-features/messages/edit-and-delete-messages)

## Connect to Moderation & Analytics

> **AI content moderation on messages**
>
> social.plus AI Moderation automatically scans message text and flags violations before they're visible to other users. Enable it in **Admin Console → AI Content Moderation**.
>
> → [AI Content Moderation](/analytics-and-moderation/console/ai-content-moderation)

> **Webhook: message events**
>
> Subscribe to `message.created`, `message.updated`, and `message.deleted` webhook events to sync message data or trigger business logic in your backend.
>
> → [Webhook Events](/analytics-and-moderation/social+-apis-and-services/webhook-event)

## Common Mistakes

> [!WARNING]
>
> **Sending to the wrong subChannelId** — For Community and Live channels, `subChannelId` is the same as `channelId`. For Conversation channels (1:1), use the channel's `defaultSubChannelId`. Double-check which ID you're using when switching channel types.

> [!WARNING]
>
> **Forgetting to dispose Live Collections** — Every `liveCollection.on('dataUpdated', …)` subscription holds an open connection. Always call `liveCollection.dispose()` when your component unmounts to prevent memory leaks and ghost re-renders.

## Best Practices

> **Optimistic rendering for send**
>
> * Show the message instantly in the UI **before** the server confirms it
> * Mark it with a `sending` state indicator (spinner or dim text)
> * Replace with the confirmed message on success, or show a **retry button** on failure
> * This is the standard pattern for all major chat apps

> **Limit history to what's visible**
>
> * Start with 20–30 messages on first load
> * Paginate backwards only when the user scrolls to the top
> * Fetching large histories upfront increases load time and memory use, especially on mobile

> **Use tags for search and filtering**
>
> * The optional `tags` field on messages supports full-text search
> * Tag system messages (join/leave events, announcements) so you can filter them out of the main feed
> * Useful for building filtered views like "only show media messages" or "only announcements"

> [!TIP]
>
> **Dive deeper**: [Messaging API Reference](/social-plus-sdk/chat/messaging-features/overview) has full parameter tables, method signatures, and platform-specific details for every API used in this guide.

## Next Steps

> **[Reactions & Replies](/use-cases/chat/message-reactions-and-replies)**
>
> Add emoji reactions and threaded replies to messages.

> **[Rich Media Messages](/use-cases/chat/rich-media-messages)**
>
> Send images, audio, video, and file attachments.

> **[Unread Counts](/use-cases/chat/unread-counts-and-read-receipts)**
>
> Surface unread badges and per-message read receipts.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.