Skip to content
Salesforce Dictionary - Free Salesforce GlossarySalesforce Dictionary
DictionaryFFeed Attachment, Chatter
Core CRMBeginner

Feed Attachment, Chatter

A Feed Attachment in Chatter is a record that links a file, image, or external link to a Chatter post.

§ 01

Definition

A Feed Attachment in Chatter is a record that links a file, image, or external link to a Chatter post. The object is named FeedAttachment, and it sits between a FeedItem (the post) and the thing being attached. When you drag a file into the feed composer or share a link in a post, the platform writes a FeedAttachment row that tells the feed what to render and where the underlying content lives.

FeedAttachment is a junction-style object. It does not store the file itself. For a file, it points to a ContentVersion record through the RecordId field. For a link, it stores the URL in the Value field. The Type field marks each attachment as Content, Link, or InlineImage, and the feed UI uses that to decide how to display it. The object has existed since API version 36.0, and one post can carry several attachments at once.

§ 02

How FeedAttachment wires posts to files

The object and the fields that matter

FeedAttachment is a standard object you query with SOQL like any other. The fields you reach for most are FeedEntityId, Type, RecordId, Value, and Title. FeedEntityId is the parent, and it points at either a FeedItem or a FeedComment, so an attachment can belong to a post or to a reply on that post. Type is a picklist with three values: Content, Link, and InlineImage. RecordId holds the Id of the related record for a Content attachment, which is the ContentVersion that represents the file. Value holds the external URL when the attachment is a Link. Title is the label shown in the feed, usually the file name or the link text. None of these fields live in isolation. A Content row without a valid RecordId renders nothing, and a Link row needs its Value populated to be useful. Because the object is thin by design, most reporting questions need a join. You start at FeedAttachment, hop to FeedItem for the author and timestamp, then hop to ContentDocument or ContentVersion for file metadata. That three-stop path answers who posted what file and when.

Content, Link, and InlineImage

The three Type values behave differently in the feed. A Content attachment is a Salesforce file. Its RecordId points to a ContentVersion, and the feed shows a preview tile with a download option. A Link attachment is an external URL stored in Value, and it renders as a link, sometimes with a small preview card pulled from the target page. An InlineImage attachment is an image dropped directly into the body of the post, so it appears in the flow of the text rather than as a separate tile below it. The split matters when you build posts in code. You attach a file by creating a Content row that references an existing ContentVersion. You attach a link by setting Type to Link and filling Value. Inline images usually come through the Chatter REST API or Connect in Apex, where you mark an image segment in the message body. Knowing which Type you need saves you from posting a screenshot as a download tile when you wanted it shown in line, or from forcing an external URL into a file attachment that has nothing to point at.

One post, several attachments, one link cap

A single FeedItem can carry more than one FeedAttachment. Drag three files into the composer and you get one post plus three Content rows, all sharing the same FeedEntityId. The feed renders them together, and a viewer scrolls through the set under the post body. There is one rule that trips people up. You can attach only one Link per feed item. The platform allows many file and image attachments on a post, but the Link type is capped at one. If your integration tries to add a second Link row to the same FeedItem, the insert fails. The workaround is to put extra URLs in the post text itself, where they still become clickable, rather than as separate Link attachments. This cap is worth remembering when you migrate posts between orgs or rebuild feeds from an export. A source post that mixed two links will not reproduce exactly, and your load logic has to fold the second link into the body. Plan for it before the data move rather than chasing failed rows afterward.

Attachments on comments, not just posts

FeedAttachment is not limited to the top-level post. Because FeedEntityId can point at a FeedComment, a reply can carry its own attachment. This is common in real conversations. Someone posts a question, and the answer arrives as a file attached to a comment further down the thread. When you query attachments for a record, filtering only on FeedItem parents misses these. You either query FeedAttachment with both parent types in mind or walk the comments separately. For admins building feed audits, this detail changes the count. A report that joins only posts to attachments undercounts, because the attachments hanging off comments never appear. The same applies to retention or cleanup jobs. If you delete posts but ignore comment attachments, files referenced from replies keep their pointers. The structure is consistent once you accept that an attachment belongs to a feed entity, and a feed entity is a post or a comment. Treat both as valid parents and your queries line up with what users actually see in the thread.

Pointers, not copies, of file storage

A FeedAttachment of type Content does not duplicate the file. The bytes live once in ContentVersion, the file row, with ContentDocument acting as the container that groups versions. FeedAttachment only holds a reference through RecordId. That design has practical consequences. Deleting a FeedAttachment removes the inline display from the post but leaves the file intact in Files. Deleting the underlying file breaks the reference, so the post loses its tile even though the attachment row may still exist for a moment. Storage is counted against the file, not against each place it is shared, so attaching one document to ten posts does not multiply your file storage ten times. When you upload a file specifically for a Chatter post in code, you set the ContentVersion Origin to H, which marks it as a Chatter-originated file. Understanding the pointer model helps you reason about cleanup, storage limits, and what actually happens when content is removed. The post and the file have separate lifecycles that meet only at the FeedAttachment reference.

