Batch Ordering

Batch ordering allows Bloom's partners to pull credit data for multiple consumers at a time on some predefined cadence.

To get started with batch ordering for your use case, follow these steps:

1. Create a Subscription

In order to start batch ordering, you must first create a Subscription.

To create the subscription, you'll need to send a POST request to our Create Subscription endpoint (replacing all {{var}} with your variables):

curl --location --request POST 'https://sandbox.bloom.dev/v2/data-access/subscriptions' \
--header 'Authorization: Bearer {{access_token}}' \
--header 'Content-Type: application/json' \
--data-raw '{
    "data": {
        "type": "subscription",
        "attributes": {
            "organization_id": "{{portfolio_id}}",
            "sku": "{{sku_name}}",
            "output_credentials": "test",
            "frequency": "WEEKLY"
        }
    }
}'
POST /v2/data-access/subscriptions/ HTTP/1.1
Host: sandbox.bloom.dev
Authorization: Bearer {{access_token}}
Content-Type: application/json
{
    "data": {
        "type": "subscription",
        "attributes": {
            "organization_id": "{{portfolio_id}}",
            "sku": "{{sku_name}}",
            "output_credentials": "test",
            "frequency": "WEEKLY"
        }
    }
}
var myHeaders = new Headers();
myHeaders.append("Authorization", "Bearer {{access_token}}");
myHeaders.append("Content-Type", "application/json");

var raw = JSON.stringify({
    "data": {
        "type": "subscription",
        "attributes": {
            "organization_id": "{{portfolio_id}}",
            "sku": "{{sku_name}}",
            "output_credentials": "test",
            "frequency": "WEEKLY"
        }
    }
});

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

fetch("https://sandbox.bloom.dev/v2/data-access/subscriptions/", requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));
import requests
import json

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

payload = json.dumps({
    "data": {
        "type": "subscription",
        "attributes": {
            "organization_id": "{{portfolio_id}}",
            "sku": "{{sku_name}}",
            "output_credentials": "test",
            "frequency": "WEEKLY"
        }
    }
})
headers = {
  'Authorization': 'Bearer {{access_token}}',
  'Content-Type': 'application/json'
}

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

print(response.text)
package main

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

func main() {

  url := "https://sandbox.bloom.dev/v2/data-access/subscriptions/"
  method := "POST"

  payload := strings.NewReader(`{
    "data": {
        "type": "subscription",
        "attributes": {
            "organization_id": "{{portfolio_id}}",
            "sku": "{{sku_name}}",
            "output_credentials": "test",
            "frequency": "WEEKLY"
        }
    }
}`)

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

  if err != nil {
    fmt.Println(err)
    return
  }
  req.Header.Add("Authorization", "Bearer {{access_token}}")
  req.Header.Add("Content-Type", "application/json")

  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))
}

📘

Subscription

A subscription encapsulates the data:

  • Frequency (DAILY / WEEKLY / BIWEEKLY / QUADWEEKLY )

The Frequency will be how often the batch order runs for the group of consumers assigned to it

  • Output Credentials

The Output Credentials will be in the format of the destination URI for the batch response file you intend to receive, an example would be: sftp://user:password@host

2. Add Consumers to Subscription

After you've created the Subscription, you'll need to add Consumers you want data fetched for into the Subscription, so that when it runs it will fetch data for those consumers. To do this, you'll need to send a PATCH request to our Subscription Consumers endpoint:

curl --location --request PATCH 'https://sandbox.bloom.dev/v2/data-access/subscriptions/{{subscription_id}}/consumers' \
--header 'Authorization: Bearer {{access_token}}' \
--header 'Content-Type: application/json' \
--data-raw '{
    "data": {
        "type": "subscription",
        "attributes": {
            "consumers_to_add": {
                "1ce99bf0-831c-4e22-9ec6-fc353891812b": "WEEKLY",
                "1ce99bf0-831c-4e22-9ec6-fc35389181ac": "BIWEEKLY"
            }
        }
    }
}'
PATCH /v2/data-access/subscriptions/{{subscription_id}}/consumers HTTP/1.1
Host: sandbox.bloom.dev
Authorization: Bearer {{access_token}}
Content-Type: application/json

