Business Login for Instagram

Business Login is a custom, login flow that allows your app to ask for permissions to access your app user's Instagram professional account data and to get an access token to use in your app's API requests.

To ensure consistency between scope values and permission names, we are introducing new scope values for the Instagram API with Instagram login. The new scope values are:

  • instagram_business_basic
  • instagram_business_content_publish
  • instagram_business_manage_messages
  • instagram_business_manage_comments

These will replace the existing business_basic, business_content_publish, business_manage_comments and business_manage_messages scope values, respectively.

Please note that the old scope values will be deprecated on January 27, 2025. It is essential to update your code before this date to avoid any disruption in your app's functionality. Failure to do so will result in your app being unable to call the Instagram endpoints.

Before you start

If you haven't already, add the Instagram product to your app and configure your Business login settings in the Meta App Dashboard.

Embed the business login URL

You should have completed this step during Instagram app setup in the App Dashboard, but if not, complete the following steps.

  1. Copy the Embed URL from the Set up business login in the App Dashboard.
  2. Paste the URL in an anchor tag or button on your app or website to launch the login flow.

Step 1. Get authorization

When a person clicks the embed URL link or button to log in to your app, they are directed to an authorization window. This window allows app users to grant your app permissions and short-lived Instagram User access tokens.

Example embed URL

https://www.instagram.com/oauth/authorize?client_id=97563852873&redirect_uri=https://my.m.redirect.net/&response_type=code&scope=business_basic%2Cbusiness_manage_messages%2Cbusiness_manage_comments%2Cbusiness_content_publish

Query string parameters

ParameterDescription

client_id
Required
Numeric string

Your Instagram App ID displayed in App Dashboard > Instagram > API setup with Instagram login > 3. Set up Instagram business login > Business login settings > Instagram App ID.

enable_fb_login
boolean

Value can be 0 or 1. When set to 1: Allows an app user, whose Facebook Page is linked to their Instagram professional account and who is already logged in to Facebook, to log in to your app. When set to 0: Forces an app user to log in with their Instagram professional account credentials even if logged into Instagram. Use in conjunction with force_authentication set to 1.

force_authentication
boolean

Value can be 0 or 1. When set to 1: Forces an app user use their Instagram professional account credentials to log into your app even if logged into Instagram. Use in conjunction with enable_fb_login set to 0. When set to 0: Allows an app user who is logged into their Instagram account.

redirect_uri
Required
String

A URI where we will redirect users after they allow or deny permission request. Make sure this exactly matches one of the base URIs in your list of valid OAuth URIs you set during API setup in the App Dashboard. Keep in mind that the App Dashboard might have added a trailing slash to your URIs, so we recommend that you verify by checking the list. App Dashboard > Instagram > API setup with Instagram login > 3. Set up Instagram business login > Business login settings> OAuth redirect URIs.

response_type
Required
String

Set this value to code.

scope
Required
Comma- or space-separated list

A comma-separated or URL-encoded space-separated list of permissions to request from the app user.

Permission nameCorresponding scope name

instagram_business_basic (Required)

business_basic (Required)

instagram_business_content_publish

business_content_publish

instagram_business_manage_comments

business_manage_comments

instagram_business_manage_messages

business_manage_messages

state
String

An optional value indicating a server-specific state. For example, you can use this to protect against CSRF issues. We will include this parameter and value when redirecting the user back to you.

Successful authorization

If authorization is successful, we will redirect the user to your redirect_uri and pass you an Authorization Code through the code query string parameter. Capture the code so your app can exchange it for a short-lived Instagram User access token.

Authorization Codes are valid for 1 hour and can only be used once.

Sample Successful Authentication Redirect

Example redirect URI response

https://my.m.redirect.net/?code=abcdefghijklmnopqrstuvwxyz#_

NOTE: The #_ appended to the end of the redirect URI is not part of the code itself, so strip it out.

Canceled authorization

If the user cancels the authorization flow, we will redirect the user to your redirect_uri and attach the following error parameters. It is your responsibility to fail gracefully in these situations and display an appropriate message to your users.

ParameterValue

error

access_denied

error_reason

user_denied

error_description

The+user+denied+your+request

Sample Canceled Authorization Redirect

https://my.m.redirect.net/auth/?error=access_denied&error_reason=user_denied&error_description=The+user+denied+your+request

Step 2. Exchange the Code For a Token

To get the access token, send a POST request to the https://api.instagram.com/oauth/access_token endpoint with the following parameters:

  • client_id set to your Instagram app ID from the App Dashboard
  • client_secret set to your Instagram App Secret from the App Dashboard
  • grant_type set to authorization_code
  • redirect_uri set to your redirect URI
  • code set to the code value from the redirect URI response

