Meta tracking pixel
Aloan

Developers

Aloan API reference

The Commercial API connects your own systems to Aloan. Open relationships and deals, send the borrower's documents in, and read the spreads, analyses and credit memo back out.

Commercial API v1 · OpenAPI 3.1.0 · 30 operations

On this page

Overview

Aloan is the AI-native commercial loan origination system. The Commercial API lets your own systems work on the same records your team works on in the browser: open a relationship, put a deal on it, send the borrower's documents in, and read the published spreads, analyses and credit memo back out.

  1. Relationship. The borrower and everyone around them.
  2. Deal. One credit request, from structured terms or from a term sheet.
  3. Documents. Sent in, classified, and filed against the deal's checklist.
  4. Analysis. Spreads, cash flow and DSCR, once an analyst publishes them.
  5. Credit memo. The submitted memo, as JSON or as the Word file approvers read.

Requests and responses are JSON over HTTPS. Work that takes longer than a request returns a job you poll, and every list can be swept for changes with updated_after. Nothing in the API waits on a person: where underwriting needs a judgment call, Aloan asks your team in the app and carries on.

Base URLs

Environments
EnvironmentBase URL and keys
Sandbox https://api-sandbox.aloan.ai/api/v1
Keys start sk_test_. Test data, the same behavior as production. Start here.
Production https://api.aloan.ai/api/v1
Keys start sk_live_. Live borrower data.

A key works only in the environment that issued it. The sandbox has its own keys and its own data.

Authentication

Send your API key as a bearer token on every request.

curl "$BASE_URL/me" \
  -H "Authorization: Bearer sk_test_xxxxxxxxxxxxxxxxxxxxxxxx"

GET /me touches no data and needs no setup, so a 200 there means the key works. It also tells you which organization the key acts for, its scope and its environment.

A key belongs to one organization and one environment. Aloan stores only a hash of it, so a lost key is replaced rather than recovered. Treat it like a password: keep it on your servers, never in a browser or a mobile app.

Each key carries one of two scopes, and every operation below names the scope it needs.

Scopes
ScopeWhat it allows
read GET requests only. A write returns 403 insufficient_scope.
read_write Everything a read key can do, plus creates and updates.

Getting a key

An administrator of your organization (the Admin or IT Admin role) creates keys in Aloan under Settings → API → Keys. Each key gets a name (the system that will hold it), a scope and an optional expiry date. The secret is shown once, when the key is created.

Keys are made in the environment they work in: create sandbox keys while signed in to the Aloan sandbox, and live keys in production.

To replace a key, choose Rotate. Aloan issues the replacement and the old key keeps working until you revoke it, so you can move your integration over before cutting the old key off.

If API does not appear under Settings, ask your Aloan contact or support@aloan.ai to turn it on for your organization.

Quickstart

One deal from start to finish against the sandbox, every call in the order you would make it.

# 1. Point at the sandbox, set your key, and check it works.
export BASE_URL="https://api-sandbox.aloan.ai/api/v1"
export ALOAN_API_KEY="sk_test_..."
curl "$BASE_URL/me" -H "Authorization: Bearer $ALOAN_API_KEY"

# 2. Create the relationship, carrying your own id for it.
curl -X POST "$BASE_URL/relationships" \
  -H "Authorization: Bearer $ALOAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"display_name": "Brookvale Holdings", "external_id": "0016A00000XyZaBQAV"}'

# 3. Create the deal on it, with the parties you know. Terms can come later.
curl -X POST "$BASE_URL/deals" \
  -H "Authorization: Bearer $ALOAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "relationship_id": "external:0016A00000XyZaBQAV",
    "external_id": "0066A00000LmNoPQRS",
    "entities": [
      { "name": "Brookvale Holdings LLC", "entity_type": "BUSINESS", "role": "BORROWER" },
      { "name": "Dana Whitfield", "entity_type": "PERSON", "role": "GUARANTOR" }
    ]
  }'

# 4. The response's entities[] carry each party's entity_id. Keep them to file
#    documents against. (They are also on GET /relationships/{id}/entities.)

# 5. Upload each document: declare it, then put the bytes straight into storage.
curl -X POST "$BASE_URL/uploads" \
  -H "Authorization: Bearer $ALOAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"file_name": "2024-tax-return.pdf", "file_type": "application/pdf", "file_size": 4718592}'

curl -X PUT "<upload_url from above>" \
  -H "Content-Type: application/pdf" \
  --data-binary @2024-tax-return.pdf

# 6. File the uploads onto the deal, naming whose each one is. Returns a job.
curl -X POST "$BASE_URL/deals/external:0066A00000LmNoPQRS/documents" \
  -H "Authorization: Bearer $ALOAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"documents": [{"upload_id": "upl_01jgx...", "entity_id": "asubj_01jgx..."}]}'

# 7. Poll the job until it is completed; each file reports where it landed.
curl "$BASE_URL/jobs/job_01jgx..." -H "Authorization: Bearer $ALOAN_API_KEY"

# 8. Once the analysts have published, read the figures.
curl "$BASE_URL/deals/external:0066A00000LmNoPQRS/analyses" \
  -H "Authorization: Bearer $ALOAN_API_KEY"

Pagination and order

Lists return {data, has_more, next_cursor}. Pass next_cursor back as cursor for the next page, and limit (1 to 200, default 50) to size it. Pages are cursor-based rather than offset-based, so a page never skips a record because something ahead of it changed. Send the same filters and order with every page; a cursor continues only the order it came from.

Every list takes order. Ties break on id in the same direction.

Values of order
orderReturns
updated_at Default. Oldest change first. Use it for sweeps with updated_after.
-updated_at Newest change first: poll for what changed. De-duplicate on id plus updated_at.
-created_at Newest record first: poll for what is new. De-duplicate on id.

Keeping in step

To mirror a list into your own system, sweep it in the default order with updated_after:

  1. Request the list with updated_after set to the updated_at of the last record you processed. The boundary is inclusive.
  2. Follow next_cursor until has_more is false.
  3. Store the newest updated_at you saw for the next sweep, and de-duplicate on id: a record that changes during a sweep comes back again later in it.

Records created in Aloan rather than through the API come back too. A change shows up in a sweep about a minute after it lands, so a sweep never runs ahead of a write that is still committing. A deleted record stops appearing: an id you hold that now returns 404 was deleted in Aloan.

To poll for what is new instead, read the first page with a newest-first order and stop at the first record you have already seen. A newest-first list is a live snapshot, and updated_after is only a lower bound there, so keep watermark sweeps on the default order.

# Sweep: everything changed since your last run, oldest change first.
curl "$BASE_URL/deals?updated_after=2026-10-01T14:02:11Z&limit=200" \
  -H "Authorization: Bearer $ALOAN_API_KEY"

# Next page of the same sweep: same filters, plus the cursor.
curl "$BASE_URL/deals?updated_after=2026-10-01T14:02:11Z&limit=200&cursor=<next_cursor>" \
  -H "Authorization: Bearer $ALOAN_API_KEY"

# Poll: the newest deals first. Read page one, stop at an id you have seen.
curl "$BASE_URL/deals?order=-created_at&limit=50" \
  -H "Authorization: Bearer $ALOAN_API_KEY"

Uploads

Every file goes in the same way, in three steps.

  1. Declare it. POST /uploads with file_name, file_type and file_size in bytes (up to 100 MB). The response carries the upload's id and an upload_url that works until expires_at, one hour later.
  2. Send the bytes. PUT the raw file to upload_url with exactly the Content-Type and size you declared. This request goes straight to storage, not to the API, so it carries no Authorization header. Both values are signed into the URL, and a mismatch comes back from storage as a signature error: check Content-Type and Content-Length before suspecting your key. If the URL expires first, POST /uploads/{upload_id}/url issues a fresh one for the same upload.
  3. Reference the upload. Pass its id to POST /deals/{deal_id}/documents for borrower documents or POST /deals/intake for a term sheet. The reference is what tells Aloan the file has landed; Aloan checks storage before using it. An upload nobody references expires after 24 hours.
curl -X PUT "$UPLOAD_URL" \
  -H "Content-Type: application/pdf" \
  --data-binary @2024-tax-return.pdf

Accepted file_type values: application/msword, application/pdf, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.openxmlformats-officedocument.wordprocessingml.document, image/gif, image/jpeg, image/png, image/tiff, image/webp, text/csv.

Jobs

Filing documents and reading a term sheet take longer than a request, so those calls answer 202 with a job. Poll GET /jobs/{job_id} until it settles: completed, failed or cancelled. A term-sheet job stops at awaiting_confirmation until you confirm or cancel it.

Poll every 10 seconds for the first two minutes, then every 30. A finished document job is a record of how each file stood when the job completed; a file that needed review and was filed later says so on GET /files/{file_id}, not on the job.

Errors

Every failure has the same shape. Branch on code, which is stable; message is for your logs, and field appears when one field is at fault.

{
  "error": {
    "code": "validation_failed",
    "message": "assigned_to is not a user in your organization.",
    "field": "assigned_to"
  }
}
The error object
Field Description
code string · required Stable. Branch on it.
message string · required For a human reading a log.
field string The field at fault, as an indexed path (entities[1].name), when one is.
reason string On conflict: why the record refused the change.
details map[] Every failing entry of a batch, with its field.
Error codes
CodeMeaning
unauthorized HTTP 401 Missing, malformed, revoked or expired API key.
insufficient_scope HTTP 403 A read-only key attempted a write.
forbidden HTTP 403 The key's organization may not access this record.
ip_not_allowed HTTP 403 Your organization limits API access to an IP allowlist (Settings → Security) and this request came from outside it. ip is the address we saw.
not_found HTTP 404 No such record, or it belongs to another organization.
method_not_allowed HTTP 405 The path exists but not for this method.
invalid_request HTTP 400 The request was malformed. field names the offender when one does.
validation_failed HTTP 422 Well-formed, but rejected by a business rule: an unknown assignee, say.
placement_conflict HTTP 422 A file's placement contradicts the deal (a closed request, another entity's request, a type or period the request is not for). details[] lists each offending entry by index; nothing was consumed.
conflict HTTP 409 The record is not in a state that permits this operation, or an external_id is already in use. reason says which; the message names the existing record.
idempotency_key_reused HTTP 409 The Idempotency-Key was already used for a request with a different body.
request_in_progress HTTP 409 A request with this Idempotency-Key is still in flight. Retry once it completes.
unsupported_media_type HTTP 415 Send JSON.
rate_limited HTTP 429 Rate limit exceeded. Retry-After gives the seconds to wait.
server_error HTTP 500 Our fault. Retry a read freely; before retrying a create, check whether it took effect (list by external_id).

Rate limits

Each API key gets 120 requests a minute sustained and 20 a second in bursts. A request over either limit returns 429 rate_limited with a Retry-After header giving the seconds to wait. If your integration needs more, email support@aloan.ai.

Retries

Send an Idempotency-Key header (any string up to 255 characters, unique per request you make) on every POST and PATCH. If the connection drops and you retry with the same key and body, you get the original response back, marked Idempotency-Replayed: true, instead of a second deal.

The same key with a different body is 409 idempotency_key_reused; a retry that overlaps the first attempt is 409 request_in_progress. Keys are remembered for 24 hours and belong to your organization, so a retry after you rotate your API key still replays. A write and its replay record commit together, so a request that failed never half-happened.

Reads are safe to retry. Before retrying a create that returned 500 without an idempotency key, check whether it took effect by listing with your external_id.

Identifiers

Every object carries a prefixed, opaque id. The prefixes are stable; treat the rest as a string.

Id prefixes
PrefixObject
crel_ Relationship
asubj_ Entity
upl_ Upload
clapp_ Deal
cfac_ Facility
cloan_ Loan
cdr_ Data request
cbfile_ File
cdoc_ Document
cdq_ Question
canalysis_ Analysis
job_ Job

Relationships and deals also take an external_id: your id for the record, unique within your organization. Anywhere a path takes an id you can pass yours instead, prefixed: /deals/external:0066A00000LmNoPQRS. You never have to store Aloan's ids.

Creating a second record with an id you have already used is refused with 409 conflict (reason: external_id_taken), and the error carries the existing record's id as current_deal_id or current_relationship_id, so a create you are unsure about is safe to send again. An id is claimed once: a record that already carries one of yours keeps it until you clear it with null, so a deal created in the app can be claimed by your system exactly once.

IP allowlists

If your organization turns on an IP allowlist in Aloan (Settings → Security), it applies to your API keys too. A request from outside the listed networks returns 403 ip_not_allowed and is recorded for your administrators. Add your integration's egress addresses before turning the list on.

Types

Timestamps are RFC 3339 in UTC (2026-09-21T14:02:11Z), dates are YYYY-MM-DD, and money is a decimal string ("2500000.00") with a separate ISO 4217 currency, never a float. Rates and fees are decimal fractions, not percentages: "0.0725" is 7.25%.

Versioning

The version is in the path (/api/v1). Within a version Aloan only adds new fields and new endpoints, so parse defensively and ignore what you don't recognize. Anything that would break an integration ships as a new version, with notice.

OpenAPI document

Everything on this page is also published as an OpenAPI 3.1.0 document. Download openapi.json, or fetch it from either environment at /api/v1/openapi.json (no key needed). Generate a client from it, or validate your own requests and responses against it.

Endpoints

Your key

The first call to make with a new key: it proves the key works and says what it is.

Describe the key in use

GET /me

Requires a read key.

Which organization the key acts for, its scope, and whether it is a sandbox or production key. Needs no setup and touches no data, so a 200 here means authentication is working.

Example request

curl "$BASE_URL/me" \
  -H "Authorization: Bearer $ALOAN_API_KEY"

Response

200 Returns a Me object.

Example response
{
  "organization": {
    "id": "org_01jgx5k2m3n4p5q6r7s8t9u0v1",
    "name": "Your Bank"
  },
  "scope": "read_write",
  "environment": "sandbox",
  "key_prefix": "sk_test_a1b2"
}

Errors: 401 unauthorized · 403 ip_not_allowed · 429 rate_limited · 500 server_error

Endpoints

Reference lists

The vocabularies you need before you write: who can own a deal, which loan types your organization has, and what a data type can be. Small tables, returned whole.

List your organization's users

GET /users

Requires a read key.

Who assigned_to and relationship_manager can name. Only users who can own a deal are assignable.

Example request

curl "$BASE_URL/users" \
  -H "Authorization: Bearer $ALOAN_API_KEY"

Response

200 Returns a page of User objects.

