PierPierdocs

Quickstart

This guide provides an introduction to getting started with our APIs.

Starter mode

Pier's Starter Mode allows you to use Pier for ledgering and compliance without Pier's funds flow. Please see Starter Mode for more information.

Environments

The Pier API is accessible in two environments:

EnvironmentAPI url
Sandboxsandbox.pier-finance.com/api
Productionproduction.pier-finance.com/api

The sandbox is designed to mimic the production environment, with a few exceptions. Loan agreements created in the sandbox will have large 'draft' watermarks and funds flows will only occur in production. Sandbox API keys are prefixed with test_ while production API keys are prefixed with prod_. Otherwise, sandbox and production behavior is identical.

API Calls

Our team will provide you with a ready-made API call collection to get you started immediately. You'll need a few variables configured:

VariableDescription
clientIdYour API client ID
secretYour API secret
tokenThe JWT token returned from the /token endpoint, included as Bearer ${token} in the Authorization header of each request
baseUrlSet to https://sandbox.pier-finance.com/api for sandbox

The pre-request script below handles token refresh automatically — it calls the /token endpoint and injects the result into each subsequent request:

pm.sendRequest({
  url:  pm.collectionVariables.get('baseUrl') + '/token',
  method: 'POST',
  header: {
    'Content-Type': 'application/json'
  },
  body: {
    mode: 'raw',
    raw: JSON.stringify({client_id: pm.collectionVariables.get('clientId'), secret: pm.collectionVariables.get('secret')})
  }
}, function (err, res) {
    pm.collectionVariables.set('token', res.json().token);
});

OpenAPI Client Generation

Generation

Please see our OpenAPI Spec Repo to access our openapi.yml spec file and generate a client in your language of choice. The following is an example on how to generate the typescript-axios SDK using openapi-generator on Mac:

brew install openapi-generator
openapi-generator generate \
  -i openapi.yml \
  -g typescript-axios \
  -o ./pier-typescript \
  --additional-properties=supportsES6=true

Utilization

Here is an example of how to use the generated typescript-axios SDK:

import axios from "axios";
import {
    Configuration,
    AuthApi,
    BorrowersApi
} from "./pier-typescript";
 
const PIER_API_BASE_PATH = "https://sandbox.pier-finance.com/api";
 
const configuration = new Configuration({ basePath: PIER_API_BASE_PATH });
const api = axios.create({ baseURL: PIER_API_BASE_PATH });
const authApi = new AuthApi(configuration);
 
let accessToken: string;
api.interceptors.request.use(
    async (config) => {
        if (!accessToken) await getAccessToken();
        config.headers.Authorization = accessToken;
        return config;
    },
    (error) => Promise.reject(error)
);
api.interceptors.response.use(
    (response) => response,
    async (error) => {
        const originalRequest = error.config;
        if (error.response.status === 401 && !originalRequest._retry) {
            originalRequest._retry = true;
            await getAccessToken();
            return api(originalRequest);
        }
        return Promise.reject(error);
    }
);
 
const getAccessToken = async () => {
    const { data: { token } } = await authApi.authGetToken({
        client_id: "<CLIENT_ID>",
        secret: "<SECRET>"
    });
    accessToken = `Bearer ${token}`;
};
 
(async () => {
    const borrowersApi = new BorrowersApi(new Configuration({}), PIER_API_BASE_PATH, api);
    const { data: borrowers } = await borrowersApi.borrowersListAllBorrowers({});
    console.log("List of borrowers: ", borrowers);
})();

Authentication

Pier uses bearer auth to authenticate API requests. Call the /token endpoint using client_id and secret in the post body to get a JWT token. The token should be included in the Authorization header of all subsequent requests in the format of Bearer ${token}.

Rate limits and retrying API requests

Only 5xx (Server Errors) and 429 (Rate Limits) errors should be retried.

Pier's rate limit is set to 1,000 requests per minute. The limit applies to both the sandbox and production environments. If a rate limit is triggered, we will respond with a 429 status code.

Timezones

All loan-related items are in Pacific Time (PT). This includes things like first_payment_date, next_payment_date, all of the loan amortization schedules, etc. These times are usually date format (e.g. YYYY-MM-DD) and simply determine the payment/accrual dates. All other (not payment related) timestamps are UTC and will follow the ISO8601 format.

Platform Status

See Pier's Status Page for platform availability and feel free to subscribe for updates.

High-level origination flow

The following diagram outlines how the Pier origination flow works with the Borrower, Application, Loan Agreement and Facility resources:

quickstart diagram

Step 1: Create Borrower

curl -X POST https://sandbox.pier-finance.com/api/borrowers/consumer \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer ${PIER_ISSUED_JWT}' \
-d '{
    "address": {
        "line_1": "15 Main Street",
        "line_2": "Unit 220",
        "city": "Seattle",
        "state": "WA",
        "zip": "98101"
    },
    "date_of_birth": "1991-06-19",
    "email": "pmartin@email.com",
    "first_name": "Pierre",
    "last_name": "Martin",
    "ssn": "111111111",
    "kyc_completion_date": "2023-03-27"
}'

Step 2: Create application

curl -X POST https://sandbox.pier-finance.com/api/applications \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer ${PIER_ISSUED_JWT}' \
-d '{
    "borrower_id": "bor_7b1b1f0d97554532a2681e4159ec2a8a",
    "credit_type": "consumer_installment_loan"
}'

Step 3: Approve application

curl -X POST https://sandbox.pier-finance.com/api/applications/app_ae982db618544da9ac6fad552cede6f0/approve \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer ${PIER_ISSUED_JWT}' \
-d '{
    "offers":[{
        "amount": 2000000,
        "interest_rate": 1300,
        "payment_period": "monthly",
        "origination_fee": 0,
        "late_payment_fee": 0,
        "type": "loan_offer",
        "loan_term": {
            "term_type": "months",
            "term": 12
        }
    }]
}'

Step 4: Create loan agreement

curl -X POST https://sandbox.pier-finance.com/api/loan_agreements \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer ${PIER_ISSUED_JWT}' \
-d '{
    "application_id": "app_ae982db618544da9ac6fad552cede6f0",
    "accepted_offer_id": "off_b71c4524ac57467e982ce5414800c27f"
}'

Step 5: Sign loan agreement

curl -X POST https://sandbox.pier-finance.com/api/loan_agreements/doc_6f9c7af667024d5f837ae5a0fb942a8a/sign \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer ${PIER_ISSUED_JWT}' \
-d '{}'

Step 6. Create credit facility

curl -X POST https://sandbox.pier-finance.com/api/facilities \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer ${PIER_ISSUED_JWT}' \
-d '{
    "loan_agreement_id": "doc_6f9c7af667024d5f837ae5a0fb942a8a"
}'