# Getting Started

Follow these steps to integrate with the Quantum Partner API:

## Authentication

Authentication is handled by a Bearer token. The token is passed in the `Authorization` header as a Bearer token.

```bash
Authorization: Bearer <token>
```

### Obtain API Credentials

1. Contact your Quantum representative
2. You'll receive a unique Bearer token for your organization
3. Include this token in all API requests

{% callout type="warning" %}
Keep your API token secure! Never expose it in client-side code or public repositories.
{% /callout %}

Enterprise partners with mutual-authentication requirements can additionally enroll in [mutual TLS](/mtls.html) for transport-layer authentication on top of the Bearer token. This is optional and most integrations do not need it.

## Submit an Application

Use the `POST /api/v3/applications/submit` endpoint to submit a loan application on behalf of your customer.

### Required Fields

**Business Information (`business`)**
- `legal_name` - The legal business name
- `address` - Business address (street, city, state, zip_code)
- `phone_number` - Business phone number
- `entity_type` - Business structure (e.g., `sole_proprietorship`, `partnership`, `corporation`, `limited_liability_company`)
- `start_date` - When the business was established (YYYY-MM-DD)
- `naics_code` - Industry classification code
- `doing_business_as` (optional) - DBA name if different from legal name

**Loan Request (`loan_request`)**
- `amount` - Requested loan amount in dollars
- `purpose` - Loan purpose (e.g., `working_capital`, `equipment`, `inventory`, `expansion`)
- `authorization` - Must be `true` to authorize the credit check

**Owner Information (`owners`)**
At least one owner is required. Total ownership must equal 100%.
- `first_name`, `last_name` - Owner's legal name
- `email`, `phone_number` - Contact information
- `date_of_birth` - Date of birth (YYYY-MM-DD)
- `ssn` - Social Security Number
- `ownership_percent` - Percentage of business owned
- `is_applicant` - Set to `true` for the primary applicant
- `address` - Owner's home address

**Additional Questions (`additional_questions`)**
- `annual_sales` - Business annual revenue in dollars

### Example Request

```javascript
const response = await fetch('https://api.quantum.com/api/v3/applications/submit', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    business: {
      legal_name: "Acme Inc LLC",
      doing_business_as: "Widgets Are Us",
      address: {
        street: "22 Acacia Ave",
        city: "Los Angeles",
        state: "CA",
        zip_code: "90025"
      },
      phone_number: "650-555-6124",
      entity_type: "limited_liability_company",
      naics_code: "312234",
      start_date: "2008-03-27"
    },
    loan_request: {
      amount: 50000,
      purpose: "working_capital",
      authorization: true
    },
    owners: [{
      first_name: "John",
      last_name: "Doe",
      email: "john@acmeinc.com",
      phone_number: "650-555-2134",
      date_of_birth: "1981-03-17",
      is_applicant: true,
      ownership_percent: 100,
      ssn: "123-45-6789",
      address: {
        street: "123 Main St",
        city: "Los Angeles",
        state: "CA",
        zip_code: "90025"
      }
    }],
    additional_questions: {
      annual_sales: 250000
    }
  })
});

const application = await response.json();
console.log('Application ID:', application.id);
```

{% callout type="info" %}
Save the `application.id` from the response — you'll need it for uploading documents, checking status, and all subsequent operations.
{% /callout %}

For the complete schema and all available fields, see the [API Reference](/api-reference.html).

## Upload Documents
After submitting an application, upload supporting documents using `POST /api/v3/applications/{app_id}/documents`.

### Example Request

```javascript
const applicationId = 'your-application-id';

// File objects from an <input type="file"> element or other source
const bankStatementFile1 = fileInput.files[0];
const bankStatementFile2 = fileInput.files[1];
const driversLicenseFile = photoIdInput.files[0];

// Create FormData with documents
const formData = new FormData();
formData.append('bank_statements', bankStatementFile1);
formData.append('bank_statements', bankStatementFile2); // Multiple files supported
formData.append('photo_id', driversLicenseFile);

const uploadResponse = await fetch(`https://api.quantum.com/api/v3/applications/${applicationId}/documents`, {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_TOKEN'
    // Note: Don't set Content-Type header - browser sets it automatically with boundary
  },
  body: formData
});

