Getting Started

About

This guide provides instructions to create a user in Bloom Enablement Services, and the steps necessary to import that user's tradelines for furnishing. Also included are instructions for closing a user's tradeline, and deleting a user.

Terminology

Pre-requisites

Getting Started

  1. Obtain a Client ID and Client Secret for Authorization from the Bloom onboarding process. An organizationSlug is also needed, and obtained during onboarding.

  2. Create a user via the RegisterOrganizationUser GraphQL Mutation, with the user's personal information and the organizationSlug obtained above. Optionally, check if a user exists with the email by using the UserExistsWithEmail GraphQL Query. In Bloom's sandbox environment, there is a limit of 100 users per organization. There is no limit in the production environment.

  3. Grab the correct GraphQL URL from What URL Should I be Using. Use this URL for all following GraphQL operations.

  4. This step requires Organization Scoped Authentication (see Enablement Services Authentication).

   Authorization: Bearer <organization_scoped_access_token>
  1. The user_id in the response needs to be stored against the consumer, and is required to interact with certain Enablement Services endpoints.

NOTE: If you've already registered a webhook endpoint you will receive a user.created event upon completion of this step

GraphQL

   mutation RegisterOrganizationUser {
       registerOrganizationUser(
           input: {
               organizationSlug: "bloom"
               email: "buzz.inga@bloomcredit.io"
               phoneNumber: "+12345678901"
               name: { first: "Buzz", last: "Inga" }
               address: {
                   line1: "123 Main "
                   city: "Athens"
                   state: "FL"
                   country: "USA"
                   zipcode: "37745"
                   type: PRIMARY
               }
               dateOfBirth: { day: 14, month: 6, year: 1986 }
               nationalId: "1234"
           }
       ) {
           user {
               id
               name {
                   first
                   middle
                   last
               }
           }
       }
   }
  1. Authenticate the user via the /v2/users/<user_id>/authenticate HTTP endpoint. Use the API URL, not the GraphQL URL, from What URL Should I Be Using?. Replace <user_id> with the user_idfrom the previous step's response. The access token will be in the response body, to be used for authorizing the user.

Sample Response

   {
     "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.KMUFsIDTnFmyG3nMiGM6H9FNFUROf3wh7SmqJp-QV30",
     "expires_in": 7200,
     "token_type": "Bearer"
   }
  1. This token is valid for 2 hours. Upon expiration, regenerate one following the same process.
  2. There may be a slight delay of no more than 10 seconds between user creation, and when authentication can be performed.
  3. Use Organization Scoped Authentication, just as in the previous step.
   curl --location --request POST 'https://api.bloomplus.dev/v2/users/<user_id>/authenticate' \
   --header 'Authorization: Bearer <organization_scoped_access_token>'
  1. For the remaining steps, use the user scoped access token obtained in Step 3 for authentication unless otherwise stated. Provide the token as a bearer token in the headers. This is referred to as User Scoped Authentication (see Enablement Services Authentication). Replace user_scoped_access_token with the user's access token.
   Authorization: Bearer <user_scoped_access_token>
  1. Check that the newly created user exists with the Me GraphQL query. Make sure you are using the User Scoped access token from the previous step for authentication.

GraphQL

   query Me {
          me {
              id
              email
              phoneNumber
              status
              notificationPreferences
              createdAt
              updatedAt
              syncedAt
              closedAt
              name {
                  first
                  middle
                  last
              }
          }
   }
  1. Obtain a connection token from Plaid. See Plaid Processor Tokens.
  2. The best sync times in the Bloom Aggregator occur when the Plaid SYNC_UPDATES_AVAILABLE webhook has been received with the field historical_update_complete set to true. Waiting for this update allows Bloom to import the full transaction history, instead of having to poll for the status periodically (potentially wasting import time).
  3. All processor tokens created in Step 12 will be passed into the ImportPlaidProcessorTokens mutation in a single request to import the processor tokens.

This will return two lists. One list contains a list of the created connection object and corresponding token, one for each successfully imported token. The other list contains contains a list of each failed token and a corresponding error code. This will start a workflow in the background to ingest the user's transactions into Bloom Enablement Services. If an error is encountered importing the processor token, the connection's status will be updated. Updates can be viewed using the Me query.

NOTE: If you've already registered a webhook endpoint you will receive one connection.created and one user.synced event for each token imported upon completion of this step. You will also receive tradeline.created webhooks if the imported tokens have recurring sets of transactions.