{
    "data": {
        "type": "subscription",
        "attributes": {
            "consumers_to_add": {
                "1ce99bf0-831c-4e22-9ec6-fc353891812b": "WEEKLY",
                "1ce99bf0-831c-4e22-9ec6-fc35389181ac": "BIWEEKLY"
            }
        }
    }
}
var myHeaders = new Headers();
myHeaders.append("Authorization", "Bearer {{access_token}}");
myHeaders.append("Content-Type", "application/json");

var raw = JSON.stringify({
    "data": {
        "type": "subscription",
        "attributes": {
            "consumers_to_add": {
                "1ce99bf0-831c-4e22-9ec6-fc353891812b": "WEEKLY",
                "1ce99bf0-831c-4e22-9ec6-fc35389181ac": "BIWEEKLY"
            }
        }
    }
});

var requestOptions = {
  method: 'PATCH',
  headers: myHeaders,
  body: raw,
  redirect: 'follow'
};

fetch("https://sandbox.bloom.dev/v2/data-access/subscriptions/{{subscription_id}}/consumers", requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));
import requests
import json

url = "https://sandbox.bloom.dev/v2/data-access/subscriptions/{{subscription_id}}/consumers"

payload = json.dumps({
    "data": {
        "type": "subscription",
        "attributes": {
            "consumers_to_add": {
                "1ce99bf0-831c-4e22-9ec6-fc353891812b": "WEEKLY",
                "1ce99bf0-831c-4e22-9ec6-fc35389181ac": "BIWEEKLY"
            }
        }
    }
})
headers = {
  'Authorization': 'Bearer {{access_token}}',
  'Content-Type': 'application/json'
}

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

print(response.text)
package main

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

func main() {

  url := "https://sandbox.bloom.dev/v2/data-access/subscriptions/{{subscription_id}}/consumers"
  method := "PATCH"

  payload := strings.NewReader(`{
    "data": {
        "type": "subscription",
        "attributes": {
            "consumers_to_add": {
                "1ce99bf0-831c-4e22-9ec6-fc353891812b": "WEEKLY",
                "1ce99bf0-831c-4e22-9ec6-fc35389181ac": "BIWEEKLY"
            }
        }
    }
}`)

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

  if err != nil {
    fmt.Println(err)
    return
  }
  req.Header.Add("Authorization", "Bearer {{access_token}}")
  req.Header.Add("Content-Type", "application/json")

  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))
}

📘

Removing Consumers from an existing Subscription

You can change the operation applied from the PATCH request simply by switching the attribute consumers_to_add with a list of consumers with the name consumers_to_remove

curl --location --request PATCH 'https://sandbox.bloom.dev/v2/data-access/subscriptions/{{subscription_id}}/consumers' \
--header 'Authorization: Bearer {{access_token}}' \
--header 'Content-Type: application/json' \
--data-raw '{
    "data": {
        "type": "subscription",
        "attributes": {
            "consumers_to_remove": [
                "1ce99bf0-831c-4e22-9ec6-fc353891812b"
            ]
        }
    }
}'
PATCH /v2/data-access/subscriptions/{{subscription_id}}/consumers HTTP/1.1
Host: sandbox.bloom.dev
Authorization: Bearer {{access_token}}
Content-Type: application/json

{
    "data": {
        "type": "subscription",
        "attributes": {
            "consumers_to_remove": [
                "1ce99bf0-831c-4e22-9ec6-fc353891812b"
            ]
        }
    }
}
var myHeaders = new Headers();
myHeaders.append("Authorization", "Bearer {{access_token}}");
myHeaders.append("Content-Type", "application/json");

