API Authentication

Overview

All requests to the Bloom API require a valid Oauth2 Access Token to be present in the Authorization header. You can think of this Access Token like an API key, it is what grants you access to the API.

Bloom will provide you with two credentials:

(1) Client ID
and
(2) Client Secret

These two credentials are what you will use to request an Access Token. You will do so using the Oauth2 client_credentials grant flow which will be explained below.

While your provided Client ID is considered a "public" credential, your Client Secret must only be known by your backend application(s). It must never be included in any front-end applications, stored in plaintext, or transmitted across unsecured (non-SSL) connections. Treat it as you would a password.

🚧

Keep your credentials safe!

If at any time you believe your credentials may have been compromised, please let Bloom know immediately so we can rotate them for you.

General Flow

You will gain and maintain access to the API with the following flow:

  1. Use your Client ID and Client Secret to fetch an Access Token
  2. Put the Access Token in the Authorization header of any request you make to the Bloom API
  3. When the token expires fetch a new one and go back to step (2)

1. Retrieving an Access Token

Make a POST request to the /oauth/token endpoint of the authorization URL.

Use the Environments page to find the authorization URL that corresponds to your target environment.

Required Parameters

ParameterValue
client_idYour Client ID
client_secretYour Client Secret
audienceSee the Environments concept page to find the audience that corresponds to your target environment
grant_typeAlways use client_credentials

πŸ“˜

Quick tip

Click the Code Generation tab below to get see an example of this request in your language of choice.

{
  "method": "post",
  "url": "https://auth.bloom.dev/oauth/token",
  "headers": {
    "Content-Type": "application/x-www-form-urlencoded"
  },
  "body": {
    "client_id": "<CLIENT_ID>",
    "client_secret": "<CLIENT_SECRET>",
    "audience": "<API_ENVIRONMENT_AUDIENCE>",
    "grant_type": "client_credentials"
  }
}
curl --location --request POST 'https://auth.bloom.dev/oauth/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=$CLIENT_ID' \
--data-urlencode 'client_secret=$CLIENT_SECRET' \
--data-urlencode 'audience=$AUDIENCE' \
--data-urlencode 'grant_type=client_credentials'
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/x-www-form-urlencoded");

var urlencoded = new URLSearchParams();
urlencoded.append("client_id", "$CLIENT_ID");
urlencoded.append("client_secret", "$CLIENT_SECRET");
urlencoded.append("audience", "$AUDIENCE");
urlencoded.append("grant_type", "client_credentials");

var requestOptions = {
  method: 'POST',
  headers: myHeaders,
  body: urlencoded,
  redirect: 'follow'
};

fetch("https://auth.bloom.dev/oauth/token", requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));
import requests

url = "https://auth.bloom.dev/oauth/token"

client_id = "$CLIENT_ID"
client_secret = "$CLIENT_SECRET"
audience = "$AUDIENCE"
payload= f'client_id={client_id}&client_secret={client_secret}&audience={audience}&grant_type=client_credentials'
headers = {
  'Content-Type': 'application/x-www-form-urlencoded'
}

response = requests.request("POST", url, headers=headers, data=payload)

print(response.text)
var https = require('follow-redirects').https;
var fs = require('fs');
var qs = require('querystring');

var options = {
  'method': 'POST',
  'hostname': 'auth.bloom.dev',
  'path': '/oauth/token',
  'headers': {
    'Content-Type': 'application/x-www-form-urlencoded'
  },
  'maxRedirects': 20
};

var req = https.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function (chunk) {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });

  res.on("error", function (error) {
    console.error(error);
  });
});

var postData = qs.stringify({
  'client_id': '$CLIENT_ID',
  'client_secret': '$CLIENT_SECRET',
  'audience': '$AUDIENCE',
  'grant_type': 'client_credentials'
});

req.write(postData);

req.end();
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://auth.bloom.dev/oauth/token"
  method := "POST"

  payload := strings.NewReader("client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET&audience=$AUDIENCE&grant_type=client_credentials")

  client := &http.Client {
  }
  req, err := http.NewRequest(method, url, payload)

  if err != nil {
    fmt.Println(err)
    return
  }
  req.Header.Add("Content-Type", "application/x-www-form-urlencoded")

  res, err := client.Do(req)
  if err != nil {
    fmt.Println(err)
    return
  }
  defer res.Body.Close()

  body, err := ioutil.ReadAll(res.Body)
  if err != nil {
    fmt.Println(err)
    return
  }
  fmt.Println(string(body))
}
{
    "access_token": "<ACCESS_TOKEN_WILL_BE_HERE>",
    "scope": "read:consumers write:consumers read:credit.bloom.score.vantage3...",
    "expires_in": 86400,
    "token_type": "Bearer"
}

🚧

Caching Access Tokens

Please note that when requesting access tokens using your client credentials, your application should use the access token until it expires. The Access Token Response includes an expires_in field which you can use to determine if the token needs to be renewed (this field contains the number of seconds from when the token was created to when it will expire).

If the token is expired, you can issue a new POST request to /oauth/token to receive a new access token as you normally would for new tokens.

2. Making API Requests

Now that you have successfully fetched an Access Token, you can make requests to the rest of the Bloom API. Simply add an HTTP Authorization header in the following format to any request you make to the Bloom API:

"Authorization: Bearer <ACCESS_TOKEN>"