Skip to content

Getting Started

This guide will walk you through the complete workflow of using the Laminr API to process financial documents and retrieve income calculations.

Prerequisites

Before you begin, you'll need:

  • A Laminr account
  • An API key (see Authentication guide for setup instructions)
  • Financial documents to upload (bank statements, pay stubs, etc.)

Quick Start Workflow

The typical Laminr workflow follows these steps:

  1. Create a Package - Container for your financial documents
  2. Upload Files - Add documents to the package for processing
  3. Monitor Progress - Check processing status
  4. Retrieve Results - Get income calculations and analysis

Step 1: Create a Package

A package is a container that holds related financial documents for a single applicant or loan request.

curl -X POST https://api.laminr.ai/api/v1/packages \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "John Doe Application"
  }'

Response:

{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "tenant": {
    "id": "tenant_123",
    "name": "Your Company"
  },
  "title": "John Doe Application",
  "public_id": "LP-2025-001",
  "created_at": "2025-11-05T10:00:00.000000+00:00",
  "updated_at": "2025-11-05T10:00:00.000000+00:00",
  "status": "Processing",
  "created_by": {
    "id": "user_123",
    "email": "you@example.com"
  },
  "progress": 0.0,
  "under_review": false
}

Save the id field - you'll need it to upload files and retrieve results.

Step 2: Upload Files

File uploads use a two-step process with presigned URLs:

Step 2a: Get a presigned upload URL

curl -X POST https://api.laminr.ai/api/v1/files \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"file_name": "bank_statement.pdf"}'

Response:

{
  "upload_url": "https://storage.example.com/presigned-url...",
  "uri": "tenants/123/files/1699123456-789-bank-statement-pdf"
}

Step 2b: Upload the file to the presigned URL

curl -X PUT "https://storage.example.com/presigned-url..." \
  --upload-file /path/to/bank_statement.pdf

Step 2c: Create the file record in your package

curl -X POST https://api.laminr.ai/api/v1/packages/LP-2025-001/files \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "uri": "tenants/123/files/1699123456-789-bank-statement-pdf",
    "file_name": "bank_statement.pdf"
  }'

Response:

{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "loan_package_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "file_name": "bank_statement.pdf",
  "file_extension": "pdf",
  "file_size": 245678,
  "file_md5_hash": "abc123def456...",
  "file_content_type": "application/pdf",
  "file_created_at": "2025-11-05T10:05:00.000000+00:00",
  "status": "queued",
  "created_at": "2025-11-05T10:05:00.000000+00:00",
  "updated_at": "2025-11-05T10:05:00.000000+00:00",
  "progress": null
}

Repeat this process for each document you want to process.

Step 3: Monitor Progress

Check the package status to see when processing is complete.

curl https://api.laminr.ai/api/v1/packages/LP-2025-001 \
  -H "x-api-key: YOUR_API_KEY"

Response:

{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "tenant": {
    "id": "tenant_123",
    "name": "Your Company"
  },
  "title": "John Doe Application",
  "public_id": "LP-2025-001",
  "created_at": "2025-11-05T10:00:00.000000+00:00",
  "updated_at": "2025-11-05T10:05:30.000000+00:00",
  "status": "Processing",
  "created_by": {
    "id": "user_123",
    "email": "you@example.com"
  },
  "progress": 0.5,
  "under_review": false
}

The status field will be "Processing" while files are being analyzed, then "Processed" when complete.

Step 4: Retrieve Income Results

Once processing is complete (status: "Processed"), retrieve the income calculation models.

curl https://api.laminr.ai/api/v1/packages/LP-2025-001/models \
  -H "x-api-key: YOUR_API_KEY"

Response:

{
  "count": 2,
  "page": 1,
  "pages": 1,
  "results": [
    {
      "id": "model_123",
      "eligibility_model_id": "em_456",
      "model_name": "Standard Income Model",
      "public_id": "MDL-2025-001",
      "status": "Success",
      "created_at": "2025-11-05T10:10:00.000000+00:00",
      "updated_at": "2025-11-05T10:15:00.000000+00:00",
      "started_at": "2025-11-05T10:10:00.000000+00:00",
      "finished_at": "2025-11-05T10:15:00.000000+00:00",
      "total_debits": "15234.50",
      "total_credits": "18450.00",
      "eligible_debit": "12000.00",
      "eligible_credit": "16500.00",
      "ineligible_debit": "3234.50",
      "ineligible_credit": "1950.00",
      "overridden_eligible_debits": "0.00",
      "overridden_eligible_credits": "0.00",
      "overridden_ineligible_debits": "0.00",
      "overridden_ineligible_credits": "0.00",
      "eligible_total_debits": "12000.00",
      "eligible_total_credits": "16500.00",
      "net_eligible_debits": "12000.00",
      "net_eligible_credits": "16500.00"
    }
  ]
}

