> ## 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.

# Set the primary offer

> **Side effects:** makes this the deal’s primary offer (any other primary is cleared), syncs the deal status to this offer’s status, and from then on status changes on this offer drive the deal stage according to the location’s event bindings (contracts requested → sent → signed → funded). If CRM opportunity sync is enabled for the location, the offer is also pushed to the CRM pipeline. `meta.deal_status` reports the resulting deal status. Idempotent.



## OpenAPI

````yaml /openapi/public-v1.json post /v1/offers/{id}/primary
openapi: 3.0.0
info:
  title: NextLevel MCA Public API
  description: >-
    REST API for the NextLevel MCA deal platform. Objects flow Businesses →
    People → Deals → Submissions → Offers → Advances.


    **Authentication.** Send `Authorization: Bearer <key>` with an API key
    (`nlmca_live_…`, created in Settings → Developers) or an OAuth access token.
    Keys are scoped to one location.


    **Conventions.** JSON only. Cursor pagination (`limit` ≤ 100, `cursor` from
    `meta.next_cursor`). Every success is `{ data, meta }`; every error is `{
    error: { type, message, code, param, request_id } }`. POST endpoints accept
    `Idempotency-Key` (24h replay). Rate limit 300 requests/min per credential
    (`X-RateLimit-*` headers).


    **Scopes.** Keys with no scopes have all of them. Otherwise:

    - `businesses:read` — Read businesses and their notes, tasks and activity

    - `businesses:write` — Create and update businesses, notes and tasks

    - `people:read` — Read people (contacts and owners)

    - `people:write` — Create and update people

    - `deals:read` — Read deals, submissions and the pipeline

    - `deals:write` — Create and update deals, move stages

    - `documents:read` — Read documents and statement analysis

    - `documents:write` — Upload documents and request documents from merchants

    - `lenders:read` — Read lenders, criteria and lender matches

    - `lenders:write` — Create and update lenders and criteria

    - `submissions:write` — Submit deals to lenders and withdraw submissions

    - `offers:read` — Read offers

    - `offers:write` — Log and update offers, set the primary offer

    - `advances:read` — Read funded advances and renewal flags

    - `advances:write` — Update advances

    - `portal:send` — Generate and send merchant portal links

    - `webhooks:manage` — Manage webhook subscriptions
  version: '1.0'
  contact: {}
servers:
  - url: https://api.nextlevelmca.com
    description: Production
security:
  - bearer: []
tags:
  - name: Businesses
    description: Merchant businesses and their notes, tasks and activity
  - name: People
    description: Contacts and owners. Phone lookups normalise to E.164.
  - name: Deals
    description: Deals, stage moves, renewals and the pipeline
  - name: Documents
    description: Documents, presigned uploads, document requests and statement analysis
  - name: Lenders
    description: Lenders and their criteria
  - name: Lender matches
    description: Criteria-driven lender matching for a deal
  - name: Submissions
    description: Sending deals to lenders
  - name: Offers
    description: Lender offers and the primary offer
  - name: Advances
    description: Funded advances and renewal readiness
  - name: Merchant portal
    description: Magic links for the merchant portal
  - name: Webhooks
    description: Outbound event subscriptions
paths:
  /v1/offers/{id}/primary:
    post:
      tags:
        - Offers
      summary: Set the primary offer
      description: >-
        **Side effects:** makes this the deal’s primary offer (any other primary
        is cleared), syncs the deal status to this offer’s status, and from then
        on status changes on this offer drive the deal stage according to the
        location’s event bindings (contracts requested → sent → signed →
        funded). If CRM opportunity sync is enabled for the location, the offer
        is also pushed to the CRM pipeline. `meta.deal_status` reports the
        resulting deal status. Idempotent.
      operationId: offers_setPrimary
      parameters:
        - name: id
          required: true
          in: path
          description: Offer id
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                  - data
                  - meta
                properties:
                  data:
                    $ref: '#/components/schemas/OfferDto'
                  meta:
                    $ref: '#/components/schemas/EmptyMetaDto'
        '401':
          description: Missing, invalid, expired or revoked credential.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelopeDto'
        '403':
          description: Credential lacks the scope, or the role lacks the permission.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelopeDto'
        '404':
          description: Resource not found in this location.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelopeDto'
        '429':
          description: Rate limit exceeded. See `X-RateLimit-*` and `Retry-After`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelopeDto'
      security:
        - bearer: []
