GuidesAPI ReferenceChangelogAPI PolicyAPI StatusGusto Security

Authentication

Gusto Embedded has two types of tokens that are used throughout development: organization-level tokens (api_token) and company-level tokens (access_token,refresh_token). You will need to securely manage and store all access tokens, api tokens, and refresh tokens in your database.

API Token Authentication

The organization-level token is available when you create an organization and application in the developer portal. Using this api_token you can create a new partner managed company. In the header of the request you will include the api_token using an Authorization HTTP header with the token scheme.

Content-Type: application/json
Authorization: Token bbb286ff1a4fe6b84742b0d49b8d0d65bd0208d27d3d50333591df71

Access Token Authentication

After creation of a partner managed company, you will receive an access_token, refresh_token, expires_in, and the uuid of the created company to make subsequent API calls on behalf of the company. expires_in is the number of seconds in which the access_token will expire.

{
  "access_token": "JKrGqRyrYfY1PB0YhsuRkbrrWBJ5iSUODDNA28D3yMc",
  "refresh_token": "T0jHy4Oc3FWi7hDPEMPdpbGiLpB0rWeb1ZJOJVB36oU",
  "company_uuid": "d525dd21-ba6e-482c-be15-c2c7237f1364",
  "expires_in": 7200
}

Refreshing Access Tokens

This access token expires 2 hours after they are issued. If an access token is expired you will receive 401 Unauthorized errors. To refresh the access token, you will need the client_id, client_secret, and redirect_uri from the application you created in the developer portal as well as your refresh_token. A refresh_token can be exchanged to get a new access_token and refresh_token.

To refresh your access_token use the POST oauth/token endpoint and include the refresh_token and "grant_type" : β€œrefresh_token” in the request body.

The client_secret cannot be passed via API request URLs. Attempting to include the client_secret in the request URL will result in a 400 Bad Request error.

curl --location --request POST 'https://api.gusto-demo.com/oauth/token' \
--header 'Content-Type: application/json' \
--header 'Authorization: Token {{API_TOKEN}}' \
--data-raw '{
  "client_id": "{{client_id}}",
  "client_secret": "{{client_secret}}",
  "redirect_uri": "https://localhost:3000",
  "refresh_token": "T0jHy4Oc3FWi7hDPEMPdpbGiLpB0rWeb1ZJOJVB36oU",
  "grant_type": "refresh_token"
}'
import fetch from 'node-fetch';

const url = 'https://api.gusto-demo.com/oauth/token`;
const options = {
  method: 'POST',
  headers: {
    accept:'application/json', 
    'content-type': 'application/json',
    'Authorization': 'Token {{API_TOKEN}}'},
  body: JSON.stringify({
    'client_id': '{{client_id}}',
    'client_secret': '{{client_secret}}',
    'redirect_uri': 'https://localhost:3000',
    'refresh_token': 'T0jHy4Oc3FWi7hDPEMPdpbGiLpB0rWeb1ZJOJVB36oU',
    'grant_type': 'refresh_token'
    })
};

fetch(url, options)
  .then(res => res.json())
  .then(json => console.log(json))
  .catch(err => console.error('error:' + err));


The corresponding response will include a new access_token and refresh_token.

{  
  "access_token": "737HdeXfIqgx-NfaUFRuhV7JDe6ns6ptanJSMuQzjlc",  
  "token_type": "bearer",  
  "expires_in": 7200,  
  "refresh_token": "iEjL96L9Pndwmi-xVX3Q-xbrvvhnjHYGX87sopgGJ8E"  
}

The previous refresh_token will be revoked on the first usage of the new access_token. In our example, the previous refresh_token T0jHy4Oc3FWi7hDPEMPdpbGiLpB0rWeb1ZJOJVB36oU is only revoked when the new access_token 737HdeXfIqgx-NfaUFRuhV7JDe6ns6ptanJSMuQzjlc is used in the Authorization header of a Gusto API call. The expires_in value is provided in seconds from when the access_token was generated.

{  
  "access_token": "de6780bc506a0446309bd9362820ba8aed28aa506c71eedbe1c5c4f9dd350e54",  
  "token_type": "bearer",  
  "expires_in": 7200,  
  "refresh_token": "8257e65c97202ed1726cf9571600918f3bffb2544b26e00a61df9897668c33a1"  
}