Draw Requests Guide
Complete guide to requesting loan draws, handling final draws with completion certificates, and managing the disbursement process
Draw Requests Guide
This guide covers everything you need to know about requesting loan draws through the Thrive Public API, including regular draws and final draws with completion certificates.
Overview
Draw requests allow you to access approved loan funds in stages throughout your project. The Thrive API supports:
- Regular Draws - Standard fund disbursements during project execution
- Final Draws - The last disbursement requiring project completion documentation
- Early Project Completion Draws - If you need to complete a project before all scheduled draws.
API Endpoint ReferenceThis guide covers the business workflows for draw requests. For complete technical documentation of the endpoint, see our API Reference.
Draw Request Process
1. Prerequisites
Before requesting a draw, ensure:
- ✅ Loan application is in "Approved" status
- ✅ No pending draw requests exist for the loan
- ✅ Available loan balance covers the requested amount
- ✅ Required authentication headers are configured
2. Authentication
This endpoint requires authentication via headers:
| Header | Required | Description |
|---|---|---|
x-thrive-client-id | Yes | Client ID for authentication |
x-thrive-client-secret | Yes | Client secret for authentication |
x-thrive-merchant-uid | No | Merchant identifier (only needed for group accounts) |
3. Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
loanApplicationUid | string (UUID) | Yes | Unique identifier of the loan application |
4. Request Body
This endpoint uses multipart/form-data format and handles both regular draw requests and final draw requests with project completion documentation.
Regular Draw Request
For a standard draw request, submit with an empty body or specify optional parameters:
| Field | Type | Required | Description |
|---|---|---|---|
updatedDisbursementAmount | string | No | Revised disbursement amount for this draw (up to 2 decimal places). Enter a specific amount less than the calculated draw amount to reduce the disbursement. This field cannot be used together with projectCompletedEarly. |
Final Draw Request
For the final draw, you must provide project completion documentation:
| Field | Type | Required | Description |
|---|---|---|---|
files | array of files | Conditional* | Project completion certificate files (PDFs, images, etc.) |
metadata | string (JSON) | Conditional* | JSON string containing completion certificate metadata |
updatedLoanAmount | string | No | Revised total loan amount (up to 2 decimal places). This value cannot exceed the original loan amount. Use this field to reduce the loan amount if the project is completed under budget. |
*Either files or metadata must be provided for final draws.
Early Project Completion
If you need to complete a project before all scheduled draws:
| Field | Type | Required | Description |
|---|---|---|---|
projectCompletedEarly | boolean | Yes | Set to true to mark project as completed early |
updatedLoanAmount | string | No | Revised total loan amount (up to 2 decimal places). This value cannot exceed the original loan amount. Use this field to reduce the loan if the project is completed under budget. |
files | array of files | Conditional* | Completion certificate files |
metadata | string (JSON) | Conditional* | Completion certificate metadata |
*Either files or metadata (or both) must be provided when completing early.
5. Understanding Draw Requests
The system automatically determines whether this is a final draw based on the loan's disbursement schedule. You don't need to explicitly specify the draw type—the system detects this and enforces the appropriate requirements.
Regular Draw
Submit the request with no body for the full calculated draw amount, or include updatedDisbursementAmount to request a specific amount less than what's calculated for the current stage.
When to use: For standard, scheduled disbursements during project progress.
Example scenarios:
- Requesting the next scheduled draw at the full calculated amount
- Requesting less than the calculated amount if the current stage cost less than expected
Final Draw
The system automatically detects when this is the final draw based on the disbursement schedule and requires completion certificate documentation (files and/or metadata).
When to use: For the last scheduled draw when the project is complete.
Requirements:
- Completion documentation is mandatory (files and/or metadata)
- If the project was completed under budget, include
updatedLoanAmountto reduce the total loan amount to reflect actual costs
Early Completion
Mark projectCompletedEarly: true and provide completion documentation to finalize a project before all scheduled draws have been requested.
When to use: When a project is completed ahead of schedule or requires fewer disbursements than originally planned.
Requirements:
- Cannot be used on the first draw of multi-disbursement loans
- Must include completion certificate documentation (files or metadata)
- If the project was completed under budget, include
updatedLoanAmountto reduce the total loan amount
Important: When completing a project (early or final), use
updatedLoanAmountto adjust the total loan amount. Do not useupdatedDisbursementAmount.
6. Making Draw Requests
Regular Draw Request
For a standard draw request:
curl -X POST https://api.partnerwiththrive.com/public/v2/loan/{loanApplicationUid}/request-draw \
-H "x-thrive-client-id: your_client_id" \
-H "x-thrive-client-secret: your_client_secret" \
-H "x-thrive-merchant-uid: your_merchant_uid" \
-F "For a standard draw with reduced draw amount:
curl -X POST https://api.partnerwiththrive.com/public/v2/loan/{loanApplicationUid}/request-draw \
-H "x-thrive-client-id: your_client_id" \
-H "x-thrive-client-secret: your_client_secret" \
-H "x-thrive-merchant-uid: your_merchant_uid" \
-F "updatedDisbursementAmount=8000.99"Final Draw Request
For the final draw with completion certificate files:
curl -X POST https://api.partnerwiththrive.com/public/v2/loan/{loanApplicationUid}/request-draw \
-H "x-thrive-client-id: your_client_id" \
-H "x-thrive-client-secret: your_client_secret" \
-H "x-thrive-merchant-uid: your_merchant_uid" \
-F "files=@completion_certificate.pdf" \
-F "files=@project_photos.jpg" \For final draw using JSON metadata:
curl -X POST https://api.partnerwiththrive.com/public/v2/loan/{loanApplicationUid}/request-draw \
-H "x-thrive-client-id: your_client_id" \
-H "x-thrive-client-secret: your_client_secret" \
-H "x-thrive-merchant-uid: your_merchant_uid" \
-F 'metadata={"projectName": "Solar Panel System", "completionDate": "2024-01-15", "certificationNumber": "CERT-123", "inspector": "John Smith"}'For final draw with reduced loan amount:
curl -X POST https://api.partnerwiththrive.com/public/v2/loan/{loanApplicationUid}/request-draw \
-H "x-thrive-client-id: your_client_id" \
-H "x-thrive-client-secret: your_client_secret" \
-H "x-thrive-merchant-uid: your_merchant_uid" \
-F "updatedLoanAmount=15000" \
-F "files=@completion_certificate.pdf" \Early Project Completion Draw Request
For early project completion draw with completion certificate files:
curl -X POST https://api.partnerwiththrive.com/public/v2/loan/{loanApplicationUid}/request-draw \
-H "x-thrive-client-id: your_client_id" \
-H "x-thrive-client-secret: your_client_secret" \
-H "x-thrive-merchant-uid: your_merchant_uid" \
-F "projectCompletedEarly=true" \
-F "files=@completion_certificate.pdf" \For early project completion draw using JSON metadata:
curl -X POST https://api.partnerwiththrive.com/public/v2/loan/{loanApplicationUid}/request-draw \
-H "x-thrive-client-id: your_client_id" \
-H "x-thrive-client-secret: your_client_secret" \
-H "x-thrive-merchant-uid: your_merchant_uid" \
-F "projectCompletedEarly=true" \
-F 'metadata={"projectName": "Solar Panel System", "completionDate": "2024-01-15", "certificationNumber": "CERT-123", "inspector": "John Smith"}'For early project completion draw using reduced loan amount:
curl -X POST https://api.partnerwiththrive.com/public/v2/loan/{loanApplicationUid}/request-draw \
-H "x-thrive-client-id: your_client_id" \
-H "x-thrive-client-secret: your_client_secret" \
-H "x-thrive-merchant-uid: your_merchant_uid" \
-F "projectCompletedEarly=true" \
-F "updatedLoanAmount=15000.25" \
-F "files=@completion_certificate.pdf" \Final Draw Requirements
When is a Final Draw Required?
The system automatically determines if a draw request is the final draw based on the loan's remaining disbursement balance. When making the final draw:
- Completion documentation is mandatory (files and/or metadata)
- Project must be completed and ready for inspection
- All previous draws must be successfully disbursed
Completion Certificate Options
You can provide completion documentation in three ways:
1. File Upload Only
- Upload PDF certificates, photos, inspection reports
- Supported file types: PDF, JPG, PNG, DOCX
- Maximum file size: 10MB per file
2. Metadata Only
- Provide completion details as JSON string
- Include project details, dates, certification numbers
- Useful for digital-only completion processes
3. Files + Metadata (Recommended)
- Combine files with structured metadata
- Provides complete documentation trail
- Best for compliance and record-keeping
Metadata Schema
When providing metadata, use this JSON structure:
{
"projectName": "Solar Panel Installation",
"completionDate": "2024-01-15",
"certificationNumber": "CERT-123456",
"inspector": "John Smith",
"inspectorLicense": "LIC-789",
"projectDescription": "20kW residential solar system installation",
"systemDetails": {
"capacity": "20kW",
"panelCount": 60,
"inverterType": "String inverters"
},
"complianceNotes": "Installation meets all local building codes"
}Response Handling
Successful Draw Response
{
"timestamp": "2025-09-10T20:17:42.562Z",
"statusCode": 200,
"result": {
"data": {
"merchantDisbursementId": 699,
"merchantUid": "e2432827-aec8-49d7-be4e-14ec91e6813d",
"loanApplicationUid": "c4ff1199-a135-4739-b110-91f7c1bf9d2f",
"grossDisbursedAmount": "12000",
"netDisbursedAmount": "11160",
"disbursementNumber": 1,
"amountFunded": "11160"
},
"error": null
}
}Key Response Fields:
| Field | Type | Description |
|---|---|---|
timestamp | string (date-time) | The exact time when the response was generated |
statusCode | number | HTTP status code |
result.data.merchantDisbursementId | number | Internal disbursement ID |
result.data.merchantUid | string (UUID) | Merchant's unique identifier |
result.data.loanApplicationUid | string (UUID) | Loan application unique identifier |
result.data.grossDisbursedAmount | string | Total disbursement amount before fees |
result.data.netDisbursedAmount | string | Net amount after deducting fees |
result.data.disbursementNumber | number | Sequential disbursement number for this loan |
result.data.amountFunded | string | Exact amount funded (same as netDisbursedAmount) |
result.error | object or null | Error object if request failed, null on success |
Common Scenarios & Solutions
Scenario 1: Multiple Regular Draws
Use Case: Solar installation with multiple milestone payments
// Draw 1: Materials purchase
const draw1 = await requestDraw(loanUid); // No files needed
// Draw 2: Installation milestone
const draw2 = await requestDraw(loanUid); // No files needed
// Final Draw: Project completion
const finalDraw = await requestDraw(loanUid, {
files: ['completion_cert.pdf', 'final_inspection.jpg'],
metadata: {
projectName: 'Solar Installation',
completionDate: '2024-01-15',
certificationNumber: 'CERT-123'
}
});Scenario 2: Single Large Project Draw
Use Case: Pool installation with one large disbursement
// Final draw for complete project
const draw = await requestDraw(loanUid, {
files: ['building_permit.pdf', 'completed_pool.jpg'],
metadata: {
projectName: 'In-ground Pool Installation',
completionDate: '2024-01-15',
permitNumber: 'PERMIT-456',
inspector: 'Jane Doe'
}
});Scenario 3: Digital-Only Completion
Use Case: Service-based project without physical documentation
// Final draw with metadata only
const draw = await requestDraw(loanUid, {
metadata: {
projectName: 'HVAC System Service',
completionDate: '2024-01-15',
serviceType: 'Complete system tune-up',
technicianName: 'Mike Johnson',
certificationNumber: 'HVAC-789'
}
});Error Handling
Common Error Patterns
Missing Completion Documentation
{
"statusCode": 400,
"result": {
"error": {
"message": "File or metadata is required for completion certificate upload."
}
}
}Solution: Add either files or metadata to your final draw request.
Documentation for Non-Final Draw
{
"statusCode": 400,
"result": {
"error": {
"message": "Project completion documentation was provided, but this is not the final draw for loan abc-123. Only submit documentation for the final draw."
}
}
}Solution: Remove files and metadata from regular draw requests.
Application Not Approved
{
"statusCode": 400,
"result": {
"error": {
"message": "The application must be in the Approved status before requesting a Draw with accompanying Completion Certificate."
}
}
}Solution: Wait for loan approval before requesting draws.
Pending Draw Exists
{
"statusCode": 500,
"result": {
"error": {
"message": "Error in requestPublicDrawV2: There is a currently pending draw for this loan."
}
}
}Solution: Wait for the current draw to complete before requesting another.
Error Handling Best Practices
async function requestDrawWithRetry(loanUid, options = {}) {
try {
const response = await fetch(`/public/v2/loan/${loanUid}/request-draw`, {
method: 'POST',
headers: {
'x-thrive-client-id': process.env.THRIVE_CLIENT_ID,
'x-thrive-client-secret': process.env.THRIVE_CLIENT_SECRET,
'x-thrive-merchant-uid': process.env.THRIVE_MERCHANT_UID
},
body: createFormData(options)
});
const result = await response.json();
if (!response.ok) {
throw new DrawRequestError(result.result.error.message, result.statusCode);
}
return result.result.data;
} catch (error) {
// Handle specific error cases
if (error.message.includes('pending draw')) {
console.log('Waiting for pending draw to complete...');
await new Promise(resolve => setTimeout(resolve, 30000)); // Wait 30s
return requestDrawWithRetry(loanUid, options); // Retry once
}
throw error;
}
}File Upload Guidelines
Supported File Types
- Documents: PDF, DOC, DOCX
- Images: JPG, JPEG, PNG, WEBP
- Spreadsheets: XLS, XLSX
File Size Limits
- Maximum per file: 10MB
- Maximum total: 50MB per request
- Recommended: Compress images and PDFs before upload
File Naming Best Practices
- Use descriptive names:
completion_certificate.pdf - Avoid special characters: Use underscores instead of spaces
- Include dates:
inspection_report_2024-01-15.pdf
Testing & Development
Sandbox Environment
Test draw requests in the sandbox environment:
# Sandbox base URL
https://dev.partnerwiththrive.com/public/v2/loan/{loanUid}/request-drawTest Data Considerations
- Use test loan applications in "Approved" status
- Test both regular and final draw scenarios
- Verify error handling with invalid requests
Integration Examples
Node.js with FormData
import FormData from 'form-data';
import fs from 'fs';
async function submitFinalDraw(loanUid, files, metadata) {
const form = new FormData();
// Add files
files.forEach(filePath => {
form.append('files', fs.createReadStream(filePath));
});
// Add metadata
if (metadata) {
form.append('metadata', JSON.stringify(metadata));
}
const response = await fetch(`/public/v2/loan/${loanUid}/request-draw`, {
method: 'POST',
headers: {
'x-thrive-client-id': process.env.THRIVE_CLIENT_ID,
'x-thrive-client-secret': process.env.THRIVE_CLIENT_SECRET,
'x-thrive-merchant-uid': process.env.THRIVE_MERCHANT_UID,
...form.getHeaders()
},
body: form
});
return response.json();
}Python with Requests
import requests
import json
def submit_draw_request(loan_uid, files=None, metadata=None):
url = f"/public/v2/loan/{loan_uid}/request-draw"
headers = {
'x-thrive-client-id': os.environ['THRIVE_CLIENT_ID'],
'x-thrive-client-secret': os.environ['THRIVE_CLIENT_SECRET'],
'x-thrive-merchant-uid': os.environ['THRIVE_MERCHANT_UID']
}
form_data = {}
files_data = []
# Add files
if files:
for file_path in files:
files_data.append(('files', open(file_path, 'rb')))
# Add metadata
if metadata:
form_data['metadata'] = json.dumps(metadata)
response = requests.post(url, headers=headers, data=form_data, files=files_data)
return response.json()Next Steps
- API Reference: See the complete endpoint documentation
- Error Handling: Review our Error Handling guide for comprehensive error management
Need Help? Contact your Thrive integration manager for assistance with draw request implementation.
Updated 18 days ago
