> ## Documentation Index
> Fetch the complete documentation index at: https://learn.social.plus/llms.txt
> Use this file to discover all available pages before exploring further.

# Edit and Delete Messages

> Edit text or custom chat messages and soft-delete messages after creation.

Use message management APIs after your app already has the target `messageId`. The client SDKs expose text-message edits, custom-message edits, and soft deletion.

Soft deletion marks a message as deleted and lets message queries or single-message observers reflect that state. It is not a hard-delete or recovery API.

## Platform Surface

| Operation   | TypeScript                                          | iOS                            | Android                                                  | Flutter                                         |
| ----------- | --------------------------------------------------- | ------------------------------ | -------------------------------------------------------- | ----------------------------------------------- |
| Edit text   | `MessageRepository.updateMessage(messageId, patch)` | `editTextMessage(withId:_:)`   | `editTextMessage(messageId).text(...).build().apply()`   | `editTextMessage(messageId).text(...).update()` |
| Edit custom | `MessageRepository.updateMessage(messageId, patch)` | `editCustomMessage(withId:_:)` | `editCustomMessage(messageId).data(...).build().apply()` | `editCustomMessage(messageId, data).update()`   |
| Soft delete | `MessageRepository.softDeleteMessage(messageId)`    | `softDeleteMessage(withId:)`   | `softDeleteMessage(messageId)`                           | `deleteMessage(messageId)`                      |

<Note>
  The Flutter `updateMessage(channelId, messageId)` builder is deprecated. Use `editTextMessage(messageId)` or `editCustomMessage(messageId, customData)` for new integrations.
</Note>

## Parameters

| Operation   | Parameter               | Required | Description                                                    |
| ----------- | ----------------------- | -------- | -------------------------------------------------------------- |
| Edit text   | `messageId`             | Yes      | Existing text message ID to update.                            |
| Edit text   | `text` / `data.text`    | Yes      | Replacement text content.                                      |
| Edit text   | `tags`                  | No       | Replacement tags where the platform edit builder exposes tags. |
| Edit text   | `metadata`              | No       | Replacement metadata stored with the message.                  |
| Edit custom | `messageId`             | Yes      | Existing custom message ID to update.                          |
| Edit custom | `data` / custom payload | Yes      | Replacement JSON-serializable custom payload.                  |
| Soft delete | `messageId`             | Yes      | Message ID to soft-delete.                                     |

## Edit A Text Message

Update the text body and optional app-owned context for an existing text message.

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

  const { data: updatedMessage } = await MessageRepository.updateMessage(
    messageId,
    {
      data: { text: 'Updated text' },
      tags: ['edited'],
      metadata: { source: 'composer' },
    },
  );

  renderResults(updatedMessage);
  ```

  ```swift iOS theme={null}
  try await messageRepository.editTextMessage(
      withId: "message-id",
      "Updated text",
      metadata: ["source": "composer"]
  )

  showSuccessMessage("Message updated")
  ```

  ```kotlin Android theme={null}
  val metadata = JsonObject().apply {
      addProperty("source", "composer")
  }

  val disposable = messageRepository
      .editTextMessage(messageId = messageId)
      .text("Updated text")
      .metadata(metadata)
      .build()
      .apply()
      .subscribe(
          { showSuccessMessage() },
          { error -> handleGeneralError(error) },
      )
  ```

  ```dart Flutter theme={null}
  final updatedMessage = await AmityChatClient.newMessageRepository()
      .editTextMessage(messageId)
      .text('Updated text')
      .tags(['edited'])
      .metadata({'source': 'composer'})
      .update();

  final editedAt = updatedMessage.editedAt;
  ```
</CodeGroup>

## Edit A Custom Message

Update the JSON-serializable payload for an existing custom message.

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

  const { data: updatedMessage } = await MessageRepository.updateMessage(
    messageId,
    {
      data: {
        value: { state: 'confirmed' },
      },
    },
  );

  renderResults(updatedMessage);
  ```

  ```swift iOS theme={null}
  try await messageRepository.editCustomMessage(
      withId: "message-id",
      ["state": "confirmed"]
  )

  showSuccessMessage("Custom message updated")
  ```

  ```kotlin Android theme={null}
  val customData = JsonObject().apply {
      addProperty("state", "confirmed")
  }

  val disposable = messageRepository
      .editCustomMessage(messageId = messageId)
      .data(customData)
      .build()
      .apply()
      .subscribe(
          { showSuccessMessage() },
          { error -> handleGeneralError(error) },
      )
  ```

  ```dart Flutter theme={null}
  final updatedMessage = await AmityChatClient.newMessageRepository()
      .editCustomMessage(messageId, {'state': 'confirmed'})
      .update();

  final editedAt = updatedMessage.editedAt;
  ```
</CodeGroup>

## Soft-Delete A Message

Soft-delete a message by ID so list and single-message observers can reflect deleted state.

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

  const deletedMessage =
    await MessageRepository.softDeleteMessage(messageId);

  renderResults(deletedMessage);
  ```

  ```swift iOS theme={null}
  try await messageRepository.softDeleteMessage(withId: "message-id")
  showSuccessMessage("Message deleted")
  ```

  ```kotlin Android theme={null}
  val disposable = messageRepository
      .softDeleteMessage(messageId = messageId)
      .subscribe(
          { showSuccessMessage() },
          { error -> handleDeletionError(error) },
      )
  ```

  ```dart Flutter theme={null}
  await AmityChatClient.newMessageRepository()
      .deleteMessage(messageId);
  ```
</CodeGroup>

## After Edit Or Delete

* Observe the message or query collection again instead of mutating app UI state by hand.
* Use `editedAt` to render edited indicators after an edit.
* Use `isDeleted` to render deleted placeholders or hide deleted messages depending on your product rule.
* Pass `includeDeleted` on query APIs only where the platform exposes that filter.

## Related Topics

<CardGroup cols={3}>
  <Card title="Send Messages" href="../message-creation/send-a-message" icon="paper-plane">
    Create the message before editing or deleting it.
  </Card>

  <Card title="Get a Message" href="./get-and-view-a-message" icon="eye">
    Observe one message after an edit or delete.
  </Card>

  <Card title="Query Messages" href="./query-and-filter-messages" icon="list-filter">
    Refresh timelines and reply threads.
  </Card>
</CardGroup>
