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.
- 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.
- 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.
- 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.
- 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.
The parent the attachment belongs to. Set it to the FeedItem Id for a post, or a FeedComment Id to attach on a reply.
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.
For a Content attachment, the Id of the ContentVersion that holds the file. The attachment points here rather than copying the file.
For a Link attachment, the external URL. Leave it empty for Content attachments, where RecordId carries the reference instead.
- 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.