Skip to content

Slack’s legacy secondary attachment: content in a box with a coloured bar down its side, sent in a message’s attachments array next to (or instead of) blocks.

Attachments are not blocks. Send them in the message’s top-level attachments array — on chat.postMessage, chat.update, chat.postEphemeral, response_url replies and the v1 chat message endpoints. The API hands them back as attachments, never inside blocks.

Slack treats attachments as legacy; prefer blocks for new apps. They are still handy for a coloured status bar, or to wrap blocks in one: put Block Kit blocks in the attachment’s blocks field and they render inside the box, controls included.

A message can carry up to 20 attachments, shown after its blocks. When a message has attachments but no blocks, its top-level text is shown above them.

Inside the box, Repzo shows the author line, the title, text, fields, blocks, image_url and then the footer; pretext sits above the box and thumb_url beside it.

A status update with fields

{
"text": "Weekly pipeline update",
"attachments": [
{
"color": "good",
"fallback": "Northwind Trading renewal moved to Negotiation (SAR 48,000)",
"pretext": "A deal moved forward in *Enterprise renewals*.",
"author_name": "Pipeline bot",
"title": "Northwind Trading renewal",
"title_link": "https://example.com/deals/northwind-renewal",
"text": "Stage changed from *Proposal* to *Negotiation*. Next step: send the revised quote by Thursday.",
"fields": [
{
"title": "Amount",
"value": "SAR 48,000",
"short": true
},
{
"title": "Close date",
"value": "Nov 28, 2026",
"short": true
},
{
"title": "Owner",
"value": "<@3f6c2a1e-8b4d-4c7a-9e21-5d0b7f9a1c34|Account owner>",
"short": true
},
{
"title": "Probability",
"value": "70%",
"short": true
}
],
"footer": "Repzo CRM",
"ts": 1791813600
}
]
}

Blocks inside an attachment

{
"attachments": [
{
"color": "#e01e5a",
"fallback": "Invoice INV-2041 is 15 days overdue",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Invoice INV-2041* for *Blue Harbor Logistics* is 15 days overdue.\nBalance due: *SAR 12,450*"
}
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "Send reminder"
},
"style": "primary",
"action_id": "send_reminder",
"value": "INV-2041"
},
{
"type": "button",
"text": {
"type": "plain_text",
"text": "Open invoice"
},
"url": "https://example.com/invoices/INV-2041",
"action_id": "open_invoice"
}
]
}
]
}
]
}
Field Type Description Required?
color String Colour of the bar down the side of the box: good (green), warning (yellow), danger (red) or a hex colour code such as #439FE0 (3 or 6 digits, # optional). Optional
fallback String A plain-text summary of the attachment. Used in notifications and message previews, and as the image’s alternative text. Recommended. Optional
pretext String Text shown above the box. Formatted as mrkdwn. Optional
author_name String Small text naming the author, shown at the top of the box. Optional
author_link String An http(s) URL that author_name links to. Only works when author_name is set. Optional
author_icon String An http(s) URL of a small (16×16) image shown before author_name. Only works when author_name is set. Optional
title String Larger, bold text near the top of the box. Optional
title_link String An http(s) URL that title links to. Optional
text String The main body text of the attachment. Formatted as mrkdwn. Optional
fields Object[] A table of values shown under text. Each field is { "title": String, "value": String, "short": Boolean }: title is a plain-text heading, value is mrkdwn (numbers are turned into strings), and short: true lets two fields sit side by side. Optional
image_url String An http(s) URL of an image shown full width inside the box. Optional
thumb_url String An http(s) URL of a small image shown on the right of the box. Optional
footer String Small text at the bottom of the box. Optional
footer_icon String An http(s) URL of a small (16×16) image shown before footer. Optional
ts Number A Unix timestamp (seconds; a numeric string also works). Shown in the footer as a date. Optional
mrkdwn_in String[] Which of pretext, text and fields to format as mrkdwn. Optional
blocks Object[] Block Kit blocks shown inside the box. They follow the same rules as top-level blocks and share the message’s block_id space, so their controls send block_actions like any other. Optional

Sent as text + attachments, without blocks: the text shows above the coloured box.

A status update with fields — how it renders in Repzo Chat

{
"text": "Weekly pipeline update",
"attachments": [
{
"color": "good",
"fallback": "Northwind Trading renewal moved to Negotiation (SAR 48,000)",
"pretext": "A deal moved forward in *Enterprise renewals*.",
"author_name": "Pipeline bot",
"title": "Northwind Trading renewal",
"title_link": "https://example.com/deals/northwind-renewal",
"text": "Stage changed from *Proposal* to *Negotiation*. Next step: send the revised quote by Thursday.",
"fields": [
{
"title": "Amount",
"value": "SAR 48,000",
"short": true
},
{
"title": "Close date",
"value": "Nov 28, 2026",
"short": true
},
{
"title": "Owner",
"value": "<@3f6c2a1e-8b4d-4c7a-9e21-5d0b7f9a1c34|Account owner>",
"short": true
},
{
"title": "Probability",
"value": "70%",
"short": true
}
],
"footer": "Repzo CRM",
"ts": 1791813600
}
]
}

An attachment’s blocks render inside the box, with working buttons.

Blocks inside an attachment — how it renders in Repzo Chat

{
"attachments": [
{
"color": "#e01e5a",
"fallback": "Invoice INV-2041 is 15 days overdue",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Invoice INV-2041* for *Blue Harbor Logistics* is 15 days overdue.\nBalance due: *SAR 12,450*"
}
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "Send reminder"
},
"style": "primary",
"action_id": "send_reminder",
"value": "INV-2041"
},
{
"type": "button",
"text": {
"type": "plain_text",
"text": "Open invoice"
},
"url": "https://example.com/invoices/INV-2041",
"action_id": "open_invoice"
}
]
}
]
}
]
}