Tekmetric Appointments API
Lists and filters a shop's scheduled appointments by date, customer, or vehicle, and retrieves a single appointment by ID.
Lists and filters a shop's scheduled appointments by date, customer, or vehicle, and retrieves a single appointment by ID.
openapi: 3.0.3
info:
title: Tekmetric API
description: >-
Tekmetric is a cloud-based auto repair shop management platform. Its REST
API is partner-gated - access requires requesting credentials at
api.tekmetric.com and Tekmetric's approval (reported at roughly 2-3
weeks); there is no self-serve signup or public API reference. The
endpoints, parameters, and response envelope documented here are sourced
from beetlebugorg/tekmetric-mcp, an independent open-source client that
holds approved credentials and calls the live API - not from an official
Tekmetric API reference document. Only read (GET) endpoints are
documented because that is all the reference client implements; write
endpoints may exist but are not evidenced in any public source.
version: v1
contact:
name: Tekmetric
url: https://www.tekmetric.com/
x-source-note: >-
Endpoint shapes confirmed via github.com/beetlebugorg/tekmetric-mcp
(pkg/tekmetric/*.go), an unofficial, independently maintained client, not
an official Tekmetric-published specification.
servers:
- url: https://shop.tekmetric.com/api/v1
description: Production
- url: https://sandbox.tekmetric.com/api/v1
description: Sandbox
security:
- oauth2: []
tags:
- name: Shops
description: Shop locations, hours, labor rates, and settings.
- name: Customers
description: Shop customers and their contact information.
- name: Vehicles
description: Customer vehicles serviced by the shop.
- name: Repair Orders
description: Estimates and invoices tracking a vehicle's work.
- name: Jobs
description: Individual services (labor and parts) within a repair order.
- name: Employees
description: Shop technicians and staff.
- name: Appointments
description: Scheduled shop appointments.
- name: Inventory
description: Parts and tire inventory.
- name: Canned Jobs
description: Pre-built menu services bundling standard labor and parts.
paths:
/oauth/token:
post:
operationId: getAccessToken
tags:
- Shops
summary: Obtain an OAuth 2.0 access token
description: >-
Exchanges an approved Client ID/Secret (sent as HTTP Basic auth) for a
bearer access token via the client_credentials grant. The token's
scope field lists the space-separated shop IDs the client may access.
security: []
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
type: object
required:
- grant_type
properties:
grant_type:
type: string
enum:
- client_credentials
responses:
'200':
description: Access token issued.
content:
application/json:
schema:
$ref: '#/components/schemas/TokenResponse'
'401':
$ref: '#/components/responses/Unauthorized'
/shops:
get:
operationId: listShops
tags:
- Shops
summary: List authorized shops
description: Lists the shop records the authenticated OAuth client is scoped to.
responses:
'200':
description: A list of shops.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Shop'
'401':
$ref: '#/components/responses/Unauthorized'
/shops/{id}:
parameters:
- $ref: '#/components/parameters/Id'
get:
operationId: getShop
tags:
- Shops
summary: Get a shop
description: Retrieves a single shop's hours, labor rates, and settings by ID.
responses:
'200':
description: The requested shop.
content:
application/json:
schema:
$ref: '#/components/schemas/Shop'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/customers:
get:
operationId: listCustomers
tags:
- Customers
summary: List or search customers
description: >-
Lists a shop's customers, optionally filtered by a search term
(name, email, or phone) and customer attributes.
parameters:
- $ref: '#/components/parameters/Shop'
- $ref: '#/components/parameters/Page'
- $ref: '#/components/parameters/Size'
- name: search
in: query
required: false
description: Free-text search across name, email, and phone.
schema:
type: string
- name: eligibleForAccountsReceivable
in: query
required: false
schema:
type: boolean
- name: okForMarketing
in: query
required: false
schema:
type: boolean
- name: customerTypeId
in: query
required: false
schema:
type: integer
responses:
'200':
description: A page of customers.
content:
application/json:
schema:
$ref: '#/components/schemas/CustomerPage'
'401':
$ref: '#/components/responses/Unauthorized'
/customers/{id}:
parameters:
- $ref: '#/components/parameters/Id'
get:
operationId: getCustomer
tags:
- Customers
summary: Get a customer
description: >-
Retrieves a single customer's contact info, addresses, and
marketing/accounts-receivable flags by ID.
responses:
'200':
description: The requested customer.
content:
application/json:
schema:
$ref: '#/components/schemas/Customer'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/vehicles:
get:
operationId: listVehicles
tags:
- Vehicles
summary: List or search vehicles
description: >-
Lists a shop's vehicles, optionally filtered by a search term (VIN,
license plate, make/model) or owning customer.
parameters:
- $ref: '#/components/parameters/Shop'
- $ref: '#/components/parameters/Page'
- $ref: '#/components/parameters/Size'
- name: search
in: query
required: false
description: Free-text search across VIN, license plate, and make/model.
schema:
type: string
- name: customerId
in: query
required: false
schema:
type: integer
responses:
'200':
description: A page of vehicles.
content:
application/json:
schema:
$ref: '#/components/schemas/VehiclePage'
'401':
$ref: '#/components/responses/Unauthorized'
/vehicles/{id}:
parameters:
- $ref: '#/components/parameters/Id'
get:
operationId: getVehicle
tags:
- Vehicles
summary: Get a vehicle
description: Retrieves a single vehicle by ID.
responses:
'200':
description: The requested vehicle.
content:
application/json:
schema:
$ref: '#/components/schemas/Vehicle'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/repair-orders:
get:
operationId: listRepairOrders
tags:
- Repair Orders
summary: List or filter repair orders
description: >-
Lists a shop's repair orders, filterable by repair order number,
status, customer, or vehicle. Combining a date-range filter with a
deleted-date filter returns only deleted records; call separately for
active/updated versus deleted records and merge client-side.
parameters:
- $ref: '#/components/parameters/Shop'
- $ref: '#/components/parameters/Page'
- $ref: '#/components/parameters/Size'
- name: repairOrderNumber
in: query
required: false
schema:
type: integer
- name: repairOrderStatusId
in: query
required: false
schema:
type: integer
- name: customerId
in: query
required: false
schema:
type: integer
- name: vehicleId
in: query
required: false
schema:
type: integer
responses:
'200':
description: A page of repair orders.
content:
application/json:
schema:
$ref: '#/components/schemas/RepairOrderPage'
'401':
$ref: '#/components/responses/Unauthorized'
/repair-orders/{id}:
parameters:
- $ref: '#/components/parameters/Id'
get:
operationId: getRepairOrder
tags:
- Repair Orders
summary: Get a repair order
description: Retrieves a single repair order, including totals and workflow status, by ID.
responses:
'200':
description: The requested repair order.
content:
application/json:
schema:
$ref: '#/components/schemas/RepairOrder'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/jobs:
get:
operationId: listJobs
tags:
- Jobs
summary: List or filter jobs
description: >-
Lists the individual jobs (services) within repair orders, filterable
by vehicle, repair order, customer, authorization state, or repair
order status.
parameters:
- $ref: '#/components/parameters/Shop'
- $ref: '#/components/parameters/Page'
- $ref: '#/components/parameters/Size'
- name: vehicleId
in: query
required: false
schema:
type: integer
- name: repairOrderId
in: query
required: false
schema:
type: integer
- name: customerId
in: query
required: false
schema:
type: integer
- name: authorized
in: query
required: false
schema:
type: boolean
- name: repairOrderStatusId
in: query
required: false
schema:
type: integer
responses:
'200':
description: A page of jobs.
content:
application/json:
schema:
$ref: '#/components/schemas/JobPage'
'401':
$ref: '#/components/responses/Unauthorized'
/jobs/{id}:
parameters:
- $ref: '#/components/parameters/Id'
get:
operationId: getJob
tags:
- Jobs
summary: Get a job
description: >-
Retrieves a single job with its labor lines, parts, and technician
assignments by ID.
responses:
'200':
description: The requested job.
content:
application/json:
schema:
$ref: '#/components/schemas/Job'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/employees:
get:
operationId: listEmployees
tags:
- Employees
summary: List employees
description: Lists a shop's employees (technicians and staff).
parameters:
- $ref: '#/components/parameters/Shop'
- $ref: '#/components/parameters/Page'
- $ref: '#/components/parameters/Size'
responses:
'200':
description: A page of employees.
content:
application/json:
schema:
$ref: '#/components/schemas/EmployeePage'
'401':
$ref: '#/components/responses/Unauthorized'
/employees/{id}:
parameters:
- $ref: '#/components/parameters/Id'
get:
operationId: getEmployee
tags:
- Employees
summary: Get an employee
description: Retrieves a single employee by ID.
responses:
'200':
description: The requested employee.
content:
application/json:
schema:
$ref: '#/components/schemas/Employee'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/appointments:
get:
operationId: listAppointments
tags:
- Appointments
summary: List or filter appointments
description: Lists a shop's scheduled appointments, filterable by customer or vehicle.
parameters:
- $ref: '#/components/parameters/Shop'
- $ref: '#/components/parameters/Page'
- $ref: '#/components/parameters/Size'
- name: customerId
in: query
required: false
schema:
type: integer
- name: vehicleId
in: query
required: false
schema:
type: integer
- name: includeDeleted
in: query
required: false
schema:
type: boolean
default: false
responses:
'200':
description: A page of appointments.
content:
application/json:
schema:
$ref: '#/components/schemas/AppointmentPage'
'401':
$ref: '#/components/responses/Unauthorized'
/appointments/{id}:
parameters:
- $ref: '#/components/parameters/Id'
get:
operationId: getAppointment
tags:
- Appointments
summary: Get an appointment
description: Retrieves a single appointment by ID.
responses:
'200':
description: The requested appointment.
content:
application/json:
schema:
$ref: '#/components/schemas/Appointment'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/inventory:
get:
operationId: listInventory
tags:
- Inventory
summary: List inventory parts
description: >-
Lists a shop's parts inventory, filterable by part type and tire
attributes (ratio, diameter).
parameters:
- $ref: '#/components/parameters/Shop'
- $ref: '#/components/parameters/Page'
- $ref: '#/components/parameters/Size'
- name: partTypeId
in: query
required: false
schema:
type: integer
- name: ratio
in: query
required: false
description: Tire aspect ratio, when filtering tire inventory.
schema:
type: number
- name: diameter
in: query
required: false
description: Tire diameter, when filtering tire inventory.
schema:
type: number
responses:
'200':
description: A page of inventory parts.
content:
application/json:
schema:
$ref: '#/components/schemas/InventoryPartPage'
'401':
$ref: '#/components/responses/Unauthorized'
/canned-jobs:
get:
operationId: listCannedJobs
tags:
- Canned Jobs
summary: List canned jobs
description: >-
Lists a shop's canned jobs - pre-built menu services bundling
standard labor and parts - available to apply to estimates.
parameters:
- $ref: '#/components/parameters/Shop'
- $ref: '#/components/parameters/Page'
- $ref: '#/components/parameters/Size'
responses:
'200':
description: A page of canned jobs.
content:
application/json:
schema:
$ref: '#/components/schemas/CannedJobPage'
'401':
$ref: '#/components/responses/Unauthorized'
components:
securitySchemes:
oauth2:
type: oauth2
description: >-
OAuth 2.0 client credentials grant. Requires an approved Client
ID/Secret issued by Tekmetric after a manual request-access review
(reported at roughly 2-3 weeks).
flows:
clientCredentials:
tokenUrl: https://shop.tekmetric.com/api/v1/oauth/token
scopes: {}
parameters:
Id:
name: id
in: path
required: true
description: The numeric ID of the resource.
schema:
type: integer
Shop:
name: shop
in: query
required: false
description: The shop ID to scope the request to.
schema:
type: integer
Page:
name: page
in: query
required: false
description: Zero-based page number.
schema:
type: integer
default: 0
Size:
name: size
in: query
required: false
description: Page size.
schema:
type: integer
default: 20
responses:
Unauthorized:
description: Missing, invalid, or revoked access token.
NotFound:
description: The requested resource was not found.
schemas:
TokenResponse:
type: object
properties:
access_token:
type: string
token_type:
type: string
example: Bearer
expires_in:
type: integer
description: >-
Reported token lifetime in seconds. Per third-party accounts,
tokens remain valid until explicitly revoked by Tekmetric
regardless of this value.
scope:
type: string
description: Space-separated shop IDs the client is authorized for.
Page:
type: object
description: Spring Data Page envelope used by all list endpoints.
properties:
totalPages:
type: integer
totalElements:
type: integer
first:
type: boolean
last:
type: boolean
size:
type: integer
number:
type: integer
numberOfElements:
type: integer
Currency:
type: number
format: double
description: Monetary value in dollars (Tekmetric stores cents internally).
Address:
type: object
properties:
id:
type: integer
address1:
type: string
address2:
type: string
city:
type: string
state:
type: string
zip:
type: string
streetAddress:
type: string
fullAddress:
type: string
Phone:
type: object
properties:
id:
type: integer
number:
type: string
type:
type: string
Shop:
type: object
properties:
id:
type: integer
name:
type: string
address:
$ref: '#/components/schemas/Address'
phone:
type: string
timezone:
type: string
Customer:
type: object
properties:
id:
type: integer
firstName:
type: string
lastName:
type: string
email:
type: string
phone:
type: array
items:
$ref: '#/components/schemas/Phone'
address:
$ref: '#/components/schemas/Address'
eligibleForAccountsReceivable:
type: boolean
okForMarketing:
type: boolean
customerTypeId:
type: integer
CustomerPage:
allOf:
- $ref: '#/components/schemas/Page'
- type: object
properties:
content:
type: array
items:
$ref: '#/components/schemas/Customer'
Vehicle:
type: object
properties:
id:
type: integer
customerId:
type: integer
vin:
type: string
year:
type: integer
make:
type: string
model:
type: string
subModel:
type: string
licensePlate:
type: string
VehiclePage:
allOf:
- $ref: '#/components/schemas/Page'
- type: object
properties:
content:
type: array
items:
$ref: '#/components/schemas/Vehicle'
RepairOrder:
type: object
properties:
id:
type: integer
shopId:
type: integer
repairOrderNumber:
type: integer
customerId:
type: integer
vehicleId:
type: integer
repairOrderStatusId:
type: integer
totalSales:
$ref: '#/components/schemas/Currency'
createdDate:
type: string
format: date-time
updatedDate:
type: string
format: date-time
deletedDate:
type: string
format: date-time
nullable: true
RepairOrderPage:
allOf:
- $ref: '#/components/schemas/Page'
- type: object
properties:
content:
type: array
items:
$ref: '#/components/schemas/RepairOrder'
Job:
type: object
properties:
id:
type: integer
repairOrderId:
type: integer
vehicleId:
type: integer
customerId:
type: integer
name:
type: string
authorized:
type: boolean
repairOrderStatusId:
type: integer
laborTotal:
$ref: '#/components/schemas/Currency'
partsTotal:
$ref: '#/components/schemas/Currency'
JobPage:
allOf:
- $ref: '#/components/schemas/Page'
- type: object
properties:
content:
type: array
items:
$ref: '#/components/schemas/Job'
Employee:
type: object
properties:
id:
type: integer
firstName:
type: string
lastName:
type: string
email:
type: string
role:
type: string
EmployeePage:
allOf:
- $ref: '#/components/schemas/Page'
- type: object
properties:
content:
type: array
items:
$ref: '#/components/schemas/Employee'
Appointment:
type: object
properties:
id:
type: integer
shopId:
type: integer
customerId:
type: integer
vehicleId:
type: integer
startTime:
type: string
format: date-time
endTime:
type: string
format: date-time
notes:
type: string
AppointmentPage:
allOf:
- $ref: '#/components/schemas/Page'
- type: object
properties:
content:
type: array
items:
$ref: '#/components/schemas/Appointment'
InventoryPart:
type: object
properties:
id:
type: integer
partTypeId:
type: integer
partNumber:
type: string
description:
type: string
quantityOnHand:
type: number
ratio:
type: number
nullable: true
diameter:
type: number
nullable: true
InventoryPartPage:
allOf:
- $ref: '#/components/schemas/Page'
- type: object
properties:
content:
type: array
items:
$ref: '#/components/schemas/InventoryPart'
CannedJob:
type: object
properties:
id:
type: integer
name:
type: string
description:
type: string
smart:
type: boolean
description: Whether this is a "smart" canned job that adapts to vehicle fitment.
CannedJobPage:
allOf:
- $ref: '#/components/schemas/Page'
- type: object
properties:
content:
type: array
items:
$ref: '#/components/schemas/CannedJob'