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/token
endpoint 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 todev-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/organization
endpoint. This endpoint will return all portfolios available under your organization:
replace the
$ACCESS_TOKEN
with the previously created access tokenFor 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/consumers
API:
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/orders
endpoint:
We use the previously fetched
consumer_id
andportfolio_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-report
endpoint. 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:
- Batch Ordering, for ways to order credit data for multiple consumers at predefined cadence.
- Credit Data Concepts, to learn about all data available within the credit reports.
- Querying Reports, for ways to search and query precisely into reports.
Updated 3 months ago