An example Link Preview for a GitHub workflow
Configure Link Preview settings in the Developer portal
Set up the authorization flow
Use the Unfurl Callback URL
Manage updates to Link Previews
Submit your connection for security review
Requirements
- You’ve requested and received access to the Link Previews API.
- You own the domain that you’re using to create Link Previews. You’ll need to share a verification code from Notion with your domain host when you initialize the connection.
- Your application supports OAuth 2.0.
- You’ve read the Link Previews overview, so you have a good idea of what you’re building and how it works.
- You’ve read the Authorization guide and have familiarized yourself with Notion connections.
Create a public Notion connection
Link Preview connections are a type of public connection. To create a Link Preview connection, you must first create a public connection. Once the public connection is created, you can enable the link preview setting through the connection’s settings. To learn how to create a public connection, follow the Authorization guide.Configure Link Preview settings in the Developer portal
This step will guide you through enabling link previews for your connection, as well as filling out the link preview connection forms found in your connection settings. To start, navigate to the public connection you will be using for your link preview connection. It can be found in the Developer portal. If you have access to the Link Preview API, you will see a Link Preview section in the Configuration tab.

- The External Authorization Setup form.
- The Unfurling Domain & Patterns form.
Enable link preview as an option, then:- Make sure that you’ve applied and received access to the Link Previews API.
- Confirm that you’re logged in to the Notion account that you used to request access.
- Reach out to developers@makenotion.com if you continue to have issues.
1. Fill out the External Authorization Setup form
The External Authorization Setup settings give Notion the information that it needs to let a user authenticate with your service when they paste a Link Preview enabled URL in Notion."Submit ->" to continue to Unfurling Domain & Patterns.
2. Fill out the Unfurling Domain & Patterns form
The Unfurling Domain & Patterns settings give Notion the information that it needs to recognize the URLs that you want to unfurl Link Previews."Submit ->" to create the connection.
Set up the authorization flow
There are two high-level parts to the auth flow for a Link Preview:- Your service authenticates with Notion. Notion sends a
codeto your OAuth Authorize URL. Your connection exchanges thiscodefor a Notionaccess_tokenthat enables your service to make authenticated requests to the Link Previews APIs. - Notion authenticates with your service. Your service responds to Notion’s request with a
code. Notion exchanges this token for your service’saccess_tokenvia your OAuth Token URL. This allows Notion to embed the data from your service in Link Previews.
access_token is long-living and doesn’t need to be updated. If you prefer, Notion can also support refresh tokens and fetch new tokens from your service.
The auth flow begins when a user shares your Link Preview enabled URL in Notion. Notion recognizes the link and redirects to the OAuth Authorize URL that you provided in the connection settings.
Notion includes the following query params to kick off the OAuth flow with your service:
1. Provide OAuth form
Listen for requests to your OAuth Authorize URL. When you detect a request from Notion, present a UI that asks the user to allow the authentication process to continue. For example, Slack shares the following interstitial when a user initiates a Link Preview from a Slack URL:
An example interstitial from a Slack Link Preview auth flow
2. Authenticate with Notion’s access_token
In your connection implementation, retrieve the code that Notion sent when it called your OAuth Authorize URL. Then, send the code as part of a POST request to Notion’s token URL: https://api.notion.com/v1/oauth/token.
code is valid for 10 minutes. If the code expires, then an error is returned and you need to reinitiate the auth flow for Notion to authenticate with your service (Step 1).To explore other possible errors, refer to the OAuth 2.0 documentation. Default to re-initiating the auth flow to handle errors.CLIENT_ID and CLIENT_SECRET: CLIENT_ID:CLIENT_SECRET. You can find these values on the connection settings page. Find your connection, and click View connection.
Use the latest Notion API version, , when sending requests to the Notion API.

You can find your connection's client ID and client secret on the connection settings page
base64 encoded before being added to the Authorization header. Notion also requires the word Basic before the base64 encoded string. A complete code param looks something like the following:Basic NjQ5Mzc0OTIzNzQ5MjM4NDc5MjM4NDc5MjM0NzkyMzc0OjQ3Mzg5Mjc0OTIzODQ3Mjk0ODcyMzkzNDgyNzk0ODcyMzQ5For more information, read about HTTP Basic Authentication in our Authorization guide.external_account object for team@makenotion.com, a Notion employee account, to authenticate with Slack to use a Slack Link Preview.
name appears in the "My connections" settings page, where a user can review their authentications for your connection.

