Skip to content

Generating A Token

To utilize the Environment API, you need an access token. Here's how to obtain one:

1. Create an Integration

Before you can generate a token, you must create an Integration. Check out our guide on Manage Integrations to get started.

2. Find Client ID and Secret

After setting up an Integration with the necessary permissions, navigate to the General tab. Here, you'll find your Client ID and Client Secret.


3. Request a Token

Use the Client ID and Client Secret to request a token. Make a POST request to:

Here are some examples for making this request:

curl -X POST "" \
 -H "Content-Type: application/json" \
 -d '{
     "grant_type": "client_credentials",
     "audience": "",
     "client_id": "<YOUR CLIENT ID>",
     "client_secret": "<YOUR CLIENT SECRET>"
import requests

endpoint = ''
client_id = '<YOUR CLIENT ID>'
client_secret = '<YOUR CLIENT SECRET>'

resp =
        "content-type": "application/json"
        "grant_type": "client_credentials",
        "audience": "",
        "client_id": client_id,
        "client_secret": client_secret,

if resp.status_code == 200:
    raise Exception(f"{resp.text}")
const client_id = '<YOUR CLIENT ID>'
const client_secret = '<YOUR CLIENT SECRET>'

fetch('', {
method: "POST",
headers: {
    'Content-Type': 'application/json'
body: JSON.stringify({
    'grant_type': 'client_credentials',
    'audience': '',
    'client_id': client_id,
    'client_secret': client_id
.then(response => response.json()
.then(data => console.log(data)))
package main

import (

type AuthResponse struct {
    Token       string  `json:"access_token"`
    Expiration  int     `json:"expires_in"`
    Type        string  `json:"token_type"`
    Scope       string  `json:"scope"`

func main() {
    posturl := ""

    body := []byte(`{
        "grant_type": "client_credentials",
        "audience": "",
        "client_id": "<YOUR CLIENT ID>",
        "client_secret": "<YOUR CLIENT SECRET>"

    r, err := http.NewRequest("POST", posturl, bytes.NewBuffer(body))
    if err != nil {

    r.Header.Add("Content-Type", "application/json")

    client := &http.Client{}
    res, err := client.Do(r)
    if err != nil {

    defer res.Body.Close()

    response := &AuthResponse{}
    derr := json.NewDecoder(res.Body).Decode(response)
    if derr != nil {

    if res.StatusCode != 200 {

    fmt.Println("Token:", response.Token)
// This expects a ResponseType class to be defined with the response JSON properties
// `access_token`, `expires_in`, `scope`, and `token_type`
Map<String, Object> body = new HashMap<>();
body.put("grant_type", "client_credentials");
body.put("audience", "");
body.put("client_id", client_id);
body.put("client_secret", client_id);

BodyBuilder requestBuilder;

try {
  requestBuilder = RequestEntity.method(HttpMethod.POST, new URI(""));
} catch (URISyntaxException e) {
  log.error("Invalid URI: {}", url);
  throw new InvalidRequestException("Invalid URL");

RequestEntity<Object> requestEntity = requestBuilder.body(body);

ResponseEntity<ResponseType> responseEntity =
  new ParameterizedTypeReference<ResponseType>() {}
if (!responseEntity.getStatusCode().is2xxSuccessful()) {
  // The error handler built into the RestTemplate should handle 400 and 500 series errors.
  throw new RestClientException(
    "API returned " + responseEntity.getStatusCode()
}"Got response: {}", responseEntity.getBody());

If all goes as intended, you will receive are response like below:

    "access_token": "<YOUR TOKEN>",
    "token_type": "Bearer",
    "expires_in": 79045,
    "scope": "font:list font:read font:write media:list media:read media:write myproject:list myproject:read myproject:write output:animated output:static template_collection:list template_collection:read template_collection:write template:list template:read template:write"

Where: - access_token is your token which you will use in further API calls. - token_type will always be "Bearer". - expires_in is be the time the token expires in seconds. - scope is the permission that we set in the Permissions tab.


Tokens are cached, so making the above API request again will not generate you a new token and return to you the original.


Keep tokens confidential. Currently, leaked tokens cannot be deactivated or replaced. Avoid unintended sharing.