OAuth 2.0

Apps connect to Box using OAuth 2.0, the standard used by most APIs for authenticating and authorizing users. The following walkthrough will show you how to authenticate a user. There are also Box SDKs that include implementations of the OAuth2 grants used by Box, or client libraries available in a number of languages that you might find useful.

If you just need OAuth tokens for your own account for testing, we recommend you use the developer token available inside your application configuration page, or check out this Heroku app or it’s github repo for generating tokens.

Customer using Active Directory, LDAP, Siteminder or ‘SSO’?

Is your customer asking that you make your application work with an Identity Provider or Single Signon system that sounds like alphabet soup? Googled it and it’s for SSO on a mainframe, or something from the dark ages of computing? No problem: Box has you covered! If you authenticate your application via Box’s OAuth 2.0, your application with automatically let the customer sign-on with their company credentials, just like they do with every other Box application. This also applies to popular commercial services like Okta, One Login, and Ping.

Initial Setup


When your app is set to ‘Development’ mode, you can set your redirect_uri to the following local http endpoints:,, and http://localhost.

Before you can start using OAuth2 with your application, you’ll need to tell Box a bit of information about your application

  1. Register your application here.
  2. Set your redirect url
  3. Select your scope
  4. Make a note of both your client_id and client_secret.

Redirect URI:

The redirect URI is the URL within your application that will receive the OAuth2 credentials.


Select the “Read and write all files and folders” scope if your application needs to perform operations on files and folders, such as creating, downloading, editing, and deleting files and folders. Select the “Manage an enterprise” scope if your application needs to perform enterprise management, such as creating, editing, and deleting users and groups, viewing admin logs, and creating collaborations for groups.

OAuth2 Scope

Read and write all files and folders

Allows the application to upload, view, download file versions, and update the current file version.

Allows the application to create, edit, and delete collaborations, tags, tasks, comments, @mentions, task assignments, notifications, and collections.

Allows the application to view the enterprise profile.

Manage an enterprise

Full set of scopes available for performing enterprise management, which includes permissions to view, create, edit, and delete users, content, collaborations, groups, reports, and admin settings.

Manage an enterprise's managed users

Subset of the Manage an enterprise scope

Allows the application to add, view, edit, delete, activate, and disable standard Box users.

Allows the application to change the primary login, reset password, and change role for managed users, as well as manage enterprise content.

Manage an enterprise's groups

Subset of the Manage an enterprise scope

Allows the application view, create, edit, and delete groups and group memberships.

Manage an enterprise's properties

Subset of the Manage an enterprise scope

Allows the application to view and edit enterprise attributes and reports; edit and delete device pinners.

Manage an enterprise's retention policies

Allows the application to view and create content retention policies with Box Governance. Learn more here.

Create and manage app users

Allows the application to provision and manage its own App Users using the App Auth feature. Learn more here.

The First Leg

First, direct your user to https://account.box.com/api/oauth2/authorize through either a POST or a GET request with the following parameters:


For POST, include the parameters in the POST body. For GET, include them as query parameters. In both cases, URL encode the parameters.



Whether the endpoint returns an authorization code. For web applications, a value of code should be used.



The client_id you obtained in the Initial Setup.


An HTTPS URI or custom URL scheme where the response will be redirected. Must be registered with Box in the application console. Wildcard redirect_uri values are also accepted in the request as long as the base url matches the URI registered in the application console. A registered redirect_uri of https://www.myboxapp.com can be dynamically redirected to https://www.myboxapp.com/user1234 if passed into the request redirect_uri parameter.



An arbitrary string of your choosing that will be included in the response to your application. Anything that might be useful for your application can be included. Box roundtrips this information back to your application, and strongly recommends that you include an anti-forgery token, and confirm it in the response to prevent CSRF attacks to your users.


The email address of the user that you want to have pre-populated in the login form

A sample GET request could therefore look like:

GET https://account.box.com/api/oauth2/authorize?response_type=code&client_id=MY_CLIENT_ID&state=security_token%3DKnhMJatFipTAnM0nHlZA

The User Experience

At this point, you’ve forwarded the user to Box’s authorization page:

Your application doesn’t need to do anything here; Box handles authenticating the user and giving them feedback on any errors:

After successfully entering their credentials, the user will be taken to a consent page, to authorize your application to access their account.

After clicking either Grant or Deny, you’ll receive a response from Box, as outlined in the next section.

Handling the Response from Box

If the user clicked Grant in the previous screen, Box will redirect to the URI you specified earlier with a code parameter and a state parameter, if you included one. For example, if your redirect URI was https://www.sean.com/rose, Box would redirect to:


Authorization Code:

The authorization code is only valid for 30 seconds.

However, if the user clicked Deny, you will receive a request with an error and error_description parameter, such as:

GET https://www.sean.com/rose?error=access_denied&error_description=The+user+denied+access+to+your+application

Assuming you got a Grant response, At this point you should verify that the CSRF security_token you received back is the same one you gave the user back in the First Leg. This will help make sure that it really is your user, and not a malicious script. If the code doesn’t match you should reject with a 401 code.

The following conditions may also cause an error:


The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.


The authorization server does not support obtaining an authorization code using this method.

Check the value of the code param in your request.


The resource owner or authorization server denied the request.


The device the user is trying to log in from is not authorized to access the user’s account.


Your device is being rate limited, you need to either decrease your rate of authorization requests, or wait a bit.

Error Handling:

The error parameter will always be present, while the human readable error_description may not. Your code should rely on error.

Getting the Access Token

Once your application has completed the above section and gotten an authorization code, it’ll now need to exchange the authorization code for an access token from Box.

Access Token:

The access token is what’s needed to sign your API requests to Box. You’re almost done!

To get the access_token, you’ll need to make a POST request to https://api.box.com/oauth2/token with the following parameters:



Must be authorization_code



The authorization code you retrieved previously



client_id gotten from Box in Initial Setup



client_secret gotten from Box in Initial Setup


Required to be configured at box.com/developers/services


The requests must be over HTTPS and the parameters must be URL encoded.

An example request in cURL looks like:

curl https://api.box.com/oauth2/token \
-d 'grant_type=authorization_code&code={your_code}&client_id={your_client_id}&client_secret={your_client_secret}' \

If everything goes right and the request is successful, you’ll receive a 200 response containing a JSON body like this:

    "access_token": "T9cE5asGnuyYCCqIZFoWjFHvNbvVqHjl",
    "expires_in": 3600,
    "restricted_to": [],
    "token_type": "bearer",
    "refresh_token": "J7rxTiWOHMoSC1isKZKBZWizoRXjkQzig5C6jFgCVJ9bUnsUfGMinKBDLZWP9BgR"

However, if the response is not successful, you’ll receive an error response, such as this:

    "error": "invalid_grant",
    "error_description": "Invalid user credentials"

Box supports the full set of error codes in the OAuth 2.0 spec:

The last four (redirect_uri_mismatch,, internal_server_error, insecure_redirect_uri, invalid_redirect_uri) are not returned to the application. Instead, they are shown to the end user in a Box-generated error page, like this:

Using the Access and Refresh TokensThe access_token is the actual string needed to make API requests. Each access_token is valid for 1 hour. In order to get a new, valid token, you can use the accompanying refresh_token. Each refresh_token is valid for one use in 60 days. Every time you get a new access_token by using a refresh_token, we reset your timer for the 60 day period and hand you a new refresh_token. This means that as long as your users use your application once every 60 days, their login is valid forever. To use the refresh_token to get a new access_token, make a POST request to https://app.box.com/oauth2/token with the following, URL encoded parameters:A sample cURL request would look like:

curl https://api.box.com/oauth2/token \ -d 'grant_type=refresh_token&refresh_token={valid refresh token}&client_id={your_client_id}&client_secret={your_client_secret}' \ -X POST

If the request is successful, you’ll see a response like this:

{ "access_token": "T9cE5asGnuyYCCqIZFoWjFHvNbvVqHjl", "expires_in": 3600, "restricted_to": [], "token_type": "bearer", "refresh_token": "J7rxTiWOHMoSC1isKZKBZWizoRXjkQzig5C6jFgCVJ9bUnsUfGMinKBDLZWP9BgR" }

In this response, you’ll receive both a new access_token and refresh_token. The refresh_token you used to make this request is no longer valid. If an error occurs, you’ll receive a 400 Bad Request, along with of the errors listed in the Getting the Access Token section.Using Your Access Token with API V2Once you have a valid access_token, you can use it to make requests to API V2. All you need to do is set it in the Authorization header like this:

Authorization: Bearer {a valid access token}

If you were, for example, trying to get a user’s folder in V2, a full cURL request would look like this:

curl https://www.box.com/api/2.0/folders/0 \ -H "Authorization: Bearer T9cE5asGnuyYCCqIZFoWjFHvNbvVqHjl"

If the protected resource request does not include authentication credentials or does not contain an access token that enabled access to the protected resource, Box sets the WWW-Authenticate response header field. If the protected resource request included an access token and failed authentication, Box sets the “error” attribute to provide the client with the reason why the access request was declined. Box also includes the error-description attribute to provide developers a human-readable explanation that is not meant to be displayed to end users. The following codes can be returned as a value for the WWW-Authenticate header.Destroying TokensIf you would like to get rid of tokens for a user (e.g. if you have a ‘logout of Box’ button in your app), make a POST request to https://www.box.com/oauth2/revoke with the following URL encoded parameters:



The client_id used to create this token

Type: string



The client_secret used to create this token

Type: string



The access_token or refresh_token to be destroyed. Only one is required, though both will be destroyed.

Type: string

For example, to destroy access_token 1234 and its associated refresh_token, you would issue this request:

curl https://www.box.com/oauth2/revoke \ -d 'client_id=CLIENT_ID&client_secret=CLIENT_SECRET&token=1234' \ -X POST


Upon success, both the access_token and refresh_token will be destroyed.

Error Description(s)
What happened


Invalid grant_type parameter or parameter missing.

Missing parameter. “code” is required

Invalid refresh token

Your request did not contain a grant type.

The code parameter is missing for the authorization code grant type.

The refresh token has expired or is malformed.


The grant type is unauthorized for this client_id

Your application is not authorized to use this grant type


Auth code doesn’t exist or is invalid for the client.

The authorization code has expired

Verify the authorization code is set correctly in your request.

Your application likely needs to get a new authorization code.


The client credentials are invalid

Verify that the client ID and secret are correct.


The redirect URI is missing or do not match

Either a redirect URI is not configured for your application or the URI in the request does not match the configured URI.


The URI is either not a custom protocol or not HTTPS.

Your application sent a bad redirect URI i.e. HTTP instead of HTTPS


The redirect_uri scheme is invalid per the RFC. A common problem is the first character being something besides a letter.

Your application sent an invalid URI.

HTTP Status
Error Code
What happened



The request is missing a required parameter, includes an unsupported parameter or parameter value, repeats the same parameter, uses more than one method for including an access token, or is otherwise malformed



The access token provided is expired, revoked, malformed or invalid for other reasons. The client may request a new access token and retry the protected resource request



The request requires higher privileges than provided by the access token

Updated about an hour ago

OAuth 2.0

Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.