Complete Example (Python)

Here's a complete example showing the entire workflow:

import requests
import time

API_KEY = "your_api_key_here"
BASE_URL = "https://api.laminr.ai/api"

headers = {
    "x-api-key": API_KEY
}

# Step 1: Create a package
response = requests.post(
    f"{BASE_URL}/v1/packages",
    headers=headers,
    json={
        "title": "John Doe Application"
    }
)
package = response.json()
package_id = package["id"]
print(f"Created package: {package_id}")

# Step 2: Upload files
files_to_upload = [
    "bank_statement_jan.pdf",
    "bank_statement_feb.pdf",
    "pay_stub.pdf"
]

for filepath in files_to_upload:
    # 2a: Get presigned URL
    response = requests.post(
        f"{BASE_URL}/v1/files",
        headers=headers,
        json={"file_name": filepath}
    )
    upload_data = response.json()
    upload_url = upload_data["upload_url"]
    uri = upload_data["uri"]

    # 2b: Upload file to presigned URL
    with open(filepath, "rb") as f:
        requests.put(upload_url, data=f)

    # 2c: Create file record in package
    requests.post(
        f"{BASE_URL}/v1/packages/{package_id}/files",
        headers=headers,
        json={"uri": uri, "file_name": filepath}
    )
    print(f"Uploaded: {filepath}")

# Step 3: Monitor progress
while True:
    response = requests.get(
        f"{BASE_URL}/v1/packages/{package_id}",
        headers=headers
    )
    package = response.json()
    status = package["status"]

    print(f"Status: {status}")

    if status == "Processed":
        break
    elif status == "Failed":
        print("Processing failed!")
        exit(1)

    time.sleep(10)  # Wait 10 seconds before checking again

# Step 4: Get results
response = requests.get(
    f"{BASE_URL}/v1/packages/{package_id}/models",
    headers=headers
)
results = response.json()

print(f"Found {results['count']} income models:")
for model in results['results']:
    print(f"\nModel: {model['model_name']}")
    print(f"Status: {model['status']}")  # "Success" or "Failed"
    print(f"Total Credits: ${model['total_credits']}")
    print(f"Eligible Credits: ${model['eligible_credit']}")

Complete Example (JavaScript/Node.js)

const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');

const API_KEY = 'your_api_key_here';
const BASE_URL = 'https://api.laminr.ai/api';

const headers = {
  'x-api-key': API_KEY
};

async function processDocuments() {
  // Step 1: Create a package
  const packageRes = await axios.post(
    `${BASE_URL}/v1/packages`,
    {
      title: 'John Doe Application'
    },
    { headers }
  );

  const packageId = packageRes.data.id;
  console.log(`Created package: ${packageId}`);

  // Step 2: Upload files
  const files = ['bank_statement.pdf', 'pay_stub.pdf'];

  for (const filepath of files) {
    // 2a: Get presigned URL
    const uploadRes = await axios.post(
      `${BASE_URL}/v1/files`,
      { file_name: filepath },
      { headers }
    );
    const { upload_url, uri } = uploadRes.data;

    // 2b: Upload file to presigned URL
    const fileData = fs.readFileSync(filepath);
    await axios.put(upload_url, fileData);

    // 2c: Create file record in package
    await axios.post(
      `${BASE_URL}/v1/packages/${packageId}/files`,
      { uri, file_name: filepath },
      { headers }
    );
    console.log(`Uploaded: ${filepath}`);
  }

  // Step 3: Monitor progress
  while (true) {
    const statusRes = await axios.get(
      `${BASE_URL}/v1/packages/${packageId}`,
      { headers }
    );

    const status = statusRes.data.status;
    console.log(`Status: ${status}`);

    if (status === 'Processed') {
      break;
    } else if (status === 'Failed') {
      console.log('Processing failed!');
      return;
    }

    await new Promise(resolve => setTimeout(resolve, 10000));
  }

  // Step 4: Get results
  const resultsRes = await axios.get(
    `${BASE_URL}/v1/packages/${packageId}/models`,
    { headers }
  );

  const results = resultsRes.data;
  console.log(`Found ${results.count} income models:`);
  results.results.forEach(model => {
    console.log(`\nModel: ${model.model_name}`);
    console.log(`Status: ${model.status}`);  // "Success" or "Failed"
    console.log(`Total Credits: $${model.total_credits}`);
    console.log(`Eligible Credits: $${model.eligible_credit}`);
  });
}

processDocuments();

Next Steps

Support

Need help? Contact us at support@laminr.ai