I'm trying to figure out if there's a way that I can leverage Salesforce Files, plus the Content Delivery and Public Links feature to create sort of a poor man's CDN for serving up images to a Salesforce Site. Right now, I can do the following things manually (in Lightning Experience):

  1. Upload an image file to my asset library.
  2. Right-click on the file and select "Public Link" and then click "Create Link".
  3. Navigate to this public link in the browser; it launches a preview page, where I can see a preview of the image.
  4. Right-click on the preview of the image in the browser and select "Copy image location".
  5. Paste this image location into the "src" attribute of an "img" tag on my Site page.

I'm basically wondering if there's a way I can programmatically do steps 2, 3 and 4 to get the URL for the image in a more direct way. I can see that creating the public link creates a ContentDistribution record in the database, which has a field (DistributionPublicUrl) that looks something like this:


This is the link that loads the preview page. The actual image location looks something like this:


Is there a way to create the public link for a file via Apex or some other mechanism?

Once I get the public link, is there a blessed way to derive the "src" URL for the image?

1 Answer 1


You can programmatically create a public link from a ContentVersionId and then get the download URL like this:

ContentDistribution publicLink = new ContentDistribution(ContentVersionId = myContentVersionId, 
    Name='External Link',
    PreferencesNotifyOnVisit = false);

insert publicLink;

publicLink = [SELECT ContentDownloadUrl, ContentDocumentId
            FROM ContentDistribution 
            WHERE Id = :publicLink.Id];

System.debug('Download from: ' + publicLink.ContentDownloadUrl);

You can then use that as the src in an image.

Note that you need to be aware of limits if you're doing this:

the total number of content-delivery views allowed within a 24-hour period is limited to 20,000 and the amount of bandwidth allocated to content deliveries is limited to 20 GB. If recipients try to view deliveries after rate limit are exceeded, they’ll be prompted to try again later. Salesforce may be able to increase rate limits on an exception basis. For more information, contact your sales representative.

From https://help.salesforce.com/articleView?id=content_delivery_about.htm&type=5

So, if you're expecting high volume, you might still need to use a caching solution like CloudFront. See my old question here:

Using File/ContentDocument as an image in an unauthenticated community

  • Thank you. This looks like just what I need. Not sure how I missed that "Content Download Url" field on ContentDistribution. However, when I try executing this code for a file which I uploaded, I'm getting the following permission related error when I try to insert the new ContentDistribution record: System.DmlException: Insert failed. First exception on row 0; first error: INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY, insufficient access rights on cross-reference id: []. I believe I have all required permissions. I can create a link manually. Any thoughts on what I'm missing?
    – tlfu
    Mar 15, 2018 at 11:41
  • I figured out my permission problem. My user had "Workspace Administrator" permission on the library itself, rather than "Author". Seems a bit counterintuitive that "Author" is the most privileged permission, and not "Workspace Administrator". Your suggestion works for me.
    – tlfu
    Mar 15, 2018 at 12:23
  • @Aidan, thanks for sharing this. The docs on this are pretty spare. In fact, the fields you query aren't even listed on this page: developer.salesforce.com/docs/atlas.en-us.sfFieldRef.meta/… Nov 14, 2018 at 18:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .