From Onboarding to your first Credit Report

Getting started with the Bloom API, from Authentication to Ordering and fetching a Credit Report.

In this tutorial we will take our first steps with the Bloom API, learning the main concepts and fetching our first credit report.

We will go through the necessary steps to get onboarded, authenticate, and call the Bloom API. It is recommended to have familiarity with scripting and/or programming as well as general concepts of HTTP before starting.

Authenticating with the API

Getting Credentials

To start the authentication process with the Bloom API, make sure you have both a client_id and client_secret ready to be used. Using these credentials, you will be able to generate the access token used to authenticate your API calls.

📘

If you don't have credentials yet, contact us to get onboarded onto our platform.

Environments

In this tutorial, we will be working with the Sandbox environment and its endpoints, where we will use training data. To learn more about environments and get information on moving to productions read Environments Overview.

Getting an access token

Access tokens are keys used to authenticate all Bloom API calls. You can generate tokens using the https://authn.bloom.dev/oauth/tokenendpoint in the following way:

Here you need to replace $CLIENT_ID and $CLIENT_SECRET with the credentials fetched earlier.

Replace $SCOPE as following:
Set as "data-access:all" for accessing Data Access endpoints.
Set as "furnishment:all" for accessing Furnishment endpoints.
Set "data-access:all furnishment:all" for accessing both Data Access and Furnishment endpoints.

You also need to use an $AUDIENCE, for the Sandbox environment, the audience is set to dev-api.

curl --location --request POST 'https://authn.bloom.dev/oauth2/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 'scope=$SCOPE' \
--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("scope", "$SCOPE");
urlencoded.append("grant_type", "client_credentials");

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

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

url = "https://authn.bloom.dev/oauth2/token"

client_id = "$CLIENT_ID"
client_secret = "$CLIENT_SECRET"
audience = "$AUDIENCE"
scope = "$SCOPE"
payload= f'client_id={client_id}&client_secret={client_secret}&audience={audience}&scope={scope}&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': 'authn.bloom.dev',
  'path': '/oauth2/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',
  'scope': '$SCOPE',
  'grant_type': 'client_credentials'
});

req.write(postData);

req.end();
package main

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

func main() {

  url := "https://authn.bloom.dev/oauth2/token"
  method := "POST"

  payload := strings.NewReader("client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET&audience=$AUDIENCE&scope=$SCOPE&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))
}

A successful call will yield the following response, containing the access_token used for the subsequent calls:

{
    "access_token": "<ACCESS_TOKEN_WILL_BE_HERE>",
    "scope": "data-access:all furnishment:all",
    "expires_in": 86400,
    "token_type": "Bearer"
}

Using the access token

To use the access token fetched in the previous step, include it in your HTTP Headers as follows:

Authorization: Bearer <ACCESS_TOKEN>

Refreshing the access token

An access token expires after a defined time (this can be seen in the response of the /oauth2/token call).
Once your access token is expired, retrieve a new one using the /oauth2/token API once again.


Fetching your organization's portfolios

Organizations are representations of a companies. They contain multiple Portfolios which represent Credit Products managed by a company.

Before creating an entity for the customer you want a credit report for, you first need to know which Portfolio the consumer belongs to within your Organization.

To do so, run the following API call to the https://sandbox.bloom.dev/v2/core/organizationendpoint. This endpoint will return all portfolios available under your organization:

replace the $ACCESS_TOKEN with the previously created access token

For more details, see the API Reference .

curl --request GET \
     --url https://sandbox.bloom.dev/v2/core/organization \
     --header 'accept: application/json' \
     --header 'authorization: Bearer $ACCESS_TOKEN'
const sdk = require('api')('@bloomcredit/v2.0#1z6kflqx2qpgd');

sdk.auth('$ACCESS_TOKEN');
sdk.coreGetOrganization()
  .then(({ data }) => console.log(data))
  .catch(err => console.error(err));
require 'uri'
require 'net/http'

url = URI("https://sandbox.bloom.dev/v2/core/organization")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer $ACCESS_TOKEN'

response = http.request(request)
puts response.read_body
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://sandbox.bloom.dev/v2/core/organization', [
  'headers' => [
    'accept' => 'application/json',
    'authorization' => 'Bearer $ACCESS_TOKEN',
  ],
]);

