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

# Create a lead

> Creates a lead + case + plaintiff + initial survey details, pinned to the validated receiving organization (no marketplace routing). leadStatus accepts new_lead (the default) and test_lead; the retired spelling PendingLead is accepted and stored as new_lead. screened_needs_match returns HTTP 400 before creating a lead because marketplace placement is unsupported. Ordinary leads immediately appear in the receiving firm’s Pending Leads and New Leads lists, even without an individual attorney; test leads remain hidden. Legacy partner keys keep working; integration keys require leads:write.

Requires the `leads:write` scope. Legacy partner API keys and OIDC bearer tokens are also accepted on this endpoint (shipped behavior, unchanged); integration keys are scope-enforced. Rate tier: `write`.



## OpenAPI

````yaml /openapi.json post /api/v1/leads
openapi: 3.1.0
info:
  title: Grand Charter Public API
  version: 1.0.0
  description: >-
    Org-scoped integration API for the Grand Charter legal platform.


    Authenticate every request with an integration API key in the `x-api-key`
    header. Keys are created in the attorney portal under **Settings →
    Integrations → API Credentials** (or by platform admins) and carry an
    explicit list of scopes; each operation below names its required scope
    (`x-required-scope`).


    Conventions: JSON bodies/responses in camelCase; money in integer cents;
    ISO-8601 UTC timestamps; keyset cursor pagination (`after`, `limit` →
    `nextCursor`); errors use `{ success: false, error, code }`.


    Idempotency: most mutations require an `X-Idempotency-Key` header — each
    operation description below says so explicitly. Exceptions that do NOT
    consume the header (retrying them can create duplicates): `POST /leads`,
    `PATCH /leads/{leadId}`, and `PATCH /cases/{caseId}`.
servers:
  - url: https://www.presolve.com
    description: Production
security:
  - integrationApiKey: []
tags:
  - name: Platform
  - name: Org & Team
  - name: Cases
  - name: Leads
  - name: Clients
  - name: Contacts
  - name: Documents
  - name: Notes
  - name: Tasks
  - name: Calendar
  - name: Deadlines
  - name: Intake
  - name: E-Sign
  - name: Billing
  - name: Settlement Funds
  - name: Referrals
  - name: Communications
  - name: Medical
  - name: Reports & Exports
  - name: Events & Webhooks
paths:
  /api/v1/leads:
    post:
      tags:
        - Leads
      summary: Create a lead
      description: >-
        Creates a lead + case + plaintiff + initial survey details, pinned to
        the validated receiving organization (no marketplace routing).
        leadStatus accepts new_lead (the default) and test_lead; the retired
        spelling PendingLead is accepted and stored as new_lead.
        screened_needs_match returns HTTP 400 before creating a lead because
        marketplace placement is unsupported. Ordinary leads immediately appear
        in the receiving firm’s Pending Leads and New Leads lists, even without
        an individual attorney; test leads remain hidden. Legacy partner keys
        keep working; integration keys require leads:write.


        Requires the `leads:write` scope. Legacy partner API keys and OIDC
        bearer tokens are also accepted on this endpoint (shipped behavior,
        unchanged); integration keys are scope-enforced. Rate tier: `write`.
      operationId: post_leads
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LegacyLeadCreateBody'
      responses:
        '201':
          description: '{ success: true, leadId, caseId }'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '400':
          description: Validation failed (VALIDATION_FAILED).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Missing, invalid, or expired API key (UNAUTHORIZED).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: API key lacks the required scope (FORBIDDEN).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Resource not found in the caller’s organization (NOT_FOUND).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: >-
            Conflict: invalid state transition, duplicate entry, stale revision,
            or idempotency conflict.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Rate limit exceeded (RATE_LIMITED). Honor Retry-After.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - integrationApiKey: []
components:
  schemas:
    LegacyLeadCreateBody:
      type: object
      properties:
        caseType:
          type: string
        description:
          type: string
          description: Required narrative, including when lemonLaw is supplied.
        surveyDetails:
          type: object
          additionalProperties:
            anyOf:
              - type: string
              - type: number
              - type: boolean
              - type: 'null'
          description: >-
            Intake answers keyed by accessor (max 200 keys). Null-valued entries
            are skipped. Do not duplicate an accessor supplied through lemonLaw,
            even with the same value.
        lemonLaw:
          $ref: '#/components/schemas/PartnerLemonLaw'
        firstName:
          type: string
        lastName:
          type: string
        email:
          type: string
        phone:
          type: string
        zipCode:
          type: string
        city:
          type: string
        state:
          type: string
      required:
        - description
        - firstName
        - lastName
        - email
        - phone
        - zipCode
        - city
        - state
      additionalProperties: {}
      description: >-
        Other legacy lead properties retain their existing imperative
        validation; see docs/api/v1-public-api.md.
    SuccessEnvelope:
      type: object
      properties:
        success:
          type: boolean
          const: true
      required:
        - success
      additionalProperties: {}
    ErrorResponse:
      type: object
      properties:
        success:
          type: boolean
          const: false
        error:
          type: string
          description: >-
            Human-readable error message. 5xx responses are always scrubbed to
            "Internal server error".
        code:
          type: string
          description: >-
            Stable machine-readable error code (ErrorCode), e.g. UNAUTHORIZED,
            FORBIDDEN, VALIDATION_FAILED, NOT_FOUND, INVALID_STATE_TRANSITION,
            DUPLICATE_ENTRY, STALE_REVISION, IDEMPOTENCY_IN_PROGRESS,
            IDEMPOTENCY_CONFLICT, RATE_LIMITED, INTERNAL_ERROR.
      required:
        - success
        - error
        - code
    PartnerLemonLaw:
      type: object
      properties:
        make:
          type: string
          minLength: 1
          maxLength: 200
        model:
          type: string
          minLength: 1
          maxLength: 200
        year:
          type: integer
          minimum: 1900
          maximum: 2100
        vin:
          type: string
          pattern: ^[A-HJ-NPR-Z0-9]{17}$
        vehicleType:
          type: string
          enum:
            - New
            - Used
            - New, purchased from dealership
            - Used, purchased from dealership
            - Used, purchased from private party
            - Certified Pre-Owned
            - Leased Vehicle
            - Not sure
        purchaseType:
          type: string
          enum:
            - purchase
            - lease
            - cpo
            - used-dealer
        purchaseState:
          type: string
          enum:
            - AL
            - AK
            - AZ
            - AR
            - CA
            - CO
            - CT
            - DE
            - DC
            - FL
            - GA
            - HI
            - ID
            - IL
            - IN
            - IA
            - KS
            - KY
            - LA
            - ME
            - MD
            - MA
            - MI
            - MN
            - MS
            - MO
            - MT
            - NE
            - NV
            - NH
            - NJ
            - NM
            - NY
            - NC
            - ND
            - OH
            - OK
            - OR
            - PA
            - RI
            - SC
            - SD
            - TN
            - TX
            - UT
            - VT
            - VA
            - WA
            - WV
            - WI
            - WY
          description: Two-letter US state or DC abbreviation; normalized to uppercase.
        purchaseDate:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}$
          description: >-
            Purchase/delivery date, YYYY-MM-DD; shown as Delivery date in the
            Lemon Law tab.
        acquisitionMonth:
          type: string
          pattern: ^(?!0000)(\d{4})-(0[1-9]|1[0-2])$
        dealerName:
          type: string
          minLength: 1
          maxLength: 200
        lienholderName:
          type: string
          minLength: 1
          maxLength: 200
        warranty:
          type: string
          enum:
            - Yes, full manufacturer warranty
            - Yes, extended warranty
            - No, out of warranty
            - Not sure
        repairAttempts:
          anyOf:
            - type: integer
              minimum: 0
              maximum: 2147483647
            - type: string
              enum:
                - None
                - '1'
                - '2'
                - '3'
                - 4 or more
          description: >-
            Reported attempts for the same issue, as a nonnegative integer or
            one of "None", "1", "2", "3", "4 or more". Exact counts prefill
            repair totals; the "4 or more" band stays reported text and may
            inform phase triage using its lower bound.
        issues:
          type: string
          minLength: 1
          maxLength: 10000
        vehicleStatus:
          type: string
          enum:
            - Still driving it with issues
            - At dealership or shop
            - Repaired, but issue returned
            - Repaired and resolved
            - Sold it or returned to dealer
            - Totaled or not drivable
        firstRepairDate:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}$
        firstRepairMileage:
          type: integer
          minimum: 0
          maximum: 2147483647
        daysOutOfService:
          type: integer
          minimum: 0
          maximum: 2147483647
        currentMileage:
          type: integer
          minimum: 0
          maximum: 2147483647
          description: Used to prefill the client intake questionnaire.
        purchaseMileage:
          type: integer
          minimum: 0
          maximum: 2147483647
          description: Used to prefill the client intake questionnaire.
        businessUse:
          type: string
          enum:
            - personal
            - business
            - mixed
        safetyDefect:
          type: string
          enum:
            - 'yes'
            - 'no'
            - unknown
        soldOrTraded:
          type: string
          enum:
            - 'yes'
            - 'no'
            - unknown
        soldOrTradedNotes:
          type: string
          minLength: 1
          maxLength: 10000
      additionalProperties: false
      description: >-
        Optional structured Lemon Law intake. Requires effective caseType "Lemon
        Law"; PATCH may inherit the stored case type. Supplied fields overwrite
        canonical survey answers and take precedence over client-derived values.
        Omitted fields are preserved. Nulls, blanks, unknown fields, and
        overlapping surveyDetails accessors return HTTP 400. Use surveyDetails
        for intentional blanks.
  securitySchemes:
    integrationApiKey:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        Org-issued integration API key (service account credential). The
        plaintext secret is shown once at creation.

````