Auth

OAuth 2 Overview

The OAuth 2 protocol is used to authenticate and authorize every API request. OAuth makes it possible for you to act on behalf of Zengine users without those users needing to share their credentials (username/password). This is made possible via a flow where the end user is redirected from your application to Zengine and grants your application permission to an access token for a finite period of time. Additionally,

You do not necessarily need to act on behalf of a user; you can be the end user. For example, you may be creating a script to run every night and extract data from your workspace. In this scenario, you must authenticate via the OAuth flow, retrieve a token for your account, and hard code that token into your script.

Registering an Application

You can retrieve any API key by creating a user, and then using the access token returned to you to create an API client. Take note of the key that is returned to you. It cannot be retrieved again.

Redirect URI

Your application must specify a redirect URI. This is the URI the end user will return to upon authenticating with Zengine. This URL must be set up to look for an OAuth response and process it accordingly.

Public vs. Private Resources

There are two types of requests you may want to make, both requiring different sets of credentials:

  1. Public: A request made by your application for publicly accessible data. Often referred to as 2-legged auth because there are 2 parties involved: the API and your application.
  2. Private: A request made by your application on behalf of a third-party user. Often referred to as 3-legged auth because there are 3 parties involved: the API, your application, and the user your application is acting on behalf of.

Most resources in the Zengine API are private.

Passing Credentials

To access public resources, you will need to provide an API key in the query string of your request:

?client_id={your API key}

To access private resources, you will need to provide an access token for the user you are acting on behalf of (even if that user is yourself).

?access_token={user's access token}

3-Legged Flows

A 3-legged flow is require in a scenario where you want to access private data on behalf of an end user. You may want to make your API calls from a server-side script (Ruby, Python, PHP, etc) or from a web client (HTML + JS). Because server-side scripts are implicitly more secure than clients, these two scenarios require different flows.

Server

The following describes a typical server-side flow:

  1. Your app needs to acquire a token for a user, and sends that user to: https://auth.zenginehq.com/oauth2/v1/authorize?client_id={your API key}&response_type=code&state={a session-based string you use to prevent CSRF}
  2. The user authenticates with Zengine and returns to the redirect URI you set up for your application with the following query string appended: ?code={a code which lasts for 30 seconds}&state={the session-based string you passed to prevent CSRF}
  3. The state parameter is checked to ensure it matches the one you passed.
  4. A POST request is made to https://auth.zenginehq.com/oauth2/v1/grant with the following payload: client_id={your API key}&client_secret={your API secret}&redirect_uri={the redirect URI associated with your application}&grant_type=authorization_code&code={the code you just received back from Zengine}
  5. Assuming the code is valid, you will receive a JSON response back with an access token in it:
    {
    	"access_token": "the token",
    	"refresh_token": "a refresh token"
    }
    		
  6. A GET request is made to: https://auth.zenginehq.com/oauth2/v1/token?access_token={the token}
  7. Assuming the token is valid, you will receive a JSON response back with an API key in it:
    			{"client_id": "your API key"}
    		
  8. The client_id (API key) is checked to ensure it is your own.

The access token you have now lasts for 24 hours. You can use it to make API requests which require authorization.

Once your token expires, you may use your refresh token (provided in Step 5) to retrieve a new access token:

GET https://auth.zenginehq.com/oauth2/v1/grant?client_id={your API key}&client_secret={your API secret}&redirect_uri={the redirect URI associated with your application}&grant_type=refresh_token&refresh_token={the refresh token you previously received from Zengine}

A sample server-side script, written in PHP, is provided below:

Client

The following describes a typical client-side flow:

  1. Your app needs to acquire a token for a user, and sends that user to: https://auth.zenginehq.com/oauth2/v1/authorize?client_id={your API key}&response_type=token&state={a session-based string you use to prevent CSRF}
  2. The user authenticates with Zengine and returns to the redirect URI you set up for your application with the following string appended after a # hashbang: ?access_token={the token}&state={the session-based string you passed to prevent CSRF}
  3. JavaScript is used to parse the parameters after the # hashbang.
  4. The state parameter is checked to ensure it matches the one you passed.
  5. A GET request is made to: https://auth.zenginehq.com/oauth2/v1/token?access_token={the token}
  6. Assuming the token is valid, you will receive a JSON response back with an API key in it:
    			{"client_id": "your API key"}
    		
  7. The client_id (API key) is checked to ensure it is your own.

The access token you have now lasts for 1 hour. You can use it to make API requests which require authorization.

Once your token expires, you must send the user back to Zengine to retrieve a new token.

A sample client-side script is provided below:

Authorizations API

An endpoint for Authorizations is made available in the API. This makes it possible for you to handle a user's third party application authorizations on behalf of that user. This is primarily provided as a way to allow your own application to remove itself from the user's authorizations list. This comes in handy if the user asks your application to disconnect from Zengine.