Skip to main content
SDK v7.x · Last verified March 2026 · iOS · Android · Web · Flutter
// 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 ↓
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.
Prerequisites: Channel created and user is a member → Channels & Conversations

Limits at a Glance

PropertyLimit
Max text length20,000 characters
Max tags per message5
Max metadata size100 KB JSON
Max mentions per message30
Soft-delete behaviorPlaceholder remains visible

Quick Start: Send and Receive Messages

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

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
2

Query message history with pagination

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
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.For advanced use cases (e.g., detecting when other users are typing), subscribe to the raw event stream:
import { ChannelRepository } from '@amityco/ts-sdk';

// Subscribe to the channel for typing indicators / presence
const sub = ChannelRepository.subscribeChannel(channelId);

// Dispose when component unmounts
return () => sub.dispose();
Real-time Events
4

Edit and delete messages

// Edit
await MessageRepository.updateMessage(messageId, {
  data: { text: 'Edited message text' },
});

// Soft delete (message placeholder remains, content removed)
await MessageRepository.deleteMessage(messageId);
Only the message author (or a moderator) can edit or delete a message.
Edit & Delete Messages

Connect to Moderation & Analytics

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
Subscribe to message.created, message.updated, and message.deleted webhook events to sync message data or trigger business logic in your backend.Webhook Events

Common Mistakes

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.
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

  • 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
  • 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
  • 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”
Dive deeper: Messaging API Reference has full parameter tables, method signatures, and platform-specific details for every API used in this guide.

Next Steps

Reactions & Replies

Add emoji reactions and threaded replies to messages.

Rich Media Messages

Send images, audio, video, and file attachments.

Unread Counts

Surface unread badges and per-message read receipts.