echo $response->getBody();
# python -m pip install requests 
import requests

url = "https://sandbox.bloom.dev/v2/core/organization"

headers = {
    "accept": "application/json",
    "authorization": "Bearer $ACCESS_TOKEN"
}

response = requests.get(url, headers=headers)

print(response.text)

Here is an example response for a successful call:

{
  "data": {
    "id": "<organization_id>",
    "type": "organizations",
    "attributes": {
      "name": "Your organization name",
      "is_active": false,
      "hubspot_company_id": "<hubspot_company_id>",
      "consumer_address_normalization_rule": "OVERRIDE",
      "portfolios": [
        {
          "id": "<portfolio_id>",
          "name": "<portfolio_name>",
          "type": "CREDIT_CARD",
          "data_access_retention": 129600,
          "furnishment_retention": 2630880
        }
      ]
    }
  }
}

Store the <portfolio_id> of the chosen portfolio to be used in the next step.


Creating a consumer

Consumers are representations of persons within the Bloom API. To order a credit report for a consumer, you first need to submit their information to Bloom.

To do so, create the consumer using the https://sandbox.bloom.dev/v2/core/consumersAPI:

Here we are using test data to create a consumer

Make sure to replace $ACCESS_TOKEN with a previously generated access token.

curl --location --request POST 'https://sandbox.bloom.dev/v2/core/consumers' \
--header 'Authorization: Bearer $ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data-raw '{
    "data": {
        "type": "consumers",
        "attributes": {
            "ssn": "666018517",
            "date_of_birth": "1986-4-17",
            "emails": [
                {
                    "email_address": "[email protected]",
                    "primary": true
                }
            ],
            "name": {
                "first_name": "Miranda",
                "middle_name": "E",
                "last_name": "Smith"
            },
            "addresses": [
                {
                    "line1": "4189 E Garford St",
                    "line2": "EXT",
                    "city": "BLACK CREEK",
                    "state_code": "NC",
                    "zipcode": "27813",
                    "primary": true
                }
            ]
        }
    }
}'
// npm install api --save
const sdk = require('api')('@bloomcredit/v2.0#5a1mg2ulle8xc1g');

sdk.auth('$ACCESS_TOKEN');
sdk.createConsumerV2({
  data: {
    attributes: {
      name: {first_name: 'Miranda', last_name: 'Smith', middle_name: 'E'},
      addresses: [
        {
          city: 'BLACK CREEK',
          line1: '4189 E Garford St',
          line2: 'EXT',
          state_code: 'NC',
          primary: true,
          zipcode: '27813'
        }
      ],
      date_of_birth: '1986-4-17',
      ssn: '666018517'
    },
    type: 'consumers'
  }
})
  .then(({ data }) => console.log(data))
  .catch(err => console.error(err));
require 'uri'
require 'net/http'

url = URI("https://sandbox.bloom.dev/v2/core/consumers")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["accept"] = 'application/json'
request["content-type"] = 'application/json'
request["authorization"] = 'Bearer $ACCESS_TOKEN'
request.body = "{\"data\":{\"attributes\":{\"name\":{\"first_name\":\"Miranda\",\"last_name\":\"Smith\",\"middle_name\":\"E\"},\"addresses\":[{\"city\":\"BLACK CREEK\",\"line1\":\"4189 E Garford St\",\"line2\":\"EXT\",\"state_code\":\"NC\",\"primary\":true,\"zipcode\":\"27813\"}],\"date_of_birth\":\"1986-4-17\",\"ssn\":\"666018517\"},\"type\":\"consumers\"}}"

response = http.request(request)
puts response.read_body
// composer require guzzlehttp/guzzle
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://sandbox.bloom.dev/v2/core/consumers', [
  'body' => '{"data":{"attributes":{"name":{"first_name":"Miranda","last_name":"Smith","middle_name":"E"},"addresses":[{"city":"BLACK CREEK","line1":"4189 E Garford St","line2":"EXT","state_code":"NC","primary":true,"zipcode":"27813"}],"date_of_birth":"1986-4-17","ssn":"666018517"},"type":"consumers"}}',
  'headers' => [
    'accept' => 'application/json',
    'authorization' => 'Bearer $ACCESS_TOKEN',
    'content-type' => 'application/json',
  ],
]);

