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 }