GraphQL

   mutation ImportPlaidProcessorTokens {
       importPlaidProcessorTokens(
           input: {
               tokens: [
                   "processor-sandbox-448c2232-72d1-4592-92a3-dc1af242fead"
               ]
           }
       ) {
           successes {
               token
               connection {
                   id
                   status
                   externalConnectionId
               }
           }
           failures {
               token
               error
           }
       }
   }
  1. Check that the user's transactions have been imported. These will be listed under the tradelines for the user in the Me query, once the ingestion process is completed. The transaction ingestion is complete when the query shows the user's tradelines or once a user.synced webhook is received. A sample query is listed below, showing the first 5 tradelines for the user. In sandbox, this takes about 5 minutes.

Tradelines will be listed as eligible or ineligible via the isEligible property. Tradelines with isEligible == true and status == UNOPENED are able to be opened in the next step.

  1. Opening a tradeline begins the process of reporting it to credit bureaus.
    1. The user's tradelines have been successfully imported when the user's syncedAt property has been set to a non-null date. This property will be updated whenever the user's tradelines are updated.
    2. In the response, the tradeline ID's will be under tradelines > edges > node > id for each tradeline.

GraphQL

   query Me {
       me {
           tradelines(input: { first: 5 }) {
               edges {
                   cursor
                   node {
                       id
                       merchant
                       category
                       status
                       isEligible
                       paymentFrequency
                       createdAt
                       updatedAt
                       transactions(input: { first: 5 }) {
                           edges {
                               cursor
                               node {
                                   id
                                   date
                                   value {
                                       amount
                                       currency
                                   }
                               }
                           }
                       }
                   }
               }
           }
       }
   }
  1. Open a tradeline to be reported with one of the corresponding open tradeline methods. Each bill type has a corresponding mutation to open the tradeline (ie. rent, utility, telco).
  2. You will need the tradeline_id obtained in the previous step as well as some extra details about the tradeline. Only tradelines with status == UNOPENED and isEligible == true can be opened.
  3. After opening a tradeline the status will change to OPEN. Retrieve the status from the response to verify. This tradeline will now be furnished to the bureaus.

NOTE: If you've already registered a webhook endpoint you will receive a tradeline.opened event upon completion of this step

For example, to open a Utility tradeline:

GraphQL

   mutation OpenUtilityTradeline {
     openUtilityTradeline(
       id: "808b1fe0-8015-4df5-8bed-89d4acf68213"
       details: { isPrimaryAddress: true, utilityTypes: [WATER] }
     ) {
       tradeline {
         id
         status
         details {
           ... on UtilityTradelineDetails {
             isPrimaryAddress
             utilityTypes
           }
         }
       }
     }
   }

Closing a Tradeline

  1. To close a tradeline, use the CloseTradeline Mutation. All that is required is the tradeline_id, which can be found with the Me query. This mutation requires an access token, as per Enablement Services Authentication. Following the example in Getting Started, the mutation may look like:

GraphQL

   mutation CloseTradeline {
       closeTradeline(id: "808b1fe0-8015-4df5-8bed-89d4acf68213") {
           tradeline {
             id
             status
             details {
               ... on UtilityTradelineDetails {
                 utilityTypes
                 isPrimaryAddress
               }
             }
           }
       }
   }
  1. This will start a background workflow in the Bloom Enablement Services to ensure the tradeline will not be furnished.
  2. After closing a tradeline the status will change to CLOSED. Retrieve the status from the response to verify.

Delete a User

To delete a user, use the DeleteMe mutation. Use the user's access token, mentioned in Enablement Services Authentication.

GraphQL

   mutation DeleteMe {
     deleteMe {
       user {
         id
         name {
           first
           middle
           last
         }
       }
     }
   }

Disconnecting a Connection

  1. Call the deleteConnection GraphQL mutation.
  2. Using the access token associated with your plaid processor token, you may wish to call the Plaid item remove endpoint. This will invalidate the processor token.

GraphQL

   mutation DeleteConnection {
       deleteConnection(id: "813bbced-d62a-4144-9f60-231f41ff5c16") {
           connection {
               id
               status
               externalConnectionId
           }
       }
   }

What URL Should I Be Using

Sandbox vs Production

Currently, there is one main difference between the Sandbox and Production environments in Bloom's Enablement Services:

Data is not shared between sandbox and production environments.