ServiceTitan Accounting API

Read and write invoices, invoice items, AP credits, payments, payment terms, payment types, journal entries, journal entry details, tax zones, and GL accounts. Integrates with QuickBooks Online, QuickBooks Desktop, Sage Intacct, and Acumatica exports.

OpenAPI Specification

servicetitan-accounting-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: ServiceTitan Accounting API
  description: |
    The Accounting API manages invoices, invoice items, AP credits, payments, payment terms,
    payment types, journal entries, journal entry details, tax zones, and GL accounts.
    Tenant-scoped; OAuth 2.0 + App Key. Integrates with QuickBooks, Sage Intacct, and Acumatica.
  version: "2.0.0"
  contact:
    name: ServiceTitan Developer Support
    url: https://developer.servicetitan.io/
    email: [email protected]
  license:
    name: ServiceTitan Terms of Service
    url: https://www.servicetitan.com/legal/terms-of-service
servers:
  - url: https://api.servicetitan.io/accounting/v2/{tenant}
    description: Production
    variables:
      tenant:
        default: "0000000"
  - url: https://api-integration.servicetitan.io/accounting/v2/{tenant}
    description: Integration (Sandbox)
    variables:
      tenant:
        default: "0000000"
security:
  - OAuth2: []
    AppKey: []
tags:
  - name: Invoices
  - name: Payments
  - name: Journal Entries
  - name: Tax Zones
  - name: GL Accounts
paths:
  /invoices:
    get:
      summary: List Invoices
      operationId: listInvoices
      tags: [Invoices]
      parameters:
        - $ref: '#/components/parameters/Page'
        - $ref: '#/components/parameters/PageSize'
        - $ref: '#/components/parameters/ModifiedOnOrAfter'
        - name: jobId
          in: query
          schema: { type: integer }
        - name: customerId
          in: query
          schema: { type: integer }
        - name: batchId
          in: query
          schema: { type: integer }
      responses:
        '200':
          description: Paginated list of invoices
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvoicePagedResponse'
  /invoices/{id}:
    get:
      summary: Get Invoice
      operationId: getInvoice
      tags: [Invoices]
      parameters:
        - $ref: '#/components/parameters/Id'
      responses:
        '200':
          description: Invoice
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Invoice'
    patch:
      summary: Update Invoice
      operationId: updateInvoice
      tags: [Invoices]
      parameters:
        - $ref: '#/components/parameters/Id'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InvoiceUpdateRequest'
      responses:
        '200':
          description: Updated invoice
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Invoice'
  /invoices/{id}/items:
    post:
      summary: Update Invoice Items
      operationId: updateInvoiceItems
      tags: [Invoices]
      parameters:
        - $ref: '#/components/parameters/Id'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                items:
                  type: array
                  items: { $ref: '#/components/schemas/InvoiceItem' }
      responses:
        '200':
          description: Items updated
  /payments:
    get:
      summary: List Payments
      operationId: listPayments
      tags: [Payments]
      parameters:
        - $ref: '#/components/parameters/Page'
        - $ref: '#/components/parameters/PageSize'
        - $ref: '#/components/parameters/ModifiedOnOrAfter'
      responses:
        '200':
          description: Paginated list of payments
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaymentPagedResponse'
    post:
      summary: Create Payment
      operationId: createPayment
      tags: [Payments]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PaymentCreateRequest'
      responses:
        '200':
          description: Created payment
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Payment'
  /payments/{id}:
    get:
      summary: Get Payment
      operationId: getPayment
      tags: [Payments]
      parameters:
        - $ref: '#/components/parameters/Id'
      responses:
        '200':
          description: Payment
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Payment'
    patch:
      summary: Update Payment
      operationId: updatePayment
      tags: [Payments]
      parameters:
        - $ref: '#/components/parameters/Id'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      responses:
        '200':
          description: Updated payment
  /payment-types:
    get:
      summary: List Payment Types
      operationId: listPaymentTypes
      tags: [Payments]
      responses:
        '200':
          description: Payment types
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        id: { type: integer }
                        name: { type: string }
                        active: { type: boolean }
                        modifiedOn: { type: string, format: date-time }
  /journal-entries:
    get:
      summary: List Journal Entries
      operationId: listJournalEntries
      tags: [Journal Entries]
      parameters:
        - $ref: '#/components/parameters/Page'
        - $ref: '#/components/parameters/PageSize'
        - $ref: '#/components/parameters/ModifiedOnOrAfter'
      responses:
        '200':
          description: Paginated list of journal entries
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items: { $ref: '#/components/schemas/JournalEntry' }
                  hasMore: { type: boolean }
  /tax-zones:
    get:
      summary: List Tax Zones
      operationId: listTaxZones
      tags: [Tax Zones]
      responses:
        '200':
          description: Tax zones
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        id: { type: integer }
                        name: { type: string }
                        rate: { type: number }
                        useTaxRate: { type: number }
                        active: { type: boolean }
  /gl-accounts:
    get:
      summary: List GL Accounts
      operationId: listGlAccounts
      tags: [GL Accounts]
      responses:
        '200':
          description: GL accounts
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        id: { type: integer }
                        name: { type: string }
                        number: { type: string }
                        accountType: { type: string }
                        active: { type: boolean }
                        isInterCompany: { type: boolean }
