Jobber is an award-winning business management platform for small home service businesses. Unlike spreadsheets or pen and paper, Jobber keeps track of everything in one place and automates day-to-day operations, so small businesses can provide 5-star service at scale. Jobber’s 300,000+ Home Service Pros have served over 12 million households in more than 47 countries.
Jobber's GraphQL API lets you build apps and integrations on top of one of the leading platforms for home service businesses. Whether you're listing an app in the Jobber App Marketplace or building a private integration for a single account, this is your starting point.
Jobber's API is GraphQL over HTTPS. All requests are sent via POST to a single endpoint:
https://api.getjobber.com/api/graphql
Every request must include the following headers:
Authorization: Bearer <ACCESS_TOKEN> (obtained via OAuth 2.0)X-JOBBER-GRAPHQL-VERSION (set to an active API version)Content-Type: application/jsonExample request:
curl -X POST \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "X-JOBBER-GRAPHQL-VERSION: 2025-04-16" \
-H "Content-Type: application/json" \
-d '{"query": "{ account { name } }"}' \
https://api.getjobber.com/api/graphql
For an introduction to GraphQL, see the official GraphQL documentation. The full Jobber API schema can be explored interactively using GraphiQL.
Jobber uses the OAuth 2.0 authorization code grant to give apps access to a user's Jobber account. When a user connects your app, they authorize it to access their data based on the scopes configured on the app. Access tokens expire after 60 minutes and must be refreshed using the refresh token, without requiring the user to re-authorize. Refresh tokens are long-lived but must be stored securely and rotated correctly; improper handling is one of the most common sources of production issues. Apps published in the Jobber App Marketplace must also handle app disconnects correctly. See App Authorization for the full flow and Refresh Token Rotation for token management guidance.
Scopes define exactly what data your app can read or write. They are configured when creating your app in the Developer Center and are displayed to users on the OAuth authorization page. Jobber recommends selecting only the scopes your app will require.
The Jobber API is versioned by date (e.g., 2025-04-16). A version must be specified on every request using the X-JOBBER-GRAPHQL-VERSION header. Versions are supported for at least 12 months. Breaking changes are documented in the Changelog, and warning messages are returned in responses when you're on a version approaching end-of-support. See API Versioning for details.
The API enforces a query cost-based rate limit (maximum 10,000 points per app/account pair, restoring at 500 points per second) and a request rate limit (2,500 requests per 5 minutes). Cost information is included in every response under the extensions.cost key.
"extensions": {
"cost": {
"requestedQueryCost": 142,
"actualQueryCost": 47,
"throttleStatus": {
"maximumAvailable": 10000,
"currentlyAvailable": 9953,
"restoreRate": 500
}
}
}
Paginating collection queries and avoiding deeply nested queries are the most effective ways to stay within these limits. See API Rate Limits for the full breakdown.
Every object in the Jobber API has an id field of type EncodedId, which is a base64-encoded string that uniquely identifies that record. For example, a client ID of “Z2lkOi8vSm9iYmVyL0NsaWVudC8xMTkxOTUzNDA” decodes to gid://Jobber/Client/119195340.
Webhooks allow your app to respond to events in Jobber in real time rather than polling the API. They are configured in the Developer Center per app, where a full list of available webhook events is also accessible. When a subscribed event occurs, Jobber sends an HTTP POST request to your configured endpoint. See Setting Up Webhooks for setup instructions and payload formats.
This section provides a high-level overview of the components in Jobber's API. Our list of field names is always changing. For the most up-to-date schema, please follow our Getting Started steps and view everything in GraphiQL.
The Jobber account used for business operations by a Service Provider.
type Account {
id: EncodedId! # The unique identifier
countryCode: String # The country the account is based in, formatted as an ISO 3166-1 alpha-2 code (e.g. "US", "CA")
createdAt: ISO8601DateTime! # The date the account was created
dedicatedPhoneNumber: String # The dedicated phone number of the account
earliestInvoiceIssuedDate: ISO8601DateTime # The earliest invoice issued date
features: [AccountFeature!] # A list of features
industry: Industry # Industry associated with the account
name: String! # The name of the company
phone: String # The phone number of the account
signupName: String # The name of the signup attribute
}
An assessment represents each time a Service Provider goes to a client property to assess and plan for future work.
type Assessment {
id: EncodedId! # The unique identifier
allDay: Boolean! # Indicates whether the scheduled item is for a full day
assignedUsers: UserConnection # Users assigned to the scheduled item
client: Client! # The client for the assessment
clientConfirmed: Boolean! # Whether the client has confirmed this assessment
completedAt: ISO8601DateTime # The time that the assessment was completed.
createdBy: User # The user that created this scheduled item
duration: Int # Minute duration between start and end time
endAt: ISO8601DateTime # End date and time of the scheduled item. An unscheduled visit has both startAt and endAt being null
instructions: String # The instructions for the assessment
isComplete: Boolean! # Whether the assessment has been completed
isDefaultTitle: Boolean! # Indicates whether the title is the default
overrideOrder: Int # An override for ordering anytime and unscheduled items
property: Property # The property for the assessment
request: Request! # The parent request associated with this assessment
routingOrder: Int # The order in which the scheduled item should be routed
startAt: ISO8601DateTime # Start date and time of the scheduled item. An unscheduled visit has both startAt and endAt being null
teamReminderOffset: Minutes # Offset in minutes from the time of the scheduled item to notify the team
title: String # The title of the scheduled item
}
Clients are the customers who pay for services on Jobber's platform - they belong to the Jobber account / service provider. Most other objects are linked to a client.
type Client {
id: EncodedId! # The unique identifier
balance: Float! # The client's current balance
billingAddress: ClientAddress # The billing address of the client
billingAddressPresent: Boolean! # Is a custom billing address present for this client?
clientProperties: PropertyConnection! # The properties belonging to the client which are serviced by the service provider
companyName: String # The name of the business
contacts: ContactModelConnection! # The contacts associated with the client
createdAt: ISO8601DateTime! # The time the client was created
customFields: [CustomFieldUnion!]! # The custom fields set for this object
defaultEmails: [String!]! # The email address stored from previous communications
defaultPhones: [String!]! # Default phone numbers to fetch for the given message type.
email: String # The client's primary email address
emails: [Email!]! # The email addresses belonging to the client
firstName: String! # The first name of the client
invoices: InvoiceConnection! # The invoices associated with the client
isArchivable: Boolean! # Is the client archivable
isArchived: Boolean! # Is the client archived
isCompany: Boolean! # Does the client represent a business
isLead: Boolean! # Is the client a prospective lead for the service provider
jobberWebUri: String! # The URI for the given record in Jobber Online
jobs: JobConnection! # The jobs associated with the client
lastName: String! # The last name of the client
name: String! # The primary name of the client
noteAttachments: ClientNoteFileConnection! # The note files attached to the client
notes: ClientNoteConnection! # The notes attached to the client
phone: String # The client's primary phone number
phones: [ClientPhoneNumber!]! # The phone numbers belonging to the client
quotes: QuoteConnection! # The quotes associated with the client
receivesFollowUps: Boolean! # Does the client receive job follow ups
receivesInvoiceFollowUps: Boolean! # Does the client receive invoice follow ups
receivesQuoteFollowUps: Boolean! # Does the client receive quote follow ups
receivesReminders: Boolean! # Does the client receive assessment or visit reminders
receivesReviewRequests: Boolean! # Does the client receive review requests
requestedWorkObjects: RequestedWorkObjectUnionConnection # The client's requests, quotes, jobs, invoices, and treatments, defaulting to descending modified date order
requests: RequestConnection! # The requests associated with the client
scheduledItems: ScheduledItemInterfaceConnection! # All scheduled items associated with the client, including both scheduled and unscheduled appointments
secondaryName: String # The secondary name of the client
sourceAttribution: SourceAttribution # The source of the client object
tags: TagConnection! # The custom tags added to the client
title: String # The title of the client
unallocatedDepositRecords: PaymentRecordInterfaceConnection! # The deposit records that haven't been applied to an invoice and have not been refunded
updatedAt: ISO8601DateTime! # The last time the client was updated
workObjects: WorkObjectUnionConnection # The client's requests, quotes, jobs, and invoices sorted descending by modified date
}
An expense incurred by a Service Provider.
type Expense {
id: EncodedId! # The unique identifier
createdAt: ISO8601DateTime! # When the expense was created
date: ISO8601DateTime! # When the expense was incurred
description: String # The description of the expense
enteredBy: User # The user who filled out the expense
linkedJob: Job # The associated Job
paidBy: User # The user who paid the expense
reimbursableTo: User # The user receiving the reimbursed expense amount
title: String! # The title of the expense
total: Float # Total cost of the expense
updatedAt: ISO8601DateTime! # When the expense was updated
}
A receipt detailing the work done as well as the cost of the service provided.
type Invoice {
id: EncodedId! # The unique identifier
allowReviewRequest: Boolean! # Allow SMS to be sent to client for Google Reviews feature
amounts: InvoiceAmounts # All amounts related to the invoice
archivedJobs: JobConnection! # The archived jobs related to the invoice
billingAddress: InvoiceBillingAddress # The billing address associated with the invoice
billingIsSameAsPropertyAddress: Boolean # Returns whether the billing address is the same as the property address
client: Client # The client the invoice is for
clientHubUri: String # URI of the invoice in client hub
contractDisclaimer: String # The contract disclaimer for the invoice
createdAt: ISO8601DateTime! # The date the invoice was created on
customFields: [CustomFieldUnion!]! # The custom fields set for this object
dateViewedInClientHub: ISO8601DateTime # The date the invoice was viewed in client hub
dueDate: ISO8601DateTime # The date the invoice is due on
hasInvoiceNumberDuplicates: Boolean! # Whether there are other invoices with the same invoice number
hasRefundableSurchargePayments: Boolean! # Whether the invoice has any payment records with refundable surcharge amounts
invoiceNet: Int # Number of whole days after the issue_date that payment is due
invoiceNumber: String! # The invoice number
invoiceStatus: InvoiceStatusTypeEnum! # The status of the invoice
issuedDate: ISO8601DateTime # The date the invoice was issued on
jobberWebUri: String! # The URI for the given record in Jobber Online
jobs: JobConnection! # The jobs related to the invoice
lineItems: InvoiceLineItemConnection! # The line items on the invoice
linkedCommunications: MessageInterfaceConnection! # All messages related to this work object
message: String # The message on the invoice
nextDateToSendReviewSms: ISO8601DateTime # The next available date to send an SMS review request
noteAttachments: InvoiceNoteUnionConnection! # The note files attached to the invoice
notes: InvoiceNoteUnionConnection! # The notes attached to the invoice
paymentRecords: PaymentRecordConnection! # The payment records applied to the invoice
properties: PropertyConnection! # The properties related to the invoice
receivedDate: ISO8601DateTime # The date the invoice was received on
salesperson: User # Salesperson for the invoice
subject: String! # The subject of the invoice
taxCalculationMethod: String! # The tax calculation method on the invoice
taxDetails: TaxDetails # The tax rate and amount details
taxRate: TaxRate # The tax rate information on the invoice
updatedAt: ISO8601DateTime! # The last time the invoice was changed in a way that is meaningful to the Service Provider
visits: VisitConnection! # The visits associated with the invoice
waitingForFinancedPayment: Boolean! # Whether the invoice is waiting for a financed payment
}
A scheduled event where work will take place (e.g., lawn service every Friday at 3pm).
type Job {
id: EncodedId! # The unique identifier
allowReviewRequest: Boolean! # Allow SMS to be sent to client for Google Reviews feature
arrivalWindow: ArrivalWindow # The time window during which the SP can arrive at the job
billingType: BillingStrategy! # Invoicing strategy selected for the job
bookingConfirmationSentAt: ISO8601DateTime # The time when booking confirmation for the job was sent
client: Client! # The client on the job
completedAndUninvoicedVisitsCount: Int! # Count of completed visits that have not been invoiced. Only relevant for visit-based billing jobs.
completedAndUninvoicedVisitsTotal: Float! # The total dollar value of completed visits that have not been invoiced. Only relevant for visit-based billing jobs; returns 0 for fixed-price jobs.
completedAt: ISO8601DateTime # The completion date of the job
createdAt: ISO8601DateTime! # The time the job was created
customFields: [CustomFieldUnion!]! # The custom fields set for this object
defaultVisitTitle: String! # The default title for new visits
endAt: ISO8601DateTime # End date of the job
expenses: ExpenseConnection! # Expenses associated with the job
instructions: String # The instructions on a job
invoicedTotal: Float! # The total invoiced amount of the job
invoices: InvoiceConnection! # The invoices associated with the job
invoiceSchedule: InvoiceSchedule! # Schedule of invoices
jobBalanceTotals: JobBalanceTotals # The total and outstanding balance of the job based on invoice and quote deposits
jobberWebUri: String! # The URI for the given record in Jobber Online
jobCosting: JobCosting # The job costing fields representing the profitability of the job
jobNumber: Integer! # The number of the job
jobStatus: JobStatusTypeEnum! # The status of the job
jobType: JobTypeTypeEnum! # The type of job
lineItems: JobLineItemConnection! # The line items associated with the job
nextDateToSendReviewSms: ISO8601DateTime # The next available date to send an SMS review request
noteAttachments: JobNoteFileConnection! # The note files attached to the job
notes: JobNoteUnionConnection! # The notes attached to the job
paymentRecords: PaymentRecordConnection! # The payment records applied to this job's invoices
property: Property # The property associated with the job
quote: Quote # When applicable, the quote associated with the job
request: Request # When applicable, the request associated with the job
salesperson: User # Salesperson for the job
source: Source! # The originating source of the job
startAt: ISO8601DateTime # Start date of the job
timesheetEntries: TimeSheetEntryConnection! # A list of all timesheet entries for this job
title: String # The scheduling information of the job
total: Float! # The total chargeable amount of the job
uninvoicedTotal: Float! # The total uninvoiced amount of the job
updatedAt: ISO8601DateTime! # The last time the job was changed in a way that is meaningful to the Service Provider
visits: VisitConnection! # The scheduled or unscheduled visits to the customer's property to complete the work associated with the job
visitsInfo: VisitsInfo! # Information about jobs visits
visitSchedule: VisitSchedule! # Schedule of visits
willClientBeAutomaticallyCharged: Boolean # The setting for automatic invoice charges
}
The collection of attributes that represent a product or service.
type ProductOrService {
id: EncodedId! # The unique identifier
bookableType: SelfServeBooking # The type of booking to be created in online booking for the product or service
category: ProductsAndServicesCategory! # The item's category
customFields: [CustomFieldUnion!]! # The custom fields set for this object
defaultUnitCost: Float! # A product or service has a default price
description: String # The description of product or service
durationMinutes: Minutes # The duration of the service in minutes
internalUnitCost: Float # A product or service has a default internal unit cost
lastJobLineItem: JobLineItem # The last line item created for this product or service
lastQuoteLineItem: QuoteLineItem # The last quote line item created for this product or service
markup: Float # A product or service has a default markup
name: String! # The name of the product or service
onlineBookingEnabled: Boolean # Whether the service is enabled on the booking page
onlineBookingSortOrder: Int # Sort order of the service on the booking page
quantityRange: QuantityRange # Quantity range for the product or service when created through online booking
taxable: Boolean # A product or service can be taxable or non-taxable
visible: Boolean # A 'visible' product or service will show up as an autocomplete suggestion on quotes/jobs/invoice line items
}
Properties are locations owned by Service Consumers where Service Providers provide service for.
type Property {
id: EncodedId! # The unique identifier
address: PropertyAddress! # The address of the property
client: Client # The client associated with the property
contacts: ContactModelConnection # The contacts associated with the property
customFields: [CustomFieldUnion!]! # The custom fields set for this object
isBillingAddress: Boolean # Whether the property is a billing address
jobberWebUri: String! # The URI for the given record in Jobber Online
jobs: JobConnection! # The jobs associated with the property
name: String # The name of the property
quotes: QuoteConnection! # The quotes associated with the property
recentPricing: ProductOrServiceConnection # The recently used work items for the property.
requests: RequestConnection! # The requests associated with the property
routingOrder: Int # The routing order of the property
scheduledItems: ScheduledItemInterfaceConnection! # All scheduled items associated with the property, including visits, tasks, assessments, events, and reminders
taxRate: TaxRate # The tax rate of the property
}
A cost estimate which service providers sent to their clients before any work is done.
type Quote {
id: EncodedId! # The unique identifier
amounts: QuoteAmounts! # All amounts related to the quote
client: Client # The client the quote was made for
clientHubUri: String # The URI of the quote in client hub
clientHubViewedAt: ISO8601DateTime # Time the quote was viewed at in Client Hub
contractDisclaimer: String # The contract disclaimer for the quote
createdAt: ISO8601DateTime! # The time the quote was created
customFields: [CustomFieldUnion!]! # The custom fields set for this object
depositAmountUnallocated: Float # Paid deposit amount that is not yet associated with an invoice
depositRecords: PaymentRecordConnection! # The deposit records applied to the quote
eligibleForFinancing: Boolean! # Indicates if the quote is eligible for Wisetack financing offers
hasRefundableSurchargePayments: Boolean! # Whether the quote has any deposit records with refundable surcharge amounts
jobberWebUri: String! # The URI for the given record in Jobber Online
jobs: JobConnection # Job IDs converted from this quote
lineItems: QuoteLineItemConnection! # The line items associated with the quote
message: String # The message to the client
noteAttachments: QuoteNoteFileConnection! # The note files attached to the quote
notes: QuoteNoteUnionConnection! # The notes attached to the quote
previewUrl: String! # The URL of the quote preview in client hub
property: Property # The property the quote was made for
quoteNumber: String! # A non-unique number assigned to the quote by a Service Provider
quoteStatus: QuoteStatusTypeEnum! # The current status the quote
request: Request # The request associated with the quote
salesperson: User # Salesperson for the quote
sentAt: ISO8601DateTime # The time a quote was last sent to the Service Client
taxDetails: TaxDetails # The tax rate and amount details
title: String # The description of the quote
transitionedAt: ISO8601DateTime! # Time the quote transitioned to its current status
unallocatedDepositRecords: PaymentRecordConnection! # The deposit records that haven't been applied to an invoice and are not refunded
updatedAt: ISO8601DateTime! # The last time the quote was changed in a way that is meaningful to the Service Provider
}
Forms which a client can fill to request work to be done.
type Request {
id: EncodedId! # The unique identifier
arrivalWindow: ArrivalWindow # The time window during which the SP can arrive at the assessment associated with the work request
assessment: Assessment # The assessment associated with the work request
client: Client! # The client associated with the work request
companyName: String # The company name provided in the work request
contactName: String # The primary contact of the client requesting work
createdAt: ISO8601DateTime! # The time the work request was created
email: String # The contact email provided in the work request
isArchivable: Boolean! # Whether the work request can be archived
isScheduled: Boolean! # Whether the work request is scheduled
jobberWebUri: String! # The URI for the given record in Jobber Online
jobs: JobConnection! # The jobs associated with the specific work request
lineItems: RequestLineItemConnection # The line items associated with the work request
noteAttachments: RequestNoteFileConnection! # The note files attached to the request
notes: RequestNoteUnionConnection! # The notes attached to the request
phone: String # The contact phone provided in the work request
property: Property # The property associated with the work request
quotes: QuoteConnection! # The quotes associated with the work request
referringClient: Client # The client that referred this work request, if this work request was referred
requestStatus: RequestStatusTypeEnum! # The status of the work request
salesperson: User # Salesperson for the request
source: String! # The source of the work request
title: String # The title of the work request
updatedAt: ISO8601DateTime! # The last time the work request was changed in a way that is meaningful to the Service Provider
}
The recorded time of a Jobber user.
type TimeSheetEntry {
id: EncodedId! # The unique identifier
approved: Boolean! # Indicates whether the time sheet entry is approved
approvedBy: User # User that approved this time sheet entry
client: Client # The client associated with the job linked to the time sheet entry
createdAt: ISO8601DateTime! # The time the time sheet was created
endAt: ISO8601DateTime # Date and time the time sheet entry was completed (resolves to nil for time sheets without a time range)
finalDuration: Seconds! # Duration of a stopped time sheet entry (resolves to 0 for ticking entries)
job: Job # Job linked to the timer
label: String # Label on the time sheet entry
labourRate: Float # Labour rate associated with this time sheet entry
note: String # Note attached
paidBy: User # User that marked this time sheet entry as paid
payable: Boolean! # Indicates whether the time sheet entry is payable.
startAt: ISO8601DateTime! # Date and time the time sheet entry was started
ticking: Boolean! # Flag indicating whether the timer is actively running or not
timeSheetCategory: TimeSheetEntryConfigurationCategory # The category of time associated with this entry
updatedAt: ISO8601DateTime! # The last time the time sheet was updated
user: User # User the time sheet entry belongs to
visit: Visit # Visit linked to the time sheet entry
visitDurationTotal: Int! # Total duration in seconds the user worked on the related visit
}
A user belongs to an account and generally completes work for clients.
type User {
id: EncodedId! # The unique identifier
account: Account # The parent account for the user
address: UserAddress # The address of the user
apps: ApplicationConnection! # List of apps user has connected
assignedColor: String # The color assigned to the user
assignedVehicle: Vehicle # The vehicle assigned to the user
availableForScheduling: Boolean! # Whether the user is available for scheduling
createdAt: ISO8601DateTime! # The time the user was created
customFields: [CustomFieldUnion!]! # The custom fields set for this object
email: UserEmail! # The email address of the user
firstDayOfTheWeek: UserFirstDayOfTheWeekEnum! # The first day of the week of the user's account
franchiseTokenLastFour: String # Returns the last four characters of the franchise access token for the user if one exists
isAccountAdmin: Boolean! # Is the user an administrator on their account
isAccountOwner: Boolean! # Is the user the owner of their account
isCurrentUser: Boolean! # Is this the authenticated user querying
lastLoginAt: ISO8601DateTime # The date the user logged in last
name: Name! # The name of the user
phone: UserPhone # The phone of the user
status: UserStatusEnum! # The status of the user
timeSheetsByDay: TimeSheetUserDayConnection! # Per-day breakdown of time sheet entries for a user
timezone: Timezone # The timezone of the user's account
uuid: String! # The uuid of the user
}
A visit that represents each time a Service Provider goes to a client property to complete work.
type Visit {
id: EncodedId! # The unique identifier
actionsUponComplete: [VisitActionUponComplete!]! # The actions available after completing the visit
allDay: Boolean! # Indicates whether the scheduled item is for a full day
arrivalWindow: ArrivalWindow # The time window during which the SP can arrive at the visit
assignedUsers: UserConnection # Users assigned to the scheduled item
client: Client! # The Client for the visit
clientConfirmed: Boolean! # Whether the client has confirmed this visit
completedAt: ISO8601DateTime # The time that the visit was completed
completedBy: String # The name of the user or system that completed the visit.
createdAt: ISO8601DateTime! # The time that the visit was created
createdBy: User # The user that created this scheduled item
duration: Int # Minute duration between start and end time
endAt: ISO8601DateTime # End date and time of the scheduled item. An unscheduled visit has both startAt and endAt being null
incompleteJobFormsCount: Int! # The number of incomplete job form submissions for this visit
instructions: String # The instructions for the visit
invoice: Invoice # The invoice for the visit
isComplete: Boolean! # Whether the visit has been completed
isDefaultTitle: Boolean! # Indicates whether the title is the default
isLastScheduledVisit: Boolean! # Whether the visit is the last visit for the associated job
job: Job! # The Job the visit is associated with
lineItems: JobLineItemConnection! # A list of all non-zero quantity line items for the visit
notes: JobNoteUnionConnection # The notes attached to the associated job
overrideOrder: Int # An override for ordering anytime and unscheduled items
property: Property! # The property for the visit
routingOrder: Int # The order in which the scheduled item should be routed
startAt: ISO8601DateTime # Start date and time of the scheduled item. An unscheduled visit has both startAt and endAt being null
teamReminderOffset: Minutes # Offset in minutes from the time of the scheduled item to notify the team
timeSheetEntries: TimeSheetEntryConnection # A list of all timesheet entries for this visit
title: String # The title of the scheduled item
visitStatus: VisitStatusTypeEnum! # The status of the visit
}
Reach out to our API support team at: [email protected].