Corgi BankDocumentation
OpenAPI

Make a loan

This page takes a 10,000.00 business term loan through application, closing, disbursement into checking, the first day's interest and the first payment. Each step is one request.

Before you start

  • A verified business customer with an open business checking account. See Getting started.
  • Two staff members. $TOKEN belongs to a lending officer with lending:write, the lending_officer role. $APPROVER_TOKEN belongs to someone else who also holds operations:approve, the lending_approver role. Closing routes want an authentication within the last five minutes from both.
  • In the local sandbox, start it with -staff-fixtures. The credentials file then holds closing_maker_token and closing_checker_token, which last five minutes. POST /sandbox/staff-tokens, with the file's staff_fixture_secret as the bearer, mints a fresh set.

Nothing here leaves the bank. The loan funds into a deposit account by a ledger journal.

1. Apply

POST /loans underwrites at once. With a score of 720 and a debt-to-income ratio of 19.17 percent, this application comes back approved at the product's 950 basis points. Keep the loan's id.

Apply
curl -X POST 'https://api.dev.bank.corgi.com/loans' \
  -H "Authorization: Bearer $TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"customer_id": "cust_2tVh8nqLxq4GbDe0K1F6S9zRcWm",
       "product_code": "term_loan_business",
       "disbursement_account_id": "acct_2tVh8nqLxq4GbDe0K1F6S9zRcWm",
       "principal_amount": 1000000, "term_months": 12,
       "monthly_income_amount": 1500000, "monthly_debt_amount": 200000,
       "credit_score": 720, "purpose": "equipment"}'

A file that comes back review needs the approver first. A decline must carry reasons.

Only for a loan in review
curl -X POST 'https://api.dev.bank.corgi.com/loans/loan_2tVh8nqLxq4GbDe0K1F6S9zRcWm/decide' \
  -H "Authorization: Bearer $APPROVER_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"decision": "approve", "reasons": ["Seasonal income documented"]}'

2. Capture the closing

An approved loan cannot be disbursed until a closing is released. The officer captures the plan with POST /loans/{id}/closings. The body is in the first panel on the right. funding_date must be the business date on which you will disburse. The business date is the Federal Reserve banking day, and it rolls to the next one at 4:00 p.m. Eastern. Keep the case's id.

Capture the plan
curl -X POST 'https://api.dev.bank.corgi.com/loans/loan_2tVh8nqLxq4GbDe0K1F6S9zRcWm/closings' \
  -H "Authorization: Bearer $TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d @closing-plan.json

3. Archive the documents

Each requirement in the plan needs a PDF. The officer uploads the lending policy under code policy and the signed note under signed_note. The policy PDF's SHA-256 must equal the plan's policy_sha256, and the note must carry a signature from every party. The second panel shows the note's body. Keep each document's id.

Upload the signed note
curl -X POST 'https://api.dev.bank.corgi.com/loans/loan_2tVh8nqLxq4GbDe0K1F6S9zRcWm/closings/3f6c2a9e-8b1d-4c57-9e0a-5d2b7c418f60/documents' \
  -H "Authorization: Bearer $TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d @signed-note.json

4. Review, sign and release

The approver does the rest, because the officer who captured the evidence cannot approve or release it. Review each document by its id, then the case by its own id. The case review is refused until the policy document is approved.

Review a document or the case
curl -X POST 'https://api.dev.bank.corgi.com/loans/loan_2tVh8nqLxq4GbDe0K1F6S9zRcWm/closings/3f6c2a9e-8b1d-4c57-9e0a-5d2b7c418f60/reviews/b81e04d7-2f3a-4e6c-a1d9-7c5f0e9b2a44' \
  -H "Authorization: Bearer $APPROVER_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"approve": true, "reason": "Reviewed against the signed original"}'

Record the signing. at is the actual time: after the case was captured, not in the future, and on the plan's consummation_date.

Consummation
curl -X POST 'https://api.dev.bank.corgi.com/loans/loan_2tVh8nqLxq4GbDe0K1F6S9zRcWm/closings/3f6c2a9e-8b1d-4c57-9e0a-5d2b7c418f60/consummation' \
  -H "Authorization: Bearer $APPROVER_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"at": "2026-09-17T15:00:00Z"}'

Then release funding. evidence_sha256 is the SHA-256 of the record the approver relied on. The closing now reads released.

Release
curl -X POST 'https://api.dev.bank.corgi.com/loans/loan_2tVh8nqLxq4GbDe0K1F6S9zRcWm/closings/3f6c2a9e-8b1d-4c57-9e0a-5d2b7c418f60/release' \
  -H "Authorization: Bearer $APPROVER_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"reason": "Closing conditions verified",
       "evidence_sha256": "9f2c6a1e5b0d4c38a7e1f4d2b6c9a0e3f5d7b8c1a2e4f6d8b0c2a4e6f8d0b1c3"}'

5. Disburse

POST /loans/{id}/disbursements takes no body. One journal debits the loan's receivable for 10,000.00, credits checking 9,900.00 and credits the 1 percent origination fee to income. The loan is now active, and GET /loans/{id}/schedule lists its 12 installments.

Disburse
curl -X POST 'https://api.dev.bank.corgi.com/loans/loan_2tVh8nqLxq4GbDe0K1F6S9zRcWm/disbursements' \
  -H "Authorization: Bearer $TOKEN" \
  -H "Idempotency-Key: $(uuidgen)"

6. Accrue the first day

Interest starts the day after funding. The next day, run the accrual for that date. One day on 10,000.00 at 9.50 percent over 365 days is 2.60273973. The loan shows that as accrued_interest, and accrued_posted_amount is 260, the whole cents recognized in the ledger.

Accrual run
curl -X POST 'https://api.dev.bank.corgi.com/loans/accrual-runs' \
  -H "Authorization: Bearer $TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"business_date": "2026-09-18"}'

7. Take a payment

POST /loans/{id}/payments debits the checking account. A payment of 876.84 on that day pays 2.60 of interest and 874.24 of principal, and the answer shows the split. A business borrower's own token cannot make this call, so bank staff or a service does. The borrower of a consumer loan can pay with a step-up within five minutes.

Pay
curl -X POST 'https://api.dev.bank.corgi.com/loans/loan_2tVh8nqLxq4GbDe0K1F6S9zRcWm/payments' \
  -H "Authorization: Bearer $TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"amount": 87684, "currency_code": "USD"}'

8. Read the loan

GET /loans/{id} returns the loan as it stands, shown in the third panel. Among the events published along the way are lending.application.approved, lending.closing.created, lending.closing.released, lending.loan.disbursed and lending.payment.received. Disbursement and repayment covers payoff and what happens when a payment is missed.

Read
curl 'https://api.dev.bank.corgi.com/loans/loan_2tVh8nqLxq4GbDe0K1F6S9zRcWm' \
  -H "Authorization: Bearer $TOKEN"

to move to open esc to close