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

# Correct and delete sent messages

> Find a message LithoBlocks posted, fix its text or data in Slack, or delete it, instead of posting a correction underneath.

> [!NOTE]
>
> Check [environment and feature availability](https://docs.lithoblocks.com/guides/availability.md) before following this guide.

A wrong message in Slack stays wrong for everyone who reads it later, and AI tools that read your
workspace take it as fact. A correction posted underneath doesn't remove it. LithoBlocks can change
or remove the message itself.

Every message LithoBlocks delivers is recorded, whichever way it was sent: the API, the web app,
`/lb-send`, a scheduled message or a batch digest. The record has its own id, `message_id`, which
every send returns.

## Who can change what

| Role | Read | Correct and expire | Delete |
| - | - | - | - |
| Owner, admin | Every message in the organization | Every message | Every message |
| Member | Every message | Only the messages they sent | Only the messages they sent |
| Viewer | Every message | — | — |

An API key's sends count as its owner's. Over the API these need the `messages:read`,
`messages:update` and `messages:delete` scopes. Existing keys don't get them automatically, so add
them to a key that should have them.

## Find a message

Use the `message_id` a send returned, or list messages:

```bash theme={null}
curl "https://api.lithoblocks.com/v1/messages?reference=ticket-123" \
  -H "Authorization: Bearer $LITHOBLOCKS_API_KEY"
```

You can filter by `template_id`, `channel_id`, `message_ts` (with `channel_id`), `lifecycle`
(`live`, `deleted`, `expired`), `source`, `reference`, sent time and `expires_before`.
`GET /v1/messages/{id}` adds the blocks as LithoBlocks last posted them, and
`GET /v1/messages/{id}/events` lists every change and who made it.

A `reference` is your own handle for a message, given when you send it:

```json theme={null}
{ "template_id": "YOUR_TEMPLATE_ID", "channel_id": "C0AS92CQ04D", "data": { "ticket": "123" }, "reference": "ticket-123" }
```

It doesn't need to be unique; a bulk send gives every destination's message the same one. With a
reference, your automation can find "the messages for ticket 123" without storing our ids.

In the web app, **Sent messages** lists them all. Search by template, reference, text or channel,
or paste a Slack message link.

## Correct the text

Change the words in place: header, section, section field, context and markdown text. Buttons,
links and what they do stay as sent. Correcting text is free.

```bash theme={null}
curl -X PATCH https://api.lithoblocks.com/v1/messages/MESSAGE_ID \
  -H "Authorization: Bearer $LITHOBLOCKS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: fix-ticket-123-total" \
  -d '{
    "revision": 0,
    "edits": [{ "index": 1, "path": "text.text", "value": "*Total:* $42.00" }],
    "remove_blocks": [3]
  }'
```

* `index` is the block's position in `blocks` from `GET /v1/messages/{id}`.
* `path` is `text.text` (header, section), `fields.N.text` (a section field), `elements.N.text`
  (context) or `text` (markdown).
* `remove_blocks` removes whole blocks.
* `text`, if you give it, replaces the notification text; otherwise it's written from the blocks.

Text can be corrected only when LithoBlocks' copy is exactly what Slack shows (`text_editable`
is `true`). A message sent from the web app with sensitive values redacted isn't; re-render it
instead.

## Re-render with corrected data

Compile the message again from its template with the data it should have had. This costs one
credit, charged only when Slack accepts the change.

```bash theme={null}
curl -X PATCH https://api.lithoblocks.com/v1/messages/MESSAGE_ID \
  -H "Authorization: Bearer $LITHOBLOCKS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "revision": 1, "data": { "total": "$42.00", "customer": "Acme" }, "version": "sent" }'
```

`version` is `sent` (the template version the message was sent from, the default) or `current`
(the template's live version). Pass the data in full: it replaces what the message was sent with.

## Delete

```bash theme={null}
curl -X DELETE "https://api.lithoblocks.com/v1/messages/MESSAGE_ID?revision=1&scrub=true" \
  -H "Authorization: Bearer $LITHOBLOCKS_API_KEY"
```

Deleting can't be undone, and people may already have read the message. Replies in its thread
stay, under Slack's "This message was deleted". `scrub=true` also clears LithoBlocks' copy of what
the message said: its blocks, metadata, notification text and the send's logged input. The record
and its history stay.

## Revisions and conflicts

Every change names the `revision` you read. If the message changed since (someone else corrected
it, a button updated it, it expired), nothing happens and the answer is `409 revision_conflict`.
Read it again and decide.

| Answer | Meaning |
| - | - |
| `409 message_not_live` | It was deleted or has expired; it can't change again. An expired message's notice can still be deleted. |
| `409 mutation_in_progress` | Another change is reaching Slack. Try again in a moment. |
| `502 slack_refused` | Slack refused and nothing changed; `details` has Slack's reason. |
| `503 rate_limited` | Slack is busy. Retry after `Retry-After`. |
| `504 slack_outcome_unknown` | Slack's answer was lost, so the change may or may not have happened. |

After `slack_outcome_unknown` the message is held. LithoBlocks can't read messages back from
Slack, so a person has to look and say what happened. Until then nothing else can change the
message:

```bash theme={null}
curl -X POST https://api.lithoblocks.com/v1/messages/MESSAGE_ID/reconcile \
  -H "Authorization: Bearer $LITHOBLOCKS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "applied": true }'
```

The web app shows these messages under **Needs review**, where you say whether the change reached
Slack. Never retry a lost change with a new idempotency key; resolve it.

## From MCP and the SDK

AI assistants connected over [MCP](https://docs.lithoblocks.com/guides/mcp.md) have `list_messages`, `get_message`,
`update_message`, `delete_message` and `reconcile_message`. LithoBlocks' instructions tell them to
correct a wrong message rather than post a correction under it. The
[TypeScript SDK](https://docs.lithoblocks.com/guides/sdk-typescript.md) has `client.messages.list`, `get`, `update`, `delete` and
`reconcile`.

To retire a message on a schedule instead, see [Expiring messages](https://docs.lithoblocks.com/guides/expiring-messages.md).


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