Response fields
Field Description
data User[] · required
has_more boolean · required Whether another page follows.
next_cursor string | null · required Pass back as cursor for the next page.
Example response
{
  "data": [
    {
      "email": "underwriter@yourbank.com",
      "name": "Jordan Ellis",
      "role": "MEMBER",
      "assignable": true
    },
    {
      "email": "analyst@yourbank.com",
      "name": "Sam Ortiz",
      "role": "VIEWER",
      "assignable": false
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Errors: 401 unauthorized · 403 ip_not_allowed · 429 rate_limited · 500 server_error

List your loan types

GET /loan-types

Requires a read key.

Your organization's loan types: what loan_type takes. Each drives a different checklist.

Example request

curl "$BASE_URL/loan-types" \
  -H "Authorization: Bearer $ALOAN_API_KEY"

Response

200 Returns a page of LoanTypeOption objects.

Response fields
Field Description
data LoanTypeOption[] · required
has_more boolean · required Whether another page follows.
next_cursor string | null · required Pass back as cursor for the next page.
Example response
{
  "data": [
    {
      "key": "cre_purchase",
      "label": "CRE Purchase"
    },
    {
      "key": "equipment",
      "label": "Equipment Financing"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Errors: 401 unauthorized · 403 ip_not_allowed · 429 rate_limited · 500 server_error

List the data types

GET /data-types

Requires a read key.

Every kind of document a data request asks for or a file can be placed as: what data_type takes.

Example request

curl "$BASE_URL/data-types" \
  -H "Authorization: Bearer $ALOAN_API_KEY"

Response

200 Returns a page of DataTypeOption objects.

Response fields
Field Description
data DataTypeOption[] · required
has_more boolean · required Whether another page follows.
next_cursor string | null · required Pass back as cursor for the next page.
Example response
{
  "data": [
    {
      "key": "BUSINESS_TAX_RETURN",
      "label": "Business Tax Return"
    },
    {
      "key": "PERSONAL_TAX_RETURN",
      "label": "Personal Tax Return"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Errors: 401 unauthorized · 403 ip_not_allowed · 429 rate_limited · 500 server_error

Endpoints

Relationships

Create and maintain the borrowing relationship a deal will hang off.

Create a relationship

POST /relationships

Requires a read_write key.

Parameters
Parameter Description
Idempotency-Key string · header Makes a retry safe: the same key and body within 24 hours replays the first response. Up to 255 characters.
Request body
Field Description
display_name string · required What the relationship is called. Up to 255 characters.
external_id string | null Your id for it. Must be unique within your organization. Up to 255 characters.
relationship_manager string | null Email of the owning RM. Must be a user in your organization.
fiscal_year_end_month integer 1–12. Defaults to 12.

Example request

curl -X POST "$BASE_URL/relationships" \
  -H "Authorization: Bearer $ALOAN_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
      "display_name": "Brookvale Holdings",
      "external_id": "0016A00000XyZaBQAV",
      "relationship_manager": "rm@yourbank.com"
    }'

Response

201 Returns a Relationship object.

Example response
{
  "id": "crel_01jgx5k2m3n4p5q6r7s8t9u0v1",
  "external_id": "0016A00000XyZaBQAV",
  "display_name": "Brookvale Holdings",
  "status": "PROSPECT",
  "relationship_manager": "rm@yourbank.com",
  "fiscal_year_end_month": 12,
  "url": "https://app.aloan.ai/relationships/crel_01jgx5k2m3n4p5q6r7s8t9u0v1?org=org_01jgx5k2m3n4p5q6r7s8t9u0v1",
  "created_at": "2026-09-21T14:02:11Z",
  "updated_at": "2026-09-21T14:02:11Z"
}

Errors: 400 invalid_request · 401 unauthorized · 403 ip_not_allowed, insufficient_scope · 409 idempotency_key_reused, request_in_progress, conflict · 415 unsupported_media_type · 422 validation_failed · 429 rate_limited · 500 server_error

List relationships

GET /relationships

Requires a read key.

Parameters
Parameter Description
updated_after timestamp · query Only records changed since (inclusive). With a newest-first order, a plain lower bound.
limit integer · query 1–200. Defaults to 50.
cursor string · query From next_cursor on the previous page. Send the same filters and order.
order ListOrder · query updated_at (default): oldest change first, for updated_after sweeps. -updated_at: newest change first, for polling what changed. -created_at: newest record first, for polling what's new. Ties break on id in the same direction.
external_id string · query Only the relationship carrying this id of yours.
status RelationshipStatus · query One of ACTIVE, EXITED, PROSPECT.

Example request

curl "$BASE_URL/relationships?updated_after=2026-09-20T00:00:00Z&limit=50" \
  -H "Authorization: Bearer $ALOAN_API_KEY"

Response

200 Returns a page of Relationship objects.

Response fields
Field Description
data Relationship[] · required
has_more boolean · required Whether another page follows.
next_cursor string | null · required Pass back as cursor for the next page.
Example response
{
  "data": [
    {
      "id": "crel_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "external_id": "0016A00000XyZaBQAV",
      "display_name": "Brookvale Holdings",
      "status": "ACTIVE",
      "relationship_manager": "rm@yourbank.com",
      "fiscal_year_end_month": 12,
      "url": "https://app.aloan.ai/relationships/crel_01jgx5k2m3n4p5q6r7s8t9u0v1?org=org_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "created_at": "2026-09-21T14:02:11Z",
      "updated_at": "2026-09-21T14:02:11Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Errors: 400 invalid_request · 401 unauthorized · 403 ip_not_allowed · 429 rate_limited · 500 server_error

Retrieve a relationship

GET /relationships/{relationship_id}

Requires a read key.

Accepts either Aloan's id or your own, prefixed: /relationships/external:0016A00000XyZaBQAV.

Parameters
Parameter Description
relationship_id string · path · required Aloan's id, or your own as external:<id> where the object carries one.

Example request

curl "$BASE_URL/relationships/external:0016A00000XyZaBQAV" \
  -H "Authorization: Bearer $ALOAN_API_KEY"

Response

200 Returns a Relationship object.

Example response
{
  "id": "crel_01jgx5k2m3n4p5q6r7s8t9u0v1",
  "external_id": "0016A00000XyZaBQAV",
  "display_name": "Brookvale Holdings",
  "status": "PROSPECT",
  "relationship_manager": "rm@yourbank.com",
  "fiscal_year_end_month": 12,
  "url": "https://app.aloan.ai/relationships/crel_01jgx5k2m3n4p5q6r7s8t9u0v1?org=org_01jgx5k2m3n4p5q6r7s8t9u0v1",
  "created_at": "2026-09-21T14:02:11Z",
  "updated_at": "2026-09-21T14:02:11Z"
}

Errors: 401 unauthorized · 403 ip_not_allowed · 404 not_found · 429 rate_limited · 500 server_error

Update a relationship

PATCH /relationships/{relationship_id}

Requires a read_write key.

Parameters
Parameter Description
relationship_id string · path · required Aloan's id, or your own as external:<id> where the object carries one.
Idempotency-Key string · header Makes a retry safe: the same key and body within 24 hours replays the first response. Up to 255 characters.
Request body
Field Description
display_name string Rename the relationship. Up to 255 characters.
external_id string | null Claim it with your id while it has none; null clears it. A record that already carries another of your ids answers 409 conflict with reason: external_id_already_set, clear it first to re-point it. Up to 255 characters.
relationship_manager string | null Reassign the owning RM.
fiscal_year_end_month integer 1–12.

Example request

curl -X PATCH "$BASE_URL/relationships/crel_01jgx5k2m3n4p5q6r7s8t9u0v1" \
  -H "Authorization: Bearer $ALOAN_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
      "relationship_manager": "rm2@yourbank.com"
    }'

Response

200 Returns a Relationship object.

Example response
{
  "id": "crel_01jgx5k2m3n4p5q6r7s8t9u0v1",
  "external_id": "0016A00000XyZaBQAV",
  "display_name": "Brookvale Holdings",
  "status": "PROSPECT",
  "relationship_manager": "rm2@yourbank.com",
  "fiscal_year_end_month": 12,
  "url": "https://app.aloan.ai/relationships/crel_01jgx5k2m3n4p5q6r7s8t9u0v1?org=org_01jgx5k2m3n4p5q6r7s8t9u0v1",
  "created_at": "2026-09-21T14:02:11Z",
  "updated_at": "2026-09-22T09:14:03Z"
}

Errors: 400 invalid_request · 401 unauthorized · 403 ip_not_allowed, insufficient_scope · 404 not_found · 409 idempotency_key_reused, request_in_progress, conflict · 415 unsupported_media_type · 422 validation_failed · 429 rate_limited · 500 server_error

List the parties on a relationship

GET /relationships/{relationship_id}/entities

Requires a read key.

The entity pool a new deal draws from. Useful before creating a deal, so you can name existing parties rather than describing them again.

Parameters
Parameter Description
relationship_id string · path · required Aloan's id, or your own as external:<id> where the object carries one.
updated_after timestamp · query Only records changed since (inclusive). With a newest-first order, a plain lower bound.
limit integer · query 1–200. Defaults to 50.
cursor string · query From next_cursor on the previous page. Send the same filters and order.
order ListOrder · query updated_at (default): oldest change first, for updated_after sweeps. -updated_at: newest change first, for polling what changed. -created_at: newest record first, for polling what's new. Ties break on id in the same direction.

Example request

curl "$BASE_URL/relationships/crel_01jgx5k2m3n4p5q6r7s8t9u0v1/entities" \
  -H "Authorization: Bearer $ALOAN_API_KEY"

Response

200 Returns a page of Entity objects.

Response fields
Field Description
data Entity[] · required
has_more boolean · required Whether another page follows.
next_cursor string | null · required Pass back as cursor for the next page.
Example response
{
  "data": [
    {
      "id": "asubj_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "name": "Brookvale Holdings LLC",
      "entity_type": "BUSINESS",
      "legal_form": "LLC",
      "tax_identifier_last4": "4417",
      "is_primary": true
    },
    {
      "id": "asubj_01jgx5k2m3n4p5q6r7s8t9u0v2",
      "name": "Dana Whitfield",
      "entity_type": "PERSON",
      "legal_form": null,
      "tax_identifier_last4": "0092",
      "is_primary": false
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Errors: 400 invalid_request · 401 unauthorized · 403 ip_not_allowed · 404 not_found · 429 rate_limited · 500 server_error

List a relationship's booked loans

GET /relationships/{relationship_id}/loans

Requires a read key.

The booked credit agreements and the notes each covers. A renewal, review or modification acts on notes: pass their ids as note_ids on POST /deals, or omit it for every active note.

Parameters
Parameter Description
relationship_id string · path · required Aloan's id, or your own as external:<id> where the object carries one.
updated_after timestamp · query Only records changed since (inclusive). With a newest-first order, a plain lower bound.
limit integer · query 1–200. Defaults to 50.
cursor string · query From next_cursor on the previous page. Send the same filters and order.
order ListOrder · query updated_at (default): oldest change first, for updated_after sweeps. -updated_at: newest change first, for polling what changed. -created_at: newest record first, for polling what's new. Ties break on id in the same direction.

Example request

curl "$BASE_URL/relationships/crel_01jgx5k2m3n4p5q6r7s8t9u0v1/loans" \
  -H "Authorization: Bearer $ALOAN_API_KEY"

Response

200 Returns a page of Loan objects.

Response fields
Field Description
data Loan[] · required
has_more boolean · required Whether another page follows.
next_cursor string | null · required Pass back as cursor for the next page.
Example response
{
  "data": [
    {
      "id": "cloan_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "external_loan_id": "100-2231-7",
      "status": "ACTIVE",
      "origination_date": "2023-04-14",
      "commitment_amount": "1850000.00",
      "note_ids": [
        "cfac_01jgx5k2m3n4p5q6r7s8t9u0v7"
      ],
      "originating_deal_id": "clapp_01jgx5k2m3n4p5q6r7s8t9u0v9",
      "created_at": "2023-04-14T16:02:11Z",
      "updated_at": "2026-09-21T14:02:11Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Errors: 400 invalid_request · 401 unauthorized · 403 ip_not_allowed · 404 not_found · 429 rate_limited · 500 server_error

Endpoints

Uploads

One way to get a file into Aloan, used everywhere a file is wanted. Declare it, put the bytes straight into our storage, then reference the upload id: that reference is what tells us the file has landed, and we verify it against storage before doing anything with it.

Declare a file and get a URL to put it at

POST /uploads

Requires a read_write key.

Returns a pre-authorized URL. PUT the raw bytes to it: the bytes go directly to our storage, not through this API, so a 300-page tax return costs you one transfer and costs us nothing. Then reference the returned id.

The PUT must send exactly the file_type and file_size you declared: both are signed into the URL. A mismatch is rejected by storage as a signature error, which reads like an auth problem but is not one: check your Content-Type and Content-Length first.

Parameters
Parameter Description
Idempotency-Key string · header Makes a retry safe: the same key and body within 24 hours replays the first response. Up to 255 characters.
Request body
Field Description
file_name string · required Name as you hold it. Kept on the document. Up to 500 characters.
file_type enum · required MIME type. PDF, DOCX, XLSX, XLS, CSV, DOC, JPEG, PNG, GIF, WEBP or TIFF. One of application/msword, application/pdf, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.openxmlformats-officedocument.wordprocessingml.document, image/gif, image/jpeg, image/png, image/tiff, image/webp, text/csv.
file_size integer · required Size in bytes. 100 MB maximum. 1 to 104857600.

Example request

curl -X POST "$BASE_URL/uploads" \
  -H "Authorization: Bearer $ALOAN_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
      "file_name": "2024-tax-return.pdf",
      "file_type": "application/pdf",
      "file_size": 4718592
    }'

Response

201 Returns an Upload object.

Example response
{
  "id": "upl_01jgx5k2m3n4p5q6r7s8t9u0v1",
  "upload_url": "https://s3.us-east-2.amazonaws.com/...&X-Amz-Signature=...",
  "expires_at": "2026-09-21T15:20:05Z",
  "status": "awaiting_bytes"
}

Errors: 400 invalid_request · 401 unauthorized · 403 ip_not_allowed, insufficient_scope · 409 idempotency_key_reused, request_in_progress · 415 unsupported_media_type · 429 rate_limited · 500 server_error

Get a fresh URL for an upload you declared

POST /uploads/{upload_id}/url

Requires a read_write key.

For when expires_at passed before the bytes went up. Same upload, same declared name, type and size; a new URL for another hour.

Parameters
Parameter Description
upload_id string · path · required Aloan's id.
Idempotency-Key string · header Makes a retry safe: the same key and body within 24 hours replays the first response. Up to 255 characters.

Example request

curl -X POST "$BASE_URL/uploads/upl_01jgx5k2m3n4p5q6r7s8t9u0v1/url" \
  -H "Authorization: Bearer $ALOAN_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)"

Response

200 Returns an Upload object.

Example response
{
  "id": "upl_01jgx5k2m3n4p5q6r7s8t9u0v1",
  "upload_url": "https://s3.us-east-2.amazonaws.com/...&X-Amz-Signature=...",
  "expires_at": "2026-09-21T16:20:05Z",
  "status": "awaiting_bytes"
}

Errors: 401 unauthorized · 403 ip_not_allowed, insufficient_scope · 404 not_found · 409 idempotency_key_reused, request_in_progress · 415 unsupported_media_type · 429 rate_limited · 500 server_error

Endpoints

Deals

Create a deal from a structured payload when you hold the terms, or from a term sheet when you hold the document.

Create a deal

POST /deals

Requires a read_write key.

Name existing parties by entity id; describe new ones inline and we will create them on the relationship. Nothing beyond the relationship is required: a deal can start before the terms are known and before anyone owns it, and both can be filled in later, here, or in the app. With no parties named, the relationship's business becomes the borrower.

Parameters
Parameter Description
Idempotency-Key string · header Makes a retry safe: the same key and body within 24 hours replays the first response. Up to 255 characters.
Request body
Field Description
relationship_id string · required Aloan id, or external:<your id>.
external_id string | null Your id for this deal. Unique within your organization. Up to 255 characters.
assigned_to string | null Email of the deal owner: the underwriter for a deal at UNDERWRITING, the RM at PRE_QUALIFICATION. Rejected if it is not a user in your organization.
title string Deal label. Up to 255 characters.
event_type enum ORIGINATION (default), RENEWAL, REVIEW or MODIFICATION. A renewal, review or modification acts on the relationship's notes (its booked facilities) and starts from their parties and terms, so it takes no entities or facilities; note_ids narrows which notes are in scope. One of ORIGINATION, RENEWAL, REVIEW, MODIFICATION, COVENANT_TEST.
stage enum UNDERWRITING (default) or PRE_QUALIFICATION.
loan_type string | null A key from GET /loan-types. Drives the checklist; can be set later with PATCH. Up to 100 characters.
note_ids string[] | null For RENEWAL, REVIEW and MODIFICATION: the notes in scope, as facility ids (cfac_) from GET /relationships/{id}/loans. Omit for every active note on the relationship.
review_period_end date | null For a REVIEW: the period end it reviews. Defaults from the relationship's fiscal year end.
entities EntityInput[] Existing parties by entity_id, or new ones by name and entity_type; we create new ones on the relationship. With none, the relationship's business becomes the borrower.
facilities FacilityInput[] What is being asked for, when you know it. Leave it out when the terms are not settled yet.

Example request

curl -X POST "$BASE_URL/deals" \
  -H "Authorization: Bearer $ALOAN_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
      "relationship_id": "external:0016A00000XyZaBQAV",
      "external_id": "0066A00000LmNoPQRS",
      "assigned_to": "underwriter@yourbank.com",
      "title": "Brookvale: equipment line",
      "event_type": "ORIGINATION",
      "loan_type": "equipment",
      "entities": [
        {
          "entity_id": "asubj_01jgx5k2m3n4p5q6r7s8t9u0v1",
          "role": "BORROWER"
        },
        {
          "name": "Dana Whitfield",
          "entity_type": "PERSON",
          "role": "GUARANTOR",
          "is_primary": true,
          "guarantee": {
            "type": "UNLIMITED"
          }
        }
      ],
      "facilities": [
        {
          "title": "Equipment Line",
          "facility_type": "EQUIPMENT",
          "commitment_amount": "2000000.00",
          "entity_id": "asubj_01jgx5k2m3n4p5q6r7s8t9u0v1",
          "term_months": 60,
          "amortization_months": 60,
          "rate_type": "FIXED",
          "interest_rate": "0.0725",
          "repayment_type": "MONTHLY_PI",
          "collateral": "Blanket lien on equipment"
        },
        {
          "title": "Working Capital Revolver",
          "facility_type": "REVOLVING_LINE_OF_CREDIT",
          "commitment_amount": "500000.00",
          "term_months": 12,
          "rate_type": "VARIABLE",
          "index_name": "PRIME",
          "spread_over_index": "0.005",
          "repayment_type": "REVOLVING_LINE"
        }
      ]
    }'

Response

201 Returns a Deal object.

Example response
{
  "id": "clapp_01jgx5k2m3n4p5q6r7s8t9u0v1",
  "external_id": "0066A00000LmNoPQRS",
  "relationship_id": "crel_01jgx5k2m3n4p5q6r7s8t9u0v1",
  "title": "Brookvale: equipment line",
  "status": "IN_PROGRESS",
  "stage": "UNDERWRITING",
  "event_type": "ORIGINATION",
  "loan_type": "equipment",
  "subject_note_ids": [],
  "assigned_to": "underwriter@yourbank.com",
  "relationship_manager": "rm@yourbank.com",
  "facilities": [
    {
      "purpose": null,
      "interest_only_months": null,
      "index_name": null,
      "spread_over_index": null,
      "rate_floor": null,
      "rate_ceiling": null,
      "payment_amount": null,
      "origination_fee": null,
      "prepayment_penalty": null,
      "id": "cfac_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "title": "Equipment Line",
      "facility_type": "EQUIPMENT",
      "commitment_amount": "2000000.00",
      "entity_id": "asubj_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "term_months": 60,
      "amortization_months": 60,
      "rate_type": "FIXED",
      "interest_rate": "0.0725",
      "repayment_type": "MONTHLY_PI",
      "interest_day_count": "ACTUAL_365",
      "collateral": "Blanket lien on equipment"
    },
    {
      "purpose": null,
      "interest_only_months": null,
      "index_name": "PRIME",
      "spread_over_index": "0.005",
      "rate_floor": null,
      "rate_ceiling": null,
      "payment_amount": null,
      "origination_fee": null,
      "prepayment_penalty": null,
      "id": "cfac_01jgx5k2m3n4p5q6r7s8t9u0v2",
      "title": "Working Capital Revolver",
      "facility_type": "REVOLVING_LINE_OF_CREDIT",
      "commitment_amount": "500000.00",
      "entity_id": null,
      "term_months": 12,
      "amortization_months": null,
      "rate_type": "VARIABLE",
      "interest_rate": null,
      "repayment_type": "REVOLVING_LINE",
      "interest_day_count": "ACTUAL_365",
      "collateral": null
    }
  ],
  "total_commitment": "2500000.00",
  "currency": "USD",
  "entities": [
    {
      "id": "asubj_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "name": "Brookvale Holdings LLC",
      "entity_type": "BUSINESS",
      "legal_form": "LLC",
      "role": "BORROWER",
      "is_primary": true,
      "is_collateral": false,
      "guarantee": null,
      "warnings": []
    },
    {
      "id": "asubj_01jgx5k2m3n4p5q6r7s8t9u0v3",
      "name": "Dana Whitfield",
      "entity_type": "PERSON",
      "legal_form": null,
      "role": "GUARANTOR",
      "is_primary": true,
      "is_collateral": false,
      "guarantee": {
        "type": "UNLIMITED",
        "cap": null
      },
      "warnings": []
    }
  ],
  "data_requests_outstanding": 11,
  "documents": 0,
  "analyses": 0,
  "url": "https://app.aloan.ai/deals/clapp_01jgx5k2m3n4p5q6r7s8t9u0v1?org=org_01jgx5k2m3n4p5q6r7s8t9u0v1",
  "created_at": "2026-09-21T14:06:40Z",
  "updated_at": "2026-09-21T14:06:40Z"
}

Errors: 400 invalid_request · 401 unauthorized · 403 ip_not_allowed, insufficient_scope · 404 not_found · 409 idempotency_key_reused, request_in_progress, conflict · 415 unsupported_media_type · 422 validation_failed · 429 rate_limited · 500 server_error

List deals

GET /deals

Requires a read key.

With updated_after, this is how you keep your system in step with ours, including deals created in Aloan rather than by you.

Parameters
Parameter Description
updated_after timestamp · query Only records changed since (inclusive). With a newest-first order, a plain lower bound.
limit integer · query 1–200. Defaults to 50.
cursor string · query From next_cursor on the previous page. Send the same filters and order.
order ListOrder · query updated_at (default): oldest change first, for updated_after sweeps. -updated_at: newest change first, for polling what changed. -created_at: newest record first, for polling what's new. Ties break on id in the same direction.
relationship_id string · query Only deals on this relationship (crel_... or external:<your id>).
external_id string · query Only the deal carrying this id of yours.
status DealStatus · query One of IN_PROGRESS, PENDING_APPROVAL, APPROVED, FUNDED, DECLINED, WITHDRAWN, COMPLETED.

Example request

curl "$BASE_URL/deals?updated_after=2026-09-20T00:00:00Z" \
  -H "Authorization: Bearer $ALOAN_API_KEY"

Response

200 Returns a page of Deal objects.

Response fields
Field Description
data Deal[] · required
has_more boolean · required Whether another page follows.
next_cursor string | null · required Pass back as cursor for the next page.
Example response
{
  "data": [
    {
      "id": "clapp_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "external_id": "0066A00000LmNoPQRS",
      "relationship_id": "crel_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "title": "Brookvale: equipment line",
      "status": "IN_PROGRESS",
      "stage": "UNDERWRITING",
      "event_type": "ORIGINATION",
      "loan_type": "equipment",
      "subject_note_ids": [],
      "assigned_to": "underwriter@yourbank.com",
      "relationship_manager": "rm@yourbank.com",
      "facilities": [
        {
          "purpose": null,
          "interest_only_months": null,
          "index_name": null,
          "spread_over_index": null,
          "rate_floor": null,
          "rate_ceiling": null,
          "payment_amount": null,
          "origination_fee": null,
          "prepayment_penalty": null,
          "id": "cfac_01jgx5k2m3n4p5q6r7s8t9u0v1",
          "title": "Equipment Line",
          "facility_type": "EQUIPMENT",
          "commitment_amount": "2000000.00",
          "entity_id": "asubj_01jgx5k2m3n4p5q6r7s8t9u0v1",
          "term_months": 60,
          "amortization_months": 60,
          "rate_type": "FIXED",
          "interest_rate": "0.0725",
          "repayment_type": "MONTHLY_PI",
          "interest_day_count": "ACTUAL_365",
          "collateral": "Blanket lien on equipment"
        },
        {
          "purpose": null,
          "interest_only_months": null,
          "index_name": "PRIME",
          "spread_over_index": "0.005",
          "rate_floor": null,
          "rate_ceiling": null,
          "payment_amount": null,
          "origination_fee": null,
          "prepayment_penalty": null,
          "id": "cfac_01jgx5k2m3n4p5q6r7s8t9u0v2",
          "title": "Working Capital Revolver",
          "facility_type": "REVOLVING_LINE_OF_CREDIT",
          "commitment_amount": "500000.00",
          "entity_id": null,
          "term_months": 12,
          "amortization_months": null,
          "rate_type": "VARIABLE",
          "interest_rate": null,
          "repayment_type": "REVOLVING_LINE",
          "interest_day_count": "ACTUAL_365",
          "collateral": null
        }
      ],
      "total_commitment": "2500000.00",
      "currency": "USD",
      "entities": [
        {
          "id": "asubj_01jgx5k2m3n4p5q6r7s8t9u0v1",
          "name": "Brookvale Holdings LLC",
          "entity_type": "BUSINESS",
          "legal_form": "LLC",
          "role": "BORROWER",
          "is_primary": true,
          "is_collateral": false,
          "guarantee": null,
          "warnings": []
        },
        {
          "id": "asubj_01jgx5k2m3n4p5q6r7s8t9u0v3",
          "name": "Dana Whitfield",
          "entity_type": "PERSON",
          "legal_form": null,
          "role": "GUARANTOR",
          "is_primary": true,
          "is_collateral": false,
          "guarantee": {
            "type": "UNLIMITED",
            "cap": null
          },
          "warnings": []
        }
      ],
      "data_requests_outstanding": 11,
      "documents": 0,
      "analyses": 0,
      "url": "https://app.aloan.ai/deals/clapp_01jgx5k2m3n4p5q6r7s8t9u0v1?org=org_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "created_at": "2026-09-21T14:06:40Z",
      "updated_at": "2026-09-21T14:06:40Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Errors: 400 invalid_request · 401 unauthorized · 403 ip_not_allowed · 429 rate_limited · 500 server_error

Create a deal from a term sheet

POST /deals/intake

Requires a read_write key.

Send a term sheet (or a plain-language description) and we read the terms and the parties out of it. Returns a job. When the job reaches awaiting_confirmation its result carries the parsed terms and the parties we read, each with a stable parsed_ref, the role and kind we read, and the existing entity we propose to reuse (proposed_entity_id, with our confidence). Confirm it to create the deal. A description is read inside the request, so that job is already awaiting confirmation when it returns; a term sheet is read in the background.

Parameters
Parameter Description
Idempotency-Key string · header Makes a retry safe: the same key and body within 24 hours replays the first response. Up to 255 characters.
Request body
Field Description
relationship_id string · required Aloan id, or external:<your id>.
upload_id string | null The term sheet, uploaded first: see Uploads.
description string | null Alternative to upload_id: the deal in prose, up to 8,000 characters.
assigned_to string | null Email of the deal owner.
external_id string | null Your id for the deal this will create. Up to 255 characters.
event_type enum ORIGINATION (default), RENEWAL, REVIEW, MODIFICATION. One of ORIGINATION, RENEWAL, REVIEW, MODIFICATION, COVENANT_TEST.

Example request

curl -X POST "$BASE_URL/deals/intake" \
  -H "Authorization: Bearer $ALOAN_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
      "relationship_id": "external:0016A00000XyZaBQAV",
      "assigned_to": "underwriter@yourbank.com",
      "external_id": "0066A00000LmNoPQRS",
      "upload_id": "upl_01jgx5k2m3n4p5q6r7s8t9u0v1"
    }'

Response

202 Returns a Job object.

Example response
{
  "id": "job_01jgx5k2m3n4p5q6r7s8t9u0v1",
  "type": "deal_intake",
  "status": "processing",
  "progress": null,
  "summary": null,
  "result": null,
  "error": null,
  "created_at": "2026-09-21T14:09:02Z",
  "updated_at": "2026-09-21T14:09:02Z",
  "completed_at": null
}

Errors: 400 invalid_request · 401 unauthorized · 403 ip_not_allowed, insufficient_scope · 404 not_found · 409 idempotency_key_reused, request_in_progress, conflict · 415 unsupported_media_type · 422 validation_failed · 429 rate_limited · 500 server_error

Confirm a parsed term sheet

POST /deals/intake/{job_id}/confirm

Requires a read_write key.

Creates the deal from the job's parsed result. Accept the entity matches we proposed, or override any of them with an entity on the relationship. The deal's external_id and owner are the ones you gave when you started the intake. Confirming a job that already created its deal returns that deal again, never a second one.

The full Deal object comes back, as POST /deals returns it.

Parameters
Parameter Description
job_id string · path · required Aloan's id.
Idempotency-Key string · header Makes a retry safe: the same key and body within 24 hours replays the first response. Up to 255 characters.
Request body
Field Description
entity_overrides EntityOverride[] Parties to bind to a specific existing entity instead of the one we proposed.

Example request

curl -X POST "$BASE_URL/deals/intake/job_01jgx5k2m3n4p5q6r7s8t9u0v1/confirm" \
  -H "Authorization: Bearer $ALOAN_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
      "entity_overrides": [
        {
          "parsed_ref": "party-1",
          "entity_id": "asubj_01jgx5k2m3n4p5q6r7s8t9u0v1"
        }
      ]
    }'

Response

201 Returns a Deal object.

Example response
{
  "id": "clapp_01jgx5k2m3n4p5q6r7s8t9u0v1",
  "external_id": "0066A00000LmNoPQRS",
  "relationship_id": "crel_01jgx5k2m3n4p5q6r7s8t9u0v1",
  "title": "Brookvale: equipment line",
  "status": "IN_PROGRESS",
  "stage": "UNDERWRITING",
  "event_type": "ORIGINATION",
  "loan_type": "equipment",
  "subject_note_ids": [],
  "assigned_to": "underwriter@yourbank.com",
  "relationship_manager": "rm@yourbank.com",
  "facilities": [
    {
      "purpose": null,
      "interest_only_months": null,
      "index_name": null,
      "spread_over_index": null,
      "rate_floor": null,
      "rate_ceiling": null,
      "payment_amount": null,
      "origination_fee": null,
      "prepayment_penalty": null,
      "id": "cfac_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "title": "Equipment Line",
      "facility_type": "EQUIPMENT",
      "commitment_amount": "2000000.00",
      "entity_id": "asubj_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "term_months": 60,
      "amortization_months": 60,
      "rate_type": "FIXED",
      "interest_rate": "0.0725",
      "repayment_type": "MONTHLY_PI",
      "interest_day_count": "ACTUAL_365",
      "collateral": "Blanket lien on equipment"
    },
    {
      "purpose": null,
      "interest_only_months": null,
      "index_name": "PRIME",
      "spread_over_index": "0.005",
      "rate_floor": null,
      "rate_ceiling": null,
      "payment_amount": null,
      "origination_fee": null,
      "prepayment_penalty": null,
      "id": "cfac_01jgx5k2m3n4p5q6r7s8t9u0v2",
      "title": "Working Capital Revolver",
      "facility_type": "REVOLVING_LINE_OF_CREDIT",
      "commitment_amount": "500000.00",
      "entity_id": null,
      "term_months": 12,
      "amortization_months": null,
      "rate_type": "VARIABLE",
      "interest_rate": null,
      "repayment_type": "REVOLVING_LINE",
      "interest_day_count": "ACTUAL_365",
      "collateral": null
    }
  ],
  "total_commitment": "2500000.00",
  "currency": "USD",
  "entities": [
    {
      "id": "asubj_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "name": "Brookvale Holdings LLC",
      "entity_type": "BUSINESS",
      "legal_form": "LLC",
      "role": "BORROWER",
      "is_primary": true,
      "is_collateral": false,
      "guarantee": null,
      "warnings": []
    },
    {
      "id": "asubj_01jgx5k2m3n4p5q6r7s8t9u0v3",
      "name": "Dana Whitfield",
      "entity_type": "PERSON",
      "legal_form": null,
      "role": "GUARANTOR",
      "is_primary": true,
      "is_collateral": false,
      "guarantee": {
        "type": "UNLIMITED",
        "cap": null
      },
      "warnings": []
    }
  ],
  "data_requests_outstanding": 11,
  "documents": 0,
  "analyses": 0,
  "url": "https://app.aloan.ai/deals/clapp_01jgx5k2m3n4p5q6r7s8t9u0v1?org=org_01jgx5k2m3n4p5q6r7s8t9u0v1",
  "created_at": "2026-09-21T14:11:27Z",
  "updated_at": "2026-09-21T14:11:27Z"
}

Errors: 400 invalid_request · 401 unauthorized · 403 ip_not_allowed, insufficient_scope · 404 not_found · 409 idempotency_key_reused, request_in_progress, conflict · 415 unsupported_media_type · 422 validation_failed · 429 rate_limited · 500 server_error

Cancel a parsed term sheet

POST /deals/intake/{job_id}/cancel

Requires a read_write key.

Discard a parsed intake without creating anything. Only a job at awaiting_confirmation can be cancelled; the job answers cancelled afterwards.

Parameters
Parameter Description
job_id string · path · required Aloan's id.
Idempotency-Key string · header Makes a retry safe: the same key and body within 24 hours replays the first response. Up to 255 characters.

Example request

curl -X POST "$BASE_URL/deals/intake/job_01jgx5k2m3n4p5q6r7s8t9u0v3/cancel" \
  -H "Authorization: Bearer $ALOAN_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)"

Response

200 Returns a Job object.

Example response
{
  "id": "job_01jgx5k2m3n4p5q6r7s8t9u0v3",
  "type": "deal_intake",
  "status": "cancelled",
  "progress": null,
  "summary": null,
  "result": null,
  "error": null,
  "created_at": "2026-09-21T14:20:05Z",
  "updated_at": "2026-09-21T14:26:12Z",
  "completed_at": null
}

Errors: 401 unauthorized · 403 ip_not_allowed, insufficient_scope · 404 not_found · 409 idempotency_key_reused, request_in_progress, conflict · 415 unsupported_media_type · 429 rate_limited · 500 server_error

Retrieve a deal

GET /deals/{deal_id}

Requires a read key.

The deal: its parties and terms, with counts of what hangs off it. The lists themselves (data requests, documents, analyses) are their own endpoints, so a deal with three hundred documents is still one small object. Accepts external:<your id>.

Parameters
Parameter Description
deal_id string · path · required Aloan's id, or your own as external:<id> where the object carries one.

Example request

curl "$BASE_URL/deals/external:0066A00000LmNoPQRS" \
  -H "Authorization: Bearer $ALOAN_API_KEY"

Response

200 Returns a Deal object.

Example response
{
  "id": "clapp_01jgx5k2m3n4p5q6r7s8t9u0v1",
  "external_id": "0066A00000LmNoPQRS",
  "relationship_id": "crel_01jgx5k2m3n4p5q6r7s8t9u0v1",
  "title": "Brookvale: equipment line",
  "status": "IN_PROGRESS",
  "stage": "UNDERWRITING",
  "event_type": "ORIGINATION",
  "loan_type": "equipment",
  "subject_note_ids": [],
  "assigned_to": "underwriter@yourbank.com",
  "relationship_manager": "rm@yourbank.com",
  "facilities": [
    {
      "purpose": null,
      "interest_only_months": null,
      "index_name": null,
      "spread_over_index": null,
      "rate_floor": null,
      "rate_ceiling": null,
      "payment_amount": null,
      "origination_fee": null,
      "prepayment_penalty": null,
      "id": "cfac_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "title": "Equipment Line",
      "facility_type": "EQUIPMENT",
      "commitment_amount": "2000000.00",
      "entity_id": "asubj_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "term_months": 60,
      "amortization_months": 60,
      "rate_type": "FIXED",
      "interest_rate": "0.0725",
      "repayment_type": "MONTHLY_PI",
      "interest_day_count": "ACTUAL_365",
      "collateral": "Blanket lien on equipment"
    },
    {
      "purpose": null,
      "interest_only_months": null,
      "index_name": "PRIME",
      "spread_over_index": "0.005",
      "rate_floor": null,
      "rate_ceiling": null,
      "payment_amount": null,
      "origination_fee": null,
      "prepayment_penalty": null,
      "id": "cfac_01jgx5k2m3n4p5q6r7s8t9u0v2",
      "title": "Working Capital Revolver",
      "facility_type": "REVOLVING_LINE_OF_CREDIT",
      "commitment_amount": "500000.00",
      "entity_id": null,
      "term_months": 12,
      "amortization_months": null,
      "rate_type": "VARIABLE",
      "interest_rate": null,
      "repayment_type": "REVOLVING_LINE",
      "interest_day_count": "ACTUAL_365",
      "collateral": null
    }
  ],
  "total_commitment": "2500000.00",
  "currency": "USD",
  "entities": [
    {
      "id": "asubj_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "name": "Brookvale Holdings LLC",
      "entity_type": "BUSINESS",
      "legal_form": "LLC",
      "role": "BORROWER",
      "is_primary": true,
      "is_collateral": false,
      "guarantee": null,
      "warnings": []
    },
    {
      "id": "asubj_01jgx5k2m3n4p5q6r7s8t9u0v3",
      "name": "Dana Whitfield",
      "entity_type": "PERSON",
      "legal_form": null,
      "role": "GUARANTOR",
      "is_primary": true,
      "is_collateral": false,
      "guarantee": {
        "type": "UNLIMITED",
        "cap": null
      },
      "warnings": []
    }
  ],
  "data_requests_outstanding": 11,
  "documents": 0,
  "analyses": 0,
  "url": "https://app.aloan.ai/deals/clapp_01jgx5k2m3n4p5q6r7s8t9u0v1?org=org_01jgx5k2m3n4p5q6r7s8t9u0v1",
  "created_at": "2026-09-21T14:06:40Z",
  "updated_at": "2026-09-21T14:06:40Z"
}

Errors: 401 unauthorized · 403 ip_not_allowed · 404 not_found · 429 rate_limited · 500 server_error

Update a deal

PATCH /deals/{deal_id}

Requires a read_write key.

Terms and ownership only. Status and stage move through the platform's own workflow, not through the API.

Parameters
Parameter Description
deal_id string · path · required Aloan's id, or your own as external:<id> where the object carries one.
Idempotency-Key string · header Makes a retry safe: the same key and body within 24 hours replays the first response. Up to 255 characters.
Request body
Field Description
external_id string | null Claim it with your id while it has none; null clears it. A record that already carries another of your ids answers 409 conflict with reason: external_id_already_set, clear it first to re-point it. Up to 255 characters.
title string Deal label. Up to 255 characters.
assigned_to string | null Email of the deal owner; null unassigns.
loan_type string | null A key from GET /loan-types. Re-derives the checklist; null clears it. Up to 100 characters.
facilities FacilityInput[] Replaces the deal's facilities. Send a facility's id to update it in place; omit the id to add one, and omit a facility entirely to remove it.

Example request

curl -X PATCH "$BASE_URL/deals/clapp_01jgx5k2m3n4p5q6r7s8t9u0v1" \
  -H "Authorization: Bearer $ALOAN_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
      "assigned_to": "underwriter2@yourbank.com"
    }'

Response

200 Returns a Deal object.

Example response
{
  "id": "clapp_01jgx5k2m3n4p5q6r7s8t9u0v1",
  "external_id": "0066A00000LmNoPQRS",
  "relationship_id": "crel_01jgx5k2m3n4p5q6r7s8t9u0v1",
  "title": "Brookvale: equipment line",
  "status": "IN_PROGRESS",
  "stage": "UNDERWRITING",
  "event_type": "ORIGINATION",
  "loan_type": "equipment",
  "subject_note_ids": [],
  "assigned_to": "underwriter2@yourbank.com",
  "relationship_manager": "rm@yourbank.com",
  "facilities": [
    {
      "purpose": null,
      "interest_only_months": null,
      "index_name": null,
      "spread_over_index": null,
      "rate_floor": null,
      "rate_ceiling": null,
      "payment_amount": null,
      "origination_fee": null,
      "prepayment_penalty": null,
      "id": "cfac_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "title": "Equipment Line",
      "facility_type": "EQUIPMENT",
      "commitment_amount": "2000000.00",
      "entity_id": "asubj_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "term_months": 60,
      "amortization_months": 60,
      "rate_type": "FIXED",
      "interest_rate": "0.0725",
      "repayment_type": "MONTHLY_PI",
      "interest_day_count": "ACTUAL_365",
      "collateral": "Blanket lien on equipment"
    },
    {
      "purpose": null,
      "interest_only_months": null,
      "index_name": "PRIME",
      "spread_over_index": "0.005",
      "rate_floor": null,
      "rate_ceiling": null,
      "payment_amount": null,
      "origination_fee": null,
      "prepayment_penalty": null,
      "id": "cfac_01jgx5k2m3n4p5q6r7s8t9u0v2",
      "title": "Working Capital Revolver",
      "facility_type": "REVOLVING_LINE_OF_CREDIT",
      "commitment_amount": "500000.00",
      "entity_id": null,
      "term_months": 12,
      "amortization_months": null,
      "rate_type": "VARIABLE",
      "interest_rate": null,
      "repayment_type": "REVOLVING_LINE",
      "interest_day_count": "ACTUAL_365",
      "collateral": null
    }
  ],
  "total_commitment": "2500000.00",
  "currency": "USD",
  "entities": [
    {
      "id": "asubj_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "name": "Brookvale Holdings LLC",
      "entity_type": "BUSINESS",
      "legal_form": "LLC",
      "role": "BORROWER",
      "is_primary": true,
      "is_collateral": false,
      "guarantee": null,
      "warnings": []
    },
    {
      "id": "asubj_01jgx5k2m3n4p5q6r7s8t9u0v3",
      "name": "Dana Whitfield",
      "entity_type": "PERSON",
      "legal_form": null,
      "role": "GUARANTOR",
      "is_primary": true,
      "is_collateral": false,
      "guarantee": {
        "type": "UNLIMITED",
        "cap": null
      },
      "warnings": []
    }
  ],
  "data_requests_outstanding": 11,
  "documents": 0,
  "analyses": 0,
  "url": "https://app.aloan.ai/deals/clapp_01jgx5k2m3n4p5q6r7s8t9u0v1?org=org_01jgx5k2m3n4p5q6r7s8t9u0v1",
  "created_at": "2026-09-21T14:06:40Z",
  "updated_at": "2026-09-22T09:14:03Z"
}

Errors: 400 invalid_request · 401 unauthorized · 403 ip_not_allowed, insufficient_scope · 404 not_found · 409 idempotency_key_reused, request_in_progress, conflict · 415 unsupported_media_type · 422 validation_failed · 429 rate_limited · 500 server_error

Withdraw a deal

POST /deals/{deal_id}/withdraw

Requires a read_write key.

The one status write: the borrower walked, or the opportunity died in your system. Runs the app's own transition, so an open approval request is withdrawn with it. A deal that is declined, funded or already withdrawn answers 409 conflict.

Parameters
Parameter Description
deal_id string · path · required Aloan's id, or your own as external:<id> where the object carries one.
Idempotency-Key string · header Makes a retry safe: the same key and body within 24 hours replays the first response. Up to 255 characters.
Request body
Field Description
reason string · required Why. Shown in the app. Up to 2000 characters.

Example request

curl -X POST "$BASE_URL/deals/clapp_01jgx5k2m3n4p5q6r7s8t9u0v1/withdraw" \
  -H "Authorization: Bearer $ALOAN_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
      "reason": "Opportunity closed lost in Salesforce"
    }'

Response

200 Returns a Deal object.

Example response
{
  "id": "clapp_01jgx5k2m3n4p5q6r7s8t9u0v1",
  "external_id": "0066A00000LmNoPQRS",
  "relationship_id": "crel_01jgx5k2m3n4p5q6r7s8t9u0v1",
  "title": "Brookvale: equipment line",
  "status": "WITHDRAWN",
  "stage": "UNDERWRITING",
  "event_type": "ORIGINATION",
  "loan_type": "equipment",
  "subject_note_ids": [],
  "assigned_to": "underwriter@yourbank.com",
  "relationship_manager": "rm@yourbank.com",
  "facilities": [
    {
      "purpose": null,
      "interest_only_months": null,
      "index_name": null,
      "spread_over_index": null,
      "rate_floor": null,
      "rate_ceiling": null,
      "payment_amount": null,
      "origination_fee": null,
      "prepayment_penalty": null,
      "id": "cfac_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "title": "Equipment Line",
      "facility_type": "EQUIPMENT",
      "commitment_amount": "2000000.00",
      "entity_id": "asubj_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "term_months": 60,
      "amortization_months": 60,
      "rate_type": "FIXED",
      "interest_rate": "0.0725",
      "repayment_type": "MONTHLY_PI",
      "interest_day_count": "ACTUAL_365",
      "collateral": "Blanket lien on equipment"
    },
    {
      "purpose": null,
      "interest_only_months": null,
      "index_name": "PRIME",
      "spread_over_index": "0.005",
      "rate_floor": null,
      "rate_ceiling": null,
      "payment_amount": null,
      "origination_fee": null,
      "prepayment_penalty": null,
      "id": "cfac_01jgx5k2m3n4p5q6r7s8t9u0v2",
      "title": "Working Capital Revolver",
      "facility_type": "REVOLVING_LINE_OF_CREDIT",
      "commitment_amount": "500000.00",
      "entity_id": null,
      "term_months": 12,
      "amortization_months": null,
      "rate_type": "VARIABLE",
      "interest_rate": null,
      "repayment_type": "REVOLVING_LINE",
      "interest_day_count": "ACTUAL_365",
      "collateral": null
    }
  ],
  "total_commitment": "2500000.00",
  "currency": "USD",
  "entities": [
    {
      "id": "asubj_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "name": "Brookvale Holdings LLC",
      "entity_type": "BUSINESS",
      "legal_form": "LLC",
      "role": "BORROWER",
      "is_primary": true,
      "is_collateral": false,
      "guarantee": null,
      "warnings": []
    },
    {
      "id": "asubj_01jgx5k2m3n4p5q6r7s8t9u0v3",
      "name": "Dana Whitfield",
      "entity_type": "PERSON",
      "legal_form": null,
      "role": "GUARANTOR",
      "is_primary": true,
      "is_collateral": false,
      "guarantee": {
        "type": "UNLIMITED",
        "cap": null
      },
      "warnings": []
    }
  ],
  "data_requests_outstanding": 11,
  "documents": 0,
  "analyses": 0,
  "url": "https://app.aloan.ai/deals/clapp_01jgx5k2m3n4p5q6r7s8t9u0v1?org=org_01jgx5k2m3n4p5q6r7s8t9u0v1",
  "created_at": "2026-09-21T14:06:40Z",
  "updated_at": "2026-09-29T11:02:45Z"
}

Errors: 400 invalid_request · 401 unauthorized · 403 ip_not_allowed, insufficient_scope · 404 not_found · 409 idempotency_key_reused, request_in_progress, conflict · 415 unsupported_media_type · 429 rate_limited · 500 server_error

Endpoints

Documents and files

Put borrower documents on a deal. Upload the bytes first, then file the uploads here; every file gets an id the moment we accept it and moves through queued → classifying → processing → filed, or to awaiting_review, duplicate, failed or dismissed. Say where a file belongs when you know, and it goes there: placement beats matching, and the more you say, the less we guess. A file you place on an entity never raises an identity question, so a package filed with entity ids rarely needs anyone in the app. Placement never silences a concern: when the document disagrees with what you said (you placed it as 2024, it reads as 2025), the placement stands and the file carries a period_mismatch or type_mismatch concern your team sees in the Data tab and you see on the file and the document. Most of the time is reading: expect one tax return in about 30 seconds, 35 documents in about 3.5 minutes, 50 in about 7, and 100 in 10 to 12. Poll a job every 10 seconds for the first two minutes, then every 30.

File documents onto a deal

POST /deals/{deal_id}/documents

Requires a read_write key.

File uploaded documents onto the deal. Reference uploads you have already sent the bytes for (one or many) and say where each belongs when you know: a data request, or an entity with a data type and period. Returns a job that reports each file separately, so a single bad file does not obscure the rest, and every file has an id from this moment.

The batch is validated whole before anything is used: a placement that contradicts the deal (a closed request, another entity's request, a type or period the request is not for) is 422 placement_conflict with each offending entry in details by index (documents[2].data_request_id), an upload whose bytes never landed is 422 validation_failed naming its position, and no upload is consumed. A file whose bytes are already on its destination is accepted as a duplicate, with the file it duplicates, and not processed again. A file we cannot place with confidence lands in the deal's review queue in Aloan (awaiting_review) for someone to resolve; the job counts it as needs_review and completes.

Parameters
Parameter Description
deal_id string · path · required Aloan's id, or your own as external:<id> where the object carries one.
Idempotency-Key string · header Makes a retry safe: the same key and body within 24 hours replays the first response. Up to 255 characters.
Request body
Field Description
upload_ids string[] The same, without the per-file detail: up to 50 upload ids to classify and file. Send one of documents or upload_ids, not both. Every upload is checked against storage as the request comes in; one whose bytes never landed is rejected here rather than failing later inside the job.
documents DocumentInput[] One entry per file, up to 50, each saying where it belongs when you know. Placement, from most to least specific: data_request_id; entity_id + data_type (+ period_end); entity_id alone; nothing, which means we match against the whole deal.

Example request

curl -X POST "$BASE_URL/deals/clapp_01jgx5k2m3n4p5q6r7s8t9u0v1/documents" \
  -H "Authorization: Bearer $ALOAN_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
      "documents": [
        {
          "upload_id": "upl_01jgx5k2m3n4p5q6r7s8t9u0v1",
          "external_reference": "box:1234",
          "data_request_id": "cdr_01jgx5k2m3n4p5q6r7s8t9u0v1"
        },
        {
          "upload_id": "upl_01jgx5k2m3n4p5q6r7s8t9u0v2",
          "external_reference": "box:1235",
          "entity_id": "asubj_01jgx5k2m3n4p5q6r7s8t9u0v1",
          "data_type": "BUSINESS_TAX_RETURN",
          "period_end": "2024-12-31"
        },
        {
          "upload_id": "upl_01jgx5k2m3n4p5q6r7s8t9u0v3",
          "external_reference": "box:1236",
          "entity_id": "asubj_01jgx5k2m3n4p5q6r7s8t9u0v3"
        },
        {
          "upload_id": "upl_01jgx5k2m3n4p5q6r7s8t9u0v4",
          "external_reference": "box:1237"
        }
      ]
    }'

Response

202 Returns a Job object.

Example response
{
  "id": "job_01jgx5k2m3n4p5q6r7s8t9u0v2",
  "type": "document_upload",
  "status": "processing",
  "progress": {
    "total": 4,
    "settled": 0
  },
  "summary": null,
  "result": null,
  "error": null,
  "created_at": "2026-09-21T14:20:05Z",
  "updated_at": "2026-09-21T14:20:05Z",
  "completed_at": null
}

Errors: 400 invalid_request · 401 unauthorized · 403 ip_not_allowed, insufficient_scope · 404 not_found · 409 idempotency_key_reused, request_in_progress, conflict · 415 unsupported_media_type · 422 validation_failed, placement_conflict · 429 rate_limited · 500 server_error

List documents on a deal

GET /deals/{deal_id}/documents

Requires a read key.

Filed documents: what each file became once it was placed and read.

status is processing until we have read the document, then ready (or failed when extraction did not succeed). A file that could not be filed is not here; it is on GET /deals/{id}/files.

Parameters
Parameter Description
deal_id string · path · required Aloan's id, or your own as external:<id> where the object carries one.
updated_after timestamp · query Only records changed since (inclusive). With a newest-first order, a plain lower bound.
limit integer · query 1–200. Defaults to 50.
cursor string · query From next_cursor on the previous page. Send the same filters and order.
order ListOrder · query updated_at (default): oldest change first, for updated_after sweeps. -updated_at: newest change first, for polling what changed. -created_at: newest record first, for polling what's new. Ties break on id in the same direction.

Example request

curl "$BASE_URL/deals/clapp_01jgx5k2m3n4p5q6r7s8t9u0v1/documents" \
  -H "Authorization: Bearer $ALOAN_API_KEY"

Response

200 Returns a page of Document objects.

Response fields
Field Description
data Document[] · required
has_more boolean · required Whether another page follows.
next_cursor string | null · required Pass back as cursor for the next page.
Example response
{
  "data": [
    {
      "id": "cdoc_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "file_id": "cbfile_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "external_reference": "box:1235",
      "file_name": "2024-tax-return.pdf",
      "data_type": "BUSINESS_TAX_RETURN",
      "data_request_id": "cdr_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "entity_id": "asubj_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "period_start": "2024-01-01",
      "period_end": "2024-12-31",
      "status": "ready",
      "concerns": [
        {
          "code": "missing_schedule",
          "message": "Schedule K-1 for one partner is referenced but not included."
        }
      ],
      "url": "https://app.aloan.ai/deals/clapp_01jgx5k2m3n4p5q6r7s8t9u0v1/data?focus=cdoc_01jgx5k2m3n4p5q6r7s8t9u0v1&org=org_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "uploaded_at": "2026-09-21T14:20:05Z",
      "updated_at": "2026-09-21T14:23:48Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Errors: 400 invalid_request · 401 unauthorized · 403 ip_not_allowed · 404 not_found · 429 rate_limited · 500 server_error

List files on a deal

GET /deals/{deal_id}/files

Requires a read key.

Every file filed on the deal, through the API or in the app, with where it is in its lifecycle. Filter by external_reference to find yours.

Parameters
Parameter Description
deal_id string · path · required Aloan's id, or your own as external:<id> where the object carries one.
updated_after timestamp · query Only records changed since (inclusive). With a newest-first order, a plain lower bound.
limit integer · query 1–200. Defaults to 50.
cursor string · query From next_cursor on the previous page. Send the same filters and order.
order ListOrder · query updated_at (default): oldest change first, for updated_after sweeps. -updated_at: newest change first, for polling what changed. -created_at: newest record first, for polling what's new. Ties break on id in the same direction.
external_reference string · query Only the file carrying this id of yours.
status FileStatus · query One of queued, classifying, processing, filed, awaiting_review, duplicate, failed, dismissed.
job_id string · query Only the files one filing job created.

Example request

curl "$BASE_URL/deals/clapp_01jgx5k2m3n4p5q6r7s8t9u0v1/files?status=awaiting_review" \
  -H "Authorization: Bearer $ALOAN_API_KEY"

Response

200 Returns a page of File objects.

Response fields
Field Description
data File[] · required
has_more boolean · required Whether another page follows.
next_cursor string | null · required Pass back as cursor for the next page.
Example response
{
  "data": [
    {
      "id": "cbfile_01jgx5k2m3n4p5q6r7s8t9u0v4",
      "deal_id": "clapp_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "upload_id": "upl_01jgx5k2m3n4p5q6r7s8t9u0v4",
      "external_reference": "box:1237",
      "file_name": "statements-q3.pdf",
      "file_type": "application/pdf",
      "file_size": 812331,
      "status": "awaiting_review",
      "placement": null,
      "review": {
        "kind": "question",
        "id": "cdq_01jgx5k2m3n4p5q6r7s8t9u0v1",
        "prompt": "Is \"BV Holdings\" the same company as Brookvale Holdings LLC?",
        "url": "https://app.aloan.ai/deals/clapp_01jgx5k2m3n4p5q6r7s8t9u0v1/data?unmatched=1&focus=cdq_01jgx5k2m3n4p5q6r7s8t9u0v1&org=org_01jgx5k2m3n4p5q6r7s8t9u0v1"
      },
      "document_id": null,
      "duplicate_of": null,
      "error": null,
      "concerns": [],
      "period_start": null,
      "period_end": null,
      "url": "https://app.aloan.ai/deals/clapp_01jgx5k2m3n4p5q6r7s8t9u0v1/data?focus=cbfile_01jgx5k2m3n4p5q6r7s8t9u0v4&org=org_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "created_at": "2026-09-21T14:20:05Z",
      "updated_at": "2026-09-21T14:21:40Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Errors: 400 invalid_request · 401 unauthorized · 403 ip_not_allowed · 404 not_found · 429 rate_limited · 500 server_error

Retrieve a file

GET /files/{file_id}

Requires a read key.

Parameters
Parameter Description
file_id string · path · required Aloan's id.

Example request

curl "$BASE_URL/files/cbfile_01jgx5k2m3n4p5q6r7s8t9u0v1" \
  -H "Authorization: Bearer $ALOAN_API_KEY"

Response

200 Returns a File object.

Example response
{
  "id": "cbfile_01jgx5k2m3n4p5q6r7s8t9u0v1",
  "deal_id": "clapp_01jgx5k2m3n4p5q6r7s8t9u0v1",
  "upload_id": "upl_01jgx5k2m3n4p5q6r7s8t9u0v2",
  "external_reference": "box:1235",
  "file_name": "brookvale-2024-1120s.pdf",
  "file_type": "application/pdf",
  "file_size": 4718592,
  "status": "filed",
  "placement": {
    "data_request_id": "cdr_01jgx5k2m3n4p5q6r7s8t9u0v2",
    "entity_id": "asubj_01jgx5k2m3n4p5q6r7s8t9u0v1",
    "data_type": "BUSINESS_TAX_RETURN",
    "period_end": "2024-12-31",
    "source": "caller"
  },
  "review": null,
  "document_id": "cdoc_01jgx5k2m3n4p5q6r7s8t9u0v1",
  "duplicate_of": null,
  "error": null,
  "concerns": [],
  "period_start": "2024-01-01",
  "period_end": "2024-12-31",
  "url": "https://app.aloan.ai/deals/clapp_01jgx5k2m3n4p5q6r7s8t9u0v1/data?focus=cbfile_01jgx5k2m3n4p5q6r7s8t9u0v1&org=org_01jgx5k2m3n4p5q6r7s8t9u0v1",
  "created_at": "2026-09-21T14:20:05Z",
  "updated_at": "2026-09-21T14:21:40Z"
}

Errors: 401 unauthorized · 403 ip_not_allowed · 404 not_found · 429 rate_limited · 500 server_error

List the deal's open questions

GET /deals/{deal_id}/questions

Requires a read key.

What a person in Aloan needs to decide about a file. Read-only in v1: each url opens the question in the app, which is where it is answered. Once answered, the file it covered moves on (filed, dismissed or failed).

Parameters
Parameter Description
deal_id string · path · required Aloan's id, or your own as external:<id> where the object carries one.
updated_after timestamp · query Only records changed since (inclusive). With a newest-first order, a plain lower bound.
limit integer · query 1–200. Defaults to 50.
cursor string · query From next_cursor on the previous page. Send the same filters and order.
order ListOrder · query updated_at (default): oldest change first, for updated_after sweeps. -updated_at: newest change first, for polling what changed. -created_at: newest record first, for polling what's new. Ties break on id in the same direction.
status QuestionStatus · query OPEN is the one worth polling. One of OPEN, ANSWERED, DEFERRED.

Example request

curl "$BASE_URL/deals/clapp_01jgx5k2m3n4p5q6r7s8t9u0v1/questions?status=OPEN" \
  -H "Authorization: Bearer $ALOAN_API_KEY"

Response

200 Returns a page of Question objects.

Response fields
Field Description
data Question[] · required
has_more boolean · required Whether another page follows.
next_cursor string | null · required Pass back as cursor for the next page.
Example response
{
  "data": [
    {
      "id": "cdq_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "kind": "IDENTITY_LINK",
      "status": "OPEN",
      "prompt": "Is \"BV Holdings\" the same company as Brookvale Holdings LLC?",
      "why": "A bank statement names an account holder we cannot place on the deal.",
      "file_id": "cbfile_01jgx5k2m3n4p5q6r7s8t9u0v4",
      "document_id": null,
      "suggestions": [
        {
          "id": "0",
          "label": "Yes, the same company."
        },
        {
          "id": "1",
          "label": "No, dismiss this document."
        }
      ],
      "url": "https://app.aloan.ai/deals/clapp_01jgx5k2m3n4p5q6r7s8t9u0v1/data?unmatched=1&focus=cdq_01jgx5k2m3n4p5q6r7s8t9u0v1&org=org_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "created_at": "2026-09-21T14:22:10Z",
      "answered_at": null,
      "updated_at": "2026-09-21T14:22:10Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Errors: 400 invalid_request · 401 unauthorized · 403 ip_not_allowed · 404 not_found · 429 rate_limited · 500 server_error

List outstanding requirements

GET /deals/{deal_id}/data-requests

Requires a read key.

What the deal still needs. The list to drive a borrower chase from.

Parameters
Parameter Description
deal_id string · path · required Aloan's id, or your own as external:<id> where the object carries one.
updated_after timestamp · query Only records changed since (inclusive). With a newest-first order, a plain lower bound.
limit integer · query 1–200. Defaults to 50.
cursor string · query From next_cursor on the previous page. Send the same filters and order.
order ListOrder · query updated_at (default): oldest change first, for updated_after sweeps. -updated_at: newest change first, for polling what changed. -created_at: newest record first, for polling what's new. Ties break on id in the same direction.
status DataRequestStatus · query One of PENDING, IN_PROGRESS, REVIEWING, ACCEPTED, COMPLETED, EXCEPTION, REJECTED, CANCELLED.
entity_id string · query Only the requests on this party.

Example request

curl "$BASE_URL/deals/clapp_01jgx5k2m3n4p5q6r7s8t9u0v1/data-requests" \
  -H "Authorization: Bearer $ALOAN_API_KEY"

Response

200 Returns a page of DataRequest objects.

Response fields
Field Description
data DataRequest[] · required
has_more boolean · required Whether another page follows.
next_cursor string | null · required Pass back as cursor for the next page.
Example response
{
  "data": [
    {
      "id": "cdr_01jgx5k2m3n4p5q6r7s8t9u0v2",
      "label": "2025 business tax return",
      "data_type": "BUSINESS_TAX_RETURN",
      "entity_id": "asubj_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "status": "PENDING",
      "required": true,
      "due_at": "2026-10-15T00:00:00Z",
      "updated_at": "2026-09-21T14:06:40Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Errors: 400 invalid_request · 401 unauthorized · 403 ip_not_allowed · 404 not_found · 429 rate_limited · 500 server_error

Endpoints

Analysis and memo

Read the work product back out.

List published analyses

GET /deals/{deal_id}/analyses

Requires a read key.

Published analyses only: the figures an analyst has committed to. Work in progress is deliberately not exposed: it changes under you.

The list omits table: it can be large. Fetch a single analysis to get it.

Parameters
Parameter Description
deal_id string · path · required Aloan's id, or your own as external:<id> where the object carries one.
updated_after timestamp · query Only records changed since (inclusive). With a newest-first order, a plain lower bound.
limit integer · query 1–200. Defaults to 50.
cursor string · query From next_cursor on the previous page. Send the same filters and order.
order ListOrder · query updated_at (default): oldest change first, for updated_after sweeps. -updated_at: newest change first, for polling what changed. -created_at: newest record first, for polling what's new. Ties break on id in the same direction.
type AnalysisType · query One of the AnalysisType values.
entity_id string · query Only analyses for this party.

Example request

curl "$BASE_URL/deals/clapp_01jgx5k2m3n4p5q6r7s8t9u0v1/analyses" \
  -H "Authorization: Bearer $ALOAN_API_KEY"

Response

200 Returns a page of Analysis objects.

Response fields
Field Description
data Analysis[] · required
has_more boolean · required Whether another page follows.
next_cursor string | null · required Pass back as cursor for the next page.
Example response
{
  "data": [
    {
      "id": "canalysis_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "type": "dscr_analysis",
      "title": "Brookvale Holdings: DSCR",
      "description": "",
      "entity_id": "asubj_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "format": "grid",
      "figures": {
        "dscr": {
          "value": "1.42",
          "unit": "ratio",
          "label": "DSCR",
          "as_of": "2024-12-31",
          "period_start": "2024-01-01",
          "period_end": "2024-12-31",
          "scenario": null,
          "basis": "business"
        }
      },
      "is_stale": false,
      "url": "https://app.aloan.ai/deals/clapp_01jgx5k2m3n4p5q6r7s8t9u0v1/analysis?node=canalysis_01jgx5k2m3n4p5q6r7s8t9u0v1&org=org_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "published_at": "2026-09-21T15:41:12Z",
      "updated_at": "2026-09-21T15:41:12Z"
    },
    {
      "id": "canalysis_01jgx5k2m3n4p5q6r7s8t9u0v2",
      "type": "combined_balance_sheet",
      "title": "Brookvale Holdings: Balance Sheet",
      "description": "Excludes closely-held business interests",
      "entity_id": "asubj_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "format": "grid",
      "figures": {
        "net_worth": {
          "value": "7170600.00",
          "unit": "currency",
          "label": "Net Worth",
          "as_of": "2024-12-31",
          "period_start": null,
          "period_end": "2024-12-31",
          "scenario": null,
          "basis": null
        },
        "total_assets": {
          "value": "19480200.00",
          "unit": "currency",
          "label": "Total Assets",
          "as_of": "2024-12-31",
          "period_start": null,
          "period_end": "2024-12-31",
          "scenario": null,
          "basis": null
        },
        "total_liabilities": {
          "value": "12309600.00",
          "unit": "currency",
          "label": "Total Liabilities",
          "as_of": "2024-12-31",
          "period_start": null,
          "period_end": "2024-12-31",
          "scenario": null,
          "basis": null
        }
      },
      "is_stale": false,
      "url": "https://app.aloan.ai/deals/clapp_01jgx5k2m3n4p5q6r7s8t9u0v1/analysis?node=canalysis_01jgx5k2m3n4p5q6r7s8t9u0v2&org=org_01jgx5k2m3n4p5q6r7s8t9u0v1",
      "published_at": "2026-09-21T15:44:02Z",
      "updated_at": "2026-09-21T15:44:02Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Errors: 400 invalid_request · 401 unauthorized · 403 ip_not_allowed · 404 not_found · 429 rate_limited · 500 server_error

Retrieve one analysis

GET /deals/{deal_id}/analyses/{analysis_id}

Requires a read key.

The same object with table included. Every tabular analysis returns the same grid whatever its type, so one parser reads all of them: columns are the periods (or, for a table whose columns are not periods, a debt schedule, a collateral schedule, its own headings), rows are the lines, and a row's values are keyed by column. Ask for format=xlsx to get the same table as the spreadsheet the app's own Export button writes.

A row's kind is line, subtotal, total, ratio or section (a heading with no values), and depth is its indent under the line above. A column's kind is value, or percent for the common-size column beside a period. Values are decimal strings, or null where the period has no figure: a ratio row is a multiple to four decimals (1.42 is 1.42x), a percent column is already scaled (12.5 is 12.5%), everything else is currency to the cent.

Parameters
Parameter Description
deal_id string · path · required Aloan's id, or your own as external:<id> where the object carries one.
analysis_id string · path · required Aloan's id.
format AnalysisDownloadFormat · query json (default) or xlsx: the same sheet the app's Export button writes.

Example request

curl "$BASE_URL/deals/clapp_01jgx5k2m3n4p5q6r7s8t9u0v1/analyses/canalysis_01jgx5k2m3n4p5q6r7s8t9u0v1" \
  -H "Authorization: Bearer $ALOAN_API_KEY"

Response

200 Returns an Analysis object. Also available as application/vnd.openxmlformats-officedocument.spreadsheetml.sheet with the format parameter.

Example response
{
  "id": "canalysis_01jgx5k2m3n4p5q6r7s8t9u0v1",
  "type": "dscr_analysis",
  "title": "Brookvale Holdings: DSCR",
  "description": "",
  "entity_id": "asubj_01jgx5k2m3n4p5q6r7s8t9u0v1",
  "format": "grid",
  "figures": {
    "dscr": {
      "value": "1.42",
      "unit": "ratio",
      "label": "DSCR",
      "as_of": "2024-12-31",
      "period_start": "2024-01-01",
      "period_end": "2024-12-31",
      "scenario": null,
      "basis": "business"
    }
  },
  "is_stale": false,
  "url": "https://app.aloan.ai/deals/clapp_01jgx5k2m3n4p5q6r7s8t9u0v1/analysis?node=canalysis_01jgx5k2m3n4p5q6r7s8t9u0v1&org=org_01jgx5k2m3n4p5q6r7s8t9u0v1",
  "published_at": "2026-09-21T15:41:12Z",
  "updated_at": "2026-09-21T15:41:12Z",
  "table": {
    "columns": [
      {
        "key": "fy2023",
        "label": "FY2023",
        "period_start": "2023-01-01",
        "period_end": "2023-12-31",
        "kind": "value",
        "scenario": null,
        "basis": "actual",
        "source": null
      },
      {
        "key": "fy2024",
        "label": "FY2024",
        "period_start": "2024-01-01",
        "period_end": "2024-12-31",
        "kind": "value",
        "scenario": null,
        "basis": "actual",
        "source": null
      }
    ],
    "rows": [
      {
        "key": "available_cash_flow",
        "label": "Available Cash Flow",
        "depth": 0,
        "kind": "subtotal",
        "unit": "currency",
        "values": {
          "fy2023": "1043900.00",
          "fy2024": "1184320.00"
        }
      },
      {
        "key": "total_debt_service",
        "label": "Total Debt Service",
        "depth": 0,
        "kind": "subtotal",
        "unit": "currency",
        "values": {
          "fy2023": "796100.00",
          "fy2024": "834000.00"
        }
      },
      {
        "key": "dscr",
        "label": "DSCR",
        "depth": 0,
        "kind": "ratio",
        "unit": "ratio",
        "values": {
          "fy2023": "1.31",
          "fy2024": "1.42"
        }
      }
    ]
  }
}

Errors: 400 invalid_request · 401 unauthorized · 403 ip_not_allowed · 404 not_found · 429 rate_limited · 500 server_error

Retrieve the credit memo

GET /deals/{deal_id}/credit-memo

Requires a read key.

The latest submitted revision of the memo, as a document or as the Word file the approvers read. Every submission for approval cuts a revision; status is the memo's live status, so while changes are requested (CHANGES_REQUESTED) this is still the last revision submitted, never the analyst's working copy. A memo never submitted returns 409 conflict (reason: memo_not_submitted). The JSON form carries revision, latest_revision, submitted_at, approved_at, its dates (prepared, submitted, decided) and document.nodes: the same headings, paragraphs and tables the Word file is built from, in order.

Parameters
Parameter Description
deal_id string · path · required Aloan's id, or your own as external:<id> where the object carries one.
format MemoDownloadFormat · query json (default) or docx.
revision integer · query An earlier revision. Defaults to the latest. At least 1.

Example request

curl "$BASE_URL/deals/clapp_01jgx5k2m3n4p5q6r7s8t9u0v1/credit-memo" \
  -H "Authorization: Bearer $ALOAN_API_KEY"

Response

200 Returns a CreditMemo object. Also available as application/vnd.openxmlformats-officedocument.wordprocessingml.document with the format parameter.

Example response
{
  "deal_id": "clapp_01jgx5k2m3n4p5q6r7s8t9u0v1",
  "revision": 2,
  "latest_revision": 2,
  "status": "APPROVED",
  "submitted_at": "2026-09-28T16:40:11Z",
  "approved_at": "2026-09-30T13:05:52Z",
  "dates": [
    {
      "label": "Prepared",
      "date": "2026-09-26"
    },
    {
      "label": "Submitted",
      "date": "2026-09-28"
    },
    {
      "label": "Approved",
      "date": "2026-09-30"
    }
  ],
  "document": {
    "title": "Credit Memorandum: Brookvale Holdings LLC",
    "subtitle_lines": [
      "Equipment Line · $2,000,000",
      "Working Capital Revolver · $500,000"
    ],
    "logo": null,
    "nodes": [
      {
        "type": "heading",
        "level": 1,
        "text": "Executive Summary"
      },
      {
        "type": "paragraph",
        "text": "Brookvale Holdings LLC requests a $2,000,000 equipment line..."
      }
    ]
  }
}

Errors: 400 invalid_request · 401 unauthorized · 403 ip_not_allowed · 404 not_found · 409 conflict · 429 rate_limited · 500 server_error

Endpoints

Jobs

One endpoint for the progress of anything asynchronous.

Retrieve a job

GET /jobs/{job_id}

Requires a read key.

A deal_intake job at awaiting_confirmation carries result.parties ({parsed_ref, parsed_name, role, entity_type, legal_form, proposed_entity_id, confidence}) and result.terms as read from the document; once confirmed, result.deal_id. A document_upload job is processing with progress until every file has settled, then completed with summary counts and result.files[]: a record of how each file stood at that moment (outcome is filed, needs_review, duplicate or failed). The job is frozen then; a file that needed review and was filed an hour later says so on GET /files/{id}, not on the job.

Parameters
Parameter Description
job_id string · path · required Aloan's id.

Example request

curl "$BASE_URL/jobs/job_01jgx5k2m3n4p5q6r7s8t9u0v2" \
  -H "Authorization: Bearer $ALOAN_API_KEY"

Response

200 Returns a Job object.

Example response
{
  "id": "job_01jgx5k2m3n4p5q6r7s8t9u0v2",
  "type": "document_upload",
  "status": "completed",
  "progress": {
    "total": 2,
    "settled": 2
  },
  "summary": {
    "filed": 1,
    "needs_review": 1,
    "duplicate": 0,
    "failed": 0
  },
  "result": {
    "deal_id": "clapp_01jgx5k2m3n4p5q6r7s8t9u0v1",
    "files": [
      {
        "file_id": "cbfile_01jgx5k2m3n4p5q6r7s8t9u0v1",
        "upload_id": "upl_01jgx5k2m3n4p5q6r7s8t9u0v1",
        "external_reference": "box:1234",
        "file_name": "2024-tax-return.pdf",
        "outcome": "filed",
        "document_id": "cdoc_01jgx5k2m3n4p5q6r7s8t9u0v1",
        "data_request_id": "cdr_01jgx5k2m3n4p5q6r7s8t9u0v1",
        "error": null
      },
      {
        "file_id": "cbfile_01jgx5k2m3n4p5q6r7s8t9u0v4",
        "upload_id": "upl_01jgx5k2m3n4p5q6r7s8t9u0v4",
        "external_reference": "box:1237",
        "file_name": "rent-roll.xlsx",
        "outcome": "needs_review",
        "document_id": null,
        "data_request_id": null,
        "error": null
      }
    ]
  },
  "error": null,
  "created_at": "2026-09-21T14:20:05Z",
  "updated_at": "2026-09-21T14:23:48Z",
  "completed_at": "2026-09-21T14:23:48Z"
}

Errors: 401 unauthorized · 403 ip_not_allowed · 404 not_found · 429 rate_limited · 500 server_error

Reference

Objects

What the API returns. Each operation above links to the object it returns.

Relationship

Id prefix crel_

The borrowing relationship: the durable home for a borrower and everyone around them. The analogue of a CIF or a Salesforce account, and the parent of every deal you create.

Relationship fields
Field Description
id string · required Aloan's id, prefixed crel_.
external_id string | null · required Your id for this relationship. Unique within your organization.
display_name string · required What the relationship is called.
status RelationshipStatus · required One of ACTIVE, EXITED, PROSPECT.
relationship_manager string | null · required Email of the owning RM.
fiscal_year_end_month integer | null · required 1–12. Defaults to 12.
url string · required The relationship in the Aloan app, for a person to open.
created_at timestamp · required RFC 3339, UTC.
updated_at timestamp · required RFC 3339, UTC. Sort key for updated_after.

Entity

Id prefix asubj_

A party on the relationship: an operating company, a holdco, a guarantor, a trust. Entities are durable: a second deal for the same borrower reuses the entity and everything already analysed for it. Read-only in v1; entities are created by the deal flows.

Entity fields
Field Description
id string · required Aloan's id, prefixed asubj_. The same party on two relationships is one entity.
name string · required Legal name.
entity_type EntityType · required One of BUSINESS, PERSON, OTHER.
legal_form LegalForm | null · required For a business: its legal form. Null for a person, or when we do not know. One of SOLE_PROPRIETORSHIP, PARTNERSHIP, LLC, CORPORATION, NON_PROFIT, TRUST, OTHER.
tax_identifier_last4 string | null · required Last four of the EIN or SSN, when we hold one.
is_primary boolean · required Whether this is the relationship's primary party.

Loan

Id prefix cloan_

A booked credit agreement on the relationship and the notes it covers. A renewal, review or modification acts on notes; pass them as note_ids on POST /deals. Read-only in v1; agreements are booked when a deal funds.

Loan fields
Field Description
id string · required Aloan's id, prefixed cloan_.
external_loan_id string | null · required The bank's loan number, as the bank writes it.
status LoanStatus · required One of ACTIVE, PAID_OFF, MATURED, DEFAULTED.
origination_date date | null · required
commitment_amount decimal string | null · required Sum of the agreement's notes. Decimal string.
note_ids string[] · required The notes (booked facilities) this agreement covers: what note_ids on POST /deals takes.
originating_deal_id string | null · required The deal that booked it, when it was booked here.
created_at timestamp · required
updated_at timestamp · required RFC 3339, UTC. Sort key for updated_after.

Upload

Id prefix upl_

A file on its way in. You declare it, put the bytes straight into our storage with the URL we hand back, then reference the upload wherever a file is wanted: a term sheet on a deal, documents on a deal. Bytes never pass through the API.

Upload fields
Field Description
id string · required Aloan's id, prefixed upl_. This is what you reference once the bytes are up.
upload_url string | null · required Pre-authorized URL to PUT the bytes to. Valid until expires_at.
expires_at timestamp · required The URL stops working here. Miss it and ask for another with POST /uploads/{id}/url; the upload id stays valid.
status UploadStatus · required awaiting_bytes until we check storage and find your file, then ready; expired after 24 hours unreferenced.

Deal

Id prefix clapp_

One credit request against a relationship: an origination, a renewal, a review or a modification. Everything the platform produces (documents, data requests, analyses, the memo) hangs off a deal.

Deal fields
Field Description
id string · required Aloan's id, prefixed clapp_.
external_id string | null · required Your id for this deal. Unique within your organization. Set once: a deal that already carries one of your ids keeps it until you clear it with null.
relationship_id string | null · required The parent relationship.
title string · required Deal label. Falls back to the primary borrower's name.
status DealStatus · required One of IN_PROGRESS, PENDING_APPROVAL, APPROVED, FUNDED, DECLINED, WITHDRAWN, COMPLETED.
stage DealStage · required One of PRE_QUALIFICATION, UNDERWRITING.
event_type EventType · required One of ORIGINATION, RENEWAL, REVIEW, MODIFICATION, COVENANT_TEST.
loan_type string | null · required Your organization's loan type, a key from GET /loan-types. Drives the checklist.
subject_note_ids string[] · required For a renewal, review or modification: the notes (booked facilities) it acts on. Empty for an origination.
assigned_to string | null · required Email of the deal's owner: the underwriter once the deal is at UNDERWRITING, the relationship manager while it is at PRE_QUALIFICATION. Null until someone is assigned.
relationship_manager string | null · required Email of the RM on the deal. Defaults from the relationship.
facilities Facility[] · required What is being asked for, facility by facility. This is the deal's terms.
total_commitment decimal string · required Sum of the facilities' commitment amounts. Decimal string.
currency string · required ISO 4217, e.g. USD.
entities Party[] · required Every party on this deal. A party the app has not yet bound to an entity has id: null and a warning; it is listed, never omitted.
data_requests_outstanding integer · required Checklist items still open. The list itself is GET /deals/{id}/data-requests.
documents integer · required Documents filed on the deal. The list itself is GET /deals/{id}/documents.
analyses integer · required Published analyses. The list itself is GET /deals/{id}/analyses.
url string · required The deal in the Aloan app, for a person to open.
created_at timestamp · required RFC 3339, UTC.
updated_at timestamp · required RFC 3339, UTC. Moves when the deal's parties, terms, checklist, documents or memo change, not only its own fields. Sort key for updated_after.

Facility

Id prefix cfac_

One line of credit being asked for: a term loan, a revolver, a CRE mortgage. A deal usually has more than one, and the facilities are the deal's terms: amount, rate, term, repayment and collateral all live here, not on the deal.

Facility fields
Field Description
id string · required Aloan's id, prefixed cfac_.
title string · required Facility name, e.g. Term Loan A.
facility_type FacilityType | null · required One of the FacilityType values.
commitment_amount decimal string | null · required The amount committed. Decimal string.
entity_id string | null · required The borrowing party. Null means the facility applies to every borrower on the deal.
purpose string | null · required What the money is for.
term_months integer | null · required Months to maturity.
amortization_months integer | null · required Amortization period. Longer than term_months means a balloon.
interest_only_months integer | null · required Interest-only months before amortization starts.
rate_type RateType | null · required One of FIXED, VARIABLE, FIXED_TO_FLOAT.
interest_rate decimal string | null · required All-in annual rate as a decimal fraction: "0.0725" is 7.25%.
index_name RateIndex | null · required For variable rates. One of PRIME, SOFR, TREASURY_5Y, TREASURY_10Y, FED_FUNDS, OTHER.
spread_over_index decimal string | null · required Margin over the index, decimal fraction: "0.026" is 2.60%.
rate_floor decimal string | null · required Minimum rate, decimal fraction.
rate_ceiling decimal string | null · required Maximum rate, decimal fraction.
repayment_type RepaymentType | null · required One of MONTHLY_PI, MONTHLY_IO, QUARTERLY_PI, INTEREST_ONLY, REVOLVING_LINE, SCHEDULED_PAYMENT.
payment_amount decimal string | null · required For SCHEDULED_PAYMENT, where the payment is quoted rather than priced from a rate.
interest_day_count InterestDayCount | null · required Defaults to your organization's setting. One of ACTUAL_365, ACTUAL_360.
origination_fee decimal string | null · required Decimal fraction: "0.01" is 1%.
prepayment_penalty string | null · required Free text, e.g. 3-2-1-0-0.
collateral string | null · required What secures it, as stated on the term sheet.

Job

Id prefix job_

A unit of work that outlives its request: parsing a term sheet, processing an upload. Every asynchronous operation returns one, and you poll it until it reaches a terminal state.

Job fields
Field Description
id string · required Aloan's id, prefixed job_.
type JobType · required One of document_upload, deal_intake.
status JobStatus · required One of processing, awaiting_confirmation, completed, failed, cancelled.
progress JobProgress | null · required For a document upload while processing.
summary JobSummary | null · required For a completed document upload.
result DocumentUploadResult | IntakeResult | null · required Populated on a terminal success, or at awaiting_confirmation. Shape depends on type.
error JobError | null · required Populated on failure.
created_at timestamp · required
updated_at timestamp · required Moves when the work behind the job does.
completed_at timestamp | null · required

File

Id prefix cbfile_

A file you filed on a deal, from the moment we accept it. It has an id before anything has read it, so you can follow it: queued → classifying → processing → filed, or awaiting_review when a person in Aloan has to decide (review says what, with a link), duplicate when the same bytes were already on its destination (duplicate_of names the original; it is not processed again), failed when it could not be filed (error says at which stage), dismissed when a reviewer set it aside. Read it with GET /files/{id}, or find yours by external_reference on GET /deals/{id}/files.

File fields
Field Description
id string · required Aloan's id for the file, prefixed cbfile_, from the moment we accept it.
deal_id string · required The deal it was filed on.
upload_id string | null · required The upload it came from. Null for a file uploaded in the app.
external_reference string | null · required Your id for the file, echoed back.
file_name string · required
file_type string · required MIME type, as declared.
file_size integer · required Bytes.
status FileStatus · required Where the file is in its lifecycle. One of queued, classifying, processing, filed, awaiting_review, duplicate, failed, dismissed.
placement Placement | null · required Where it is filed, or going, and who decided.
review Review | null · required What a person in the app needs to do, while awaiting_review.
document_id string | null · required The filed document, once there is one.
duplicate_of DuplicateOf | null · required For a duplicate, the file it duplicates.
error FileError | null · required For a failed file, why.
concerns Concern[] · required Disagreements between your placement and the document, and findings about the document. Never silenced by a placement.
period_start date | null · required Once read.
period_end date | null · required Once read.
url string · required The file in the Aloan app's Data tab, for a person to open.
created_at timestamp · required
updated_at timestamp · required RFC 3339, UTC. Sort key for updated_after.

Document

Id prefix cdoc_

A file on a deal, filed against its checklist and the party it belongs to. Created by uploading; read back from the deal's document list.

Document fields
Field Description
id string · required Aloan's id, prefixed cdoc_.
file_id string | null · required The file it came from, when it was filed as one.
external_reference string | null · required Your id for the file, as you sent it when filing.
file_name string · required As uploaded.
data_type string | null · required What the document is, e.g. BUSINESS_TAX_RETURN.
data_request_id string | null · required The checklist item it satisfies.
entity_id string | null · required The party it belongs to.
period_start date | null · required Once read.
period_end date | null · required The period the document covers, once read.
status DocumentStatus · required processing while we extract its contents, then ready, or failed when the extraction did not succeed.
concerns Concern[] · required
url string · required Where to open it in the Aloan app.
uploaded_at timestamp | null · required
updated_at timestamp · required RFC 3339, UTC. Sort key for updated_after.

Question

Id prefix cdq_

Something a person in Aloan has to decide about a file: is "BV Holdings" the same company as Brookvale Holdings LLC? Read-only in v1, url opens it in the app, where it is answered in one click. The file it is about is file_id.

Question fields
Field Description
id string · required Aloan's id, prefixed cdq_.
kind QuestionKind · required One of IDENTITY_LINK, NEW_ENTITY, WRONG_DEAL, DOC_CONVENTION.
status QuestionStatus · required One of OPEN, ANSWERED, DEFERRED.
prompt string · required The question, as your team sees it.
why string | null · required One line of context.
file_id string | null · required The file it is about.
document_id string | null · required The document, once the file is filed.
suggestions Suggestion[] · required The answers the app offers.
url string · required Opens the question in the Aloan app.
created_at timestamp · required
answered_at timestamp | null · required
updated_at timestamp · required RFC 3339, UTC. Sort key for updated_after.

DataRequest

Id prefix cdr_

One outstanding item on a deal's checklist: a tax return, a rent roll, a debt schedule. The list of what is still needed from the borrower.

DataRequest fields
Field Description
id string · required Aloan's id, prefixed cdr_.
label string · required Human-readable description of what is being asked for.
data_type string | null · required Machine-readable type, e.g. BUSINESS_TAX_RETURN.
entity_id string | null · required The party this is being asked of.
status DataRequestStatus · required One of PENDING, IN_PROGRESS, REVIEWING, ACCEPTED, COMPLETED, EXCEPTION, REJECTED, CANCELLED.
required boolean · required Whether the deal can proceed without it.
due_at timestamp | null · required
updated_at timestamp · required RFC 3339, UTC. Sort key for updated_after.

Analysis

Id prefix canalysis_

A published piece of analysis: a spread, a DSCR worksheet, a global cash flow. Only published analyses are exposed: they are what an analyst has committed to, and the only ones stable enough to store in another system.

Analysis fields
Field Description
id string · required Aloan's id, prefixed canalysis_.
type AnalysisType · required One of the AnalysisType values.
title string · required What the analyst called it.
description string · required The analyst's note on which view this is.
entity_id string | null · required The party analysed. Null for deal-wide analyses.
format AnalysisFormat · required Branch on this before reading table. One of grid, chart, markdown.
figures map · required Named scalars published beside the table, by key.
is_stale boolean · required True when source data changed after this was published.
url string · required The analysis in the Aloan app, for a person to open.
published_at timestamp | null · required
updated_at timestamp · required RFC 3339, UTC. Sort key for updated_after.
table Grid | null The analysis as a grid. Present when format is grid and you fetched the single analysis.
content string The written content, when format is markdown and you fetched the single analysis.

CreditMemo

The credit memo as submitted for approval. Every submission cuts a revision; the API serves revisions, never the analyst's working copy.

CreditMemo fields
Field Description
deal_id string · required
revision integer · required The revision this is: 1 for the first submission.
latest_revision integer · required The memo's current revision number.
status CreditMemoStatus · required The memo's live status. One of DRAFT, SUBMITTED, CHANGES_REQUESTED, APPROVED, DECLINED.
submitted_at timestamp · required
approved_at timestamp | null · required When this revision was decided, if it was.
dates MemoDate[] · required The dates printed under the memo's title, in order.
document MemoDocument | null · required

Supporting objects

Concern

A disagreement between a placement and the document, or a finding from reading it.

Concern fields
Field Description
code string · required period_mismatch, type_mismatch, or a document finding's code.
message string · required
observed string What the document showed (placement concerns).
declared string What was declared (placement concerns).

DataTypeOption

DataTypeOption fields
Field Description
key DataType · required What data_type takes. One of the DataType values.
label string · required

DocumentInput

One file to file, and where the caller says it belongs (plan D20–D21).

DocumentInput fields
Field Description
upload_id string · required An upload whose bytes you have sent.
external_reference string | null Your own id for the file (a Box id), echoed back on the file, the document and the job. Up to 255 characters.
data_request_id string | null File it on this checklist item; matching is skipped. The request must be on the deal and open.
entity_id string | null The party it belongs to. Alone, we choose among the entity's open requests, creating one of the type we read when none fits.
data_type enum | null With entity_id: files it on the entity's open request of this type (and period_end). With none, an optional request is created; with several, we choose among them only. One of FINANCIAL_STATEMENTS, AR_AGING, AP_AGING, INVENTORY_AGING, BUSINESS_TAX_RETURN, BUSINESS_TAX_RETURN_SCHEDULE_K, PERSONAL_TAX_RETURN, TRUST_TAX_RETURN, TAX_COMPLIANCE_HISTORY, TAX_LIABILITIES_SCHEDULE, TAX_TRANSCRIPT, PERSONAL_FINANCIAL_STATEMENT, PERSONAL_CREDIT_REPORT, PAY_STUB, RESUME, KYC, FORMATION_DOCUMENTS, FICTITIOUS_NAME_STATEMENT, BUSINESS_LICENSE, CAP_TABLE, EIN_LETTER, CORPORATE_RESOLUTION, W_9, REGULATORY_DISCLOSURES, INSURANCE_CLAIMS, SETTLEMENT_DOCUMENTS, PURCHASE_AGREEMENT, APPRAISAL, INVOICE, CONSTRUCTION_CONTRACT, CONSTRUCTION_BUDGET, PLANS_AND_SPECS, PERMITS, RENT_ROLL, LEASE, ENVIRONMENTAL_REPORT, FLOOD_CERTIFICATE, BANK_STATEMENTS, INVESTMENT_STATEMENT, BUSINESS_CREDIT_REPORT, REAL_ESTATE_OWNED, DEBT_SCHEDULE, RELATED_PARTY_TRANSACTIONS, OFF_BALANCE_SHEET_DISCLOSURE, SUPPLIER_CONTRACTS, DISTRIBUTOR_AGREEMENTS, PRICING_AGREEMENTS, MATERIAL_CONTRACTS, RISK_DISCLOSURE, GIFT_TAX_RETURN, CERTIFICATE_OF_GOOD_STANDING, TRUST_DOCUMENT, PROPERTY_RECORDS, PROPERTY_IMPROVEMENT_PLAN, SURVEY, TITLE_WORK, GROUND_LEASE, SNDA, TENANT_ESTOPPELS, MASTER_DEED, DEED_RESTRICTIONS, MARKET_STUDY, INSURANCE_CERTIFICATE, SWORN_STATEMENT, TITLE_CERTIFICATE_OF_ORIGIN, VEHICLE_TITLE, FIELD_AUDIT, SITE_INSPECTION, STAR_REPORT, ASSET_LIST, INVENTORY_LIST, PAYOFF_STATEMENT, TERM_SHEET, DEAL_BACKGROUND, OFFERING_MEMORANDUM, LOAN_APPLICATION, SBA_AUTHORIZATION, SBA_GUARANTY, SBA_FORM, SBA_CITIZENSHIP_CERTIFICATION, IRS_FORM_4506C, GOVERNMENT_ID, FRANCHISE_AGREEMENT, EQUITY_INJECTION_VERIFICATION, BENEFICIAL_OWNERSHIP, UCC_SEARCH, UCC_FILING, OFAC_REPORT, CAIVRS_CHECK, SAM_SEARCH, BACKGROUND_SEARCH, LITIGATION_SEARCH, BUSINESS_PLAN, CUSTOM.
period_end date | null With entity_id and data_type: the period the file covers.

DocumentUploadResult

DocumentUploadResult fields
Field Description
deal_id string · required
files JobFileOutcome[] · required How each file stood when the job completed.

DuplicateOf

DuplicateOf fields
Field Description
file_id string | null · required Null when the original was uploaded in the app before files had ids.
document_id string | null · required

EntityInput

An existing party by id, or a new one by name and type (D24).

EntityInput fields
Field Description
entity_id string | null An existing party, from GET /relationships/{id}/entities.
name string | null For a new party: its name. A person's name is first and last. Up to 255 characters.
entity_type enum | null For a new party. One of BUSINESS, PERSON.
legal_form enum | null For a new business: its legal form. One of SOLE_PROPRIETORSHIP, PARTNERSHIP, LLC, CORPORATION, NON_PROFIT, TRUST, OTHER.
role enum · required The party's role on this deal. One of BORROWER, GUARANTOR, RELATED.
is_primary boolean The primary party for its role. The first borrower is primary unless another is marked.
guarantee GuaranteeInput | null For a guarantor: what they guarantee.

EntityOverride

Bind one parsed party to a specific existing entity instead of the one we proposed.

EntityOverride fields
Field Description
parsed_ref string | null The party's parsed_ref from the job's result.
parsed_name string | null Instead of parsed_ref, when the name is unambiguous.
entity_id string · required An entity on the relationship.

Error

The one error shape. code is stable: branch on it. message is for a person reading a log.

Error fields
Field Description
code string · required Stable. Branch on it.
message string · required For a human reading a log.
field string The field at fault, as an indexed path (entities[1].name), when one is.
reason string On conflict: why the record refused the change.
details map[] Every failing entry of a batch, with its field.

FacilityInput

One facility. title and commitment_amount are required; everything else can be filled in later.

FacilityInput fields
Field Description
id string | null On PATCH: the facility to update in place. Omit to add one.
title string · required Facility name, e.g. Term Loan A. Up to 255 characters.
facility_type enum | null One of CRE_MORTGAGE, TERM_LOAN, LINE_OF_CREDIT, CONSTRUCTION, SBA_7A, SBA_504, SBA_EXPRESS_LINE_OF_CREDIT, SBA_EXPRESS_TERM_LOAN, EQUIPMENT, BRIDGE, AGRICULTURAL, REVOLVING_LINE_OF_CREDIT, LETTER_OF_CREDIT, PARTICIPATION, SALE_LEASEBACK, OPTION_BRIDGE, OTHER.
commitment_amount decimal string · required The amount asked for. Decimal string.
entity_id string | null The borrowing party, from the deal's entities. Omit when the facility applies to every borrower.
purpose string | null What the money is for.
term_months integer | null Months to maturity.
amortization_months integer | null Amortization period. Longer than term_months means a balloon.
interest_only_months integer | null Interest-only months before amortization starts.
rate_type enum | null One of FIXED, VARIABLE, FIXED_TO_FLOAT.
interest_rate decimal string | null All-in annual rate as a decimal fraction: "0.0725" is 7.25%.
index_name enum | null For variable rates. One of PRIME, SOFR, TREASURY_5Y, TREASURY_10Y, FED_FUNDS, OTHER.
spread_over_index decimal string | null Margin over the index, decimal fraction: "0.026" is 2.60%.
rate_floor decimal string | null Minimum rate, decimal fraction.
rate_ceiling decimal string | null Maximum rate, decimal fraction.
repayment_type enum | null One of MONTHLY_PI, MONTHLY_IO, QUARTERLY_PI, INTEREST_ONLY, REVOLVING_LINE, SCHEDULED_PAYMENT.
payment_amount decimal string | null For SCHEDULED_PAYMENT, where the payment is quoted rather than priced from a rate.
interest_day_count enum | null Defaults to your organization's setting. One of ACTUAL_365, ACTUAL_360.
origination_fee decimal string | null Decimal fraction: "0.01" is 1%.
prepayment_penalty string | null Free text, e.g. 3-2-1-0-0.
collateral string | null What secures it, as stated on the term sheet.

Figure

Figure fields
Field Description
value decimal string · required Currency to the cent; a ratio as a bare multiple; a percent already scaled.
unit FigureUnit · required One of currency, ratio, percent, count.
label string · required
as_of date | null · required
period_start date | null · required
period_end date | null · required
scenario string | null · required
basis string | null · required Which view of the analysis the figure is from (a DSCR worksheet type, say).

FileError

FileError fields
Field Description
code FileErrorCode · required One of password_required, classification_failed, processing_failed.
message string · required

GridColumn

GridColumn fields
Field Description
key string · required Stable within the table; the key of each row's values.
label string · required
period_start date | null · required
period_end date | null · required
kind GridColumnKind · required percent is the common-size column beside a period. One of value, percent.
scenario string | null · required
basis GridColumnBasis | null · required One of actual, projected.
source string | null · required The owner on a split personal statement, or the source of one of two readings of a year.

GridRow

GridRow fields
Field Description
key string · required Stable within the table (a metric key, a category group).
label string · required
depth integer · required Indent under the line above.
kind GridRowKind · required One of line, subtotal, total, ratio, section.
unit GridRowUnit · required How to read values. One of currency, percent, ratio, count, text.
values map · required By column key: a decimal string, the text the table holds, or null.

Guarantee

Guarantee fields
Field Description
type GuaranteeType · required One of UNLIMITED, LIMITED, CORPORATE.
cap decimal string | null · required For a LIMITED guarantee, the cap. Decimal string.

GuaranteeInput

The guarantee a guarantor gives.

GuaranteeInput fields
Field Description
type enum · required UNLIMITED, LIMITED or CORPORATE.
cap decimal string | null For a LIMITED guarantee, the cap. Decimal string.

IntakeParty

IntakeParty fields
Field Description
parsed_ref string · required The stable handle a confirm override names.
parsed_name string · required
role ParsedRole · required One of BORROWER, GUARANTOR, RELATED, OWNER.
entity_type EntityType | null · required One of BUSINESS, PERSON, OTHER.
legal_form LegalForm | null · required One of SOLE_PROPRIETORSHIP, PARTNERSHIP, LLC, CORPORATION, NON_PROFIT, TRUST, OTHER.
proposed_entity_id string | null · required The existing entity we propose to reuse.
confidence number | null · required

IntakeResult

IntakeResult fields
Field Description
relationship_id string | null · required
parties IntakeParty[] · required
terms any[] · required The loan request(s) as the parser read them.
deal_id string Once confirmed.

JobError

JobError fields
Field Description
code string · required
message string · required

JobFileOutcome

JobFileOutcome fields
Field Description
file_id string · required
upload_id string | null · required
external_reference string | null · required
file_name string · required
outcome FileOutcome | null · required One of filed, needs_review, duplicate, failed.
document_id string | null · required
data_request_id string | null · required
error FileError | null · required

JobProgress

JobProgress fields
Field Description
total integer · required
settled integer · required Files that need nothing more from us.

JobSummary

JobSummary fields
Field Description
filed integer · required
needs_review integer · required
duplicate integer · required
failed integer · required

LoanTypeOption

LoanTypeOption fields
Field Description
key string · required What loan_type takes.
label string · required

Me

Me fields
Field Description
organization Organization · required
scope Scope · required What the key may do. One of read, read_write.
environment Environment · required One of sandbox, production.
key_prefix string · required The start of the key, enough to recognize it.

MemoDate

MemoDate fields
Field Description
label string · required Prepared, Submitted, Approved or Declined.
date date · required

MemoDocument

MemoDocument fields
Field Description
title string · required
subtitle_lines string[] · required
logo string | null · required A data URI, when the lender has a logo.
nodes any[] · required Headings, paragraphs and tables, in order: the same nodes the Word file is built from.

Organization

Organization fields
Field Description
id string · required
name string · required

Party

A party on a deal: the durable entity it points at, its role here, and what it gives.

Party fields
Field Description
id string | null · required The entity. Null only for a party we cannot address yet; warnings says so.
name string · required The party's name.
entity_type EntityType | null · required One of BUSINESS, PERSON, OTHER.
legal_form LegalForm | null · required As on the Entity object. Null for a person. One of SOLE_PROPRIETORSHIP, PARTNERSHIP, LLC, CORPORATION, NON_PROFIT, TRUST, OTHER.
role PartyRole | null · required BORROWER, GUARANTOR or RELATED, which you can set; TARGET, COLLATERAL and SELLER, which only the app sets. Null for a party with no role on the deal.
is_primary boolean · required Whether this is the primary party for its role.
is_collateral boolean · required Whether the party also serves as collateral.
guarantee Guarantee | null · required The guarantee this party gives, if any.
warnings Warning[] · required Problems with this party, such as entity_unmapped.

Placement

Placement fields
Field Description
data_request_id string | null · required
entity_id string | null · required
data_type string | null · required e.g. BUSINESS_TAX_RETURN.
period_end date | null · required
source PlacementSource · required Who decided: you, the matcher, or a person in the app. One of caller, matcher, reviewer.

Review

Review fields
Field Description
kind ReviewKind · required One of question, unmatched.
id string · required The question (cdq_) or review-queue item (cumd_).
prompt string | null · required The question your team is asked, when it is one.
url string · required Opens it in the Aloan app.

Suggestion

Suggestion fields
Field Description
id string · required
label string · required

User

User fields
Field Description
email string · required
name string · required
role UserRole · required One of ADMIN, UNDERWRITER, MEMBER, RELATIONSHIP_MANAGER, VIEWER, IT_ADMIN.
assignable boolean · required Whether assigned_to and relationship_manager can name this user.

Warning

Warning fields
Field Description
code string · required entity_unmapped: the party has no durable entity yet.
message string · required

Enumerations

Every named set of values a field can take. Within a version, values are only added.

Enumerations
EnumerationValues
AnalysisDownloadFormat json, xlsx
AnalysisFormat grid, chart, markdown
AnalysisType combined_income_statement, combined_trust_income_statement, combined_balance_sheet, combined_cash_flow, combined_personal_income_statement, combined_personal_balance_sheet, combined_operating_statement, consolidated_income_statement, consolidated_balance_sheet, dscr_analysis, personal_income, property_schedule, ratios_analysis, cash_bridge, global_cash_flow, cash_flow_chart, custom_table, metrics_table, debt_service_summary, debt_schedule, bank_statement_monthly_summary, bank_statement_cash_flow_chart, bank_statement_score_card, bank_statement_risk_flags, rent_roll_summary, markdown_content, collateral_analysis, pre_screen_summary
CreditMemoStatus DRAFT, SUBMITTED, CHANGES_REQUESTED, APPROVED, DECLINED
DataRequestStatus PENDING, IN_PROGRESS, REVIEWING, ACCEPTED, COMPLETED, EXCEPTION, REJECTED, CANCELLED
DataType FINANCIAL_STATEMENTS, AR_AGING, AP_AGING, INVENTORY_AGING, BUSINESS_TAX_RETURN, BUSINESS_TAX_RETURN_SCHEDULE_K, PERSONAL_TAX_RETURN, TRUST_TAX_RETURN, TAX_COMPLIANCE_HISTORY, TAX_LIABILITIES_SCHEDULE, TAX_TRANSCRIPT, PERSONAL_FINANCIAL_STATEMENT, PERSONAL_CREDIT_REPORT, PAY_STUB, RESUME, KYC, FORMATION_DOCUMENTS, FICTITIOUS_NAME_STATEMENT, BUSINESS_LICENSE, CAP_TABLE, EIN_LETTER, CORPORATE_RESOLUTION, W_9, REGULATORY_DISCLOSURES, INSURANCE_CLAIMS, SETTLEMENT_DOCUMENTS, PURCHASE_AGREEMENT, APPRAISAL, INVOICE, CONSTRUCTION_CONTRACT, CONSTRUCTION_BUDGET, PLANS_AND_SPECS, PERMITS, RENT_ROLL, LEASE, ENVIRONMENTAL_REPORT, FLOOD_CERTIFICATE, BANK_STATEMENTS, INVESTMENT_STATEMENT, BUSINESS_CREDIT_REPORT, REAL_ESTATE_OWNED, DEBT_SCHEDULE, RELATED_PARTY_TRANSACTIONS, OFF_BALANCE_SHEET_DISCLOSURE, SUPPLIER_CONTRACTS, DISTRIBUTOR_AGREEMENTS, PRICING_AGREEMENTS, MATERIAL_CONTRACTS, RISK_DISCLOSURE, GIFT_TAX_RETURN, CERTIFICATE_OF_GOOD_STANDING, TRUST_DOCUMENT, PROPERTY_RECORDS, PROPERTY_IMPROVEMENT_PLAN, SURVEY, TITLE_WORK, GROUND_LEASE, SNDA, TENANT_ESTOPPELS, MASTER_DEED, DEED_RESTRICTIONS, MARKET_STUDY, INSURANCE_CERTIFICATE, SWORN_STATEMENT, TITLE_CERTIFICATE_OF_ORIGIN, VEHICLE_TITLE, FIELD_AUDIT, SITE_INSPECTION, STAR_REPORT, ASSET_LIST, INVENTORY_LIST, PAYOFF_STATEMENT, TERM_SHEET, DEAL_BACKGROUND, OFFERING_MEMORANDUM, LOAN_APPLICATION, SBA_AUTHORIZATION, SBA_GUARANTY, SBA_FORM, SBA_CITIZENSHIP_CERTIFICATION, IRS_FORM_4506C, GOVERNMENT_ID, FRANCHISE_AGREEMENT, EQUITY_INJECTION_VERIFICATION, BENEFICIAL_OWNERSHIP, UCC_SEARCH, UCC_FILING, OFAC_REPORT, CAIVRS_CHECK, SAM_SEARCH, BACKGROUND_SEARCH, LITIGATION_SEARCH, BUSINESS_PLAN, CUSTOM
DealStage PRE_QUALIFICATION, UNDERWRITING
DealStatus IN_PROGRESS, PENDING_APPROVAL, APPROVED, FUNDED, DECLINED, WITHDRAWN, COMPLETED
DocumentStatus processing, ready, failed
EntityType BUSINESS, PERSON, OTHER
Environment sandbox, production
EventType ORIGINATION, RENEWAL, REVIEW, MODIFICATION, COVENANT_TEST
FacilityType CRE_MORTGAGE, TERM_LOAN, LINE_OF_CREDIT, CONSTRUCTION, SBA_7A, SBA_504, SBA_EXPRESS_LINE_OF_CREDIT, SBA_EXPRESS_TERM_LOAN, EQUIPMENT, BRIDGE, AGRICULTURAL, REVOLVING_LINE_OF_CREDIT, LETTER_OF_CREDIT, PARTICIPATION, SALE_LEASEBACK, OPTION_BRIDGE, OTHER
FigureUnit currency, ratio, percent, count
FileErrorCode password_required, classification_failed, processing_failed
FileOutcome filed, needs_review, duplicate, failed
FileStatus queued, classifying, processing, filed, awaiting_review, duplicate, failed, dismissed
GridColumnBasis actual, projected
GridColumnKind value, percent
GridRowKind line, subtotal, total, ratio, section
GridRowUnit currency, percent, ratio, count, text
GuaranteeType UNLIMITED, LIMITED, CORPORATE
InterestDayCount ACTUAL_365, ACTUAL_360
JobStatus processing, awaiting_confirmation, completed, failed, cancelled
JobType document_upload, deal_intake
LegalForm SOLE_PROPRIETORSHIP, PARTNERSHIP, LLC, CORPORATION, NON_PROFIT, TRUST, OTHER
ListOrder updated_at, -updated_at, -created_at
LoanStatus ACTIVE, PAID_OFF, MATURED, DEFAULTED
MemoDownloadFormat json, docx
ParsedRole BORROWER, GUARANTOR, RELATED, OWNER
PartyRole BORROWER, GUARANTOR, RELATED, TARGET, COLLATERAL, SELLER
PlacementSource caller, matcher, reviewer
QuestionKind IDENTITY_LINK, NEW_ENTITY, WRONG_DEAL, DOC_CONVENTION
QuestionStatus OPEN, ANSWERED, DEFERRED
RateIndex PRIME, SOFR, TREASURY_5Y, TREASURY_10Y, FED_FUNDS, OTHER
RateType FIXED, VARIABLE, FIXED_TO_FLOAT
RelationshipStatus ACTIVE, EXITED, PROSPECT
RepaymentType MONTHLY_PI, MONTHLY_IO, QUARTERLY_PI, INTEREST_ONLY, REVOLVING_LINE, SCHEDULED_PAYMENT
ReviewKind question, unmatched
Scope read, read_write
UploadStatus awaiting_bytes, ready, expired
UserRole ADMIN, UNDERWRITER, MEMBER, RELATIONSHIP_MANAGER, VIEWER, IT_ADMIN

Published figures

A few analyses carry named figures beside their table, for systems that want one number without walking rows. Read them from an analysis's figures; the table remains the analysis.

Published figures
FigureMeaning
net_worth currency Total assets less total liabilities on a published balance sheet. NOT the equity section: on an unbalanced sheet the two differ, and this is the figure a lender underwrites. For a personal statement it is the bottom line; contingent liabilities are excluded, as the statement excludes them. Published by combined_balance_sheet, combined_personal_balance_sheet.
total_assets currency Every asset-side line on a published balance sheet, after contra lines. Excludes anything the statement discloses beside the sheet rather than on it. Published by combined_balance_sheet, combined_personal_balance_sheet.
total_liabilities currency Every liability-side line on a published balance sheet. Excludes contingent liabilities, which are not owed today and are disclosed beside the sheet. Published by combined_balance_sheet, combined_personal_balance_sheet.
dscr ratio The coverage ratio the published DSCR analysis prints, in its latest historical column: cash available for debt service over debt service. A bare multiple (1.42 is 1.42x). The worksheet type, carried as the figure's basis, says whose coverage it is (business, personal, global). Published by dscr_analysis.
available_cash_flow currency The cash the DSCR divides, in the same column: the row that, over total_debt_service, gives the printed ratio. Published only when the worksheet's own figures prove it. Published by dscr_analysis.
total_debt_service currency The annual debt service the DSCR divides by, in the same column. Published only when the worksheet's own figures prove it. Published by dscr_analysis.