Authentication

All endpoints in the Shutterstock API require authentication. The API accepts HTTP basic authentication for some endpoints and OAuth authentication for all endpoints.

All requests must also specify a User-Agent header. The value of this header should either be the type of client, such as "NodeJS" or "PHP," or the name of the customer's application.

In the API reference, each endpoint is labeled with the types of authentication it accepts and the OAuth scopes it requires, if any. In general, HTTP basic authentication is sufficient for search queries and for getting information about pieces of media. The API requires OAuth authentication for actions that require customers to log in to shutterstock.com, such as licensing and downloading media.

Before you authenticate to the API, you need an API subscription and an API application. See Subscriptions.

Subscriptions

To access the API, you need an API application and an API subscription or free account. To get started, see the API subscription page.

These API subscriptions are separate from the subscriptions that are available on the Shutterstock web site, so be sure to get an API subscription if you want to work with the API. See https://www.shutterstock.com/api/pricing.

You can use an API subscription to license and download media only with the API; API subscriptions don't work on the Shutterstock web site. If you have a subscription that does not include API access and want to use it with the API, contact us.

For a summary of what each type of API subscription provides, see Subscriptions in the API reference.

Applications

To access the REST API you need an application, which represents the application, program, or computer commands that are accessing the API. To use the API, you need the application's consumer key and consumer secret, which are shown on the https://www.shutterstock.com/account/developers/apps page.

When you have the application's consumer key and consumer secret, you can use them to access the API directly or to request a token that you can use to access the API. For more information on these methods of authentication, see Authentication.

To create an application:

  1. Log in at shutterstock.com, go to your account page, and and click Developers.
  2. On the Developers page, click Create new app.
  3. On the Create New App popup, fill in these fields:
    • App name: Specify any name that describes your application.
    • Callback URL: Specify a comma-separated list of the host names (not full URLs) where your application is running. If you’ve got an application running on a server, use the host name of the server. Otherwise, leave the default host name localhost for testing purposes.
    • Referrer: If you are using referrer authentication, specify a comma-separated list of valid referrer domains. Each item in the list must match one of the callback host names. The API accepts only requests that have an HTTP Referrer header from this list. Otherwise, leave this field blank.
    • Included products: This list shows the API products that the application has access to. To get access to other products, contact your Shutterstock representative, visit the Pricing page or contact us.
    • Company name: The name of your company.
    • Website: Your company's web site.
    • Intended use: Select an option that describes how you will use the API.
    • Description: Describe in detail how the application will use the API.
    • Terms of service: Read an accept the Terms of Service.
  4. Click Save.

The new application appears on the My apps page. Each application has a consumer key and a consumer secret. You use this consumer key and consumer secret either to use the API directly with basic authentication or to request a token for OAuth authentication; see Authentication. Do not share your key and secret, because they can be used to access your account through the API.

Products

Each application has access to one or more API products. These products control the level of access that the application has to the API and the Shutterstock media library. These products are separate from the subscriptions that control how many assets you can license and download.

If you create an application without buying an API subscription first, the application uses the free API product, which is labeled as the "Self Serve" product. Applications that use this free API product can search and view media but not license or download media. If you have a paid API subscription, your applications use an API product with additional access to license and download media, within the limitations of the subscription. Other products include access to computer vision and editorial endpoints.

To tell which API products your application is using, open your applications, expand your application, and go to its Details tab.

Basic authentication

The API accepts HTTP basic authentication (also known as basic authentication) for some endpoints that do not access specific customer information. Follow these steps to use basic authentication:

  1. Create an account at https://www.shutterstock.com if you don't already have one.
  2. Set up an application at https://www.shutterstock.com/account/developers/apps and get the consumer key and consumer secret (also referred to as the consumer key and consumer secret) from the application.
  3. Pass the consumer key and consumer secret to the API along with the request. For example, you can use basic authentication to search for images by using the GET /v2/images/search endpoint. The following example passes the ID and secret (in this case, 123abc456def and 1a2b3c4d) in place of a user name and password.
curl -X GET --user 123abc456def:1a2b3c4d \
https://api.shutterstock.com/v2/images/search \
--data-urlencode "query=sunrise"

API endpoints that require an OAuth scope do not accept basic authentication. To use these endpoints, you must use OAuth authentication.

OAuth authentication

Most endpoints require OAuth 2.0 authentication. In this type of authentication, you use an application and an individual user's login credentials to obtain a token. Then you can use that token as credentials for API requests in place of a user name and password.

Some endpoints require one or more scopes, or permissions, which let the user control what the application can do with the token. For example, to edit a user's collections, the token must include the collections.edit scope. Applications can request multiple tokens with different scopes or a single token with multiple scopes.