Sample request

Formatted for readability.

curl -X POST https://api.instagram.com/oauth/access_token \
  -F 'client_id=<YOUR_INSTAGRAM_APP_ID>' \
  -F 'client_secret=<YOUR_INSTAGRAM_APP_SECRET>' \
  -F 'grant_type=authorization_code' \
  -F 'redirect_uri=https://<YOUR_REDIRECT_URI>/' \
  -F 'code=<CODE>'

On success, your app receives a JSON response containing the app user's short-lived access token, their Instagram App-scoped User ID, and a list of the permissions granted by the app user.

{
  "data": [
    {
      "access_token": "<THE_ACCESS_TOKEN>", 
      "user_id": "<INSTAGRAM_APP_SCOPED_USER_ID>",
      "permissions": "<LIST_OF_GRANTED_PERMISSIONS>"
    }
  ]
}         

Capture the access_token value. This is the user’s short-lived Instagram User access token which your app can use to access Instagram API with Instagram Login endpoints.

Parameter reference

ParameterSample ValueDescription

client_id
Required
Numeric string

990602627938098

Your Instagram App ID displayed in App Dashboard > Instagram > API setup with Instagram login > 3. Set up Instagram business login > Business login settings > Instagram App ID.

client_secret
Required
String

a1b2C3D4

Your Instagram App Secret displayed in App Dashboard > Instagram > API setup with Instagram login > 3. Set up Instagram business login > Business login settings > Instagram app secret.

code
Required
String

AQBx-hBsH3...

The authorization code we passed you in the code parameter when redirecting the user to your redirect_uri.

grant_type
Required
String

authorization_code

Set this value to authorization_code.

redirect_uri
Required
String

https://my.m.redirect.net/

The redirect URI you passed us when you directed the user to our Authorization Window. This must be the same URI or we will reject the request. App Dashboard > Instagram > API setup with Instagram login > 3. Set up Instagram business login > Business login settings> OAuth redirect URIs.

Sample Rejected Response

If the request is malformed in some way, the API will return an error.

{
  "error_type": "OAuthException",
  "code": 400,
  "error_message": "Matching code was not found or was already used"
}

Step 3. Get a long-lived access token

You can exchange your app user's short-lived access token for a long-lived access token that is valid for 60 days.

Requirements

  • The short-lived access token must be valid (not expired)
  • Requests for long-lived tokens must be made in server-side code. These requesting include your app secret which you never want to expose in client-side code or in an app binary that could be decompiled. Do not share your app secret with anyone, expose it in code, send it to a client, or store it in a device.

To get a long-lived access token, send a GET request to the /access_token endpoint with the following parameters:

  • grant_type set to ig_exchange_token
  • client_secret set to your Instagram app secret
  • Your app user's valid (unexpired) short-lived Instagram user access token

Sample Requests

curl -i -X GET "https://graph.instagram.com/access_token
  ?grant_type=ig_exchange_token
  &client_secret=<YOUR_INSTAGRAM_APP_SECRET>
  &access_token=<VALID_SHORT_LIVED_ACCESS_TOKEN>"

On success, your app receives a JSON response with your app user's long-lived access token, the token type, and the expiration.

{
  "access_token":"<LONG_LIVED_ACCESS_TOKEN>",
  "token_type": "bearer",
  "expires_in": 5183944  // Number of seconds until token expires
}

Refresh a long-lived token

Your app user's long-lived access token can be refreshed for another 60 days as long as the existing conditions are true:

  • The existing long-lived access token is at least 24 hours old
  • The existing long-lived access token is valide (not expired)
  • The app user has granted your app the instagram_business_basic permission

Tokens that have not been refreshed in 60 days will expire and can no longer be refreshed.

To exchange your app user's long-lived token that is set to expire, send a GET request to the /refresh_access_token endpoint with the following parameters:

  • grant_type set to ig_refresh_token
  • access_token set to the long-lived access token that is about to expire

Sample Requests

curl -i -X GET "https://graph.instagram.com/refresh_access_token
  ?grant_type=ig_refresh_token
  &access_token=<LONG_LIVED_ACCESS_TOKEN>"

On success, your app receives a JSON response with your app user's long-lived access token, the token type, and the expiration.

{
  "access_token":"<LONG_LIVED_ACCESS_TOKEN>",
  "token_type": "bearer",
  "expires_in": 5183944  // Number of seconds until token expires
}