Using the SharePoint Online EmbedService API to Fetch the Title, Thumbnail Image, and More for Any URL

In my current SharePoint Online intranet project, one of the requirements is to have a web part similar to the five-tile grid “Hero” web part that displays a comment count (if linking to a modern news page) in addition to the title text. For the web part, I wanted to make it as easy as possible for users to enter a URL and then auto-populate all relevant fields for each tile in the web part. Fortunately there is an API endpoint that the Quick Links and Link web parts use that I can leverage.
I thought it was convenient that the Link and Quick Links web parts would auto-populate the title, image, and description fields after you enter a URL. After some searching online I was a bit surprised that I did not find any obvious documentation or tutorials/blogs about this feature. So I opened my browser dev tools and watched the network requests as I entered a URL into a Link web part. Sure enough, an XHR/fetch request to a SharePoint API endpoint returned the data that the web part used to populate the image, title, and description.

The endpoint is /_api/SP.Publishing.EmbedService/EmbedData?url='[url]'&version=1
where the [url]
is replaced with the URL to the page you want to retrieve data from. It looks like it uses some internal querying if you use a URL in your SharePoint tenant, because it returns not only the typical open graph data like title, image, description, but also CreatorName
with data about the SharePoint user and WebId
, SiteId
, ListId
, and UniqueId
. These actually came in very handy because I needed to make some additional REST calls to determine if the URL was in fact a news article with comments. Also note that the ThumbnailUrl
uses the getpreview.ashx
service to return an optimized version of the image from SharePoint Online. Here is an example of the data returned for a call to an internal SharePoint URL (https://yourtenant.sharepoint.com/sites/yoursite/_api/SP.Publishing.EmbedService/EmbedData?url=’https://yourtenant.sharepoint.com/sites/yoursite/SitePages/Communication%20Site%20Templates%20Enable%20News%20Posts.aspx’&version=1):
{
"@odata.context": "https://yourtenant.sharepoint.com/sites/yoursite/_api/$metadata#EmbedDataV1s/$entity",
"@odata.type": "#SP.Publishing.EmbedDataV1",
"@odata.id": "https://yourtenant.sharepoint.com/sites/yoursite/_api/SP.Publishing.EmbedService/EmbedData",
"@odata.editLink": "SP.Publishing.EmbedService/EmbedData",
"AllowHttpsEmbed": false,
"CreatorName": "11;#Josh McCarty,#i:0#.f|membership|josh.mccarty@yourtenant.com,#josh.mccarty@yourtenant.com,#josh.mccarty@yourtenant.com,#Josh McCarty",
"DatePublishedAt": "2017-10-26T08:09:19.0000000",
"Description": "These new site templates also have new web parts that are responsively designed to work on any screen size.",
"EmbedServiceResponseCode": 0,
"ErrorMessage": null,
"Html": "<iframe width='100%' height='70%' src='https://yourtenant.sharepoint.com/sites/yoursite/SitePages/Communication%2520Site%2520Templates%2520Enable%2520News%2520Posts.aspx' allowfullscreen></iframe>",
"ListId": "4b649c15-79dd-4c93-9826-824759da51e3",
"PublisherName": "",
"ResponseCode": 0,
"SiteId": "0a5fbe4a-1c6b-4cc7-b061-bc7c7285c464",
"ThumbnailUrl": "https://yourtenant.sharepoint.com:443/sites/yoursite/_layouts/15/getpreview.ashx?guidFile=47e8ace6%2Daaa4%2D432b%2D9517%2D80d301142e33&guidWeb=208e5d9f%2Db154%2D4ad2%2D932a%2De79c8a82e908&guidSite=0a5fbe4a%2D1c6b%2D4cc7%2Db061%2Dbc7c7285c464",
"Title": "Communication Site Templates Enable News Posts",
"Type": "rich",
"UniqueId": "47e8ace6-aaa4-432b-9517-80d301142e33",
"Url": "https://yourtenant.sharepoint.com/sites/yoursite/SitePages/Communication%20Site%20Templates%20Enable%20News%20Posts.aspx",
"VideoId": null,
"WebId": "208e5d9f-b154-4ad2-932a-e79c8a82e908"
}
For external URLs, SharePoint appears to proxy the request to the Bing Preview API. Here is an example of the data returned from a recent post on my website (https://yourtenant.sharepoint.com/sites/yoursite/_api/SP.Publishing.EmbedService/EmbedData?url=’https://joshmccarty.com/made-tool-generate-images-using-office-ui-fabric-icons/’&version=1):
{
"@odata.context": "https://yourtenant.sharepoint.com/sites/yoursite/_api/$metadata#EmbedDataV1s/$entity",
"@odata.type": "#SP.Publishing.EmbedDataV1",
"@odata.id": "https://yourtenant.sharepoint.com/sites/yoursite/_api/SP.Publishing.EmbedService/EmbedData",
"@odata.editLink": "SP.Publishing.EmbedService/EmbedData",
"AllowHttpsEmbed": false,
"CreatorName": "",
"DatePublishedAt": "",
"Description": "I've been working on a new intranet project that uses modern communication sites in SharePoint Online, and we're using the new Quick Links web part in two",
"EmbedServiceResponseCode": 200,
"ErrorMessage": null,
"Html": "",
"ListId": "",
"PublisherName": "",
"ResponseCode": 0,
"SiteId": "",
"ThumbnailUrl": "https://dyukvup4sm4dk.cloudfront.net/wp-content/uploads/2017/12/office-ui-fabric-icon-images.png",
"Title": "I Made a Tool to Generate Images Using Office UI Fabric ...",
"Type": "rich",
"UniqueId": "",
"Url": "https://joshmccarty.com/made-tool-generate-images-using-office-ui-fabric-icons/",
"VideoId": null,
"WebId": ""
}
I found out external requests use the Bing Preview API because when I tried a bogus URL this was the response:
{
"@odata.context": "https://yourtenant.sharepoint.com/sites/yoursite/_api/$metadata#EmbedDataV1s/$entity",
"@odata.type": "#SP.Publishing.EmbedDataV1",
"@odata.id": "https://yourtenant.sharepoint.com/sites/yoursite/_api/SP.Publishing.EmbedService/EmbedData",
"@odata.editLink": "SP.Publishing.EmbedService/EmbedData",
"AllowHttpsEmbed": false,
"CreatorName": "",
"DatePublishedAt": "",
"Description": "",
"EmbedServiceResponseCode": 200,
"ErrorMessage": "Bing Preview API return empty data or error data.",
"Html": "",
"ListId": "",
"PublisherName": "",
"ResponseCode": 3,
"SiteId": "",
"ThumbnailUrl": "",
"Title": "",
"Type": "rich",
"UniqueId": "",
"Url": "http://fakewebsite",
"VideoId": null,
"WebId": ""
}
It also works nicely for YouTube videos (and I presume many other services that offer oEmbed or similar functionality) by returning the VideoID
and the iframe
embed code in the Html
property:
{
"@odata.context": "https://yourtenant.sharepoint.com/sites/yoursite/_api/$metadata#EmbedDataV1s/$entity",
"@odata.type": "#SP.Publishing.EmbedDataV1",
"@odata.id": "https://yourtenant.sharepoint.com/sites/yoursite/_api/SP.Publishing.EmbedService/EmbedData",
"@odata.editLink": "SP.Publishing.EmbedService/EmbedData",
"AllowHttpsEmbed": true,
"CreatorName": "Microsoft Ignite",
"DatePublishedAt": "2016-09-29T03:38:57.0000000",
"Description": "In this session, learn how to manage your Microsoft SharePoint Online (SPO) and Microsoft OneDrive for Business environments in the browser (the SharePoint Online ...",
"EmbedServiceResponseCode": 200,
"ErrorMessage": null,
"Html": "<iframe width=\"1280\" height=\"720\" src=\"https://www.youtube.com/embed/FaRy3I9P6E4?autoplay=0\" frameborder=\"0\" allowfullscreen=\"\"></iframe>",
"ListId": "",
"PublisherName": "YouTube",
"ResponseCode": 0,
"SiteId": "",
"ThumbnailUrl": "https://www.bing.com/th?id=OVP.hGV1bS9uCTeLh8v1f88Q7wEsCo&pid=Api",
"Title": "Learn best practices for managing and administering SharePoint Online and OneDrive for Business",
"Type": "video",
"UniqueId": "",
"Url": "https://www.youtube.com/watch?v=FaRy3I9P6E4",
"VideoId": "0F99BFC84706882501540F99BFC8470688250154",
"WebId": ""
}
I’m a little concerned that this API may change or stop working in the future because I can’t seem to find any documentation on it. However the version parameter could mean that if changes are necessary they’ll just increment that number and keep the existing version in-place (I hope). The custom web part I’m creating still allows manual entry of all data–in case the API call fails for some reason or if the user simply wants to tweak the title or change the image. Regardless, this is exactly the kind of additional capability you would expect out of an evolving service like Office 365, and I’m very impressed with it so far. If anyone knows more about this API or has a link to official documentation, please let me know in the comment section!
Comments
Comments are closed