API Reference

Everything you need to integrate the Credit Decision API — authentication, endpoints, every request and response field, and how the scoring engine makes decisions.

Authentication

All credit endpoints require an API key passed in the x-api-key request header.

http
x-api-key: YOUR_API_KEY

Demo key

A fixed demo key is available with no sign-up required:

http
x-api-key: demo-key-123

The demo key always returns a pre-computed response for a sample applicant. It is rate-limited and intended for integration testing only, not production use.

Getting a real API key

Register at /register, then find your API key in the dashboard under API Key. Keys can be rotated at any time; rotated keys are immediately invalidated.

Rate limits

Key typeLimit
Demo key1,000 requests / minute
Production key10,000 requests / minute

Rate limit status is returned in standard response headers:

http
RateLimit-Limit: 10000
RateLimit-Remaining: 9997
RateLimit-Reset: 1

When the limit is exceeded the API returns 429 Too Many Requests:

response — 429
{ "error": "Too many requests, please try again later." }

POST /api/v1/decision

Scores an applicant and returns a full credit decision. Every call is recorded for usage billing.

Request

bash
$ curl -X POST https://creditdecisionapi.com/api/v1/decision \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "age": 30,
    "income": 65000,
    "existingDebt": 4500,
    "requestedAmount": 12000,
    "yearsAtJob": 5,
    "openCreditLines": 1
  }'

Response — 200 OK

response — 200 OK
# 200 OK
{
  "success": true,
  "payload": {
    "applicant": {
      "age": 30, "income": 65000, "existingDebt": 4500,
      "requestedAmount": 12000, "yearsAtJob": 5, "openCreditLines": 1
    },
    "decision": {
      "score": 760,
      "riskLevel": "low",
      "approved": true,
      "approvalReason": "Low debt-to-income ratio (6.9%) with income that comfortably supports the requested amount.",
      "declineReason": null,
      "nextSteps": ["Offer competitive APR", "Enable instant funding"],
      "factors": {
        "incomeScore": 40, "debtScore": 27.9, "amountPressure": 3.7,
        "ageScore": 6, "tenureScore": 7.5, "openLineScore": 8.5,
        "debtRatio": 0.069,
        "estimatedFields": []
      }
    },
    "pricing": {
      "perCall": 0.05,
      "currency": "USD",
      "description": "Usage-based credit decision call"
    }
  }
}

POST /api/v1/score

Returns a credit score and factor breakdown. Every call is recorded for usage billing.

Request

Same body as /decision.

Response — 200 OK

response — 200 OK
# 200 OK
{
  "success": true,
  "result": {
    "score": 760,
    "riskLevel": "low",
    "approved": true,
    "approvalReason": "Low debt-to-income ratio (6.9%) with income that comfortably supports the requested amount.",
    "declineReason": null,
    "nextSteps": ["Offer competitive APR", "Enable instant funding"],
    "factors": {
      "incomeScore": 40, "debtScore": 27.9, "amountPressure": 3.7,
      "ageScore": 6, "tenureScore": 7.5, "openLineScore": 8.5,
      "debtRatio": 0.069,
      "estimatedFields": []
    }
  }
}

GET /api/v1/usage

Returns aggregate usage statistics for the authenticated API key.

Response — 200 OK

response — 200 OK
# 200 OK
{
  "success": true,
  "usage": {
    "tenantId": "abc123",
    "calls": 142,
    "callsThisMonth": 38,
    "createdAt": "2026-01-15T09:00:00.000Z"
  }
}

Request fields

All monetary values (income, existingDebt, requestedAmount) must use the same currency and denomination — e.g. all in USD, full dollars not cents.

FieldTypeRequiredDescription
age integer ≥ 18 Yes Applicant's age in years
income number ≥ 0 Yes Annual gross income
existingDebt number ≥ 0 Yes Total outstanding debt balance
requestedAmount number > 0 Yes Amount of credit being requested
yearsAtJob integer ≥ 0 No Years at current employer. Defaults to 0 if omitted; field appears in estimatedFields
openCreditLines integer ≥ 0 No Number of open credit accounts. Defaults to 0 if omitted; field appears in estimatedFields
name string No Applicant name. Echoed back in the response — not used in scoring

Response fields

decision object

FieldTypeDescription
score integer Credit score on a 200–850 scale
riskLevel "low" | "medium" | "high" Risk tier assigned to the applicant
approved boolean Whether the application is approved
approvalReason string | null Human-readable explanation of why the application was approved. null when declined
declineReason string | null Human-readable explanation of the primary reason for decline. null when approved
nextSteps string[] Recommended actions based on the decision outcome

factors object

Each factor shows the points contributed (or deducted) toward the final score.

FieldRangeDescription
incomeScore 0–40 Points contributed by annual income
debtScore 0–30 Points contributed by debt-to-income ratio
amountPressure 0–20 Points deducted for a high requested amount relative to income
ageScore 0–10 Points contributed by applicant age
tenureScore 0–10 Points contributed by job tenure
openLineScore 0–10 Points contributed by number of open credit lines
debtRatio 0–1 Debt-to-income ratio (existingDebt / income). Informational — used to compute debtScore and approval thresholds
estimatedFields string[] Names of optional fields not supplied and estimated with defaults. Empty array when all fields were provided

pricing object

FieldTypeDescription
perCallnumberCost of this call in USD
currencystringAlways "USD"
descriptionstringBilling line description

Approval tiers

The approval decision is determined by three thresholds evaluated together. All three conditions must be met for a tier to apply.

TierriskLevelapprovedMin scoreDTI must be <Amount-to-income must be ≤
Low risk "low" true 700 35% 50%
Medium risk "medium" true 620 45% 65%
High risk "high" false

An applicant falls into high risk if they fail any condition of the medium risk tier: score below 620, DTI of 45% or higher, or amount-to-income above 65%. The declineReason field identifies which threshold was the primary cause.

Score scale

Scores range from 200 (lowest) to 850 (highest). The same inputs always produce the same score — the algorithm is fully deterministic.

RangeInterpretation
750–850Excellent
700–749Good
650–699Fair
620–649Below average
200–619Poor

Error responses

All errors follow the same shape:

response — error
{ "error": "Description of what went wrong." }
StatusCause
400Missing or invalid request body fields
401Missing or invalid x-api-key header
429Rate limit exceeded
500Internal server error

Validation error (400)

When request fields fail validation the response includes a structured error object:

response — 400
{
  "error": {
    "formErrors": [],
    "fieldErrors": {
      "age": ["Number must be greater than or equal to 18"],
      "income": ["Number must be greater than 0"]
    }
  }
}

Unauthorized (401)

Returned when the x-api-key header is missing or does not match a valid key.

response — 401
{ "error": "Invalid or missing API key." }

Rate limited (429)

Returned when the request volume exceeds the limit for your key type. Retry after the window resets.

response — 429
{ "error": "Too many requests, please try again later." }

Server error (500)

Returned when an unexpected error occurs on our end. The request can be retried.

response — 500
{ "error": "Internal server error." }