---
openapi: 3.0.3
info:
  title: Clio Accounting API
  version: v1
  description: |
    # Developer Support and Feedback
    * Clio takes the availability and stability of our API seriously; please report any **degradations** or **breakages** to Clio Accounting's API Support team at [api@clio.com](mailto:api@clio.com).
    * For business and partnership inquiries, contact our API Partnerships team at [api.partnerships@clio.com](mailto:api.partnerships@clio.com).
    * For best practices and tips from the Clio development community, join the conversation in the [Clio Developer Slack Channel](https://join.slack.com/t/clio-public/shared_invite/zt-36i0eqgo1-7POORPtMJpp2N0~_auL2IQ).

    # Getting Started
    > **Note:** Clio Accounting is available in the **US region only**. Every request goes to a single base URL,
    > `https://api.clio.com/accounting`. There are no region-specific endpoints.

    Public REST API for the Clio Accounting service. Every path below is relative to that base URL, and all
    endpoints serve JSON.

    ## Authentication
    Authenticate with an OAuth 2.0 bearer token (`Authorization: Bearer <jwt>`) issued through the Clio API Hub.
    Pass the OpenAPI version with `X-API-Version: YYYY-MM-DD` to pin a specific contract, or `unstable` to opt
    in to the latest spec.

    ## Responses
    Successful responses use `{ "data": ... }` envelopes (with `{ "meta": { "paging": ... } }`
    on paginated collections). Errors use `{ "error": { "status": "<code>", "message": "..." } }`.
  contact:
    name: Clio Accounting API Support
    email: api@clio.com
  x-logo:
    url: https://www.clio.com/wp-content/uploads/2015/05/Container-5-Logo.png
  license:
    name: Proprietary
    url: https://www.clio.com/terms/
servers:
- url: https://api.clio.com/accounting
  description: US region Production Server
tags:
- name: Account
  description: Operations for the authenticated firm's account
- name: Users
  description: Operations for managing users on the authenticated firm's account
- name: Journal Entries
  description: Operations for journal entries on the authenticated firm's account
- name: Ledger Accounts
  description: Operations for the firm's ledger accounts
- name: Ledger Account Types
  description: Operations for the firm's ledger account types
- name: Vendor Bills
  description: Operations for the firm's vendor bills
- name: Vendor Bill Payments
  description: Operations for the firm's vendor bill payments
- name: Reports
  description: Operations for generating and downloading the firm's reports
- name: Vendors
  description: Operations for the firm's vendors
- name: Matters
  description: Operations for the firm's matters
- name: Clients
  description: Operations for the firm's clients
- name: Expenses
  description: Operations for the firm's expenses
paths:
  "/account":
    get:
      operationId: getAccount
      summary: Retrieve the authenticated firm's account
      tags:
      - Account
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      responses:
        '200':
          description: The authenticated firm's account
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/AccountResource"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
  "/users":
    get:
      operationId: listUsers
      summary: List users on the authenticated firm's account
      tags:
      - Users
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          minimum: 1
          maximum: 200
          default: 25
      - name: page_token
        in: query
        required: false
        description: Opaque token for cursor-based pagination. Pass back the value
          from `meta.paging.next` to fetch the next page.
        schema:
          type: string
      - name: email
        in: query
        required: false
        description: Filter users by email address (exact match). An unrecognized
          or malformed address returns an empty collection rather than an error.
        schema:
          type: string
      responses:
        '200':
          description: A paginated list of users
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/UserCollection"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
  "/users/{id}":
    get:
      operationId: getUser
      summary: Retrieve a user by ID
      tags:
      - Users
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - name: id
        in: path
        required: true
        schema:
          "$ref": "#/components/schemas/ResourceId"
      responses:
        '200':
          description: A single user
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/UserResource"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '404':
          "$ref": "#/components/responses/NotFoundResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
  "/journal_entries":
    get:
      operationId: listJournalEntries
      summary: List journal entries on the authenticated firm's account
      tags:
      - Journal Entries
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          minimum: 1
          maximum: 200
          default: 25
      - name: page_token
        in: query
        required: false
        description: Opaque token for cursor-based pagination. Pass back the value
          from `meta.paging.next` to fetch the next page.
        schema:
          type: string
      - name: date_from
        in: query
        required: false
        description: Only return entries on or after this date (inclusive).
        schema:
          type: string
          format: date
      - name: date_to
        in: query
        required: false
        description: Only return entries on or before this date (inclusive).
        schema:
          type: string
          format: date
      responses:
        '200':
          description: A paginated list of journal entries
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/JournalEntryCollection"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
    post:
      operationId: createJournalEntry
      summary: Create a journal entry on the authenticated firm's account
      tags:
      - Journal Entries
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - "$ref": "#/components/parameters/IdempotencyKeyHeader"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/JournalEntryCreateRequest"
      responses:
        '201':
          description: The created journal entry
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/JournalEntryResource"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '422':
          "$ref": "#/components/responses/UnprocessableEntityResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
  "/journal_entries/{id}":
    get:
      operationId: getJournalEntry
      summary: Retrieve a journal entry by ID
      tags:
      - Journal Entries
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - name: id
        in: path
        required: true
        schema:
          "$ref": "#/components/schemas/ResourceId"
      responses:
        '200':
          description: A single journal entry
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/JournalEntryResource"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '404':
          "$ref": "#/components/responses/NotFoundResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
    patch:
      operationId: updateJournalEntry
      summary: Update a journal entry by ID
      tags:
      - Journal Entries
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - name: id
        in: path
        required: true
        schema:
          "$ref": "#/components/schemas/ResourceId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/JournalEntryUpdateRequest"
      responses:
        '200':
          description: The updated journal entry
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/JournalEntryResource"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '404':
          "$ref": "#/components/responses/NotFoundResponse"
        '422':
          "$ref": "#/components/responses/UnprocessableEntityResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
    delete:
      operationId: deleteJournalEntry
      summary: Delete a journal entry by ID
      description: Soft-deletes the journal entry. The entry is marked deleted rather
        than removed from the database.
      tags:
      - Journal Entries
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - name: id
        in: path
        required: true
        schema:
          "$ref": "#/components/schemas/ResourceId"
      responses:
        '204':
          description: The journal entry was deleted. No content is returned.
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '404':
          "$ref": "#/components/responses/NotFoundResponse"
        '422':
          "$ref": "#/components/responses/UnprocessableEntityResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
  "/ledger_accounts":
    get:
      operationId: listLedgerAccounts
      summary: List ledger accounts on the authenticated firm's account
      tags:
      - Ledger Accounts
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          minimum: 1
          maximum: 200
          default: 25
      - name: page_token
        in: query
        required: false
        description: Opaque token for cursor-based pagination. Pass back the value
          from `meta.paging.next` to fetch the next page.
        schema:
          type: string
      - name: status
        in: query
        required: false
        description: Filter by account status. When omitted, only active accounts
          are returned.
        schema:
          type: string
          enum:
          - active
          - inactive
      - name: kind
        in: query
        required: false
        description: Filter by account kind.
        schema:
          type: string
          enum:
          - operating
          - trust
      - name: ledger_type
        in: query
        required: false
        description: Filter by ledger type.
        schema:
          type: string
          enum:
          - default
          - bank
          - accounts_receivable
          - accounts_payable
          - expense
          - undeposited_funds
          - fixed
          - trust_liability
          - income
          - trust_clearing
      responses:
        '200':
          description: A paginated list of ledger accounts
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/LedgerAccountCollection"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
    post:
      operationId: createLedgerAccount
      summary: Create a ledger account on the authenticated firm's account
      tags:
      - Ledger Accounts
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/LedgerAccountCreateRequest"
      responses:
        '201':
          description: The created ledger account
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/LedgerAccountResource"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '422':
          "$ref": "#/components/responses/UnprocessableEntityResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
  "/ledger_accounts/{id}":
    get:
      operationId: getLedgerAccount
      summary: Retrieve a ledger account by ID
      tags:
      - Ledger Accounts
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - name: id
        in: path
        required: true
        schema:
          "$ref": "#/components/schemas/ResourceId"
      responses:
        '200':
          description: A single ledger account
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/LedgerAccountResource"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '404':
          "$ref": "#/components/responses/NotFoundResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
    patch:
      operationId: updateLedgerAccount
      summary: Update a ledger account by ID
      tags:
      - Ledger Accounts
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - name: id
        in: path
        required: true
        schema:
          "$ref": "#/components/schemas/ResourceId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/LedgerAccountUpdateRequest"
      responses:
        '200':
          description: The updated ledger account
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/LedgerAccountResource"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '404':
          "$ref": "#/components/responses/NotFoundResponse"
        '422':
          "$ref": "#/components/responses/UnprocessableEntityResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
  "/ledger_account_types":
    get:
      operationId: listLedgerAccountTypes
      summary: List ledger account types on the authenticated firm's account
      tags:
      - Ledger Account Types
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          minimum: 1
          maximum: 200
          default: 25
      - name: page_token
        in: query
        required: false
        schema:
          type: string
      - name: primary_type
        in: query
        required: false
        schema:
          type: string
          enum:
          - unknown
          - asset
          - liability
          - equity
          - income
          - expense
      - name: ledger_type
        in: query
        required: false
        schema:
          type: string
          enum:
          - default
          - bank
          - accounts_receivable
          - accounts_payable
          - expense
          - undeposited_funds
          - fixed
          - trust_liability
          - income
          - trust_clearing
      - name: bank_feed_connectable
        in: query
        required: false
        schema:
          type: boolean
      - name: reconcilable
        in: query
        required: false
        schema:
          type: boolean
      responses:
        '200':
          description: A paginated list of ledger account types
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/LedgerAccountTypeCollection"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
  "/ledger_account_types/{id}":
    get:
      operationId: getLedgerAccountType
      summary: Retrieve a ledger account type by ID
      tags:
      - Ledger Account Types
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - name: id
        in: path
        required: true
        schema:
          "$ref": "#/components/schemas/ResourceId"
      responses:
        '200':
          description: A single ledger account type
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/LedgerAccountTypeResource"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '404':
          "$ref": "#/components/responses/NotFoundResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
  "/vendor_bills":
    get:
      operationId: listVendorBills
      summary: List vendor bills on the authenticated firm's account
      tags:
      - Vendor Bills
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          minimum: 1
          maximum: 200
          default: 25
      - name: page_token
        in: query
        required: false
        description: Opaque token for cursor-based pagination. Pass back the value
          from `meta.paging.next` to fetch the next page.
        schema:
          type: string
      - name: status
        in: query
        required: false
        description: Filter by bill status.
        schema:
          type: string
          enum:
          - draft
          - posted
          - partially_paid
          - paid
      responses:
        '200':
          description: A paginated list of vendor bills
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/VendorBillCollection"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
    post:
      operationId: createVendorBill
      summary: Create a vendor bill on the authenticated firm's account
      tags:
      - Vendor Bills
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - "$ref": "#/components/parameters/IdempotencyKeyHeader"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/VendorBillCreateRequest"
      responses:
        '201':
          description: The created vendor bill
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/VendorBillResource"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '422':
          "$ref": "#/components/responses/UnprocessableEntityResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
  "/vendor_bills/{id}":
    get:
      operationId: getVendorBill
      summary: Retrieve a vendor bill by ID
      tags:
      - Vendor Bills
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - name: id
        in: path
        required: true
        schema:
          "$ref": "#/components/schemas/ResourceId"
      responses:
        '200':
          description: A single vendor bill
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/VendorBillResource"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '404':
          "$ref": "#/components/responses/NotFoundResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
    patch:
      operationId: updateVendorBill
      summary: Update a vendor bill by ID
      tags:
      - Vendor Bills
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - name: id
        in: path
        required: true
        schema:
          "$ref": "#/components/schemas/ResourceId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/VendorBillUpdateRequest"
      responses:
        '200':
          description: The updated vendor bill
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/VendorBillResource"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '404':
          "$ref": "#/components/responses/NotFoundResponse"
        '422':
          "$ref": "#/components/responses/UnprocessableEntityResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
    delete:
      operationId: deleteVendorBill
      summary: Delete a vendor bill by ID
      description: Soft-deletes the vendor bill. The bill is marked deleted rather
        than removed from the database.
      tags:
      - Vendor Bills
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - name: id
        in: path
        required: true
        schema:
          "$ref": "#/components/schemas/ResourceId"
      responses:
        '204':
          description: The vendor bill was deleted. No content is returned.
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '404':
          "$ref": "#/components/responses/NotFoundResponse"
        '422':
          "$ref": "#/components/responses/UnprocessableEntityResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
  "/vendor_bill_payments":
    get:
      operationId: listVendorBillPayments
      summary: List vendor bill payments on the authenticated firm's account
      tags:
      - Vendor Bill Payments
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          minimum: 1
          maximum: 200
          default: 25
      - name: page_token
        in: query
        required: false
        description: Opaque token for cursor-based pagination. Pass back the value
          from `meta.paging.next` to fetch the next page.
        schema:
          type: string
      responses:
        '200':
          description: A paginated list of vendor bill payments
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/VendorBillPaymentCollection"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
    post:
      operationId: createVendorBillPayment
      summary: Create a vendor bill payment on the authenticated firm's account
      tags:
      - Vendor Bill Payments
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - "$ref": "#/components/parameters/IdempotencyKeyHeader"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/VendorBillPaymentCreateRequest"
      responses:
        '201':
          description: The created vendor bill payment
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/VendorBillPaymentResource"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '422':
          "$ref": "#/components/responses/UnprocessableEntityResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
  "/vendor_bill_payments/{id}":
    get:
      operationId: getVendorBillPayment
      summary: Retrieve a vendor bill payment by ID
      tags:
      - Vendor Bill Payments
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - name: id
        in: path
        required: true
        schema:
          "$ref": "#/components/schemas/ResourceId"
      responses:
        '200':
          description: A single vendor bill payment
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/VendorBillPaymentResource"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '404':
          "$ref": "#/components/responses/NotFoundResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
    delete:
      operationId: deleteVendorBillPayment
      summary: Void a vendor bill payment by ID
      description: Voids (soft-deletes) the vendor bill payment. The payment is marked
        deleted rather than removed from the database, releasing the amounts it had
        applied to the associated bills.
      tags:
      - Vendor Bill Payments
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - name: id
        in: path
        required: true
        schema:
          "$ref": "#/components/schemas/ResourceId"
      responses:
        '204':
          description: The vendor bill payment was deleted. No content is returned.
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '404':
          "$ref": "#/components/responses/NotFoundResponse"
        '422':
          "$ref": "#/components/responses/UnprocessableEntityResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
  "/reports":
    get:
      operationId: listReports
      summary: List reports on the authenticated firm's account
      tags:
      - Reports
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          minimum: 1
          maximum: 200
          default: 25
      - name: page_token
        in: query
        required: false
        description: Opaque token for cursor-based pagination. Pass back the value
          from `meta.paging.next` to fetch the next page.
        schema:
          type: string
      - name: kind
        in: query
        required: false
        description: Filter by report kind.
        schema:
          type: string
          enum:
          - balance_sheet
          - general_ledger
          - income_statement
      - name: state
        in: query
        required: false
        description: Filter by generation state.
        schema:
          type: string
          enum:
          - queued
          - in_progress
          - completed
          - errored
          - timed_out
      responses:
        '200':
          description: A paginated list of reports
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ReportCollection"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
    post:
      operationId: createReport
      summary: Request generation of a report on the authenticated firm's account
      description: 'Enqueues generation of a report and returns it in the `queued`
        state. Report generation is asynchronous: poll `GET /reports/{id}` until `state`
        reaches a terminal value (`completed`, `errored`, or `timed_out`). Once `completed`,
        the resource carries a short-lived signed `download_url`.'
      tags:
      - Reports
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - "$ref": "#/components/parameters/IdempotencyKeyHeader"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/CreateReportRequest"
      responses:
        '201':
          description: The queued report. Poll `GET /reports/{id}` until it reaches
            a terminal state (`completed`, `errored`, or `timed_out`).
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ReportResource"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '422':
          "$ref": "#/components/responses/UnprocessableEntityResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
  "/reports/{id}":
    get:
      operationId: getReport
      summary: Retrieve a report by ID
      description: Retrieve a report and its current generation state. Poll this endpoint
        until `state` reaches a terminal value (`completed`, `errored`, or `timed_out`);
        once `completed`, the resource includes a short-lived signed `download_url`
        for the generated file.
      tags:
      - Reports
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - name: id
        in: path
        required: true
        schema:
          "$ref": "#/components/schemas/ResourceId"
      responses:
        '200':
          description: A single report
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ReportResource"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '404':
          "$ref": "#/components/responses/NotFoundResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
  "/vendors":
    get:
      operationId: listVendors
      summary: List vendors on the authenticated firm's account
      tags:
      - Vendors
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          minimum: 1
          maximum: 200
          default: 25
      - name: page_token
        in: query
        required: false
        description: Opaque token for cursor-based pagination. Pass back the value
          from `meta.paging.next` to fetch the next page.
        schema:
          type: string
      - name: status
        in: query
        required: false
        description: Filter by vendor status.
        schema:
          type: string
          enum:
          - active
          - inactive
      responses:
        '200':
          description: A paginated list of vendors
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/VendorCollection"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
    post:
      operationId: createVendor
      summary: Create a vendor on the authenticated firm's account
      tags:
      - Vendors
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - "$ref": "#/components/parameters/IdempotencyKeyHeader"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/VendorCreateRequest"
      responses:
        '201':
          description: The created vendor
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/VendorResource"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '422':
          "$ref": "#/components/responses/UnprocessableEntityResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
  "/vendors/{id}":
    get:
      operationId: getVendor
      summary: Retrieve a vendor by ID
      tags:
      - Vendors
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - name: id
        in: path
        required: true
        schema:
          "$ref": "#/components/schemas/ResourceId"
      responses:
        '200':
          description: A single vendor
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/VendorResource"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '404':
          "$ref": "#/components/responses/NotFoundResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
    patch:
      operationId: updateVendor
      summary: Update a vendor by ID
      tags:
      - Vendors
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - name: id
        in: path
        required: true
        schema:
          "$ref": "#/components/schemas/ResourceId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/VendorUpdateRequest"
      responses:
        '200':
          description: The updated vendor
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/VendorResource"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '404':
          "$ref": "#/components/responses/NotFoundResponse"
        '422':
          "$ref": "#/components/responses/UnprocessableEntityResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
    delete:
      operationId: deleteVendor
      summary: Delete a vendor by ID
      description: 'Permanently deletes the vendor. This action cannot be undone.
        Deletion is only allowed if the vendor has no transaction history and is not
        the Clio system vendor. To retire a vendor reversibly, use `PATCH /api/v1/vendors/{id}`
        with `status: inactive`.'
      tags:
      - Vendors
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - name: id
        in: path
        required: true
        schema:
          "$ref": "#/components/schemas/ResourceId"
      responses:
        '204':
          description: The vendor was deleted. No content is returned.
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '404':
          "$ref": "#/components/responses/NotFoundResponse"
        '422':
          "$ref": "#/components/responses/UnprocessableEntityResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
  "/matters":
    get:
      operationId: listMatters
      summary: List matters on the authenticated firm's account
      tags:
      - Matters
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          minimum: 1
          maximum: 200
          default: 25
      - name: page_token
        in: query
        required: false
        description: Opaque token for cursor-based pagination. Pass back the value
          from `meta.paging.next` to fetch the next page.
        schema:
          type: string
      responses:
        '200':
          description: A paginated list of matters
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/MatterCollection"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
  "/matters/{id}":
    get:
      operationId: getMatter
      summary: Retrieve a matter by ID
      tags:
      - Matters
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - name: id
        in: path
        required: true
        schema:
          "$ref": "#/components/schemas/ResourceId"
      responses:
        '200':
          description: A single matter
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/MatterResource"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '404':
          "$ref": "#/components/responses/NotFoundResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
  "/clients":
    get:
      operationId: listClients
      summary: List clients on the authenticated firm's account
      tags:
      - Clients
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          minimum: 1
          maximum: 200
          default: 25
      - name: page_token
        in: query
        required: false
        description: Opaque token for cursor-based pagination. Pass back the value
          from `meta.paging.next` to fetch the next page.
        schema:
          type: string
      responses:
        '200':
          description: A paginated list of clients
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ClientCollection"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
  "/clients/{id}":
    get:
      operationId: getClient
      summary: Retrieve a client by ID
      tags:
      - Clients
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - name: id
        in: path
        required: true
        schema:
          "$ref": "#/components/schemas/ResourceId"
      responses:
        '200':
          description: A single client
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ClientResource"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '404':
          "$ref": "#/components/responses/NotFoundResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
  "/expenses":
    get:
      operationId: listExpenses
      summary: List expenses on the authenticated firm's account
      tags:
      - Expenses
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          minimum: 1
          maximum: 200
          default: 25
      - name: page_token
        in: query
        required: false
        description: Opaque token for cursor-based pagination. Pass back the value
          from `meta.paging.next` to fetch the next page.
        schema:
          type: string
      - name: ledger_account_id
        in: query
        required: false
        description: Filter to expenses paid from this ledger account.
        schema:
          type: integer
          format: int64
      - name: vendor_id
        in: query
        required: false
        description: Filter to expenses associated with this vendor.
        schema:
          type: integer
          format: int64
      - name: date_from
        in: query
        required: false
        description: Only return expenses on or after this date (inclusive).
        schema:
          type: string
          format: date
      - name: date_to
        in: query
        required: false
        description: Only return expenses on or before this date (inclusive).
        schema:
          type: string
          format: date
      responses:
        '200':
          description: A paginated list of expenses
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ExpenseCollection"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
    post:
      operationId: createExpense
      summary: Create an expense on the authenticated firm's account
      tags:
      - Expenses
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - "$ref": "#/components/parameters/IdempotencyKeyHeader"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/ExpenseCreateRequest"
      responses:
        '201':
          description: The created expense
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ExpenseResource"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '422':
          "$ref": "#/components/responses/UnprocessableEntityResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
  "/expenses/{id}":
    get:
      operationId: getExpense
      summary: Retrieve an expense by ID
      tags:
      - Expenses
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - name: id
        in: path
        required: true
        schema:
          "$ref": "#/components/schemas/ResourceId"
      responses:
        '200':
          description: A single expense
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ExpenseResource"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '404':
          "$ref": "#/components/responses/NotFoundResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
    patch:
      operationId: updateExpense
      summary: Update an expense by ID
      tags:
      - Expenses
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - name: id
        in: path
        required: true
        schema:
          "$ref": "#/components/schemas/ResourceId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/ExpenseUpdateRequest"
      responses:
        '200':
          description: The updated expense
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ExpenseResource"
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '404':
          "$ref": "#/components/responses/NotFoundResponse"
        '422':
          "$ref": "#/components/responses/UnprocessableEntityResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
    delete:
      operationId: deleteExpense
      summary: Delete an expense by ID
      description: Deletes the expense. Returns no body.
      tags:
      - Expenses
      parameters:
      - "$ref": "#/components/parameters/ApiVersionHeader"
      - name: id
        in: path
        required: true
        schema:
          "$ref": "#/components/schemas/ResourceId"
      responses:
        '204':
          description: The expense was deleted
        '400':
          "$ref": "#/components/responses/BadRequestResponse"
        '401':
          "$ref": "#/components/responses/UnauthorizedResponse"
        '403':
          "$ref": "#/components/responses/ForbiddenResponse"
        '404':
          "$ref": "#/components/responses/NotFoundResponse"
        '422':
          "$ref": "#/components/responses/UnprocessableEntityResponse"
        '500':
          "$ref": "#/components/responses/InternalServerErrorResponse"
components:
  parameters:
    ApiVersionHeader:
      name: X-API-Version
      in: header
      required: false
      description: |
        Pins the request to a specific OpenAPI contract. Pass a date in `YYYY-MM-DD`
        format to select that version, or `unstable` to opt in to the latest spec.
        Omit to use the default (latest stable) contract.
      schema:
        type: string
        pattern: "^(unstable|\\d{4}-\\d{2}-\\d{2})$"
        example: '2026-03-31'
    IdempotencyKeyHeader:
      name: Idempotency-Key
      in: header
      required: false
      description: Optional client-supplied key that makes the create idempotent.
        Replaying a request with the same key and the same request body returns `201`
        with the originally created resource instead of creating a second one. Reusing
        the same key with a different request body returns `422`.
      schema:
        type: string
        maxLength: 255
  schemas:
    ResourceId:
      type: integer
      format: int64
      description: Unique numeric identifier for a resource. 64-bit to avoid overflow
        in generated clients.
      example: 626
    Account:
      type: object
      required:
      - id
      - name
      - currency
      - country
      - status
      - created_at
      - updated_at
      additionalProperties: false
      properties:
        id:
          "$ref": "#/components/schemas/ResourceId"
        name:
          type: string
          example: Doe & Associates
        currency:
          type: string
          description: ISO 4217 currency code for the account.
          example: USD
        country:
          type: string
          description: ISO 3166-1 alpha-2 country code for the account.
          example: US
        status:
          type: string
          description: Current account state.
          example: active
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    AccountResource:
      type: object
      required:
      - data
      additionalProperties: false
      properties:
        data:
          "$ref": "#/components/schemas/Account"
    Error:
      type: object
      required:
      - status
      - message
      additionalProperties: false
      properties:
        status:
          type: string
          description: Error status code (e.g. `not_found`, `validation_error`, `forbidden`).
        message:
          type: string
          description: Human-readable error message.
    ErrorResponse:
      type: object
      required:
      - error
      additionalProperties: false
      properties:
        error:
          "$ref": "#/components/schemas/Error"
    UserAccount:
      type: object
      description: Summary of the account (firm) the user belongs to.
      required:
      - id
      - firm_name
      additionalProperties: false
      properties:
        id:
          type: integer
          format: int64
          example: 350
        firm_name:
          type: string
          example: Doe & Associates
    User:
      type: object
      required:
      - id
      - first_name
      - last_name
      - email
      - created_at
      - updated_at
      - account
      additionalProperties: false
      properties:
        id:
          "$ref": "#/components/schemas/ResourceId"
        first_name:
          type: string
          example: Jane
        last_name:
          type: string
          example: Doe
        email:
          type: string
          format: email
          example: jane.doe@example.com
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        account:
          "$ref": "#/components/schemas/UserAccount"
    PagingMeta:
      type: object
      required:
      - paging
      additionalProperties: false
      properties:
        paging:
          type: object
          required:
          - next
          - previous
          additionalProperties: false
          properties:
            next:
              type: string
              format: uri
              nullable: true
              description: Absolute URL for the next page of results, or null if there
                are no more pages forward.
            previous:
              type: string
              format: uri
              nullable: true
              description: Absolute URL for the previous page of results, or null
                if there are no more pages backward (i.e. you're on the first page).
    UserCollection:
      type: object
      required:
      - data
      - meta
      additionalProperties: false
      properties:
        data:
          type: array
          items:
            "$ref": "#/components/schemas/User"
        meta:
          "$ref": "#/components/schemas/PagingMeta"
    UserResource:
      type: object
      required:
      - data
      additionalProperties: false
      properties:
        data:
          "$ref": "#/components/schemas/User"
    Money:
      type: object
      description: A monetary value expressed as a decimal-string amount paired with
        its ISO 4217 currency.
      required:
      - amount
      - currency
      additionalProperties: false
      properties:
        amount:
          type: string
          description: Decimal amount as a string, with the currency's natural number
            of fractional digits (e.g. "5.05"; "5" for JPY). String to avoid float
            rounding.
          example: '5.05'
        currency:
          type: string
          description: ISO 4217 currency code.
          example: USD
    JournalEntryItem:
      type: object
      required:
      - id
      - ledger_account
      - operation_type
      - amount
      - created_at
      - updated_at
      additionalProperties: false
      properties:
        id:
          type: integer
          format: int64
          example: 811
        ledger_account:
          type: object
          description: The ledger account this line item posts against.
          required:
          - id
          - name
          additionalProperties: false
          properties:
            id:
              type: integer
              format: int64
              example: 704
            name:
              type: string
              description: Display name of the ledger account.
        operation_type:
          type: string
          description: Whether the line item debits or credits its ledger account.
          enum:
          - debit
          - credit
        amount:
          "$ref": "#/components/schemas/Money"
        description:
          type: string
          nullable: true
          description: Free-text description of the line item.
        user:
          type: object
          description: The user who recorded the line item.
          required:
          - id
          - first_name
          - last_name
          additionalProperties: false
          properties:
            id:
              type: integer
              format: int64
              example: 513
            first_name:
              type: string
              description: First name of the user.
            last_name:
              type: string
              description: Last name of the user.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    JournalEntry:
      type: object
      required:
      - id
      - date
      - journal_entry_items
      - created_at
      - updated_at
      additionalProperties: false
      properties:
        id:
          "$ref": "#/components/schemas/ResourceId"
        date:
          type: string
          format: date
          description: Calendar date the journal entry is recorded against.
        description:
          type: string
          nullable: true
          description: Free-text description of the journal entry.
        user:
          type: object
          description: The user who recorded the journal entry.
          required:
          - id
          - first_name
          - last_name
          additionalProperties: false
          properties:
            id:
              type: integer
              format: int64
              example: 512
            first_name:
              type: string
              description: First name of the user.
            last_name:
              type: string
              description: Last name of the user.
        vendor:
          type: object
          nullable: true
          description: The related vendor, or null when the entry is not associated
            with a vendor.
          required:
          - id
          - name
          additionalProperties: false
          properties:
            id:
              type: integer
              format: int64
              example: 418
            name:
              type: string
              nullable: true
              description: Display name of the vendor, from its company name.
        client:
          type: object
          nullable: true
          description: The related client, or null when the entry is not client-related.
          required:
          - id
          - display_name
          additionalProperties: false
          properties:
            id:
              type: integer
              format: int64
              example: 205
            display_name:
              type: string
              description: Display name of the client.
        matter:
          type: object
          nullable: true
          description: The related matter, or null when the entry is not matter-related.
          required:
          - id
          - display_name
          additionalProperties: false
          properties:
            id:
              type: integer
              format: int64
              example: 337
            display_name:
              type: string
              nullable: true
              description: The matter's display name. Nullable, as the underlying
                column has no non-null guarantee.
        journal_entry_items:
          type: array
          description: Line items belonging to this journal entry. Monetary values
            appear only on these items.
          items:
            "$ref": "#/components/schemas/JournalEntryItem"
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    JournalEntryCollection:
      type: object
      required:
      - data
      - meta
      additionalProperties: false
      properties:
        data:
          type: array
          items:
            "$ref": "#/components/schemas/JournalEntry"
        meta:
          "$ref": "#/components/schemas/PagingMeta"
    JournalEntryItemCreateRequest:
      type: object
      required:
      - ledger_account
      - operation_type
      - amount
      additionalProperties: false
      properties:
        ledger_account:
          type: object
          description: The ledger account this line item posts against.
          required:
          - id
          additionalProperties: false
          properties:
            id:
              "$ref": "#/components/schemas/ResourceId"
        operation_type:
          type: string
          description: Whether the line item debits or credits its ledger account.
          enum:
          - debit
          - credit
        amount:
          "$ref": "#/components/schemas/Money"
        description:
          type: string
          nullable: true
          maxLength: 500
          description: Optional free-text description of the line item.
    JournalEntryCreateRequest:
      type: object
      required:
      - data
      additionalProperties: false
      properties:
        data:
          type: object
          required:
          - date
          - journal_entry_items
          additionalProperties: false
          properties:
            date:
              type: string
              format: date
              description: Calendar date the journal entry is recorded against.
            description:
              type: string
              nullable: true
              maxLength: 500
              description: Optional free-text description of the journal entry.
            vendor:
              type: object
              nullable: true
              description: The related vendor, or null when the entry is not associated
                with a vendor.
              required:
              - id
              additionalProperties: false
              properties:
                id:
                  description: ID of the related vendor.
                  allOf:
                  - "$ref": "#/components/schemas/ResourceId"
                  example: 418
            client:
              type: object
              nullable: true
              description: The related client, or null when the entry is not client-related.
              required:
              - id
              additionalProperties: false
              properties:
                id:
                  description: ID of the related client.
                  allOf:
                  - "$ref": "#/components/schemas/ResourceId"
                  example: 205
            matter:
              type: object
              nullable: true
              description: The related matter, or null when the entry is not matter-related.
              required:
              - id
              additionalProperties: false
              properties:
                id:
                  description: ID of the related matter.
                  allOf:
                  - "$ref": "#/components/schemas/ResourceId"
                  example: 337
            journal_entry_items:
              type: array
              minItems: 2
              description: Line items for the entry. At least two are required, and
                the sum of debit amounts must equal the sum of credit amounts. Balance
                is enforced server-side; an unbalanced entry returns 422.
              items:
                "$ref": "#/components/schemas/JournalEntryItemCreateRequest"
    JournalEntryResource:
      type: object
      required:
      - data
      additionalProperties: false
      properties:
        data:
          "$ref": "#/components/schemas/JournalEntry"
    JournalEntryUpdateRequest:
      type: object
      required:
      - data
      additionalProperties: false
      properties:
        data:
          type: object
          additionalProperties: false
          description: Partial update of a journal entry. Omitted fields are left
            unchanged.
          properties:
            date:
              type: string
              format: date
              description: Calendar date the journal entry is recorded against.
            description:
              type: string
              nullable: true
              maxLength: 500
              description: Free-text description of the journal entry.
            vendor:
              type: object
              nullable: true
              description: The related vendor, or null when the entry is not associated
                with a vendor. Send null to clear a previously set vendor.
              required:
              - id
              additionalProperties: false
              properties:
                id:
                  description: ID of the related vendor.
                  allOf:
                  - "$ref": "#/components/schemas/ResourceId"
                  example: 418
            client:
              type: object
              nullable: true
              description: The related client, or null when the entry is not client-related.
                Send null to clear a previously set client.
              required:
              - id
              additionalProperties: false
              properties:
                id:
                  description: ID of the related client.
                  allOf:
                  - "$ref": "#/components/schemas/ResourceId"
                  example: 205
            matter:
              type: object
              nullable: true
              description: The related matter, or null when the entry is not matter-related.
                Send null to clear a previously set matter.
              required:
              - id
              additionalProperties: false
              properties:
                id:
                  description: ID of the related matter.
                  allOf:
                  - "$ref": "#/components/schemas/ResourceId"
                  example: 337
            journal_entry_items:
              type: array
              minItems: 2
              description: Replaces the entry's full set of line items. When provided,
                the sum of debit amounts must equal the sum of credit amounts; an
                unbalanced entry returns 422.
              items:
                "$ref": "#/components/schemas/JournalEntryItemCreateRequest"
    LedgerAccount:
      type: object
      required:
      - id
      - name
      - status
      - kind
      - ledger_account_type
      - created_at
      - updated_at
      additionalProperties: false
      properties:
        id:
          "$ref": "#/components/schemas/ResourceId"
        name:
          type: string
          example: Operating Account
        code:
          type: string
          nullable: true
          description: Optional chart-of-accounts code for the ledger account. Stored
            as a string to preserve leading zeros; digits and hyphens only. Null when
            unset.
          example: '0100'
        status:
          type: string
          description: Whether the account is active or inactive.
          enum:
          - active
          - inactive
          example: active
        kind:
          type: string
          description: Whether the account holds operating or trust funds. Derived
            server-side from the ledger account type; not settable via the API.
          enum:
          - operating
          - trust
          example: operating
        ledger_type:
          type: string
          nullable: true
          description: The ledger classification of the account. Derived server-side
            from the ledger account type; not settable via the API. Null when unclassified.
          enum:
          - default
          - bank
          - accounts_receivable
          - accounts_payable
          - expense
          - undeposited_funds
          - fixed
          - trust_liability
          - income
          - trust_clearing
          example: bank
        ledger_account_type:
          type: object
          description: The ledger account type that classifies this account.
          required:
          - id
          - name
          additionalProperties: false
          properties:
            id:
              type: integer
              format: int64
              example: 314
            name:
              type: string
              description: Display name of the ledger account type.
        parent:
          type: object
          nullable: true
          description: The parent ledger account, or null for top-level accounts.
          required:
          - id
          - name
          additionalProperties: false
          properties:
            id:
              type: integer
              format: int64
              example: 271
            name:
              type: string
              description: Display name of the parent ledger account.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    LedgerAccountCollection:
      type: object
      required:
      - data
      - meta
      additionalProperties: false
      properties:
        data:
          type: array
          items:
            "$ref": "#/components/schemas/LedgerAccount"
        meta:
          "$ref": "#/components/schemas/PagingMeta"
    LedgerAccountCreateRequest:
      type: object
      required:
      - data
      additionalProperties: false
      properties:
        data:
          type: object
          required:
          - name
          - ledger_account_type
          additionalProperties: false
          properties:
            name:
              type: string
              maxLength: 200
              example: Operating Account
            code:
              type: string
              maxLength: 32
              nullable: true
              pattern: "^[0-9-]+$"
              description: Optional chart-of-accounts code. Digits and hyphens only;
                null when unset.
              example: '0100'
            ledger_account_type:
              type: object
              required:
              - id
              additionalProperties: false
              properties:
                id:
                  "$ref": "#/components/schemas/ResourceId"
            parent:
              type: object
              nullable: true
              additionalProperties: false
              description: The parent ledger account for a sub-account; omit or null
                for a top-level account.
              required:
              - id
              properties:
                id:
                  type: integer
                  format: int64
                  example: 271
    LedgerAccountResource:
      type: object
      required:
      - data
      additionalProperties: false
      properties:
        data:
          "$ref": "#/components/schemas/LedgerAccount"
    LedgerAccountUpdateRequest:
      type: object
      required:
      - data
      additionalProperties: false
      properties:
        data:
          type: object
          additionalProperties: false
          properties:
            name:
              type: string
              maxLength: 200
              example: Operating Account
            code:
              type: string
              maxLength: 32
              nullable: true
              pattern: "^[0-9-]+$"
              description: Optional chart-of-accounts code. Digits and hyphens only;
                null when unset.
              example: '0100'
            status:
              type: string
              description: Set to `inactive` to deactivate the account or `active`
                to reactivate it. Subject to validation — e.g. a parent with active
                sub-accounts cannot be deactivated, and a sub-account cannot be reactivated
                while its parent is inactive.
              enum:
              - active
              - inactive
              example: inactive
            ledger_account_type:
              type: object
              description: Re-types the account. Only permitted while the account
                is unused — an account with a linked bank account or any ledger entries
                cannot be re-typed (422).
              required:
              - id
              additionalProperties: false
              properties:
                id:
                  "$ref": "#/components/schemas/ResourceId"
            parent:
              type: object
              nullable: true
              additionalProperties: false
              description: The parent ledger account for a sub-account. Omit to leave
                the parent unchanged; send `null` to make the account top-level.
              required:
              - id
              properties:
                id:
                  type: integer
                  format: int64
                  example: 271
    LedgerAccountType:
      type: object
      required:
      - id
      - name
      - primary_type
      - ledger_type
      - bank_feed_connectable
      - reconcilable
      - created_at
      - updated_at
      additionalProperties: false
      properties:
        id:
          "$ref": "#/components/schemas/ResourceId"
        name:
          type: string
          example: Bank - Operating
        primary_type:
          type: string
          enum:
          - unknown
          - asset
          - liability
          - equity
          - income
          - expense
          example: asset
        ledger_type:
          type: string
          enum:
          - default
          - bank
          - accounts_receivable
          - accounts_payable
          - expense
          - undeposited_funds
          - fixed
          - trust_liability
          - income
          - trust_clearing
          example: bank
        bank_feed_connectable:
          type: boolean
          example: true
        reconcilable:
          type: boolean
          example: true
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    LedgerAccountTypeCollection:
      type: object
      required:
      - data
      - meta
      additionalProperties: false
      properties:
        data:
          type: array
          items:
            "$ref": "#/components/schemas/LedgerAccountType"
        meta:
          "$ref": "#/components/schemas/PagingMeta"
    LedgerAccountTypeResource:
      type: object
      required:
      - data
      additionalProperties: false
      properties:
        data:
          "$ref": "#/components/schemas/LedgerAccountType"
    VendorBillItem:
      type: object
      required:
      - id
      - ledger_account
      - amount
      additionalProperties: false
      properties:
        id:
          allOf:
          - "$ref": "#/components/schemas/ResourceId"
          example: 811
        ledger_account:
          type: object
          description: The ledger account this vendor bill line item posts against.
          required:
          - id
          - name
          additionalProperties: false
          properties:
            id:
              allOf:
              - "$ref": "#/components/schemas/ResourceId"
              example: 815
            name:
              type: string
              description: Display name of the ledger account.
        client:
          type: object
          nullable: true
          description: The related client, or null when the vendor bill line item
            is not client-related.
          required:
          - id
          - display_name
          additionalProperties: false
          properties:
            id:
              allOf:
              - "$ref": "#/components/schemas/ResourceId"
              example: 205
            display_name:
              type: string
              description: Display name of the client.
        matter:
          type: object
          nullable: true
          description: The related matter, or null when the vendor bill line item
            is not matter-related.
          required:
          - id
          - display_name
          additionalProperties: false
          properties:
            id:
              allOf:
              - "$ref": "#/components/schemas/ResourceId"
              example: 337
            display_name:
              type: string
              nullable: true
              description: The matter's display name. Nullable, as the underlying
                column has no non-null guarantee.
        description:
          type: string
          nullable: true
          description: Free-text description of the vendor bill line item.
        amount:
          "$ref": "#/components/schemas/Money"
    VendorBill:
      type: object
      required:
      - id
      - vendor
      - status
      - date
      - due_date
      - client_related
      - amount
      - balance_due
      - vendor_bill_items
      - created_at
      - updated_at
      additionalProperties: false
      properties:
        id:
          allOf:
          - "$ref": "#/components/schemas/ResourceId"
          example: 921
        vendor:
          type: object
          description: The vendor this bill is owed to.
          required:
          - id
          - company_name
          additionalProperties: false
          properties:
            id:
              allOf:
              - "$ref": "#/components/schemas/ResourceId"
              example: 418
            company_name:
              type: string
              description: The vendor's company name.
        status:
          type: string
          description: Lifecycle state of the bill.
          enum:
          - draft
          - posted
          - partially_paid
          - paid
          example: posted
        bill_number:
          type: string
          nullable: true
          description: The vendor's bill or invoice number. Null when unset.
          example: INV-1042
        account_number:
          type: string
          nullable: true
          description: The firm's account number with the vendor. Null when unset.
          example: ACME-88231
        description:
          type: string
          nullable: true
          description: Free-text description of the bill.
        date:
          type: string
          format: date
          description: Calendar date the bill is recorded against.
        due_date:
          type: string
          format: date
          description: Calendar date the bill is due.
        client_related:
          type: boolean
          description: Whether the bill relates to client work.
        amount:
          "$ref": "#/components/schemas/Money"
        balance_due:
          "$ref": "#/components/schemas/Money"
        vendor_bill_items:
          type: array
          description: Vendor bill line items belonging to this bill.
          items:
            "$ref": "#/components/schemas/VendorBillItem"
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    VendorBillCollection:
      type: object
      required:
      - data
      - meta
      additionalProperties: false
      properties:
        data:
          type: array
          items:
            "$ref": "#/components/schemas/VendorBill"
        meta:
          "$ref": "#/components/schemas/PagingMeta"
    VendorBillItemCreateRequest:
      type: object
      required:
      - ledger_account
      - amount
      additionalProperties: false
      properties:
        ledger_account:
          type: object
          description: The ledger account this vendor bill line item posts against.
          required:
          - id
          additionalProperties: false
          properties:
            id:
              description: ID of the ledger account this vendor bill line item posts
                against.
              allOf:
              - "$ref": "#/components/schemas/ResourceId"
        client:
          type: object
          nullable: true
          description: The related client, when the vendor bill line item is client-related.
          required:
          - id
          additionalProperties: false
          properties:
            id:
              description: ID of the related client, when the vendor bill line item
                is client-related.
              allOf:
              - "$ref": "#/components/schemas/ResourceId"
        matter:
          type: object
          nullable: true
          description: The related matter, when the vendor bill line item is matter-related.
          required:
          - id
          additionalProperties: false
          properties:
            id:
              description: ID of the related matter, when the vendor bill line item
                is matter-related.
              allOf:
              - "$ref": "#/components/schemas/ResourceId"
        amount:
          "$ref": "#/components/schemas/Money"
        description:
          type: string
          nullable: true
          maxLength: 500
          description: Optional free-text description of the vendor bill line item.
    VendorBillCreateRequest:
      type: object
      required:
      - data
      additionalProperties: false
      properties:
        data:
          type: object
          required:
          - vendor
          - date
          - due_date
          - vendor_bill_items
          additionalProperties: false
          properties:
            vendor:
              type: object
              description: The vendor this bill is owed to.
              required:
              - id
              additionalProperties: false
              properties:
                id:
                  description: ID of the vendor this bill is owed to.
                  allOf:
                  - "$ref": "#/components/schemas/ResourceId"
            date:
              type: string
              format: date
              description: Calendar date the bill is recorded against.
            due_date:
              type: string
              format: date
              description: Calendar date the bill is due.
            bill_number:
              type: string
              nullable: true
              maxLength: 255
              description: The vendor's bill or invoice number.
            account_number:
              type: string
              nullable: true
              maxLength: 255
              description: The firm's account number with the vendor.
            description:
              type: string
              nullable: true
              maxLength: 500
              description: Optional free-text description of the bill.
            vendor_bill_items:
              type: array
              minItems: 1
              description: Vendor bill line items for the bill. At least one is required.
                The bill's amount and balance are derived server-side from these items.
              items:
                "$ref": "#/components/schemas/VendorBillItemCreateRequest"
    VendorBillResource:
      type: object
      required:
      - data
      additionalProperties: false
      properties:
        data:
          "$ref": "#/components/schemas/VendorBill"
    VendorBillUpdateRequest:
      type: object
      required:
      - data
      additionalProperties: false
      properties:
        data:
          type: object
          additionalProperties: false
          description: Partial update of a vendor bill. Omitted fields are left unchanged.
          properties:
            vendor:
              type: object
              description: The vendor this bill is owed to.
              required:
              - id
              additionalProperties: false
              properties:
                id:
                  description: ID of the vendor this bill is owed to.
                  allOf:
                  - "$ref": "#/components/schemas/ResourceId"
            date:
              type: string
              format: date
              description: Calendar date the bill is recorded against.
            due_date:
              type: string
              format: date
              description: Calendar date the bill is due.
            bill_number:
              type: string
              nullable: true
              maxLength: 255
              description: The vendor's bill or invoice number.
            account_number:
              type: string
              nullable: true
              maxLength: 255
              description: The firm's account number with the vendor.
            description:
              type: string
              nullable: true
              maxLength: 500
              description: Free-text description of the bill.
            vendor_bill_items:
              type: array
              minItems: 1
              description: Replaces the bill's full set of vendor bill line items.
                When provided, the existing line items are removed and these are created
                in their place.
              items:
                "$ref": "#/components/schemas/VendorBillItemCreateRequest"
    VendorBillPaymentItem:
      type: object
      required:
      - id
      - vendor_bill
      - amount
      additionalProperties: false
      properties:
        id:
          allOf:
          - "$ref": "#/components/schemas/ResourceId"
          example: 937
        vendor_bill:
          type: object
          description: The vendor bill this portion of the payment is applied to.
          required:
          - id
          additionalProperties: false
          properties:
            id:
              allOf:
              - "$ref": "#/components/schemas/ResourceId"
              example: 921
            bill_number:
              type: string
              nullable: true
              description: The vendor's bill or invoice number. Null when unset.
        amount:
          "$ref": "#/components/schemas/Money"
    VendorBillPayment:
      type: object
      required:
      - id
      - vendor
      - ledger_account
      - created_from
      - date
      - amount
      - vendor_bill_payment_items
      - created_at
      - updated_at
      additionalProperties: false
      properties:
        id:
          allOf:
          - "$ref": "#/components/schemas/ResourceId"
          example: 933
        vendor:
          type: object
          description: The vendor the payment was made to.
          required:
          - id
          - name
          additionalProperties: false
          properties:
            id:
              allOf:
              - "$ref": "#/components/schemas/ResourceId"
              example: 418
            name:
              type: string
              nullable: true
              description: Display name of the vendor, from its company name.
        ledger_account:
          type: object
          description: The ledger account the payment was drawn from.
          required:
          - id
          - name
          additionalProperties: false
          properties:
            id:
              allOf:
              - "$ref": "#/components/schemas/ResourceId"
              example: 704
            name:
              type: string
              nullable: true
              description: Display name of the ledger account.
        payment_method:
          type: string
          nullable: true
          description: How the payment was made. Null when unset.
          enum:
          - cash
          - check
          - wire_transfer
          - debit_card
          - eft
          - credit_card
          - payment_apps
          - other
          example: check
        created_from:
          type: string
          description: The origin of the payment record.
          enum:
          - manual
          - bank_feed
          - check
          example: manual
        description:
          type: string
          nullable: true
          description: Free-text description of the payment.
        date:
          type: string
          format: date
          description: Calendar date the payment is recorded against.
        amount:
          "$ref": "#/components/schemas/Money"
        vendor_bill_payment_items:
          type: array
          description: Line items tying portions of this payment to specific bills.
          items:
            "$ref": "#/components/schemas/VendorBillPaymentItem"
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    VendorBillPaymentCollection:
      type: object
      required:
      - data
      - meta
      additionalProperties: false
      properties:
        data:
          type: array
          items:
            "$ref": "#/components/schemas/VendorBillPayment"
        meta:
          "$ref": "#/components/schemas/PagingMeta"
    VendorBillPaymentItemCreateRequest:
      type: object
      required:
      - vendor_bill
      - amount
      additionalProperties: false
      properties:
        vendor_bill:
          type: object
          description: The vendor bill this portion of the payment is applied to.
          required:
          - id
          additionalProperties: false
          properties:
            id:
              description: ID of the vendor bill this portion of the payment is applied
                to.
              allOf:
              - "$ref": "#/components/schemas/ResourceId"
              example: 921
        amount:
          "$ref": "#/components/schemas/Money"
    VendorBillPaymentCreateRequest:
      type: object
      required:
      - data
      additionalProperties: false
      properties:
        data:
          type: object
          required:
          - ledger_account
          - date
          - vendor_bill_payment_items
          additionalProperties: false
          properties:
            ledger_account:
              type: object
              description: The ledger account the payment is drawn from.
              required:
              - id
              additionalProperties: false
              properties:
                id:
                  description: ID of the ledger account the payment is drawn from.
                  allOf:
                  - "$ref": "#/components/schemas/ResourceId"
                  example: 704
            date:
              type: string
              format: date
              description: Calendar date the payment is recorded against.
            payment_method:
              type: string
              nullable: true
              description: How the payment was made. Omit or send null when unset.
              enum:
              - cash
              - check
              - wire_transfer
              - debit_card
              - eft
              - credit_card
              - payment_apps
              - other
              example: check
            description:
              type: string
              nullable: true
              maxLength: 500
              description: Optional free-text description of the payment.
            vendor_bill_payment_items:
              type: array
              minItems: 1
              description: Line items tying portions of this payment to specific bills.
                At least one is required. The payment's total amount is derived server-side
                as the sum of the item amounts. Overpayment is not allowed — an item
                amount exceeding its bill's outstanding balance returns 422.
              items:
                "$ref": "#/components/schemas/VendorBillPaymentItemCreateRequest"
    VendorBillPaymentResource:
      type: object
      required:
      - data
      additionalProperties: false
      properties:
        data:
          "$ref": "#/components/schemas/VendorBillPayment"
    Report:
      type: object
      required:
      - id
      - kind
      - state
      - format
      - accounting_basis
      - start_date
      - end_date
      - download_url
      - download_url_expires_at
      - created_at
      - updated_at
      additionalProperties: false
      properties:
        id:
          "$ref": "#/components/schemas/ResourceId"
        kind:
          type: string
          description: The type of report.
          enum:
          - balance_sheet
          - general_ledger
          - income_statement
        state:
          type: string
          description: Generation state. Poll until a terminal state (`completed`,
            `errored`, or `timed_out`); the file is available via `download_url` once
            `completed`.
          enum:
          - queued
          - in_progress
          - completed
          - errored
          - timed_out
        format:
          type: string
          description: File format of the generated report. Only CSV is currently
            supported.
          enum:
          - csv
        accounting_basis:
          type: string
          description: Accounting basis the report was generated on.
          enum:
          - cash
          - accrual
        start_date:
          type: string
          format: date
          nullable: true
          description: Start of the reporting period. Null for point-in-time reports
            (balance sheet).
        end_date:
          type: string
          format: date
          nullable: true
          description: End of the reporting period (or as-of date for balance sheet).
        download_url:
          type: string
          format: uri
          nullable: true
          description: |
            Short-lived signed URL for the generated CSV. Present only once `state` is
            `completed` and the file is available. A fresh URL is minted on every fetch
            of the resource; if it expires, re-fetch the report to get a new one.
        download_url_expires_at:
          type: string
          format: date-time
          nullable: true
          description: When `download_url` stops working. Null whenever `download_url`
            is null.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    ReportCollection:
      type: object
      required:
      - data
      - meta
      additionalProperties: false
      properties:
        data:
          type: array
          items:
            "$ref": "#/components/schemas/Report"
        meta:
          "$ref": "#/components/schemas/PagingMeta"
    CreateReportRequest:
      type: object
      required:
      - data
      additionalProperties: false
      properties:
        data:
          type: object
          required:
          - kind
          additionalProperties: false
          properties:
            kind:
              type: string
              description: The type of report to generate.
              enum:
              - balance_sheet
              - general_ledger
              - income_statement
            start_date:
              type: string
              format: date
              description: Start of the reporting period. Ignored for balance sheet.
                Defaults to the beginning of the current month.
            end_date:
              type: string
              format: date
              description: End of the reporting period (or as-of date for balance
                sheet). Defaults to the end of the current month.
            accounting_basis:
              type: string
              enum:
              - cash
              - accrual
              description: Defaults to the firm's default accounting basis.
    ReportResource:
      type: object
      required:
      - data
      additionalProperties: false
      properties:
        data:
          "$ref": "#/components/schemas/Report"
    VendorAddress:
      type: object
      description: The vendor's mailing address. Omitted when the vendor has no address
        on file.
      additionalProperties: false
      properties:
        street:
          type: string
          nullable: true
          example: 123 Main St
        city:
          type: string
          nullable: true
          example: Vancouver
        state:
          type: string
          nullable: true
          example: BC
        zip_code:
          type: string
          nullable: true
          example: V6B 1A1
        country:
          type: string
          nullable: true
          description: ISO 3166-1 alpha-2 country code, upper case. Null when the
            address has no country on file, and also when the country on file is outside
            the set Clio Accounting can map to an alpha-2 code (`US`, `CA`, `GB`)
            — the underlying reference table stores alpha-3. Send this same value
            back as `address.country` on a create or update request.
          example: CA
    Vendor:
      type: object
      required:
      - id
      - company_name
      - status
      - is_clio
      - created_at
      - updated_at
      additionalProperties: false
      properties:
        id:
          allOf:
          - "$ref": "#/components/schemas/ResourceId"
          example: 918
        external_id:
          type: integer
          format: int64
          nullable: true
          description: Identifier of the corresponding vendor in Clio Manage, for
            cross-system correlation.
          example: 4815162342
        company_name:
          type: string
          example: Acme Supplies Inc.
        first_name:
          type: string
          nullable: true
          example: Jane
        last_name:
          type: string
          nullable: true
          example: Doe
        email:
          type: string
          format: email
          nullable: true
          example: billing@acmesupplies.example.com
        phone:
          type: string
          nullable: true
          example: "+1-604-555-0142"
        description:
          type: string
          nullable: true
        employer_identification_number:
          type: string
          nullable: true
          description: The vendor's Employer Identification Number (EIN).
          example: 12-3456789
        tax_1099:
          type: boolean
          description: Whether the vendor should receive a 1099 tax form.
        is_clio:
          type: boolean
          description: Whether this vendor represents Clio itself (e.g. Clio Payments).
        status:
          type: string
          enum:
          - active
          - inactive
        address:
          "$ref": "#/components/schemas/VendorAddress"
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    VendorCollection:
      type: object
      required:
      - data
      - meta
      additionalProperties: false
      properties:
        data:
          type: array
          items:
            "$ref": "#/components/schemas/Vendor"
        meta:
          "$ref": "#/components/schemas/PagingMeta"
    VendorAddressRequest:
      type: object
      nullable: true
      description: 'The vendor''s mailing address, for create and update requests.
        Distinct from the read `VendorAddress`: `country` is a bare ISO 3166-1 alpha-2
        string here, which Clio Accounting resolves to a country record server-side.
        An unsupported code returns 422.'
      additionalProperties: false
      properties:
        street:
          type: string
          nullable: true
          maxLength: 255
          example: 123 Main St
        city:
          type: string
          nullable: true
          maxLength: 255
          example: Vancouver
        state:
          type: string
          nullable: true
          maxLength: 255
          example: BC
        zip_code:
          type: string
          nullable: true
          maxLength: 255
          example: V6B 1A1
        country:
          type: string
          nullable: true
          maxLength: 2
          pattern: "^[A-Za-z]{2}$"
          description: ISO 3166-1 alpha-2 country code. Send back the `address.country.code`
            value from a read response. Case-insensitive. Exactly two letters — a
            shorter, longer or non-alphabetic value is rejected with a 400 rather
            than reaching the server's country lookup.
          example: CA
    VendorCreateRequest:
      type: object
      required:
      - data
      additionalProperties: false
      properties:
        data:
          type: object
          required:
          - company_name
          - status
          additionalProperties: false
          properties:
            company_name:
              type: string
              maxLength: 255
              description: The vendor's company name.
              example: Acme Supplies Inc.
            first_name:
              type: string
              nullable: true
              maxLength: 255
            last_name:
              type: string
              nullable: true
              maxLength: 255
            email:
              type: string
              format: email
              nullable: true
            phone:
              type: string
              nullable: true
              maxLength: 255
            description:
              type: string
              nullable: true
              maxLength: 500
            employer_identification_number:
              type: string
              nullable: true
              maxLength: 255
              description: The vendor's Employer Identification Number (EIN).
            tax_1099:
              type: boolean
              description: Whether the vendor should receive a 1099 tax form.
            status:
              type: string
              enum:
              - active
              - inactive
            address:
              "$ref": "#/components/schemas/VendorAddressRequest"
    VendorResource:
      type: object
      required:
      - data
      additionalProperties: false
      properties:
        data:
          "$ref": "#/components/schemas/Vendor"
    VendorUpdateRequest:
      type: object
      required:
      - data
      additionalProperties: false
      properties:
        data:
          type: object
          additionalProperties: false
          description: Partial update of a vendor. Omitted fields are left unchanged.
          properties:
            company_name:
              type: string
              maxLength: 255
              description: The vendor's company name.
            first_name:
              type: string
              nullable: true
              maxLength: 255
            last_name:
              type: string
              nullable: true
              maxLength: 255
            email:
              type: string
              format: email
              nullable: true
            phone:
              type: string
              nullable: true
              maxLength: 255
            description:
              type: string
              nullable: true
              maxLength: 500
            employer_identification_number:
              type: string
              nullable: true
              maxLength: 255
              description: The vendor's Employer Identification Number (EIN).
            tax_1099:
              type: boolean
              description: Whether the vendor should receive a 1099 tax form.
            status:
              type: string
              enum:
              - active
              - inactive
            address:
              "$ref": "#/components/schemas/VendorAddressRequest"
    MatterClient:
      type: object
      description: Summary of a client associated with the matter.
      required:
      - id
      - display_name
      additionalProperties: false
      properties:
        id:
          allOf:
          - "$ref": "#/components/schemas/ResourceId"
          example: 589
        display_name:
          type: string
          example: Doe & Associates
    Matter:
      type: object
      required:
      - id
      - external_id
      - display_name
      - clients
      - created_at
      - updated_at
      additionalProperties: false
      properties:
        id:
          allOf:
          - "$ref": "#/components/schemas/ResourceId"
          example: 447
        external_id:
          type: integer
          format: int64
          description: Identifier of the corresponding matter in Clio Manage, for
            cross-system correlation.
          example: 4815162342
        display_name:
          type: string
          nullable: true
          description: The matter's display name. Nullable, as the underlying column
            has no non-null guarantee and no coalescing accessor.
          example: Smith v. Jones
        clients:
          type: array
          description: Clients associated with the matter.
          items:
            "$ref": "#/components/schemas/MatterClient"
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    MatterCollection:
      type: object
      required:
      - data
      - meta
      additionalProperties: false
      properties:
        data:
          type: array
          items:
            "$ref": "#/components/schemas/Matter"
        meta:
          "$ref": "#/components/schemas/PagingMeta"
    MatterResource:
      type: object
      required:
      - data
      additionalProperties: false
      properties:
        data:
          "$ref": "#/components/schemas/Matter"
    Client:
      type: object
      required:
      - id
      - external_id
      - display_name
      - created_at
      - updated_at
      additionalProperties: false
      properties:
        id:
          allOf:
          - "$ref": "#/components/schemas/ResourceId"
          example: 733
        external_id:
          type: integer
          format: int64
          description: Identifier of this client in Clio Manage, for cross-system
            correlation.
          example: 4815162342
        display_name:
          type: string
          example: Jane Doe
        first_name:
          type: string
          nullable: true
          description: Given name of the client's linked contact. Null for organization
            clients or when no contact is linked.
          example: Jane
        last_name:
          type: string
          nullable: true
          description: Family name of the client's linked contact. Null for organization
            clients or when no contact is linked.
          example: Doe
        email:
          type: string
          format: email
          nullable: true
          description: Primary email address of the client's linked contact. Null
            when no contact or email is on file.
          example: jane.doe@example.com
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    ClientCollection:
      type: object
      required:
      - data
      - meta
      additionalProperties: false
      properties:
        data:
          type: array
          items:
            "$ref": "#/components/schemas/Client"
        meta:
          "$ref": "#/components/schemas/PagingMeta"
    ClientResource:
      type: object
      required:
      - data
      additionalProperties: false
      properties:
        data:
          "$ref": "#/components/schemas/Client"
    ExpenseItem:
      type: object
      required:
      - id
      - ledger_account
      - amount
      additionalProperties: false
      properties:
        id:
          type: integer
          format: int64
          example: 811
        ledger_account:
          type: object
          description: The ledger account (expense category) this line item posts
            against.
          required:
          - id
          - name
          additionalProperties: false
          properties:
            id:
              type: integer
              format: int64
              example: 815
            name:
              type: string
              description: Display name of the ledger account.
        description:
          type: string
          nullable: true
          description: Free-text description of the expense line item.
        memo:
          type: string
          nullable: true
          description: Free-text memo on the expense line item.
        amount:
          "$ref": "#/components/schemas/Money"
    Expense:
      type: object
      required:
      - id
      - date
      - payment_method
      - amount
      - ledger_account
      - reversal
      - expense_items
      - created_at
      - updated_at
      additionalProperties: false
      properties:
        id:
          "$ref": "#/components/schemas/ResourceId"
        date:
          type: string
          format: date
          description: Calendar date the expense is recorded against.
        description:
          type: string
          nullable: true
          description: Free-text description of the expense. Null when unset.
        reference_num:
          type: string
          nullable: true
          description: The firm's reference number for the expense (e.g. a cheque
            number). Null when unset.
          example: '1024'
        payment_method:
          type: string
          nullable: true
          description: How the expense was paid. Null when unset.
          enum:
          - cash
          - check
          - wire_transfer
          - debit_card
          - eft
          - credit_card
          - payment_apps
          - other
          example: check
        payment_method_description:
          type: string
          nullable: true
          description: Free-text detail about the payment method. Null when unset.
        amount:
          "$ref": "#/components/schemas/Money"
        ledger_account:
          type: object
          description: The ledger account the expense was paid from.
          required:
          - id
          - name
          additionalProperties: false
          properties:
            id:
              type: integer
              format: int64
              example: 704
            name:
              type: string
              description: Display name of the ledger account.
        vendor:
          type: object
          nullable: true
          description: The related vendor, or null when the expense is not associated
            with a vendor.
          required:
          - id
          - name
          additionalProperties: false
          properties:
            id:
              type: integer
              format: int64
              example: 418
            name:
              type: string
              description: Display name of the vendor.
        client:
          type: object
          nullable: true
          description: The related client, or null when the expense is not client-related.
          required:
          - id
          - display_name
          additionalProperties: false
          properties:
            id:
              type: integer
              format: int64
              example: 205
            display_name:
              type: string
              description: Display name of the client.
        matter:
          type: object
          nullable: true
          description: The related matter, or null when the expense is not matter-related.
          required:
          - id
          - display_name
          additionalProperties: false
          properties:
            id:
              type: integer
              format: int64
              example: 337
            display_name:
              type: string
              nullable: true
              description: The matter's display name. Nullable, as the underlying
                column has no non-null guarantee.
        reversal:
          type: boolean
          description: Whether the expense is a reversal of another transaction.
        expense_items:
          type: array
          description: Expense line items belonging to this expense, each carrying
            its own expense category.
          items:
            "$ref": "#/components/schemas/ExpenseItem"
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    ExpenseCollection:
      type: object
      required:
      - data
      - meta
      additionalProperties: false
      properties:
        data:
          type: array
          items:
            "$ref": "#/components/schemas/Expense"
        meta:
          "$ref": "#/components/schemas/PagingMeta"
    ExpenseItemCreateRequest:
      type: object
      required:
      - ledger_account
      - amount
      additionalProperties: false
      properties:
        ledger_account:
          type: object
          description: The ledger account (expense category) this line item posts
            against.
          required:
          - id
          additionalProperties: false
          properties:
            id:
              description: ID of the ledger account this line item posts against.
              allOf:
              - "$ref": "#/components/schemas/ResourceId"
              example: 815
        amount:
          "$ref": "#/components/schemas/Money"
        description:
          type: string
          nullable: true
          description: Free-text description of the expense line item.
        memo:
          type: string
          nullable: true
          maxLength: 255
          description: Free-text memo on the expense line item.
    ExpenseCreateRequest:
      type: object
      required:
      - data
      additionalProperties: false
      properties:
        data:
          type: object
          required:
          - date
          - ledger_account
          - expense_items
          additionalProperties: false
          properties:
            date:
              type: string
              format: date
              description: Calendar date the expense is recorded against.
            ledger_account:
              type: object
              description: The ledger account the expense is paid from. Distinct from
                the per-item expense-category account on each `expense_items` entry.
              required:
              - id
              additionalProperties: false
              properties:
                id:
                  description: ID of the ledger account the expense is paid from.
                  allOf:
                  - "$ref": "#/components/schemas/ResourceId"
                  example: 704
            vendor:
              type: object
              nullable: true
              description: The related vendor, or null when the expense is not associated
                with a vendor.
              required:
              - id
              additionalProperties: false
              properties:
                id:
                  description: ID of the related vendor.
                  allOf:
                  - "$ref": "#/components/schemas/ResourceId"
                  example: 418
            client:
              type: object
              nullable: true
              description: The related client, or null when the expense is not client-related.
              required:
              - id
              additionalProperties: false
              properties:
                id:
                  description: ID of the related client.
                  allOf:
                  - "$ref": "#/components/schemas/ResourceId"
                  example: 205
            matter:
              type: object
              nullable: true
              description: The related matter, or null when the expense is not matter-related.
              required:
              - id
              additionalProperties: false
              properties:
                id:
                  description: ID of the related matter.
                  allOf:
                  - "$ref": "#/components/schemas/ResourceId"
                  example: 337
            description:
              type: string
              nullable: true
              description: Optional free-text description of the expense.
            reference_num:
              type: string
              nullable: true
              maxLength: 32
              description: The firm's reference number for the expense (e.g. a cheque
                number).
              example: '1024'
            payment_method:
              type: string
              nullable: true
              description: How the expense was paid. Omit or send null when unset.
              enum:
              - cash
              - check
              - wire_transfer
              - debit_card
              - eft
              - credit_card
              - payment_apps
              - other
              example: check
            payment_method_description:
              type: string
              nullable: true
              maxLength: 255
              description: Free-text detail about the payment method.
            expense_items:
              type: array
              minItems: 1
              description: Expense line items belonging to this expense. At least
                one is required. The expense's total amount is derived server-side
                as the sum of the item amounts.
              items:
                "$ref": "#/components/schemas/ExpenseItemCreateRequest"
    ExpenseResource:
      type: object
      required:
      - data
      additionalProperties: false
      properties:
        data:
          "$ref": "#/components/schemas/Expense"
    ExpenseUpdateRequest:
      type: object
      required:
      - data
      additionalProperties: false
      properties:
        data:
          type: object
          additionalProperties: false
          description: Partial update of an expense. Omitted fields are left unchanged.
          properties:
            date:
              type: string
              format: date
              description: Calendar date the expense is recorded against.
            ledger_account:
              type: object
              description: The ledger account the expense is paid from. Distinct from
                the per-item expense-category account on each `expense_items` entry.
              required:
              - id
              additionalProperties: false
              properties:
                id:
                  description: ID of the ledger account the expense is paid from.
                  allOf:
                  - "$ref": "#/components/schemas/ResourceId"
                  example: 704
            vendor:
              type: object
              nullable: true
              description: The related vendor, or null when the expense is not associated
                with a vendor.
              required:
              - id
              additionalProperties: false
              properties:
                id:
                  description: ID of the related vendor.
                  allOf:
                  - "$ref": "#/components/schemas/ResourceId"
                  example: 418
            client:
              type: object
              nullable: true
              description: The related client, or null when the expense is not client-related.
              required:
              - id
              additionalProperties: false
              properties:
                id:
                  description: ID of the related client.
                  allOf:
                  - "$ref": "#/components/schemas/ResourceId"
                  example: 205
            matter:
              type: object
              nullable: true
              description: The related matter, or null when the expense is not matter-related.
              required:
              - id
              additionalProperties: false
              properties:
                id:
                  description: ID of the related matter.
                  allOf:
                  - "$ref": "#/components/schemas/ResourceId"
                  example: 337
            description:
              type: string
              nullable: true
              description: Optional free-text description of the expense.
            reference_num:
              type: string
              nullable: true
              maxLength: 32
              description: The firm's reference number for the expense (e.g. a cheque
                number).
              example: '1024'
            payment_method:
              type: string
              nullable: true
              description: How the expense was paid. Omit or send null when unset.
              enum:
              - cash
              - check
              - wire_transfer
              - debit_card
              - eft
              - credit_card
              - payment_apps
              - other
              example: check
            payment_method_description:
              type: string
              nullable: true
              maxLength: 255
              description: Free-text detail about the payment method.
            expense_items:
              type: array
              minItems: 1
              description: Replaces the expense's full set of line items. When provided,
                the expense's total amount is derived server-side as the sum of the
                item amounts.
              items:
                "$ref": "#/components/schemas/ExpenseItemCreateRequest"
  responses:
    UnauthorizedResponse:
      description: Authentication token missing or invalid
      content:
        application/json:
          schema:
            "$ref": "#/components/schemas/ErrorResponse"
    ForbiddenResponse:
      description: Insufficient scopes, disabled OAuth application, or inactive user
      content:
        application/json:
          schema:
            "$ref": "#/components/schemas/ErrorResponse"
    InternalServerErrorResponse:
      description: An unexpected error occurred while processing the request
      content:
        application/json:
          schema:
            "$ref": "#/components/schemas/ErrorResponse"
    BadRequestResponse:
      description: Bad request — missing or invalid parameters
      content:
        application/json:
          schema:
            "$ref": "#/components/schemas/ErrorResponse"
    NotFoundResponse:
      description: Resource not found
      content:
        application/json:
          schema:
            "$ref": "#/components/schemas/ErrorResponse"
    UnprocessableEntityResponse:
      description: Validation failed or invalid state transition
      content:
        application/json:
          schema:
            "$ref": "#/components/schemas/ErrorResponse"
