> For the complete documentation index, see [llms.txt](https://developers.bloomcredit.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers.bloomcredit.io/quick-start/onboarding-to-first-credit-report.md).

# 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.

{% hint style="info" %}
**If you don't have credentials yet,** [**contact us**](https://www.bloomcredit.io/contact-us) **to get onboarded onto our platform.**
{% endhint %}

### 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-started/environments.md).

### Getting an access token

Access tokens are keys used to authenticate all Bloom API calls. You can generate tokens using the `https://authn.bloomcredit.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 to `dev-api`.

{% tabs %}
{% tab title="cUrl" %}

```bash
curl --location --request POST 'https://authn.bloomcredit.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'
```

{% endtab %}

{% tab title="js-fetch" %}

```javascript
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.bloomcredit.dev/oauth2/token", requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://authn.bloomcredit.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)
```

{% endtab %}

{% tab title="Javascript" %}

```python
var https = require('follow-redirects').https;
var fs = require('fs');
var qs = require('querystring');

var options = {
  'method': 'POST',
  'hostname': 'authn.bloomcredit.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();
```

{% endtab %}

{% tab title="Go" %}

```go
package main

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

func main() {

  url := "https://authn.bloomcredit.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))
}
```

{% endtab %}
{% endtabs %}

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

{% code title="JSON" %}

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

{% endcode %}

### Using the access token

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

{% code title="Authorization Header" %}

```bash
Authorization: Bearer <ACCESS_TOKEN>
```

{% endcode %}

### 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](/core-concepts/organizations.md) are representations of a companies. They contain multiple [Portfolios](/core-concepts/portfolios.md) 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 token
>
> For more details, see the [API Reference](/reference/core/organizations/returns-an-organization.md) .

{% tabs %}
{% tab title="cURL" %}

```bash
curl --request GET \
     --url https://sandbox.bloom.dev/v2/core/organization \
     --header 'accept: application/json' \
     --header 'authorization: Bearer $ACCESS_TOKEN'
```

{% endtab %}

{% tab title="Node" %}

```javascript
const sdk = require('api')('@bloomcredit/v2.0#1z6kflqx2qpgd');

sdk.auth('$ACCESS_TOKEN');
sdk.coreGetOrganization()
  .then(({ data }) => console.log(data))
  .catch(err => console.error(err));
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
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
```

{% endtab %}

{% tab title="PHP" %}

```php
<?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();
```

{% endtab %}

{% tab title="Python" %}

```python
# 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)
```

{% endtab %}
{% endtabs %}

Here is an example response for a successful call:

{% code title="JSON" %}

```json
{
  "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
        }
      ]
    }
  }
}
```

{% endcode %}

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

***

## Creating a consumer

[Consumers](/core-concepts/consumers.md) 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.

{% tabs %}
{% tab title="cURL" %}

```bash
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": "consumeremail@up.com",
                    "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
                }
            ]
        }
    }
}'
```

{% endtab %}

{% tab title="Node" %}

```javascript
// 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));
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
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
```

{% endtab %}

{% tab title="PHP" %}

```php
// 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();
```

{% endtab %}

{% tab title="Python" %}

```python
# 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)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**To view more details for the consumer creation payload see the** [**API Reference**](/reference/core/consumers/creates-a-consumer.md)
{% endhint %}

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

Here is an example of the response.

{% code title="JSON" %}

```json
{
    "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": "consumeremail@up.com",
                    "primary": true
                }
            ],
            "addresses": [
                {
                    "id": "<address_id>",
                    "line1": "4189 E Garford St",
                    "line2": "EXT",
                    "city": "BLACK CREEK",
                    "state_code": "NC",
                    "zipcode": "27813",
                    "primary": true
                }
            ]
        }
    }
}
```

{% endcode %}

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` and `portfolio_id` for this call, also we authenticate this call using the previously generated `$ACCESS_TOKEN`.
>
> For more details, see the [API Reference](/reference/data-access/orders/build-a-new-order-for-ingestion.md) .

{% tabs %}
{% tab title="cURL" %}

```bash
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"
        }
    }
}'
```

{% endtab %}

{% tab title="Node" %}

```javascript
// 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));
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
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
```

{% endtab %}

{% tab title="PHP" %}

```php
// 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();
```

{% endtab %}

{% tab title="Python" %}

```python
# 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)
```

{% endtab %}
{% endtabs %}

Here is a sample success response for the previous call:

{% code title="JSON" %}

```json
{
    "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"
        }
    }
}
```

{% endcode %}

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

{% hint style="info" %}
**To learn more about the credit report ordering process see** [**Order Credit Data**](/quick-start/ordering-credit-data.md) **and** [**Credit Data Order**](/reference/data-access/schema/credit-data-order.md)
{% endhint %}

***

## 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`

{% tabs %}
{% tab title="Shell" %}

```bash
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'
```

{% endtab %}

{% tab title="Node" %}

```javascript
// 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));
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
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
```

{% endtab %}

{% tab title="PHP" %}

```php
// 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();
```

{% endtab %}

{% tab title="Python" %}

```python
# 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)
```

{% endtab %}
{% endtabs %}

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

{% code title="JSON" %}

```json
{
    "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. 
```

{% endcode %}

{% hint style="info" %}
**To learn about all the data available within a credit report see** [**Credit Data Concepts**](/data-access/credit-reports.md)
{% endhint %}

***

## 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](/data-access/batch-ordering.md), for ways to order credit data for multiple consumers at predefined cadence.
* [Credit Data Concepts](/data-access/credit-reports.md), to learn about all data available within the credit reports.
* [Querying Reports](/data-access/querying-reports.md), for ways to search and query precisely into reports.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://developers.bloomcredit.io/quick-start/onboarding-to-first-credit-report.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