var raw = JSON.stringify({
    "data": {
        "type": "subscription",
        "attributes": {
            "consumers_to_remove": [
                "1ce99bf0-831c-4e22-9ec6-fc353891812b"
            ]
        }
    }
});

var requestOptions = {
  method: 'PATCH',
  headers: myHeaders,
  body: raw,
  redirect: 'follow'
};

fetch("https://sandbox.bloom.dev/v2/data-access/subscriptions/{{subscription_id}}/consumers", requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));
import requests
import json

url = "https://sandbox.bloom.dev/v2/data-access/subscriptions/{{subscription_id}}/consumers"

payload = json.dumps({
    "data": {
        "type": "subscription",
        "attributes": {
            "consumers_to_remove": [
                "1ce99bf0-831c-4e22-9ec6-fc353891812b"
            ]
        }
    }
})
headers = {
  'Authorization': 'Bearer {{access_token}}',
  'Content-Type': 'application/json'
}

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

print(response.text)
package main

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

func main() {

  url := "https://sandbox.bloom.dev/v2/data-access/subscriptions/{{subscription_id}}/consumers"
  method := "PATCH"

  payload := strings.NewReader(`{
    "data": {
        "type": "subscription",
        "attributes": {
            "consumers_to_remove": [
                "1ce99bf0-831c-4e22-9ec6-fc353891812b"
            ]
        }
    }
}`)

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

  if err != nil {
    fmt.Println(err)
    return
  }
  req.Header.Add("Authorization", "Bearer {{access_token}}")
  req.Header.Add("Content-Type", "application/json")

  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))
}

3. Get Subscription with Consumers

To check an existing subscription that you created in the past, it can be achieved by sending a GET request to our Subscription Consumers endpoint:

curl --location --request GET 'https://sandbox.bloom.dev/v2/data-access/subscriptions/{{subscription_id}}/consumers' \
--header 'Authorization: Bearer {{access_token}}' \
--header 'Content-Type: application/json' \
GET /v2/data-access/subscriptions/{{subscription_id}}/consumers HTTP/1.1
Host: sandbox.bloom.dev
Authorization: Bearer {{access_token}}
Content-Type: application/json
var myHeaders = new Headers();
myHeaders.append("Authorization", "Bearer {{access_token}}");
myHeaders.append("Content-Type", "application/json");

var requestOptions = {
  method: 'GET',
  headers: myHeaders,
  redirect: 'follow'
};

fetch("https://sandbox.bloom.dev/v2/data-access/subscriptions/{{subscription_id}}/consumers", requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));
import requests
import json

url = "https://sandbox.bloom.dev/v2/data-access/subscriptions/{{subscription_id}}/consumers"

headers = {
  'Authorization': 'Bearer {{access_token}}',
  'Content-Type': 'application/json'
}

response = requests.request("GET", url, headers=headers, data=None)
print(response.text)
package main

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

func main() {

  url := "https://sandbox.bloom.dev/v2/data-access/subscriptions/{{subscription_id}}/consumers"
  method := "GET"

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

  if err != nil {
    fmt.Println(err)
    return
  }
  req.Header.Add("Authorization", "Bearer {{access_token}}")
  req.Header.Add("Content-Type", "application/json")

  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))
}

4. Fetching Batch order results

Following the execution of periodic orders, result files will be uploaded to the given location during the creation of subscriptions using the Output credentials field.

The uploaded files contain details of each subscription jobs, here is the schema they will be following

{
 "<subscription_job_id>":  {
   //credit report  
 }, 
 "<subscription_job_id2>": {
  //credit report 
 },
 ...
}

Each subscription_job_id can be used to fetch a full report separately, should you need it.

Use the Get Full Report endpoint with this id to fetch the full report separately.

📘

The content of the credit report held in Batch Order response is identical to the ones documented in regular report call, to learn more see Querying Reports.