echo $response->getBody();
# python -m pip install requests
import requests

url = "https://sandbox.bloom.dev/v2/core/consumers"

payload = { "data": {
        "attributes": {
            "name": {
                "first_name": "Miranda",
                "last_name": "Smith",
                "middle_name": "E"
            },
            "addresses": [
                {
                    "city": "BLACK CREEK",
                    "line1": "4189 E Garford St",
                    "line2": "EXT",
                    "state_code": "NC",
                    "primary": True,
                    "zipcode": "27813"
                }
            ],
            "date_of_birth": "1986-4-17",
            "ssn": "666018517"
        },
        "type": "consumers"
    } }
headers = {
    "accept": "application/json",
    "content-type": "application/json",
    "authorization": "Bearer $ACCESS_TOKEN"
}

response = requests.post(url, json=payload, headers=headers)

print(response.text)

📘

To view more details for the consumer creation payload see the API Reference

Upon a successful consumer creation, you will receive a response containing the id of the consumer.

Here is an example of the response.

{
    "data": {
        "id": "<consumer_id>",
        "type": "consumers",
        "attributes": {
            "ssn": "666018517",
            "date_of_birth": "1986-04-17",
            "name": {
                "first_name": "Miranda",
                "middle_name": "E",
                "last_name": "Smith"
            },
            "emails": [
                {
                    "email_address": "[email protected]",
                    "primary": true
                }
            ],
            "addresses": [
                {
                    "id": "<address_id>",
                    "line1": "4189 E Garford St",
                    "line2": "EXT",
                    "city": "BLACK CREEK",
                    "state_code": "NC",
                    "zipcode": "27813",
                    "primary": true
                }
            ]
        }
    }
}

Store the <consumer_id> for the next step, as it will be needed to order a credit report for that consumer.


Ordering a credit report

Once your consumer is created, you can order a credit report via the Bloom API. This order will be made for Bloom to fetch the credit report for your order.

Here is a sample for ordering a credit report, using the https://sandbox.bloom.dev/v2/data-access/ordersendpoint:

We use the previously fetched consumer_id and portfolio_id for this call, also we authenticate this call using the previously generated $ACCESS_TOKEN.

For more details, see the API Reference .

curl --location --request POST 'https://sandbox.bloom.dev/v2/data-access/orders' \
--header 'Authorization: Bearer $ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data-raw '{
    "data": {
        "type": "order",
        "attributes": {
            "consumer_id": "<consumer_id>",
            "portfolio_id": "<portfolio_id>",
            "sku": "equifax-bronze-soft-vantage-internet"
        }
    }
}'
// npm install api --save
const sdk = require('api')('@bloomcredit/v2.0#1760q2tlqgyl8um');

sdk.auth('$ACCESS_TOKEN');
sdk.dataAccessNewOrder({
  data: {
    attributes: {
      consumer_id: '<consumer_id>',
      portfolio_id: '<portfolio_id>',
      sku: 'equifax-bronze-soft-vantage-internet'
    },
    type: 'order'
  }
})
  .then(({ data }) => console.log(data))
  .catch(err => console.error(err));
require 'uri'
require 'net/http'

url = URI("https://sandbox.bloom.dev/v2/data-access/orders")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["accept"] = 'application/json'
request["content-type"] = 'application/json'
request["authorization"] = 'Bearer $ACCESS_TOKEN'
request.body = "{\"data\":{\"attributes\":{\"consumer_id\":\"<consumer_id>\",\"portfolio_id\":\"<portfolio_id>\",\"sku\":\"equifax-bronze-soft-vantage-internet\"},\"type\":\"order\"}}"

response = http.request(request)
puts response.read_body
// composer require guzzlehttp/guzzle
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://sandbox.bloom.dev/v2/data-access/orders', [
  'body' => '{"data":{"attributes":{"consumer_id":"<consumer_id>","portfolio_id":"<portfolio_id>","sku":"equifax-bronze-soft-vantage-internet"},"type":"order"}}',
  'headers' => [
    'accept' => 'application/json',
    'authorization' => 'Bearer $ACCESS_TOKEN',
    'content-type' => 'application/json',
  ],
]);