Follow these steps to use OAuth authentication:

  1. Create an account at https://www.shutterstock.com if you don't already have one.
  2. Set up an application at https://www.shutterstock.com/account/developers/apps and get the consumer key and consumer secret (also referred to as the consumer key and consumer secret) from the application.
  3. Give the application a callback host name. If you've got an application running on a server, use the host name of the server. Otherwise, leave the default host name localhost for testing purposes.
  4. Pass your consumer key to the GET /v2/oauth/authorize endpoint to get a temporary authentication code.

    Use these parameters:

    • client_id: The consumer key for your application on https://www.shutterstock.com/account/developers/apps.
    • redirect_uri: The callback URI for your application. This callback URI must use a host name that you set up in your application. (Again, for testing purposes, you can use "localhost," as in http://localhost:3000/callback.)
    • response_type: Specify code to receive a temporary authentication code that you can use to get an access token.
    • scope: A space-separated list of scopes (or permissions) for the token. See OAuth scopes.
    • state: A value that the endpoint passes back to your application so you can include other information or verify that the request worked.

    For example:

    curl -X GET \"https://api.shutterstock.com/v2/oauth/authorize" \
        -G \
        --data-urlencode "scope=licenses.create licenses.view purchases.view" \
        --data-urlencode "state=demo_`date +%s`" \
        --data-urlencode "response_type=code" \
        --data-urlencode "redirect_uri=http://localhost:3000/callback" 
        --data-urlencode "client_id=860bde70bb335163e2e4"

    The endpoint returns a 301 return code and a URL. Here's an example:

    Moved Temporarily. Redirecting to https://accounts.shutterstock.com/login?next=%2Foauth%2Fauthorize%3Fscope%3Dlicenses.create%20licenses.view%20purchases.view%26state%3Ddemo_1498496256%26response_type%3Dcode%26redirect_uri%3Dhttp%3A%2F%2Flocalhost%3A3000%2Fcallback%26client_id%3D860bde70bb335163e2e4%26realm%3Dcustomer
  5. Open the URL in a web browser, log in, and allow your Shutterstock account to access the callback host name. The Permission Request window lets you make sure that you want to let programs with the token access your Shutterstock account with the specific permissions:

    When you click Allow, the Shutterstock API redirects your web browser to the callback URL with information in the parameters. If you don't have a full application set up yet, the browser gives an error because the web page isn't available, but that's OK because for now, all you need is the URL. Here's an example:

    http://localhost:3000/callback?code=VaRLQ3rICmWjGr4ciI-GwR&state=demo_1498496256

    For testing the API, copy the authentication code from the URL (in the previous example, it's VaRLQ3rICmWjGr4ciI-GwR) and use it in the next step. When you're ready to code a complete application, you can set it up to embed or refer to the login web page, accept the request from this URL, and store the information from the URL parameters. This code can be used only once, and it expires after 5 minutes.

  6. Finally, authenticate to the API and get an access token. To request a token that does not expire, specify expires=false or omit the expires parameter. To request a token that expires after one hour and then can be refreshed, specify expires=true.

Use the POST /v2/oauth/access_token endpoint, as in the following example. The parameters for this endpoint include the application's consumer key, consumer secret, and the code you got from the URL in the previous step:

curl -X POST "https://api.shutterstock.com/v2/oauth/access_token" \
--data-urlencode "client_id=860bde70bb335163e2e4" \
--data-urlencode "client_secret=225d245d28e5b1a37db7fd4ceb8cdf360a3ae5a7" \
--data-urlencode "grant_type=authorization_code" \
--data-urlencode "expires=false" \
--data-urlencode "code=VaRLQ3rICmWjGr4ciI-GwR"

This endpoint returns the access token in a JSON response. If you requested a token that does not expire, the API returns an access token that starts with v2/, as in this example:

{
  "access_token": "v2/ODYwYmRlNzBiYjMzNTE2M2UyZTQvMTc4NzI2OTM4L2N1c3RvbWVyLzIvWEtXR01HQ1FaVHRLOG85a",
  "token_type": "Bearer"
}

If you requested a token that expires, the API returns an access token that starts with 1/ and a refresh token, as in this example. You will need the refresh token to refresh the access token later.

{
  "access_token": "1/eyJjbGllbnRfaWQiOiJjNDc4Yi0yNjYzMC1",
  "expires_in": 3600,
  "token_type": "Bearer",
  "user_token": "eyJhbGciOiTtcXy71dhyfjBVU",
  "refresh_token": "3/d_0F6_AmGRO5a7NNhjdCwobDudbdvDNdPQTWV1IovpWPgWy"
}

Now you can use the token to access the API by passing it as an authorization header, as in this example of searching for images:

curl -X GET "https://api.shutterstock.com/v2/images/search" \
--header "Authorization: Bearer v2/ODYwYmRlNzBiYjMzNTE2M2UyZTQvMTc4NzI2OTM4L2N1c3RvbWVyLzIvWEtXR01HQ1FaVHRLOG85a" \
-G \
--data-urlencode "query=kites" \
--data-urlencode "image_type=photo" \
--data-urlencode "page=1" \
--data-urlencode "per_page=5" \
--data-urlencode "sort=popular" \
--data-urlencode "view=minimal"

Further examples in this documentation assume that you put the token in the SHUTTERSTOCK_API_TOKEN environment variable, but you can also store the token in a variable in your code.

Keep this token private, because other people could use it to access the account's subscriptions and media.

You can use the same application to get tokens for any number of users. Just repeat the request to GET /v2/oauth/authorize with the application information and then sign in as a different user. Each token is tied to the user's account.

Refreshing tokens

If you requested a token with the parameter expires=true, the token begins with "1/", and it expires in one hour. You can refresh the token to continue using it.

If you requested a token that does not expire, the token does not need to be refreshed. This type of token is valid until the user account that is associated with the token changes its password.

To refresh a token that expires, pass the refresh token, which begins with "3/", to the POST /v2/oauth/access_token endpoint. You must also pass either the consumer secret from the application or the user ID of the user account that is associated with the token. Use these parameters:

  • refresh_token: The refresh token from the initial request to the POST /v2/oauth/access_token endpoint.
  • grant_type: Specify "refresh_token" to refresh the token.
  • client_id: The consumer key from your application on https://www.shutterstock.com/account/developers/apps.
  • client_secret: The consumer secret from your application. You must pass either this field or the user_id field.
  • user_id: The ID uf the user account that is associated with the token. You must pass either this field or the client_secret field. As long as the current token is active, you can retrieve the user ID from the GET /v2/user endpoint.

The response includes the existing refresh token and a new token that is valid for one hour.

curl -X POST "https://api.shutterstock.com/v2/oauth/access_token" \
--data-urlencode "client_id=860bde70bb335163e2e4" \
--data-urlencode "client_secret=225d245d28e5b1a37db7fd4ceb8cdf360a3ae5a7"
--data-urlencode "grant_type=refresh_token" \
--data-urlencode "refresh_token=3/d_0F6_AmGRO5a7NNhjdCwobDudbdvDNdPQTWV1IovpW" \

Common errors

Redirect URI mismatch

For security reasons, the callback URI that you send to GET /v2/oauth/authorize must use a host name that is registered with your application. If you provide a redirect_uri that does not use one of your application's host names, Shutterstock displays an error message to your users. The error indicates that your application was blocked from doing something potentially dangerous:

Invalid redirect URI:
The Redirect URI http://someplace.com doesn't match the valid hostnames for this client.
invalid_redirect_url

Access denied

If the user rejects access to your application, Shutterstock returns parameters that summarize the error:

http://localhost:3000/callback?error=access_denied
  &error_description=The user denied the authorization request.
  &error_reason=user_denied

You can't get an access token if the user chooses not to authorize your application. In this case, your application should fail gracefully. Often, users close the window or press the browser back button rather than explicitly decline permission, so your application may not get this error.

Missing required parameters

If you leave out a required parameter, you receive an error response status code of 400 with the message "Validation failed," as in this example:

{
  "message": "Validation failed",
  "errors": [{
    "code": "VALIDATION_OBJECT_REQUIRED",
    "message": "Missing required property: client_id"
  }]
}

If you leave out the client_id or client_secret parameters, or if they don't match, you receive an error response status code of 403 with text "Invalid client_id/secret given."

OAuth scopes

Most endpoints require an access token with one or more scopes, or permissions. You can see the scopes that an individual endpoint requires in the API reference.

The following table shows the available scopes.

ScopeDescription
No scopeGrants the user.view scope by default
collections.editGrants the ability to create collections, edit collections, and modify the contents of collections; does not grant read access to collections
collections.viewGrants read-only access to collections and their contents
earnings.viewGrants the ability to view a user's current earnings and payouts
licenses.createGrants the ability to download and license media on behalf of the user
licenses.viewGrants read-only access to a user's licenses
media.editGrants the ability to make changes to a user's approved media; does not grant read access to media
media.submitGrants the ability to submit a user's uploaded media for review and check the approval states
media.uploadGrants the ability to upload media to a user's account
organization.addressGrants read-only access to an organization's physical address
organization.viewGrants read-only access to an organization's basic information
purchases.viewGrants read-only access to a user's purchase history
reseller.purchaseGrants the ability for a reseller to purchase products for a user
reseller.viewGrants the ability for a reseller to view the products they can sell
user.addressGrants read-only access to a user's physical address
user.editGrants read and write access to all user account information; does not grant read access to account information
user.emailGrants read-only access to a user's email address
user.viewGrants read-only access to a user's basic account information (including the user name, id, and first and last name); if the user's email address is the same as their user name, this scope also implies the user.email scope