Application-only authentication

Overview

Twitter offers applications the ability to issue authenticated requests on behalf of the application itself (as opposed to on behalf of a specific user). Twitter’s implementation is based on the Client Credentials Grant flow of the OAuth 2 specification. Note that OAuth 1.0a is still required to issue requests on behalf of users.

Application-only authentication doesn't include any user contet. This means that you can only make requests to a Twitter API that doesn't require an authenticated user.

With application-only authentication, you can perform the following:

  • Pull user timelines;
  • Access friends and followers of any account;
  • Access lists resources;
  • Search in Tweets;
  • Retrieve any user information, excluding the user's email address;
     

You will need user context, or user authentication with an access token to perform the following:

  • Post Tweets or other resources;
  • Connect to Streaming endpoints;
  • Search for users;
  • Use any geo endpoint;
  • Access Direct Messages or account credentials;
  • Retrieve user's email addresses;
     

You can check if an endpoint is available for app-only auth in the sidebox at endpoint page.

 

Auth Flow

The application-only auth flow follows these steps:

  • An application encodes its consumer key and secret into a specially encoded set of credentials.
  • An application makes a request to the POST oauth2 / token endpoint to exchange these credentials for a bearer token.
  • When accessing the REST API, the application uses the bearer token to authenticate.

Because there is no need to sign a request, this approach is dramatically simpler than the standard OAuth 1.0a model.

Diagram illustrating the application-only auth flow

 

About application-only auth

Tokens are passwords

Keep in mind that the consumer key & secret, bearer token credentials, and the bearer token itself grant access to make requests on behalf of an application. These values should be considered as sensitive as passwords, and must not be shared or distributed to untrusted parties.

SSL required

All requests (both to obtain and use the tokens) must use HTTPS endpoints. Follow the best practices detailed in Connecting to Twitter API using TLS — peers should always be verified.

No user context

When issuing requests using application-only auth, there is no concept of a “current user.” Therefore, endpoints such as POST statuses / update will not function with application-only auth. See using OAuth for more information for issuing requests on behalf of a user.

Rate limiting

Applications have two kinds of rate limiting pools.

Requests made on behalf of users with access tokens depletes from a different rate limiting context than that used in application-only authentication. In other words, requests made on behalf of users will not deplete from the rate limits available through app-only auth and requests made through app-only auth will not deplete from the rate limits used in user-based auth.

GET application / rate_limit_status supports application-only authentication. By issuing requests to this method with your application bearer token, you’ll receive a response indicating the current window’s per-resource rate limiting context. Instead of receiving a “rate_limit_context” field indicating the access token being used, you will receive a “application” field instead, with the value being your application’s consumer key.

{
  "rate_limit_context": {
      "application": "nXtEH7H0mi0qT8kSyo7DQ"
  },
  "resources": {
    "search": {
      "/search/tweets": {
        "limit": 450,
        "remaining": 420,
        "reset": 1362436375 }
    }
  }
}

Another way to discover which methods support application-only auth is by finding those methods with application-only auth rate limits on the rate limit index documentation.

 

Issuing application-only requests

Step 1: Encode consumer key and secret

The steps to encode an application’s consumer key and secret into a set of credentials to obtain a bearer token are:

  1. URL encode the consumer key and the consumer secret according to RFC 1738. Note that at the time of writing, this will not actually change the consumer key and secret, but this step should still be performed in case the format of those values changes in the future.
  2. Concatenate the encoded consumer key, a colon character ”:”, and the encoded consumer secret into a single string.
  3. Base64 encode the string from the previous step.

Below are example values showing the result of this algorithm. Note that the consumer secret used in this page has been disabled and will not work for real requests.

Consumer key xvz1evFS4wEEPTGEFPHBog
Consumer secret L8qq9PZyRg6ieKGEKhZolGC0vJWLw8iEJ88DRdyOg
RFC 1738 encoded consumer
key (does not change)
xvz1evFS4wEEPTGEFPHBog
RFC 1738 encoded consumer
secret (does not change)
L8qq9PZyRg6ieKGEKhZolGC0vJWLw8iEJ88DRdyOg
Bearer token credentials xvz1evFS4wEEPTGEFPHBog:L8qq9PZyRg6ieKGEKhZolGC0vJWLw8iEJ88DRdyOg
Base64 encoded bearer token credentials :: eHZ6MWV2RlM0d0VFUFRHRUZQSEJvZzpMOHFxOVBaeVJnNmllS0dFS2hab2xHQzB2SldMdzhpRUo4OERSZHlPZw==

