REST endpoints for pricebook in ServFlo: 26 operations with parameters, request and response fields, permissions and curl examples.
Base URL: https://app.servflo.ai/api. Every call needs Authorization: Bearer sfk_… (Authentication); {organizationId} ($ORGANIZATION_ID in the examples) is your business's id.
POST /organizations/{organizationId}/pricebook/categories/{categoryId}/image/content
Sets the picture of a pricebook category in one call, replacing the old one: send contentBase64 or a public sourceUrl (an image, up to 10 MB). Shown on quotes, the presenter and the technician app. Returns the image with a 10-minute URL.
Permission
pricebook.manage (Owner, Admin)
Risk
write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
The file's name, e.g. receipt.jpg (default: from the URL, else 'file'). Up to 500 characters.
contentType
string
No
MIME type, e.g. image/jpeg or application/pdf. Optional: taken from a data: URL, the URL's answer or the file's first bytes. Up to 200 characters.
contentBase64
string
No
The file's bytes as base64 (a data: URL is accepted too). Up to 10 MB. Give this or sourceUrl.
sourceUrl
string (uri)
No
A public http(s) URL ServFlo downloads the file from (up to 10 MB, 20 s, 3 redirects; private and internal addresses are refused). Give this or contentBase64. Up to 2000 characters.
GET /organizations/{organizationId}/pricebook/items
Items with price, member price, stock on hand and image (and, with costing.read, cost and margin), filtered by text (name, code, description, vendor part number), category (sub-categories included), kind or vendor; active only unless includeInactive. Paged with a total. The original materials and service types appear here as items (linked by materialId / serviceTypeId). Read-only.
Free-text search over the list's names, numbers and contact details. Up to 200 characters.
categoryId
query
string
No
kind
query
enum
No
SERVICE (labour, a visit), MATERIAL (parts kept in stock), EQUIPMENT (units installed, kept in stock) or FEE (trip charge, disposal). One of SERVICE, MATERIAL, EQUIPMENT, FEE.
vendorId
query
string
No
includeInactive
query
boolean or enum
No
limit
query
integer
No
Page size, 1–200. Default 50.
offset
query
integer
No
Rows to skip; the answer's total counts every match. Default 0.
SERVICE (labour, a visit), MATERIAL (parts kept in stock), EQUIPMENT (units installed, kept in stock) or FEE (trip charge, disposal). One of SERVICE, MATERIAL, EQUIPMENT, FEE.
items[].code
string or null
items[].name
string
items[].description
string or null
items[].internalNotes
string or null
items[].categoryId
string or null
items[].unit
string
items[].costCents
integer
Our unit cost. Present only for roles with costing.read.
items[].priceCents
integer
Integer cents.
items[].priceMode
enum
Fixed:priceCents is the price. MARKUP: the price is computed from costCents through the markup tiers (GET /pricing-settings) and follows the cost. One of FIXED, MARKUP.
items[].memberPriceCents
integer or null
items[].taxable
boolean
items[].durationMinutes
integer or null
items[].vendorId
string or null
items[].vendorPartNumber
string or null
items[].active
boolean
items[].serviceTypeId
string or null
items[].materialId
string or null
The original material (Settings → Materials) this item is, if any.
items[].createdAt
string (date-time)
items[].updatedAt
string (date-time)
items[].category
object or null
items[].category.id
string
items[].category.name
string
items[].category.parentId
string or null
items[].vendor
object or null
items[].vendor.id
string
items[].vendor.name
string
items[].serviceType
object or null
items[].serviceType.id
string
items[].serviceType.name
string
items[].serviceType.color
string
items[].imageUrl
string or null
A 10-minute signed URL of the item's image.
items[].marginCents
integer
Price − cost. Present only for roles with costing.read.
items[].marginPercent
number or null
Margin as a percent of the price. Present only for roles with costing.read.
items[].onHand
number
Stock on hand across every location (stocked kinds).
POST /organizations/{organizationId}/pricebook/items
Adds an item. In MARKUP mode the price is computed from the cost through the markup tiers. A duplicate code is 409. Documents already written are never changed by pricebook edits (their lines keep snapshots). Returns the item.
Permission
pricebook.manage (Owner, Admin)
Risk
write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
SERVICE (labour, a visit), MATERIAL (parts kept in stock), EQUIPMENT (units installed, kept in stock) or FEE (trip charge, disposal). One of SERVICE, MATERIAL, EQUIPMENT, FEE.
code
string or null
No
Code / SKU, unique in the organization when set. Up to 100 characters.
name
string
Yes
Up to 500 characters.
description
string or null
No
Customer-facing: printed on quotes and invoices.
internalNotes
string or null
No
Staff only.
categoryId
string or null
No
From GET /pricebook/categories.
unit
string
No
ea, hr, ft…; blank means "ea". Up to 50 characters.
costCents
integer
No
Our unit cost in cents (purchase receipts update it by moving average). 0–100000000.
priceCents
integer
No
The unit price in cents (ignored in MARKUP mode). 0–100000000.
priceMode
enum
No
Fixed:priceCents is the price. MARKUP: the price is computed from costCents through the markup tiers (GET /pricing-settings) and follows the cost. One of FIXED, MARKUP.
memberPriceCents
integer or null
No
Price for customers with an active membership; it replaces the plan's discount on this item. Null: the plan's discount applies. 0–100000000.
taxable
boolean
No
durationMinutes
integer or null
No
Services: how long the work usually takes. 0–100000.
vendorId
string or null
No
From GET /vendors.
vendorPartNumber
string or null
No
Up to 200 characters.
active
boolean
No
Retired items (false) leave the pickers.
serviceTypeId
string or null
No
The service type this item is (one item per service type).
SERVICE (labour, a visit), MATERIAL (parts kept in stock), EQUIPMENT (units installed, kept in stock) or FEE (trip charge, disposal). One of SERVICE, MATERIAL, EQUIPMENT, FEE.
code
string or null
name
string
description
string or null
internalNotes
string or null
categoryId
string or null
unit
string
costCents
integer
Our unit cost. Present only for roles with costing.read.
priceCents
integer
Integer cents.
priceMode
enum
Fixed:priceCents is the price. MARKUP: the price is computed from costCents through the markup tiers (GET /pricing-settings) and follows the cost. One of FIXED, MARKUP.
memberPriceCents
integer or null
taxable
boolean
durationMinutes
integer or null
vendorId
string or null
vendorPartNumber
string or null
active
boolean
serviceTypeId
string or null
materialId
string or null
The original material (Settings → Materials) this item is, if any.
createdAt
string (date-time)
updatedAt
string (date-time)
category
object or null
category.id
string
category.name
string
category.parentId
string or null
vendor
object or null
vendor.id
string
vendor.name
string
serviceType
object or null
serviceType.id
string
serviceType.name
string
serviceType.color
string
imageUrl
string or null
A 10-minute signed URL of the item's image.
marginCents
integer
Price − cost. Present only for roles with costing.read.
marginPercent
number or null
Margin as a percent of the price. Present only for roles with costing.read.
onHand
number
Stock on hand across every location (stocked kinds).
SERVICE (labour, a visit), MATERIAL (parts kept in stock), EQUIPMENT (units installed, kept in stock) or FEE (trip charge, disposal). One of SERVICE, MATERIAL, EQUIPMENT, FEE.
code
string or null
name
string
description
string or null
internalNotes
string or null
categoryId
string or null
unit
string
costCents
integer
Our unit cost. Present only for roles with costing.read.
priceCents
integer
Integer cents.
priceMode
enum
Fixed:priceCents is the price. MARKUP: the price is computed from costCents through the markup tiers (GET /pricing-settings) and follows the cost. One of FIXED, MARKUP.
memberPriceCents
integer or null
taxable
boolean
durationMinutes
integer or null
vendorId
string or null
vendorPartNumber
string or null
active
boolean
serviceTypeId
string or null
materialId
string or null
The original material (Settings → Materials) this item is, if any.
createdAt
string (date-time)
updatedAt
string (date-time)
category
object or null
category.id
string
category.name
string
category.parentId
string or null
vendor
object or null
vendor.id
string
vendor.name
string
serviceType
object or null
serviceType.id
string
serviceType.name
string
serviceType.color
string
imageUrl
string or null
A 10-minute signed URL of the item's image.
marginCents
integer
Price − cost. Present only for roles with costing.read.
marginPercent
number or null
Margin as a percent of the price. Present only for roles with costing.read.
onHand
number
Stock on hand across every location (stocked kinds).
Changes the fields sent; MARKUP items are repriced from their cost. The original material or service type linked to the item takes the new name, unit, price and duration. Quotes, invoices and jobs already written keep their own prices and costs. Returns the item.
Permission
pricebook.manage (Owner, Admin)
Risk
write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
SERVICE (labour, a visit), MATERIAL (parts kept in stock), EQUIPMENT (units installed, kept in stock) or FEE (trip charge, disposal). One of SERVICE, MATERIAL, EQUIPMENT, FEE.
code
string or null
No
Code / SKU, unique in the organization when set. Up to 100 characters.
name
string
No
Up to 500 characters.
description
string or null
No
Customer-facing: printed on quotes and invoices.
internalNotes
string or null
No
Staff only.
categoryId
string or null
No
From GET /pricebook/categories.
unit
string
No
ea, hr, ft…; blank means "ea". Up to 50 characters.
costCents
integer
No
Our unit cost in cents (purchase receipts update it by moving average). 0–100000000.
priceCents
integer
No
The unit price in cents (ignored in MARKUP mode). 0–100000000.
priceMode
enum
No
Fixed:priceCents is the price. MARKUP: the price is computed from costCents through the markup tiers (GET /pricing-settings) and follows the cost. One of FIXED, MARKUP.
memberPriceCents
integer or null
No
Price for customers with an active membership; it replaces the plan's discount on this item. Null: the plan's discount applies. 0–100000000.
taxable
boolean
No
durationMinutes
integer or null
No
Services: how long the work usually takes. 0–100000.
vendorId
string or null
No
From GET /vendors.
vendorPartNumber
string or null
No
Up to 200 characters.
active
boolean
No
Retired items (false) leave the pickers.
serviceTypeId
string or null
No
The service type this item is (one item per service type).
SERVICE (labour, a visit), MATERIAL (parts kept in stock), EQUIPMENT (units installed, kept in stock) or FEE (trip charge, disposal). One of SERVICE, MATERIAL, EQUIPMENT, FEE.
code
string or null
name
string
description
string or null
internalNotes
string or null
categoryId
string or null
unit
string
costCents
integer
Our unit cost. Present only for roles with costing.read.
priceCents
integer
Integer cents.
priceMode
enum
Fixed:priceCents is the price. MARKUP: the price is computed from costCents through the markup tiers (GET /pricing-settings) and follows the cost. One of FIXED, MARKUP.
memberPriceCents
integer or null
taxable
boolean
durationMinutes
integer or null
vendorId
string or null
vendorPartNumber
string or null
active
boolean
serviceTypeId
string or null
materialId
string or null
The original material (Settings → Materials) this item is, if any.
createdAt
string (date-time)
updatedAt
string (date-time)
category
object or null
category.id
string
category.name
string
category.parentId
string or null
vendor
object or null
vendor.id
string
vendor.name
string
serviceType
object or null
serviceType.id
string
serviceType.name
string
serviceType.color
string
imageUrl
string or null
A 10-minute signed URL of the item's image.
marginCents
integer
Price − cost. Present only for roles with costing.read.
marginPercent
number or null
Margin as a percent of the price. Present only for roles with costing.read.
onHand
number
Stock on hand across every location (stocked kinds).
Destructive: deletes an item that was never stocked or ordered (409 otherwise: retire it with active: false). An original service type's or material's item deletes that record too: jobs, quotes and requests that used the service type keep their own details; a material comes off the jobs that used it. Document lines that used it keep their text and prices.
Permission
pricebook.manage (Owner, Admin)
Risk
sensitive, OAuth scope servflo.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access.
MCP tool
pricebookItems_delete (toolset pricebook)
Approval
Over MCP, this tool always waits for your approval in ServFlo. See Approvals.
POST /organizations/{organizationId}/pricebook/items/{itemId}/duplicate
Copies an item as "<name> (copy)" with the same category, prices, cost, unit, duration, vendor and notes; no code, no stock, no image. A service type's item gets its own new service type (bookable and schedulable like the original), a material's item its own new material. Returns the new item; rename it with update.
Permission
pricebook.manage (Owner, Admin)
Risk
write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
SERVICE (labour, a visit), MATERIAL (parts kept in stock), EQUIPMENT (units installed, kept in stock) or FEE (trip charge, disposal). One of SERVICE, MATERIAL, EQUIPMENT, FEE.
code
string or null
name
string
description
string or null
internalNotes
string or null
categoryId
string or null
unit
string
costCents
integer
Our unit cost. Present only for roles with costing.read.
priceCents
integer
Integer cents.
priceMode
enum
Fixed:priceCents is the price. MARKUP: the price is computed from costCents through the markup tiers (GET /pricing-settings) and follows the cost. One of FIXED, MARKUP.
memberPriceCents
integer or null
taxable
boolean
durationMinutes
integer or null
vendorId
string or null
vendorPartNumber
string or null
active
boolean
serviceTypeId
string or null
materialId
string or null
The original material (Settings → Materials) this item is, if any.
createdAt
string (date-time)
updatedAt
string (date-time)
category
object or null
category.id
string
category.name
string
category.parentId
string or null
vendor
object or null
vendor.id
string
vendor.name
string
serviceType
object or null
serviceType.id
string
serviceType.name
string
serviceType.color
string
imageUrl
string or null
A 10-minute signed URL of the item's image.
marginCents
integer
Price − cost. Present only for roles with costing.read.
marginPercent
number or null
Margin as a percent of the price. Present only for roles with costing.read.
onHand
number
Stock on hand across every location (stocked kinds).
POST /organizations/{organizationId}/pricebook/items/{itemId}/image/{attachmentId}/confirm
Step 2 of 2: the uploaded image becomes the item's image (replacing the previous one), shown in the pricebook browser. Returns it with a 10-minute URL.
Permission
pricebook.manage (Owner, Admin)
Risk
write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
GET /organizations/{organizationId}/pricebook/export
Every item (active or not) as CSV: code, name, kind, category path, unit, cost, price, price mode, member price, taxable, duration, vendor, vendor part number, description, internal notes, active. Money in dollars (12.50). The same format POST /pricebook/import reads. Includes costs, so it needs pricebook.manage (owners and admins). Read-only.
POST /organizations/{organizationId}/pricebook/import
Reads the export's CSV format (only name is required). Rows whose code matches an item update it; others create items. Missing categories (by path, e.g. Parts › Filters) are created; vendors must exist (by name). dryRun: true (do this first) writes nothing and returns what would be created or updated and every problem with its line and column. Applying writes the valid rows in one transaction and reports the skipped ones.
Permission
pricebook.manage (Owner, Admin)
Risk
write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
GET /organizations/{organizationId}/pricebook/starter
The usual services (with duration), materials and fees for a trade (hvac, plumbing, car-detailing, … as in the website builder), at typical US prices, each flagged exists when the pricebook already has that name; genericCount is how many generic starter items (Standard Service, Filter Replacement, …) are still active. Read-only; add with POST /pricebook/starter.
SERVICE (labour, a visit), MATERIAL (parts kept in stock), EQUIPMENT (units installed, kept in stock) or FEE (trip charge, disposal). One of SERVICE, MATERIAL, EQUIPMENT, FEE.
POST /organizations/{organizationId}/pricebook/starter
Adds the trade's starter items (all, or only names from the preview) in a category named after the trade, skipping names the pricebook already has. Services also become service types, so they can be booked and used on jobs. With clearGeneric, the generic starter items are deleted when nothing uses them and retired (inactive, not bookable) when something does. Returns the counts.
Permission
pricebook.manage (Owner, Admin)
Risk
write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
POST /organizations/{organizationId}/pricebook/items/{itemId}/image/content
Sets the picture of a pricebook item in one call, replacing the old one: send contentBase64 or a public sourceUrl (an image, up to 10 MB). Shown on quotes, the presenter and the technician app. Returns the image with a 10-minute URL.
Permission
pricebook.manage (Owner, Admin)
Risk
write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
The file's name, e.g. receipt.jpg (default: from the URL, else 'file'). Up to 500 characters.
contentType
string
No
MIME type, e.g. image/jpeg or application/pdf. Optional: taken from a data: URL, the URL's answer or the file's first bytes. Up to 200 characters.
contentBase64
string
No
The file's bytes as base64 (a data: URL is accepted too). Up to 10 MB. Give this or sourceUrl.
sourceUrl
string (uri)
No
A public http(s) URL ServFlo downloads the file from (up to 10 MB, 20 s, 3 redirects; private and internal addresses are refused). Give this or contentBase64. Up to 2000 characters.
Replaces the markup tiers (ascending upToCents, the last open-ended). Prices do not change until a reprice: preview with GET /pricebook/reprice, apply with POST /pricebook/reprice.
Permission
pricebook.manage (Owner, Admin)
Risk
write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
GET /organizations/{organizationId}/pricebook/reprice
The MARKUP items whose stored price differs from their cost through the current tiers, with the old and new price. Read-only; apply with POST /pricebook/reprice.
POST /organizations/{organizationId}/pricebook/reprice
Sets every MARKUP item (or only itemIds) to its price from the current tiers, and their original materials / service types with them. Quotes, invoices and jobs already written keep their prices. Returns what changed.
Permission
pricebook.manage (Owner, Admin)
Risk
write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.