components:
  securitySchemes:
    OAuth2:
      type: oauth2
      flows:
        clientCredentials:
          tokenUrl: https://auth.servicetitan.io/connect/token
          scopes: {}
    AppKey:
      type: apiKey
      in: header
      name: ST-App-Key
  parameters:
    Id:
      name: id
      in: path
      required: true
      schema: { type: integer, format: int64 }
    Page:
      name: page
      in: query
      schema: { type: integer, default: 1 }
    PageSize:
      name: pageSize
      in: query
      schema: { type: integer, default: 50, maximum: 500 }
    ModifiedOnOrAfter:
      name: modifiedOnOrAfter
      in: query
      schema: { type: string, format: date-time }
  schemas:
    Invoice:
      type: object
      properties:
        id: { type: integer, format: int64 }
        number: { type: string }
        jobId: { type: integer, format: int64, nullable: true }
        projectId: { type: integer, format: int64, nullable: true }
        customerId: { type: integer, format: int64 }
        locationId: { type: integer, format: int64 }
        businessUnitId: { type: integer }
        invoiceDate: { type: string, format: date }
        dueDate: { type: string, format: date }
        subTotal: { type: number, format: double }
        salesTax: { type: number, format: double }
        salesTaxCode: { type: string, nullable: true }
        total: { type: number, format: double }
        balance: { type: number, format: double }
        royalty:
          type: object
          properties:
            status: { type: string }
            date: { type: string, format: date-time, nullable: true }
            sentOn: { type: string, format: date-time, nullable: true }
            memo: { type: string, nullable: true }
        status: { type: string, enum: [Pending, Posted, Exported] }
        depositedOn: { type: string, format: date-time, nullable: true }
        items:
          type: array
          items: { $ref: '#/components/schemas/InvoiceItem' }
        payments:
          type: array
          items:
            type: object
            properties:
              paymentId: { type: integer }
              amount: { type: number }
              memo: { type: string }
        modifiedOn: { type: string, format: date-time }
    InvoiceItem:
      type: object
      properties:
        id: { type: integer }
        skuId: { type: integer, nullable: true }
        skuName: { type: string }
        skuType: { type: string }
        description: { type: string }
        quantity: { type: number }
        cost: { type: number }
        totalCost: { type: number }
        price: { type: number }
        total: { type: number }
        generalLedgerAccountId: { type: integer, nullable: true }
        taxable: { type: boolean }
        chargeable: { type: boolean }
    InvoiceUpdateRequest:
      type: object
      properties:
        invoiceDate: { type: string, format: date }
        dueDate: { type: string, format: date }
        summary: { type: string }
        royalty:
          type: object
    InvoicePagedResponse:
      type: object
      properties:
        page: { type: integer }
        pageSize: { type: integer }
        hasMore: { type: boolean }
        data:
          type: array
          items: { $ref: '#/components/schemas/Invoice' }
    Payment:
      type: object
      properties:
        id: { type: integer, format: int64 }
        active: { type: boolean }
        referenceNumber: { type: string, nullable: true }
        date: { type: string, format: date-time }
        type: { type: string }
        typeId: { type: integer, nullable: true }
        total: { type: number }
        unappliedAmount: { type: number }
        memo: { type: string, nullable: true }
        customer:
          type: object
          properties:
            id: { type: integer }
            name: { type: string }
        batch:
          type: object
          properties:
            id: { type: integer, nullable: true }
            name: { type: string, nullable: true }
            number: { type: string, nullable: true }
        status: { type: string }
        splits:
          type: array
          items:
            type: object
            properties:
              invoiceId: { type: integer }
              amount: { type: number }
        modifiedOn: { type: string, format: date-time }
    PaymentCreateRequest:
      type: object
      required: [date, typeId, total, splits]
      properties:
        date: { type: string, format: date-time }
        typeId: { type: integer }
        total: { type: number }
        referenceNumber: { type: string }
        memo: { type: string }
        splits:
          type: array
          items:
            type: object
            required: [invoiceId, amount]
            properties:
              invoiceId: { type: integer }
              amount: { type: number }
    PaymentPagedResponse:
      type: object
      properties:
        page: { type: integer }
        pageSize: { type: integer }
        hasMore: { type: boolean }
        data:
          type: array
          items: { $ref: '#/components/schemas/Payment' }
    JournalEntry:
      type: object
      properties:
        id: { type: integer, format: int64 }
        number: { type: string }
        memo: { type: string, nullable: true }
        date: { type: string, format: date-time }
        active: { type: boolean }
        status: { type: string }
        modifiedOn: { type: string, format: date-time }
        details:
          type: array
          items:
            type: object
            properties:
              accountId: { type: integer }
              debit: { type: number }
              credit: { type: number }
              description: { type: string, nullable: true }