Step 2: Obtain a bearer token

The value calculated in step 1 must be exchanged for a bearer token by issuing a request to POST oauth2 / token:

  • The request must be a HTTP POST request.
  • The request must include an Authorization header with the value of Basic <base64 encoded value from step 1>.
  • The request must include a Content-Type header with the value of application/x-www-form-urlencoded;charset=UTF-8.
  • The body of the request must be grant_type=client_credentials.

Example request (Authorization header has been wrapped):

POST /oauth2/token HTTP/1.1
Host: api.twitter.com
User-Agent: My Twitter App v1.0.23
Authorization: Basic eHZ6MWV2RlM0d0VFUFRHRUZQSEJvZzpMOHFxOVBaeVJn
                     NmllS0dFS2hab2xHQzB2SldMdzhpRUo4OERSZHlPZw==
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Content-Length: 29
Accept-Encoding: gzip

grant_type=client_credentials

If the request was formatted correctly, the server will respond with a JSON-encoded payload:

Example response:

HTTP/1.1 200 OK
Status: 200 OK
Content-Type: application/json; charset=utf-8
...
Content-Encoding: gzip
Content-Length: 140

{"token_type":"bearer","access_token":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%2FAAAAAAAAAAAAAAAAAAAA%3DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"}

Applications should verify that the value associated with the token_type key of the returned object is bearer. The value associated with the access_token key is the bearer token.

Note that one bearer token is valid for an application at a time. Issuing another request with the same credentials to /oauth2/token will return the same token until it is invalidated.

Step 3: Authenticate API requests with the bearer token

The bearer token may be used to issue requests to API endpoints which support application-only auth. To use the bearer token, construct a normal HTTPS request and include an Authorization header with the value of Bearer <base64 bearer token value from step 2>. Signing is not required.

Example request (Authorization header has been wrapped):

GET /1.1/statuses/user_timeline.json?count=100&screen_name=twitterapi HTTP/1.1
Host: api.twitter.com
User-Agent: My Twitter App v1.0.23
Authorization: Bearer AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%2FAAAAAAAAAAAA
                      AAAAAAAA%3DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Accept-Encoding: gzip

 

Invalidating a bearer token

Should a bearer token become compromised or need to be invalidated for any reason, issue a call to POST oauth2 / invalidate_token.

Example request (Authorization header has been wrapped):

POST /oauth2/invalidate_token HTTP/1.1
Authorization: Basic eHZ6MWV2RlM0d0VFUFRHRUZQSEJvZzpMOHFxOVBaeVJn
                     NmllS0dFS2hab2xHQzB2SldMdzhpRUo4OERSZHlPZw==
User-Agent: My Twitter App v1.0.23
Host: api.twitter.com
Accept: */*
Content-Length: 119
Content-Type: application/x-www-form-urlencoded

access_token=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%2FAAAAAAAAAAAAAAAAAAAA%3DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Example response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 127
...

{"access_token":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%2FAAAAAAAAAAAAAAAAAAAA%3DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"}

 

Common error cases

This section describes some common mistakes involved in the negotiation and use of bearer tokens. Be aware that not all possible error responses are covered here - be observant of unhandled error codes and responses!

Invalid requests to obtain or revoke bearer tokens

Attempts to:

  • Obtain a bearer token with an invalid request (for example, leaving out grant_type=client_credentials).
  • Obtain or revoke a bearer token with incorrect or expired app credentials.
  • Invalidate an incorrect or revoked bearer token.
  • Obtain a bearer token too frequently in a short period of time.

Will result in:

HTTP/1.1 403 Forbidden
Content-Length: 105
Content-Type: application/json; charset=utf-8
...

{"errors":[{"code":99,"label":"authenticity_token_error","message":"Unable to verify your credentials"}]}

API request contains invalid bearer token

Using an incorrect or revoked bearer token to make API requests will result in:

HTTP/1.1 401 Unauthorized
Content-Type: application/json; charset=utf-8
Content-Length: 61
...

{"errors":[{"message":"Invalid or expired token","code":89}]}

Bearer token used on endpoint which doesn’t support application-only auth

Requesting an endpoint which requires a user context (such as statuses/home_timeline) with a bearer token will produce:

HTTP/1.1 403 Forbidden
Content-Type: application/json; charset=utf-8
Content-Length: 91
...

{"errors":[{"message":"Your credentials do not allow access to this resource","code":220}]}