const documents = await uploadResponse.json();
console.log('Uploaded documents:', documents);
```

{% callout type="info" %}
You can upload multiple files of the same type by appending them with the same field name. At least one file must be provided.
{% /callout %}

{% callout type="warning" %}
**File size limits:** Individual files must be under 20MB, and the total request size must not exceed 40MB.
{% /callout %}

**Document Types:**

| Type | Description |
|------|-------------|
| `bank_statements` | Bank statements for the primary business operating account |
| `business_tax_return` | Business tax returns (typically last 2 years) |
| `personal_tax_return` | Personal tax returns for business owners |
| `ytd_financials` | Year-to-date financial statements |
| `ye_financials` | Year-end financial statements |
| `debt_schedule` | Schedule of existing business debts and obligations |
| `photo_id` | Government-issued photo identification (driver's license, passport, etc.) |
| `utility_bill` | Utility bill for address verification |
| `lease_agreement` | Commercial lease or rental agreement |
| `business_license` | Business license or permit |
| `sos_record` | Secretary of State registration documents |
| `lien_release` | Lien release documentation |
| `ssn_card` | Social Security card |
| `void_check` | Voided check for bank account verification |
| `insurance_document` | Business insurance documentation |
| `mortgage_document` | Mortgage or property documentation |
| `personal_document` | Other personal documentation |
| `formation_documents` | Business formation documents (articles of incorporation, operating agreement, etc.) |
| `unknown` | Other/miscellaneous documents |

## Add Bank Accounts

Bank accounts can be provided during the initial application submission (in the `bank_accounts` field of the `/submit` payload) or added afterward using the dedicated endpoint.

There are two types of bank accounts:

- **Aggregator accounts** (Plaid/MX) — Used for bank statement analysis. Connected via a bank aggregation provider.
- **Direct-from-customer accounts** — Used for loan disbursement. The customer provides their account and routing numbers directly.

### Add Bank Accounts After Submission

Use `POST /api/v3/applications/{app_id}/bank-accounts` to add bank accounts to an existing application.

#### Example: Aggregator Account (Plaid)

```javascript
const applicationId = 'your-application-id';

const response = await fetch(`https://api.quantum.com/api/v3/applications/${applicationId}/bank-accounts`, {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify([
    {
      source: "plaid_link",
      aggregator: {
        provider: "plaid",
        access_token: "access-sandbox-xxx",
        primary_account_id: "account-123",
        transactions: true,
        balances: true,
        identities: true
      }
    }
  ])
});
```

#### Example: Direct-from-Customer Account

```javascript
const response = await fetch(`https://api.quantum.com/api/v3/applications/${applicationId}/bank-accounts`, {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify([
    {
      source: "direct_from_customer",
      direct_from_customer: {
        account_number: "1234567890",
        routing_number: "021000021"
      }
    }
  ])
});
```

{% callout type="info" %}
You can include both account types in a single request. Aggregator accounts are used for bank statement analysis, while direct-from-customer accounts are used for loan disbursement.
{% /callout %}

{% callout type="warning" %}
Only one `direct_from_customer` account is allowed per request. The `account_number` must be 4–17 digits and the `routing_number` must be exactly 9 digits.
{% /callout %}

### Include Bank Accounts at Submission

You can also include bank accounts in the initial `POST /api/v3/applications/submit` request by adding a `bank_accounts` array to the payload. The format is the same as shown above.

For the complete schema and all available fields, see the [API Reference](/api-reference.html).

## Monitor Application Status
Use `GET /api/v3/applications/{app_id}/status` to check the application status as it moves through underwriting. This lightweight endpoint returns only the status, timestamps, and reference ID — ideal for polling without fetching the full application payload.

### Example Request

```javascript
const applicationId = 'your-application-id';

const statusResponse = await fetch(`https://api.quantum.com/api/v3/applications/${applicationId}/status`, {
  headers: {
    'Authorization': 'Bearer YOUR_API_TOKEN'
  }
});

const status = await statusResponse.json();
console.log('Status:', status.status);
console.log('Last modified:', status.modified);
```

### Example Response

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440001",
  "status": "Under Credit Review",
  "reference_id": "your-internal-id-12345",
  "created": "2024-01-15T10:30:00Z",
  "modified": "2024-01-16T14:45:00Z"
}
```

{% callout type="info" %}
Instead of polling, you can receive real-time status updates via webhooks. See the [Webhooks Overview](/webhooks-overview.html) to get started.
{% /callout %}

{% callout type="info" %}
Need the full application details including decision data? Use `GET /api/v3/applications/{app_id}` instead.
{% /callout %}

### Application Lifecycle

Understanding the application status flow:

1. **submitted** → Application received
2. **In Processing** → Initial processing
3. **Under Credit Review** → Underwriting review
4. **Approved** → Credit decision made
5. **Awaiting Offer Acceptance** → Customer needs to accept offer
6. **Preparing Loan Documents** → Documents being prepared
7. **Awaiting Document Execution** → Customer needs to sign
8. **Awaiting Funding** → Funding in progress
9. **Booked** → Loan is active

**Alternative outcomes:**
- **Declined** - Application did not meet credit criteria
- **Offer Declined** - Customer declined the offer
- **Withdrawn** - Application withdrawn

## Review and Accept Offers
When approved, retrieve offers using `GET /api/v3/applications/{app_id}/offers` and accept the best offer with `POST /api/v3/applications/{app_id}/offer/{offer_id}/accept`.

## Service the Account
Once booked, use the Accounts API to manage draws and payments.

---

## Common Workflows

### Requesting a Draw from a Line of Credit

Once a line of credit account is active, you can request draws:

```javascript
const drawResponse = await fetch(`https://api.quantum.com/api/v3/accounts/${accountId}/draw-requests`, {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    draw_amount_in_cents: 1000000, // $10,000
    reference_id: "partner-draw-12345"
  })
});

const drawRequest = await drawResponse.json();
// Draw is processed asynchronously - check status or wait for webhook
```

{% callout type="info" %}
Draw and payment requests are processed asynchronously. You'll receive webhook notifications when the status changes.
{% /callout %}

### Making a Payment

Submit payments for loan repayment or payoff:

```javascript
const paymentResponse = await fetch(`https://api.quantum.com/api/v3/accounts/${accountId}/payment-requests`, {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    payment_amount_in_cents: 500000, // $5,000
    request_type: "Payment Request",
    reference_id: "partner-payment-456"
  })
});
```

---

## Error Handling

The API uses standard HTTP status codes to indicate success or failure:

| Status Code | Description |
|-------------|-------------|
| 200 | OK - Request succeeded |
| 201 | Created - Resource created successfully |
| 400 | Bad Request - Invalid request parameters |
| 403 | Forbidden - Insufficient permissions |
| 404 | Not Found - Resource not found |
| 422 | Unprocessable Entity - Validation error |
| 500 | Internal Server Error |
| 503 | Service Unavailable |

**Error Response Format:**

```json
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Some fields are missing or invalid.",
    "details": [
      {
        "field": "application.business.legal_name",
        "message": "This field is required."
      }
    ]
  }
}
```

{% callout type="warning" %}
Always check the `error.details` array for field-specific validation errors when you receive a 422 response.
{% /callout %}

---

## Best Practices

### Use Reference IDs
Include your own `reference_id` in applications, draw requests, and payment requests to track operations in your system:

```json
{
  "reference_id": "your-internal-id-12345"
}
```

### Handle Asynchronous Operations
Draw requests and payment requests are processed asynchronously. Implement webhook handlers to receive status updates rather than polling.

### Validate Before Submitting
Ensure all required fields are present and properly formatted before submitting applications to avoid validation errors.

### Store Application IDs
Save the `application.id` returned from the submit endpoint - you'll need it for all subsequent operations (uploading documents, checking status, etc.).

---

## Querying These Docs With AI Assistants

If you're using an AI assistant (Claude, Cursor, ChatGPT with browsing, etc.) to integrate with the Quantum Partner API, point your tool at one of these machine-readable entry points instead of crawling the HTML site:

- **`https://docs.quantumlends.com/llms.txt`** — Compact index following the [llms.txt convention](https://llmstxt.org/). Lists every doc and the canonical API spec with absolute URLs the assistant can follow.
- **`https://docs.quantumlends.com/llms-full.txt`** — Single file containing the full body of every guide plus a structured summary of the OpenAPI spec. Useful when you want one fetch to cover the whole integration surface.
- **`https://docs.quantumlends.com/merged-api.json`** — Raw OpenAPI 3.1 spec, suitable for codegen or tool definitions.

Each guide page also exposes its source markdown via `<link rel="alternate" type="text/markdown" href="/content/<page>.md">`, so an assistant that lands on a guide page can fetch the source directly. The API reference page uses an `application/json` alternate that points at the OpenAPI spec.

---

## Next Steps

- Review the [complete API Reference](/api-reference.html) for detailed endpoint documentation
- Contact your Quantum representative for API credentials and sandbox access
- Test your integration in the sandbox environment before going live