Access control follows the file and the post

Seeing an attachment in a feed requires two things at once. The viewer has to be able to see the FeedItem, and the viewer has to have access to the underlying file through file sharing and field-level security. The platform composes both checks. A user who can read the post but lacks access to the ContentVersion does not get to bypass that by way of the feed. This matters in Experience Cloud sites and shared groups, where the audience for a post can be wide. Posting a confidential file into a broadly visible feed does not strip the file of its own sharing. The attachment shows for those who already have rights to the content and stays hidden from those who do not. Search behaves the same way. Salesforce indexes posts and the contents of supported file types, so a search can surface a post by words inside an attached PDF or Word document. Results still respect access, so a user only finds attachments they were allowed to see in the first place. Security lives on the file and the post, and the attachment inherits both.

Not triggerable, so read it in the post trigger

FeedAttachment is not a triggerable object. You cannot write an Apex trigger that fires on FeedAttachment insert, update, or delete. That surprises developers who want to react the moment a file lands on a post. The supported pattern is to handle the event on FeedItem instead. In a FeedItem update trigger you query the related FeedAttachment rows with SOQL and act on what you find. The attachments are available there even though you cannot hook the attachment object directly. This shapes how you design feed automation. If your requirement is to scan attached files for a keyword, tag posts that include documents, or notify a team when a file appears, the logic belongs in FeedItem handling backed by a query. The same applies to validation. You cannot block an attachment with a FeedAttachment trigger, so any guardrail runs against the post and inspects its attachments after the fact. Building on FeedItem with a SOQL lookup is the path the platform expects, and it keeps your automation on supported ground.

§ 03

Attach a file to a Chatter post in code

You usually do not insert a FeedAttachment by hand. You create one by posting a file to a feed, either in the UI or in code. The code path is the one worth knowing, because integrations and Apex often attach an existing Salesforce file to a post. Here is the shape of that flow.

  1. Have a ContentVersion ready

    Make sure the file exists as a ContentVersion. If you are uploading fresh for a post, set the Origin field to H to mark it as Chatter-originated. Capture the ContentVersion Id you will reference.

  2. Create the FeedItem

    Insert a FeedItem with ParentId set to the record or user the post belongs to and a Body for the text. This is the post the attachment will hang on. Keep its Id.

  3. Insert the FeedAttachment

    Create a FeedAttachment with FeedEntityId set to the FeedItem Id, Type set to Content, and RecordId set to the ContentVersion Id. Insert it, and the file now renders inline on the post.

  4. Verify in the feed

    Open the record or profile feed and confirm the file tile appears under the post. Check that users without file access do not see it, which confirms sharing is intact.

FeedEntityIdrequired

The parent the attachment belongs to. Set it to the FeedItem Id for a post, or a FeedComment Id to attach on a reply.

Typerequired

Content for a Salesforce file, Link for an external URL, or InlineImage for an image shown in the body. This drives how the feed renders it.

RecordIdrequired

For a Content attachment, the Id of the ContentVersion that holds the file. The attachment points here rather than copying the file.

Valuerequired

For a Link attachment, the external URL. Leave it empty for Content attachments, where RecordId carries the reference instead.

Gotchas
  • Only one Link attachment is allowed per feed item. A second Link insert on the same post fails, so put extra URLs in the post body.
  • FeedAttachment is not triggerable. Query it from a FeedItem update trigger instead of trying to hook the attachment object directly.
  • Deleting the attachment does not delete the file. The ContentVersion stays in Files, so cleanup of storage is a separate step.

Prefer this walkthrough as its own page? How to Feed Attachment, Chatter in Salesforce, step by step

§

Trust & references

Official documentation

Straight from the source - Salesforce's reference material on Feed Attachment, Chatter.

Keep learning

Hands-on resources to go deeper on Feed Attachment, Chatter.

Was this entry helpful?
Help us write better definitions. Quick reactions or detailed edit suggestions.

About the Author

Dipojjal Chakrabarti is a B2C Solution Architect with 29 Salesforce certifications and over 13 years in the Salesforce ecosystem. He runs salesforcedictionary.com to help admins, developers, architects, and cert/interview candidates sharpen their fundamentals. More about Dipojjal.

§

Test your knowledge

Q1. What underlying object does a Chatter Feed Attachment most commonly point to for a file dropped into a feed post?

Q2. How does the platform handle one feed post when a user drags three files into the Chatter composer?

Q3. What happens to a file in Salesforce when its Feed Attachment record is deleted from a Chatter post?

§

Discussion

Loading…

Loading discussion…