> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nextlevelmca.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Create a business and a deal, match lenders, submit to two of them and read the offers, all with curl.

This walk-through takes a deal from nothing to offers in five requests. You need an API key with `businesses:write`, `deals:write`, `lenders:read`, `submissions:write` and `offers:read`, or one with no scope restriction.

```bash theme={null}
export NLMCA_KEY="nlmca_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
export NLMCA_API="https://api.nextlevelmca.com/v1"
```

<Note>
  The request bodies below carry only the fields the flow needs, and the responses are trimmed. Every field, filter and response property is listed on the endpoint's page in the **API reference** tab.
</Note>

<Steps>
  <Step title="Create a business">
    ```bash theme={null}
    curl -X POST "$NLMCA_API/businesses" \
      -H "Authorization: Bearer $NLMCA_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "legal_name": "ACME Plumbing LLC",
        "dba": "ACME Plumbing",
        "ein": "12-3456789",
        "entity_type": "LLC",
        "industry": "Plumbing",
        "state": "NY",
        "phone": "+12125550123",
        "email": "owner@acmeplumbing.example",
        "business_start_date": "2018-03-01"
      }'
    ```

    ```json Response 201 theme={null}
    {
      "data": {
        "id": "0f6b0d2e-1c3a-4b8e-9d2f-7a1e5c4b3d21",
        "legal_name": "ACME Plumbing LLC",
        "dba": "ACME Plumbing",
        "ein": "12-3456789",
        "entity_type": "LLC",
        "industry": "Plumbing",
        "address": null,
        "city": null,
        "state": "NY",
        "zip": null,
        "phone": "+12125550123",
        "email": "owner@acmeplumbing.example",
        "business_start_date": "2018-03-01",
        "status": "active",
        "tags": [],
        "custom_data": {},
        "primary_contact": null,
        "deal_count": 0,
        "lifetime_funded": 0,
        "active_advances": 0,
        "outstanding_balance": 0,
        "last_activity_at": null,
        "created_at": "2026-09-04T14:02:11.000Z",
        "updated_at": "2026-09-04T14:02:11.000Z"
      },
      "meta": {}
    }
    ```

    If a business with the same EIN, or the same normalised legal name and state, already exists you get `409` with `code: "duplicate_business"` and `existing_id`. Use that id, or repeat the call with `?force=true` to create a second record anyway.
  </Step>

  <Step title="Create a deal">
    ```bash theme={null}
    curl -X POST "$NLMCA_API/deals" \
      -H "Authorization: Bearer $NLMCA_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "business_id": "0f6b0d2e-1c3a-4b8e-9d2f-7a1e5c4b3d21",
        "requested_amount": 75000
      }'
    ```

    ```json Response 201 theme={null}
    {
      "data": {
        "id": "3c9d1f70-8e5a-4d26-b1f4-2a7e6c5d4b39",
        "business_id": "0f6b0d2e-1c3a-4b8e-9d2f-7a1e5c4b3d21",
        "business": {
          "id": "0f6b0d2e-1c3a-4b8e-9d2f-7a1e5c4b3d21",
          "legal_name": "ACME Plumbing LLC",
          "dba": "ACME Plumbing"
        },
        "business_name": "ACME Plumbing LLC",
        "requested_amount": 75000,
        "product_type": "mca",
        "paper_grade": null,
        "paper_grade_source": null,
        "status": "new",
        "stage": {
          "id": "2b8c4d6e-0f1a-4b2c-9d3e-4f5a6b7c8d90",
          "label": "New app",
          "phase": "preoffer",
          "sort_order": 0,
          "event": null
        },
        "stage_entered_at": "2026-09-04T14:03:40.000Z",
        "days_in_stage": 0,
        "primary_offer": null,
        "source": "api",
        "submissions_count": 0,
        "offers_count": 0,
        "created_at": "2026-09-04T14:03:40.000Z",
        "updated_at": "2026-09-04T14:03:40.000Z"
      },
      "meta": {}
    }
    ```

    The deal starts in the first stage of the `preoffer` phase (`stage.phase`) and a `deal.created` webhook fires. You can also create the business inline by sending a `business` object instead of `business_id`; duplicate detection applies the same way. An optional `owner` object creates the primary owner or links an existing person matched by email or phone.
  </Step>

  <Step title="Match lenders">
    If you have bank statements, upload them first (see [Documents and uploads](/guides/documents-and-uploads)): once they are analysed, matching uses bank-verified revenue instead of the stated figure. Without them, matching still runs on the application data.

    ```bash theme={null}
    curl "$NLMCA_API/deals/3c9d1f70-8e5a-4d26-b1f4-2a7e6c5d4b39/lender-matches?view=recommended" \
      -H "Authorization: Bearer $NLMCA_KEY"
    ```

    ```json Response 200 theme={null}
    {
      "data": [
        {
          "lender_id": "6a2d9e11-4f0b-4c7d-8e3a-9b1c2d3e4f50",
          "lender_name": "Northwind Capital",
          "score": 88,
          "confidence": "high",
          "recommended": true,
          "eligible": true,
          "auto_eligible": true,
          "disqualify_reasons": [],
          "unknown_gates": [],
          "paper_grades": ["A", "B"],
          "checks": [
            {
              "field": "min_monthly_revenue",
              "label": "Minimum monthly revenue",
              "kind": "gate",
              "criterion": "at least $25,000",
              "deal_value": "$41,200 (bank-verified)",
              "passed": true,
              "skipped": false
            },
            {
              "field": "state",
              "label": "State",
              "kind": "gate",
              "criterion": "not CA, NV",
              "deal_value": "NY",
              "passed": true,
              "skipped": false
            }
          ],
          "explanation": "Northwind Capital funds NY plumbing businesses with $25k+ monthly revenue. This deal clears every gate and scores 88.",
          "approval_rate": 0.62
        },
        {
          "lender_id": "9d4b7c21-0a5e-4f13-9c8d-1e2f3a4b5c67",
          "lender_name": "Harbor Funding",
          "score": 81,
          "confidence": "medium",
          "recommended": true,
          "eligible": true,
          "auto_eligible": false,
          "disqualify_reasons": [],
          "unknown_gates": ["time_in_business"],
          "paper_grades": ["B", "C"],
          "checks": [
            {
              "field": "time_in_business",
              "label": "Time in business",
              "kind": "gate",
              "criterion": "at least 12 months",
              "deal_value": "unknown",
              "passed": true,
              "skipped": true
            }
          ],
          "explanation": "Harbor Funding is a fit on revenue and state; time in business is missing, so confirm it before an automated send.",
          "approval_rate": null
        }
      ],
      "meta": {
        "next_cursor": null,
        "has_more": false,
        "total": 2,
        "recommended_count": 2,
        "eligible_count": 5,
        "matched_at": "2026-09-04T14:05:02.000Z",
        "deal": {
          "paper_grade": null,
          "paper_grade_computed": "B",
          "missing_fields": ["time_in_business"],
          "completeness_percent": 86,
          "threshold": 75
        }
      }
    }
    ```

    `view=recommended` is the shortlist an underwriter would send to: score at or above the location's threshold, with the data to back it. `view=eligible` also includes lenders that pass every hard gate but score lower; `view=all` adds disqualified lenders with their reasons. `auto_eligible` marks matches with no unknown gates, safe for an automated send. `meta.deal.missing_fields` tells you what to collect to raise confidence.
  </Step>

  <Step title="Submit to two lenders">
    Submissions send email, so use an `Idempotency-Key`. A retry with the same key replays the original response instead of emailing the lenders twice.

    ```bash theme={null}
    curl -X POST "$NLMCA_API/deals/3c9d1f70-8e5a-4d26-b1f4-2a7e6c5d4b39/submissions" \
      -H "Authorization: Bearer $NLMCA_KEY" \
      -H "Content-Type: application/json" \
      -H "Idempotency-Key: 5d0c9b8a-7e6f-4d5c-b4a3-2f1e0d9c8b7a" \
      -d '{
        "lender_ids": [
          "6a2d9e11-4f0b-4c7d-8e3a-9b1c2d3e4f50",
          "9d4b7c21-0a5e-4f13-9c8d-1e2f3a4b5c67"
        ],
        "send": true
      }'
    ```

    ```json Response 201 theme={null}
    {
      "data": [
        {
          "id": "b1e2d3c4-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
          "deal_id": "3c9d1f70-8e5a-4d26-b1f4-2a7e6c5d4b39",
          "lender_id": "6a2d9e11-4f0b-4c7d-8e3a-9b1c2d3e4f50",
          "lender_name": "Northwind Capital",
          "status": "queued",
          "response_type": null,
          "response_notes": null,
          "decline_reason": null,
          "decline_category": null,
          "requested_items": [],
          "match_score": 88,
          "match_eligible": true,
          "submitted_by_id": null,
          "submitted_at": null,
          "responded_at": null,
          "created_at": "2026-09-04T14:06:15.000Z",
          "updated_at": "2026-09-04T14:06:15.000Z"
        },
        {
          "id": "c2f3e4d5-6a7b-4c8d-9e0f-1a2b3c4d5e6f",
          "deal_id": "3c9d1f70-8e5a-4d26-b1f4-2a7e6c5d4b39",
          "lender_id": "9d4b7c21-0a5e-4f13-9c8d-1e2f3a4b5c67",
          "lender_name": "Harbor Funding",
          "status": "queued",
          "response_type": null,
          "response_notes": null,
          "decline_reason": null,
          "decline_category": null,
          "requested_items": [],
          "match_score": 81,
          "match_eligible": true,
          "submitted_by_id": null,
          "submitted_at": null,
          "responded_at": null,
          "created_at": "2026-09-04T14:06:15.000Z",
          "updated_at": "2026-09-04T14:06:15.000Z"
        }
      ],
      "meta": { "created": 2, "already_submitted": [], "sending": true }
    }
    ```

    One submission is recorded per lender, with the lender-match score snapshotted as `match_score`, and each comes back as `queued`. A background worker emails it through the location's connected mailbox, sets `submitted_at` and flips the status to `sent` (until then `GET /v1/submissions/{id}` shows `pending`); a `submission.sent` webhook fires per lender when the email goes out. If the location has no connected mailbox the submissions are still recorded, returned with `status: "recorded"` and `meta.warning: "no_email_sender"`, for the team to send from the app. Lenders that already had a submission on the deal are left unchanged and listed in `meta.already_submitted`; lenders without a submissions email are listed in `meta.not_sent`. Pass `"send": false` to record submissions as `pending` without emailing. The first submission also moves the deal to the stage bound to `first_submission_sent` (*Submitted* on the default board).
  </Step>

  <Step title="Read offers">
    Offers appear as lenders respond (`offer.received` webhook) or when someone logs them.

    ```bash theme={null}
    curl "$NLMCA_API/deals/3c9d1f70-8e5a-4d26-b1f4-2a7e6c5d4b39/offers" \
      -H "Authorization: Bearer $NLMCA_KEY"
    ```

    ```json Response 200 theme={null}
    {
      "data": [
        {
          "id": "d3a4b5c6-7e8f-4a9b-8c0d-1e2f3a4b5c6d",
          "deal_id": "3c9d1f70-8e5a-4d26-b1f4-2a7e6c5d4b39",
          "lender_id": "6a2d9e11-4f0b-4c7d-8e3a-9b1c2d3e4f50",
          "lender_name": "Northwind Capital",
          "submission_id": "b1e2d3c4-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
          "amount": 70000,
          "factor_rate": 1.32,
          "buy_rate": null,
          "term": 9,
          "term_unit": "months",
          "payment_frequency": "daily",
          "payment_amount": 488.89,
          "payback_amount": 92400,
          "points": null,
          "commission_estimate": null,
          "position": 1,
          "status": "new_offer",
          "status_name": "New offer",
          "status_type": "open",
          "is_primary": false,
          "is_selected": false,
          "notes": null,
          "decline_reason": null,
          "merchant_response": null,
          "expires_at": null,
          "received_at": "2026-09-05T09:12:44.000Z",
          "accepted_at": null,
          "created_at": "2026-09-05T09:12:44.000Z",
          "updated_at": "2026-09-05T09:12:44.000Z"
        }
      ],
      "meta": { "next_cursor": null, "has_more": false, "primary_offer_id": null }
    }
    ```

    To pick one, call `POST /v1/offers/{id}/primary`. That syncs the deal status to the offer's status, and from then on status changes on that offer (`contracts_requested`, `contracts_out`, `contracts_signed`) move the deal stage through the location's event bindings; `GET /v1/pipeline` shows them. Funding goes through `POST /v1/deals/{id}/stage` with `event: "mark_funded"`, which creates the advance.
  </Step>
</Steps>

## Where next

<CardGroup cols={3}>
  <Card title="Conventions" icon="sliders" href="/guides/conventions">
    Errors, pagination, idempotency and rate limits in detail.
  </Card>

  <Card title="Webhooks" icon="bolt" href="/guides/webhooks">
    Get told when offers arrive instead of polling.
  </Card>

  <Card title="AI-first workflow" icon="wand-magic-sparkles" href="/guides/ai-first-workflow">
    Turn these five calls into an agent.
  </Card>
</CardGroup>


## Related topics

- [Overview](/getting-started/overview.md)
