QFAST API Documentation
  1. API
  • Authentication
  • Onboarding
    • Overview
    • Reference
      • Area Reference
    • API
      • Onboarding Personal
        POST
      • Get Onboarding Status
        GET
      • Submit Loan
        POST
      • Get Loan
        GET
    • Webhook
      • Onboarding Webhooks
  • Disbursement
    • Overview
    • Webhook
      • Disbursement Webhooks
  • Repayment
    • Overview
    • Webhook
      • Repayment Webhooks
  • Schemas
    • Loan Schema
    • Onboarding Schema
  1. API

Submit Loan

Developing
POST
/v1/loans/submit

Loan Submission API#

After a merchant passes KYB and reaches active status, submit the loan details to create and queue it for disbursement.
Prerequisite: The merchant's onboarding_status must be active before calling this endpoint. Get the merchant_id from the Register Personal response. If the status is not yet active, wait for the kyb.status_updated webhook or poll Get Onboarding Status.

1. Endpoint Information#

ItemDescription
MethodPOST
Path/v1/loans/submit
AuthOAuth2 Client Credentials (Bearer Token)
Content-Typeapplication/json

2. Request Headers#

HeaderTypeRequiredDescription
AuthorizationStringYesBearer <access_token>
Request-IdUUIDYesIdempotency key. Use UUID v4. A duplicate Request-Id returns the original loan response without re-creating.

3. Request Body#

FieldTypeRequiredDescription
merchant_idUUIDYesThe merchant_id from the registration response.
loanObjectYesLoan financial details. See below.

Loan Object (loan)#

FieldTypeRequiredDescription
reference_account_numberStringYesYour internal reference for this loan. Max 50 characters. Must be unique per lender.
principal_amountNumberYesLoan principal in IDR (e.g., 5000000).
interest_amountNumberYesTotal interest amount for the full term, in IDR.
admin_fee_amountNumberNoAdmin fee deducted from the disbursed amount. In IDR.
reserve_amountNumberYesReserve/collateral deposit held by QFAST. In IDR.
term_lengthIntegerYesDuration of the loan in months. Must equal the number of repayment_schedules.
penalty_rateNumberNoDaily late penalty rate as a decimal (e.g., 0.01 = 1%). Range: 0.0–1.0.
start_dateStringYesLoan start date in YYYY-MM-DD format.
repayment_schedulesArrayYesList of scheduled repayment entries. Count must equal term_length.

Repayment Schedule Object#

FieldTypeRequiredDescription
principal_amountNumberYesPrincipal portion due on this schedule entry, in IDR.
interest_amountNumberYesInterest portion due on this schedule entry, in IDR.
due_dateStringYesExpected payment date in YYYY-MM-DD format.
daily_amountNumberYesDaily deduction amount from the merchant's revenue, in IDR.
Validation rule: repayment_schedules.count must exactly equal term_length. Mismatches return a 422 error.

4. Example Request#


5. Response#

Success Response (200 OK)#

{
  "data": {
    "loan_id": "019e15a1-c644-705c-9330-fffa62cd44ed",
    "reference_account_number": "1234567890",
    "status": "pending",
    "principal_amount": 5000000,
    "interest_amount": 900000,
    "admin_fee_amount": 250000,
    "reserve_amount": 230533,
    "term_unit": "month",
    "term_length": 6,
    "penalty_rate": "0.0000",
    "start_date": "2026-06-01"
  }
}
FieldTypeDescription
loan_idUUIDUnique identifier for the loan. Store this — required for operations.
reference_account_numberStringYour reference number for this loan.
statusStringLoan status. Initial value: pending.
principal_amountNumberLoan principal in IDR.
interest_amountNumberTotal interest amount in IDR.
admin_fee_amountNumberAdmin fee in IDR. Deducted from disbursed amount.
reserve_amountNumberReserve amount held by QFAST, in IDR.
term_unitStringLoan term unit. Value: month.
term_lengthIntegerLoan duration in months.
penalty_rateStringDaily late penalty rate as a string.
start_dateStringLoan start date in YYYY-MM-DD format.

Disbursed Amount#

The actual amount transferred to the borrower's wallet is:
disburse_amount = principal_amount - admin_fee_amount

Error Responses#