An example authenticated Slack connection listed in a user’s "My connections" settings page.
access_tokens, check out the auth guide.3. Redirect to the redirect_uri with code
When a user selects "Allow" to grant Notion the requested permissions, redirect to the redirect_uri , the constant string notion.so/externalIntegrationAuthCallback, with your service’s unique code and the state that Notion sent to your service when it initiated the auth flow.
When Notion receives the redirect, it sends a POST request to the OAuth Token URL that you provided with the following body:
application/x-www-form-urlencoded format and expects a JSON response.
4. Share the access_token with Notion
From your OAuth Token URL, respond to Notion’s POST request with an access_token body parameter in your 200 response.
Notion saves the access_token to send in future requests. Notion sends a request to your Unfurl Callback URL every time that the user associated with the token pastes a new Link Preview enabled URL or revisits a page with an existing Link Preview to refresh data.
How Notion handles OAuth errors
Notion handles error responses as described by the OAuth Error Spec. The message that Notion displays to the user varies depending on the information that you provide.
For example, you can respond with an error and a standard error code like access_denied:
https://notion.so/externalintegrationauthcallback?error=access_denied
In this instance, Notion shares the following message:

The message that Notion displays in the UI when it receives an access denied error code from your service
error_description to the response:
https://notion.so/externalintegrationauthcallback?error=access_denied&error_description=The+user+has+denied+your+application+access
If Notion detects a description, then it replaces the standard dialogue prompt with the specified description, as in the below:

If you provide an error_description parameter, then the message in the Notion UI displays it

The message that Notion displays in the UI when it doesn't recognize an error code
How to use refresh tokens (optional)
Return a refresh_token
Instead of creating a long-living access_token, you can send a refresh_token alongside a temporary access token. Notion can then use the refresh_token to fetch new tokens from your service.
If you return a refresh_token, then you need to also return an expires_in integer, as in the following example:
expires_in represents the number of seconds until the access_token expires.
Notion requests to refresh a token
If Notion detects that theaccess_token is expired, meaning that the current time exceeds the time of the last refresh plus the expires_in value, then Notion refreshes the tokens when it calls your endpoints.
To refresh the token, Notion sends a POST request to your OAuth Token URL with the following parameters:
Respond to Notion’s request to refresh a token
From your OAuth Token URL, return anaccess_token in your 200 response. You can optionally return new refresh_token and expires_in values.
5. Test the auth flow in Notion
To test the auth flow, make sure that you’ve added the connection to a workspace. Then, navigate to"My connections" in the workspace settings. Click "Show all". Find the connection that you created in the list, and select "Connect" to kick off the auth flow.

Guess which icon represents our test connection
"My connections" menu.

The new entry that appeared when we connected a much happier test Link Preview connection
key for this connection is unique, repeat the auth flow multiple times using the same credentials to validate that you only get a single entry.
Use the Unfurl Callback URL
1. Configure unfurl attributes
After a user pastes a Link Preview enabled link and completes the auth flow, Notion sends a POST request to the Unfurl Callback URL that you provided in the connection settings.
Notion sends the access_token from your service in a POST to the Unfurl Callback URL that you provide
access_token from your service, and the payload is a single field called uri that includes the link that the user shared:
uri, and an array of all of the unfurl attributes, the values to display in the Link Preview. The array must include a title attribute that gives the Link Preview a title and a dev attribute that indicates the developer or company that created the Link Preview.
The following is an example response:
2. Handle unfurl request errors
Set up the Unfurl Callback URL to handle errors, as in the following example.Manage updates to Link Previews
Update Link Previews to reflect data shared in unfurl attributes
If the unfurl attributes from your service change over time, then you can alert Notion to update the Link Preview to mirror those changes. When your service detects changes to data that is referenced by a Link Preview, send a PATCH request to Notion’s/v1/external/object endpoint to update the unfurl attributes.

To update the unfurl attributes displayed in a Link Preview, send a PATCH request to Notion’s /v1/external/object endpoint using all of the attributes from the original Unfurl Callback URL response
error. If no error is sent, then the error is automatically cleared.Notion updates your service when a user deletes Link Preview enabled URLs
When a user deletes all Link Previews associated with a URL from their workspace, Notion sends a DELETE request to your Unfurl Callback URL.
Notion sends a DELETE request to your /unfurl endpoint.
Submit your connection for security review
Before a Link Preview connection can be publicly distributed, it needs to pass a security review. Fill out this form to submit your connection for review. Next steps- To learn more about customizing a Link Preview’s unfurl attributes, refer to the reference docs