OAuth 2.0

Our API supports authenticating using OAuth 2.0. Using it, your integration can access the API on behalf of you or another Appfigures user without using passwords.

Most languages and frameworks have one or more good toolkits or packages to integrate with OAuth 2.0 APIs. If you are using one of those you’ll need to configure it with your API Client’s client_key (also called client_id) and client_secret. You’ll also need to input the below Authorization and Token endpoints.

Summary URLs and Signature Methods

  • Client Registration: https://appfigures.com/developers/keys
  • Authorization Endpoint: https://api.appfigures.com/v2/oauth2/authorize
  • Token Endpoint: https://api.appfigures.com/v2/oauth2/access_token
  • Token Revocation Endpoint: https://api.appfigures.com/v2/oauth2/revoke (rfc7009)
  • Token Introspection Endpoint: https://api.appfigures.com/v2/oauth2/tokeninfo (rfc7662)
  • Supported Grant Types: authorization_code only. (rfc6749 4.1)

Scopes

The following scopes are supported: account:read, account:write, products:read, products:write, public:read, public:write, private:read, private:write

Redirect Urls

A redirect_url is required by both the Authorization and Token Endpoint. It must match a pre-configured redirect URL that is set up in your Appfigures API Client. It MUST be an https url in production. Query string parameters are supported, but they must also match completely. You can set up the redirect urls for an API Client by going to the API Client management page and selecting a client to edit.

No normalization is done on the redirect_url, so the value given must exactly match a valid redirect URL in the API Client configuration.

Out of Band Flows: If you must support an out-of-band flow, use urn:ietf:wg:oauth:2.0:oob as the redirect_uri. In this case, Appfigures will display a token that the user will need to paste back into your application.

Token Expiration

The access_token that is given by the Token Endpoint does not have an expiration time. No refresh_token is issued. The access_token can be revoked via the Token Revocation Endpoint or via your Key Management page

Using an Access Token

To authenticate API calls, the bearer returned from the Token Endpoint should be passed in the Authorization header: Authorization: Bearer THE_TOKEN. Here’s an example assuming that the token is t_1234:

curl -H"Authorization: Bearer t_1234" "https://api.appfigures.com/v2/"

Example Flow

To make the examples look realistic we’ll assume:

  1. That the Client ID is client_id_1234 and the Client Secret is client_secret_abcd
  2. That the desired scopes are account:read private:read products:write
  3. That the redirect_url is https://mydomain.com/oauth_callback

1. Make the authorization request.

Each OAuth 2.0 flow requires a random state to be generated. This is so that you can verify that your client is not being fooled into accepting a token for/from an attacker. You can also use it to match the two legs of the flow together.

In this example, the state is state_wxyz. You then submit a request to the Authorization Endpoint with response_type=code, the client_id, the redirect_uri, the desired scope and the generated state.

GET https://api.appfigures.com/v2/oauth2/authorize?response_type=code&client_id=client_id_1234&redirect_uri=https%3A%2F%2Fmydomain.com%2Foauth_callback&scope=account%3Aread%20private%3Aread%20products%3Awrite&state=state_wxyz

Response (To Appfigures, the user will now approve the request on the Appfigures website)

302 Temporary Redirect
Location: (appfigures.com)

Response (After approval the user is redirected back to your application)

302 Temporary Redirect
Location: https://mydomain.com/oauth_callback?code=code_5678&state=state_wxyz

Error

302 Temporary Redirect
Location: https://mydomain.com/oauth_callback?error=invalid_scope&error_description=scopes%20cannot%20exceed%20scopes%20configured%20in%20api%20client&state=state_wxyz

2. Verifying the results of the authorization request

Now, the user has approved your application’s request and has been redirected back to your redirect_url with the additional parameters state and code. You MUST verify that state matches the state you generated in step 1. The URL in this case will look like: https://mydomain.com/oauth_callback?code=code_5678&state=state_wxyz .

If there was an error, instead you will get error and error_description parameters as documented in rfc6749 4.1.2.1. In the case that the redirect_uri or client cannot be verified, the user will be shown a message by Appfigures.

3. Exchanging the intermediate code for an access_token

You can now exchange the code from step 2 for an access_token that can be used to make requests on behalf of the authorizing user. You will make an application/x-www-form-urlencoded POST request to the Token Endpoint with grant_type=authorization_code, the code obtained from step 2, and the redirect_uri given in step 1.

You will need to authenticate your client for this request.

The easiest way to authenticate your API client at this point is to send your client_id and client_password as the HTTP Basic username and password. You could instead give these client_id and client_secret values in the request body, but it is not recommended.

    >> Request
    POST https://api.appfigures.com/v2/oauth2/access_token
    Authorization: Basic Y2xpZW50X2lkXzEyMzQ6Y2xpZW50X3NlY3JldF9hYmNk
    Content-Type: application/x-www-form-urlencoded
    
    grant_type=authorization_code&code=code_5678&redirect_uri=https%3A%2F%2Fmydomain.com%2Foauth_callback
    
    << Sample Success Response
    200 OK
    Content-Type: application/json
    
    {
      "token_type": "bearer",
      "access_token": "access_token_rstu",
      "scope": "account:read"
    }
    
    << Sample Error Response
    400 Bad Request
    Content-Type: application/json
    
    {"error": "invalid_request", "error_description": "redirect_uri does not match"}

4. Making authenticated requests

You can now use the access_token to from the Token Endpoint response to authenticate requests to the API

    >> Request
    GET https://api.appfigures.com/v2/
    Authorization: Bearer access_token_rstu
    
    << Response
    200 OK
    {
      "status": "200",
      "message": "OK",
      "see": "http://docs.appfigures.com/api",
      "version": "2.0",
      "user": {
        "id": 42,
        "name": "Test User",
        "email": "test@test.com",
        "avatar_url": "https://secure.gravatar.com/avatar/dbe9de53f77958ee4ff7e19697a58990?d=mm"
      },
      . . . snip . . .
    }

Inspecting a token

You will need to authenticate your client for this request.

    >> Request
    POST https://api.appfigures.com/v2/oauth2/tokeninfo
    Authorization: Basic Y2xpZW50X2lkXzEyMzQ6Y2xpZW50X3NlY3JldF9hYmNk
    Content-Type: application/x-www-form-urlencoded
    
    token=access_token_rstu
    
    << Response
    200 OK
    {
      "active": true,
      "scope": "account:read",
      "client_id": "client_id_1234",
      "username": "test@test.com"
    }

Revoking a token

You will need to authenticate your client for this request.

    >> Request
    POST https://api.appfigures.com/v2/oauth2/revoke
    Authorization: Basic Y2xpZW50X2lkXzEyMzQ6Y2xpZW50X3NlY3JldF9hYmNk
    Content-Type: application/x-www-form-urlencoded
    
    token=access_token_rstu
    
    << Response
    200 OK
    {}