components:
  schemas:
    OfferDto:
      type: object
      properties:
        id:
          type: string
          description: Offer id.
        deal_id:
          type: string
          description: Deal the offer is for.
        lender_id:
          type: string
          description: Lender that made the offer.
        lender_name:
          type: string
          nullable: true
          description: Lender name at read time.
        submission_id:
          type: string
          nullable: true
          description: Submission the offer answers, when linked.
        amount:
          type: number
          description: Funded amount offered, USD.
        factor_rate:
          type: number
          nullable: true
          description: Factor rate, e.g. `1.35`.
        buy_rate:
          type: number
          nullable: true
          description: Buy rate (the lender’s rate before commission).
        term:
          type: number
          description: Term length in `term_unit`.
        term_unit:
          type: string
          nullable: true
          enum:
            - days
            - weeks
            - months
          description: Unit of `term`.
        payment_frequency:
          type: string
          nullable: true
          enum:
            - daily
            - weekly
            - bi-weekly
            - monthly
          description: Payment cadence.
        payment_amount:
          type: number
          nullable: true
          description: Amount per payment.
        payback_amount:
          type: number
          nullable: true
          description: Total payback. Computed as amount × factor_rate when not given.
        points:
          type: number
          nullable: true
          description: Commission points (percentage of the funded amount).
        commission_estimate:
          type: number
          nullable: true
          description: amount × points / 100, when both are known.
        position:
          type: number
          nullable: true
          description: Position the advance would take (1 = first position).
        status:
          type: string
          nullable: true
          description: >-
            Status slug from the location’s offer statuses, e.g. `new_offer`,
            `waiting_on_stips`, `sold`, `contracts_requested`, `contracts_out`,
            `contracts_signed`, `funded`.
        status_name:
          type: string
          nullable: true
          description: Human name of the status.
        status_type:
          type: string
          nullable: true
          enum:
            - open
            - won
            - lost
          description: '`open` = still in play, `won` = funded, `lost` = declined / failed.'
        is_primary:
          type: boolean
          description: >-
            True for the deal’s primary offer (the one that drives the deal
            status and stage).
        is_selected:
          type: boolean
          description: True when the team is actively pursuing this offer.
        notes:
          type: string
          nullable: true
          description: Free-text notes.
        decline_reason:
          type: string
          nullable: true
          description: Decline reason slug when the offer was declined.
        merchant_response:
          type: string
          nullable: true
          description: >-
            Whether the merchant accepted or declined the offer in the portal:
            `accepted`, `declined`.
        expires_at:
          type: string
          nullable: true
          description: When the offer expires (ISO 8601).
        received_at:
          type: string
          nullable: true
          description: When the offer was received (ISO 8601).
        accepted_at:
          type: string
          nullable: true
          description: When the offer was accepted / funded (ISO 8601).
        created_at:
          type: string
          description: Creation time (ISO 8601).
        updated_at:
          type: string
          nullable: true
          description: Last update time (ISO 8601).
      required:
        - id
        - deal_id
        - lender_id
        - lender_name
        - submission_id
        - amount
        - factor_rate
        - buy_rate
        - term
        - term_unit
        - payment_frequency
        - payment_amount
        - payback_amount
        - points
        - commission_estimate
        - position
        - status
        - status_name
        - status_type
        - is_primary
        - is_selected
        - notes
        - decline_reason
        - merchant_response
        - expires_at
        - received_at
        - accepted_at
        - created_at
        - updated_at
    EmptyMetaDto:
      type: object
      properties: {}
    ErrorEnvelopeDto:
      type: object
      properties:
        error:
          $ref: '#/components/schemas/PublicErrorDto'
      required:
        - error
    PublicErrorDto:
      type: object
      properties:
        type:
          type: string
          enum:
            - validation_error
            - authentication_error
            - permission_error
            - not_found
            - conflict
            - rate_limit_error
            - api_error
        message:
          type: string
          description: Human-readable explanation, safe to show to an operator or an agent.
        code:
          type: string
          description: >-
            Stable machine-readable code, e.g. `missing_scope`,
            `duplicate_business`.
        param:
          type: string
          description: Request field the error refers to, when applicable.
        request_id:
          type: string
          description: Echo of the `X-Request-Id` header. Quote it when contacting support.
      required:
        - type
        - message
        - request_id
  securitySchemes:
    bearer:
      scheme: bearer
      bearerFormat: API key or JWT
      type: http
      description: API key (`nlmca_live_…`) or OAuth access token

````

## Related topics

- [Authentication](/getting-started/authentication.md)
- [MCP server](/mcp/overview.md)
- [Connect from ChatGPT](/mcp/connect-from-chatgpt.md)