401 Unauthorized
{
  "error": "invalid_token",
  "error_description": "The access token is missing or invalid.",
  "code": 401
}
404 Not Found
{
  "error": "merchant_not_found",
  "error_description": "Merchant ID [019db2ee-3857-7148-b320-6f6e7c4deedd] does not exist or belongs to a different lender.",
  "code": 404
}
409 Conflict
{
  "error": "duplicate_reference",
  "error_description": "Reference account number [LND-ACC-2026-0001] already exists.",
  "code": 409
}
422 Unprocessable Entity
{
  "error": "merchant_not_active",
  "error_description": "Merchant onboarding_status is not active. Complete KYB first.",
  "code": 422
}
{
  "error": "validation_failed",
  "error_description": "repayment_schedules count (2) does not match term_length (3).",
  "code": 422
}
{
  "error": "borrower_has_active_loan",
  "error_description": "The borrower already has a PENDING or ACTIVE loan.",
  "code": 422
}
HTTP StatusErrorCause
401invalid_tokenMissing or invalid access token.
404merchant_not_foundmerchant_id does not exist or belongs to a different lender.
409duplicate_referencereference_account_number already exists for this lender.
422merchant_not_activeMerchant onboarding_status is not active. Complete KYB first.
422validation_failedMissing required fields, invalid formats, or repayment_schedules count mismatch.
422borrower_has_active_loanThe borrower already has a PENDING or ACTIVE loan.

6. What Happens Next#

After a successful loan submission:
1.
QFAST dispatches a loan_submitted webhook to your configured webhook URL — see Onboarding Events.
2.
Poll loan status at any time using Get Onboarding Status.
3.
Lender accesses the QFAST dashboard to complete the disbursement.

Request

Authorization
OAuth 2.0
Client Credentials
Add the parameter
Authorization
to Headers
,whose value is to concatenate the Token after the Bearer.
Example:
Authorization: Bearer ********************
Token URL: https://api.sandbox.qfast.id/v1/oauth2/token
or
Header Params

Body Params application/jsonRequired

Example
{
    "merchant_id": "019ebaab-d692-732d-b9e2-cffc3c59e7ea",
    "loan": {
        "reference_account_number": "LND-ACC-2026-8765",
        "principal_amount": 5000000,
        "interest_amount": 750000,
        "admin_fee_amount": 50000,
        "reserve_amount": 500000,
        "term_length": 3,
        "penalty_rate": 0.01,
        "start_date": "2026-06-12",
        "repayment_schedules": [
            {
                "principal_amount": 1666667,
                "interest_amount": 250000,
                "due_date": "2026-07-12",
                "daily_amount": 15000
            },
            {
                "principal_amount": 1666667,
                "interest_amount": 250000,
                "due_date": "2026-08-12",
                "daily_amount": 15000
            },
            {
                "principal_amount": 1666666,
                "interest_amount": 250000,
                "due_date": "2026-09-12",
                "daily_amount": 15000
            }
        ]
    }
}

Request Code Samples

Shell
JavaScript
Java
Swift
Go
PHP
Python
HTTP
C
C#
Objective-C
Ruby
OCaml
Dart
R
Request Request Example
Shell
JavaScript
Java
Swift
curl --location 'https://api.sandbox.qfast.id/v1/loans/submit' \
--header 'Request-Id: b92f3b00-df6a-43bb-b597-97c43b523674' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
    "merchant_id": "019ebaab-d692-732d-b9e2-cffc3c59e7ea",
    "loan": {
        "reference_account_number": "LND-ACC-2026-8765",
        "principal_amount": 5000000,
        "interest_amount": 750000,
        "admin_fee_amount": 50000,
        "reserve_amount": 500000,
        "term_length": 3,
        "penalty_rate": 0.01,
        "start_date": "2026-06-12",
        "repayment_schedules": [
            {
                "principal_amount": 1666667,
                "interest_amount": 250000,
                "due_date": "2026-07-12",
                "daily_amount": 15000
            },
            {
                "principal_amount": 1666667,
                "interest_amount": 250000,
                "due_date": "2026-08-12",
                "daily_amount": 15000
            },
            {
                "principal_amount": 1666666,
                "interest_amount": 250000,
                "due_date": "2026-09-12",
                "daily_amount": 15000
            }
        ]
    }
}'

Responses

🟢200Success
application/json
Bodyapplication/json

Example
{
    "data": {
        "loan_id": "019e15a1-c644-705c-9330-fffa62cd44ed",
        "reference_account_number": "1234567890",
        "status": "pending",
        "principal_amount": 5000000,
        "interest_amount": 900000,
        "admin_fee_amount": 250000,
        "reserve_amount": 230533,
        "term_unit": "month",
        "term_length": 6,
        "penalty_rate": "0.0000",
        "start_date": "2026-06-01"
    }
}
🟠404Merchant Not Found
🟠409Duplicate Reference
🟠422Merchant Not Active
🟠422Validation Failed
🟠422Borrower Has Active Loan
Previous
Get Onboarding Status
Next
Get Loan
Built with