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

# Extract recurring-invoice terms from a contract

> Upload a contract as a PDF or image — PNG, JPEG, GIF, or WebP (multipart/form-data, field name 'file') — and get back the recurring-billing terms (customer, currency, cadence, start date, line items) as NAMES — this does not create anything. Resolve the names to ids (customers, products, tax rates) and POST /recurring-invoices to create the schedule. Required fields the contract omits are listed in missingFields; currency falls back to the organisation default. Admin-gated. Max 5 MB.



## OpenAPI

````yaml /api-reference/openapi.json post /recurring-invoices/from-contract
openapi: 3.1.1
info:
  title: Dolfin API
  description: >-
    Dolfin API for AR & AP. Authenticate using the `x-dolfin-api-key` header
    with the API key distributed to your organisation.
  version: v1
servers:
  - url: https://api.dolfinai.co
    description: Production
security:
  - {}
tags:
  - name: Webhooks
  - name: Users
  - name: TaxRates
  - name: Suppliers
  - name: Supplier Credit Notes
  - name: Bills
  - name: SpendCategories
  - name: Payables
  - name: RecurringInvoices
  - name: Receivables
  - name: Purchase Orders
  - name: Products
  - name: Payments
  - name: Invoices
  - name: Organisations
  - name: Members
  - name: MCP
  - name: Matching
  - name: Invoice Reminders
  - name: Industries
  - name: Gmail
  - name: Delivery Notes
  - name: Customers
  - name: Currencies
  - name: Credit Notes
  - name: Clients
  - name: ClientInvites
  - name: BankPayments
  - name: Bank details
  - name: Auth
  - name: ApprovalPolicies
  - name: ApiKeys
  - name: Agent
paths:
  /recurring-invoices/from-contract:
    post:
      tags:
        - RecurringInvoices
      summary: Extract recurring-invoice terms from a contract
      description: >-
        Upload a contract as a PDF or image — PNG, JPEG, GIF, or WebP
        (multipart/form-data, field name 'file') — and get back the
        recurring-billing terms (customer, currency, cadence, start date, line
        items) as NAMES — this does not create anything. Resolve the names to
        ids (customers, products, tax rates) and POST /recurring-invoices to
        create the schedule. Required fields the contract omits are listed in
        missingFields; currency falls back to the organisation default.
        Admin-gated. Max 5 MB.
      requestBody:
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                file:
                  $ref: '#/components/schemas/IFormFile'
        required: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExtractedContractTerms'
        '400':
          description: >-
            Contract.TooLarge — the contract exceeds the 5 MB upload limit


            Contract.ExtractionFailed — the document was empty, an unsupported
            file type, unreadable, or yielded no schedule fields
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: >-
            Organisation.InsufficientRole — caller's organisation role is below
            the level this action requires
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
components:
  schemas:
    IFormFile:
      type: string
      format: binary
    ExtractedContractTerms:
      type: object
      properties:
        customerName:
          type:
            - 'null'
            - string
        customerEmail:
          type:
            - 'null'
            - string
        currency:
          type:
            - 'null'
            - string
        memo:
          type:
            - 'null'
            - string
        startDate:
          type:
            - 'null'
            - string
          format: date-time
        cadence:
          oneOf:
            - type: 'null'
            - $ref: '#/components/schemas/RecurrenceCadence'
        totalOccurrences:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
            - 'null'
            - integer
            - string
          format: int32
        lineItems:
          type: array
          items:
            $ref: '#/components/schemas/ExtractedContractLineItem'
        sourceQuotes:
          type: object
          additionalProperties:
            type: string
        confidence:
          type: object
          additionalProperties:
            pattern: ^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$
            type:
              - number
              - string
            format: double
        missingFields:
          type: array
          items:
            type: string
    ProblemDetails:
      type: object
      properties:
        type:
          type:
            - 'null'
            - string
        title:
          type:
            - 'null'
            - string
        status:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
            - 'null'
            - integer
            - string
          format: int32
        detail:
          type:
            - 'null'
            - string
        instance:
          type:
            - 'null'
            - string
    RecurrenceCadence:
      enum:
        - Weekly
        - Monthly
        - Quarterly
        - Annually
    ExtractedContractLineItem:
      type: object
      properties:
        productName:
          type:
            - 'null'
            - string
        quantity:
          pattern: ^-?(?:0|[1-9]\d*)(?:\.\d+)?$
          type:
            - 'null'
            - number
            - string
          format: double
        unitPriceOverride:
          pattern: ^-?(?:0|[1-9]\d*)(?:\.\d+)?$
          type:
            - 'null'
            - number
            - string
          format: double
        taxRateName:
          type:
            - 'null'
            - string

````