echo $response->getBody();
# python -m pip install requests 
import requests

url = "https://sandbox.bloom.dev/v2/data-access/orders"

payload = { "data": {
        "attributes": {
            "async": True,
            "consumer_id": "8932c731-8a5b-40d6-92d5-f338d8e4e5be",
            "portfolio_id": "19b0174f-d831-4bca-a13c-9acf75497a9b",
            "sku": "equifax-bronze-hard"
        },
        "type": "orders"
    } }
headers = {
    "accept": "application/json",
    "content-type": "application/json",
    "authorization": "Bearer $ACCESS_TOKEN"
}

response = requests.post(url, json=payload, headers=headers)

print(response.text)

Here is a sample success response for the previous call:

{
    "data": {
        "type": "orders",
        "id": "<order_id>",
        "attributes": {
            "consumer_id": "<consumer_id>",
            "sku": "equifax-silver-soft-vantage-internet",
            "order_placed": "2024-04-13T14:19:16.37393Z",
            "order_filled": "2024-04-13T14:19:17.655478427Z",
            "order_updated": "2024-04-13T14:19:17.659033043Z",
            "status": "SUCCESS",
            "status_code": "30",
            "status_message": "Hit",
            "status_details": "https://developers.bloomcredit.io/docs/status-codes#30"
        }
    }
}

Store the <order_id>for the next step, as it will be needed to fetch the report.

📘

To learn more about the credit report ordering process see Order Credit Data and Credit Data Order


Fetching a full report

Once credit data has been ordered and successfully fulfilled, you can use the Bloom API to fetch a full credit data report. To do so, use the https://sandbox.bloom.dev/v2/data-access/orders/<order_id>/full-reportendpoint. A full-report contains all information collected regarding a credit data order for a single consumer:

Replace <order_id>with the previously fetched id and authenticate this call using the previously generated $ACCESS_TOKEN

curl --request GET \
     --url https://sandbox.bloom.dev/v2/data-access/orders/<order_id>/full-report \
     --header 'accept: application/json' \
     --header 'authorization: Bearer $ACCESS_TOKEN'
// npm install api --save 
const sdk = require('api')('@bloomcredit/v2.0#es0dinlt7kfibt');

sdk.auth('$ACCESS_TOKEN');
sdk.getOrdersOrderidFullReport({orderId: '<order_id>'})
  .then(({ data }) => console.log(data))
  .catch(err => console.error(err));
require 'uri'
require 'net/http'

url = URI("https://sandbox.bloom.dev/v2/data-access/orders/<order_id>/full-report")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer $ACCESS_TOKEN'

response = http.request(request)
puts response.read_body
// composer require guzzlehttp/guzzle
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://sandbox.bloom.dev/v2/data-access/orders/<order_id>/full-report', [
  'headers' => [
    'accept' => 'application/json',
    'authorization' => 'Bearer $ACCESS_TOKEN',
  ],
]);

echo $response->getBody();
# python -m pip install requests
import requests

url = "https://sandbox.bloom.dev/v2/data-access/orders/%3Corder_id%3E/full-report"

headers = {
    "accept": "application/json",
    "authorization": "Bearer $ACCESS_TOKEN"
}

response = requests.get(url, headers=headers)

print(response.text)

This call will return a response containing the full data for the previously ordered credit report. Here is a sample snippet for a response:

{
    "credit_data_order": null,
    "tradeline_attributes": [
        {
            "total_tradelines": null,
            "open_tradelines": null,
            "tradeline_open_last_3_months": null,
            "tradeline_open_last_6_months": null,
            "tradeline_open_last_9_months": null,
            "tradeline_open_last_12_months": null,
...cont. 

📘

To learn about all the data available within a credit report see Credit Data Concepts


What's next

Through this tutorial, we had an overview of the interactions with the Bloom API, from authentication through creating consumers and ordering credit reports for them. This is only the first step and there are many more features available through the API to access credit data information of your consumers.

For further reading, see: