REST endpoints for imports in ServFlo: 18 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.
GET /organizations/{organizationId}/migration/sources
What can be imported: the sources (JOBBER, SERVICETITAN, SPREADSHEET = "Other spreadsheet"), each with the steps to export every dataset from that system, and the ServFlo fields of each dataset (mapping targets). The Jobber and ServiceTitan presets come from the vendors' public documentation and are not yet verified against real exports: unknown columns go to AI mapping. Read-only. Next: POST /imports.
One of DRAFT, QUEUED, RUNNING, COMPLETED, FAILED, UNDONE.
lockHistory
boolean
progress
object
progress.phase
string
progress.done
number
progress.total
number
preview
object or null
The last dry run; null until previewed or after a change.
preview.counts
object
Per entity: customers, properties, jobs, visits, invoices, payments…
preview.problems
array of object
preview.problems[].fileId
string or null
preview.problems[].fileName
string or null
preview.problems[].row
integer or null
1-based line in the file (the header is line 1).
preview.problems[].column
string or null
preview.problems[].severity
enum
Errors skip the row; warnings are only reported. One of error, warning.
preview.problems[].message
string
preview.errors
integer
preview.warnings
integer
preview.samples
object
A few records as they will look.
preview.openingBalances
object
preview.openingBalances.payments
integer
"Opening balance (imported)" payments so invoice balances match the export.
preview.openingBalances.invoices
integer
Opening-balance invoices for account balances without open invoices.
preview.openingBalances.amountCents
integer
preview.needsPaymentMethod
integer
Customers who paid by card on file or autopay: to re-collect.
preview.files
integer
preview.rows
integer
previewedAt
string (date-time) or null
summary
object or null
What the applied run did, per entity.
problems
array of object
problems[].fileId
string or null
problems[].fileName
string or null
problems[].row
integer or null
1-based line in the file (the header is line 1).
problems[].column
string or null
problems[].severity
enum
Errors skip the row; warnings are only reported. One of error, warning.
problems[].message
string
queuedAt
string (date-time) or null
startedAt
string (date-time) or null
finishedAt
string (date-time) or null
error
string or null
undoUntil
string (date-time) or null
canUndo
boolean
undoneAt
string (date-time) or null
undoReport
object or null
files
array of object
files[].id
string
files[].uploadId
string
files[].fileName
string
files[].sheetName
string or null
files[].sizeBytes
integer
files[].status
enum
One of UPLOADING, READY, ERROR.
files[].error
string or null
files[].dataset
enum or null
What the rows are; null = not recognised (skipped until set). One of pricebook, customers, contacts, properties, equipment, memberships, quotes, jobs, visits, invoices, payments, notes.
files[].detectedDataset
enum or null
One of pricebook, customers, contacts, properties, equipment, memberships, quotes, jobs, visits, invoices, payments, notes.
files[].detectionConfidence
number or null
files[].headers
array of string
files[].rowCount
integer
files[].sampleRows
array of array of string
files[].mapping
object
files[].needsReview
array of string
Headers mapped by a guess below 0.7 confidence: confirm them.
Creates a draft import from one source. Nothing is written to customers or jobs until it is applied. Next: add files (POST /imports/{importId}/files), check the mapping, preview, apply. A re-run on cutover day is a new import on fresh exports: records match by their source id (then email/phone, address, code, number) and are updated in place, never duplicated.
Permission
import.manage (Owner, Admin)
Risk
write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
One of DRAFT, QUEUED, RUNNING, COMPLETED, FAILED, UNDONE.
lockHistory
boolean
progress
object
progress.phase
string
progress.done
number
progress.total
number
preview
object or null
The last dry run; null until previewed or after a change.
preview.counts
object
Per entity: customers, properties, jobs, visits, invoices, payments…
preview.problems
array of object
preview.problems[].fileId
string or null
preview.problems[].fileName
string or null
preview.problems[].row
integer or null
1-based line in the file (the header is line 1).
preview.problems[].column
string or null
preview.problems[].severity
enum
Errors skip the row; warnings are only reported. One of error, warning.
preview.problems[].message
string
preview.errors
integer
preview.warnings
integer
preview.samples
object
A few records as they will look.
preview.openingBalances
object
preview.openingBalances.payments
integer
"Opening balance (imported)" payments so invoice balances match the export.
preview.openingBalances.invoices
integer
Opening-balance invoices for account balances without open invoices.
preview.openingBalances.amountCents
integer
preview.needsPaymentMethod
integer
Customers who paid by card on file or autopay: to re-collect.
preview.files
integer
preview.rows
integer
previewedAt
string (date-time) or null
summary
object or null
What the applied run did, per entity.
problems
array of object
problems[].fileId
string or null
problems[].fileName
string or null
problems[].row
integer or null
1-based line in the file (the header is line 1).
problems[].column
string or null
problems[].severity
enum
Errors skip the row; warnings are only reported. One of error, warning.
problems[].message
string
queuedAt
string (date-time) or null
startedAt
string (date-time) or null
finishedAt
string (date-time) or null
error
string or null
undoUntil
string (date-time) or null
canUndo
boolean
undoneAt
string (date-time) or null
undoReport
object or null
files
array of object
files[].id
string
files[].uploadId
string
files[].fileName
string
files[].sheetName
string or null
files[].sizeBytes
integer
files[].status
enum
One of UPLOADING, READY, ERROR.
files[].error
string or null
files[].dataset
enum or null
What the rows are; null = not recognised (skipped until set). One of pricebook, customers, contacts, properties, equipment, memberships, quotes, jobs, visits, invoices, payments, notes.
files[].detectedDataset
enum or null
One of pricebook, customers, contacts, properties, equipment, memberships, quotes, jobs, visits, invoices, payments, notes.
files[].detectionConfidence
number or null
files[].headers
array of string
files[].rowCount
integer
files[].sampleRows
array of array of string
files[].mapping
object
files[].needsReview
array of string
Headers mapped by a guess below 0.7 confidence: confirm them.
GET /organizations/{organizationId}/imports/{importId}
One import: its files with their detected dataset and column mapping, the last preview, progress while it runs (progress.done of progress.total rows), the summary and problems when finished, and the undo deadline. Poll it while status is QUEUED or RUNNING. Read-only.
One of DRAFT, QUEUED, RUNNING, COMPLETED, FAILED, UNDONE.
lockHistory
boolean
progress
object
progress.phase
string
progress.done
number
progress.total
number
preview
object or null
The last dry run; null until previewed or after a change.
preview.counts
object
Per entity: customers, properties, jobs, visits, invoices, payments…
preview.problems
array of object
preview.problems[].fileId
string or null
preview.problems[].fileName
string or null
preview.problems[].row
integer or null
1-based line in the file (the header is line 1).
preview.problems[].column
string or null
preview.problems[].severity
enum
Errors skip the row; warnings are only reported. One of error, warning.
preview.problems[].message
string
preview.errors
integer
preview.warnings
integer
preview.samples
object
A few records as they will look.
preview.openingBalances
object
preview.openingBalances.payments
integer
"Opening balance (imported)" payments so invoice balances match the export.
preview.openingBalances.invoices
integer
Opening-balance invoices for account balances without open invoices.
preview.openingBalances.amountCents
integer
preview.needsPaymentMethod
integer
Customers who paid by card on file or autopay: to re-collect.
preview.files
integer
preview.rows
integer
previewedAt
string (date-time) or null
summary
object or null
What the applied run did, per entity.
problems
array of object
problems[].fileId
string or null
problems[].fileName
string or null
problems[].row
integer or null
1-based line in the file (the header is line 1).
problems[].column
string or null
problems[].severity
enum
Errors skip the row; warnings are only reported. One of error, warning.
problems[].message
string
queuedAt
string (date-time) or null
startedAt
string (date-time) or null
finishedAt
string (date-time) or null
error
string or null
undoUntil
string (date-time) or null
canUndo
boolean
undoneAt
string (date-time) or null
undoReport
object or null
files
array of object
files[].id
string
files[].uploadId
string
files[].fileName
string
files[].sheetName
string or null
files[].sizeBytes
integer
files[].status
enum
One of UPLOADING, READY, ERROR.
files[].error
string or null
files[].dataset
enum or null
What the rows are; null = not recognised (skipped until set). One of pricebook, customers, contacts, properties, equipment, memberships, quotes, jobs, visits, invoices, payments, notes.
files[].detectedDataset
enum or null
One of pricebook, customers, contacts, properties, equipment, memberships, quotes, jobs, visits, invoices, payments, notes.
files[].detectionConfidence
number or null
files[].headers
array of string
files[].rowCount
integer
files[].sampleRows
array of array of string
files[].mapping
object
files[].needsReview
array of string
Headers mapped by a guess below 0.7 confidence: confirm them.
POST /organizations/{organizationId}/imports/{importId}/files
Adds an export to the import in one call: text for CSV / TSV, or contentBase64 for any file including .xlsx (each sheet becomes a file of the import). It is stored privately, read, and sniffed: the dataset it holds (customers, properties, pricebook, quotes, jobs, visits, invoices, payments, memberships, contacts, notes) and the mapping from the source's preset, the saved mapping and the name heuristic. Several files may hold one dataset (Jobber splits clients into files of 1,500 rows). The browser uses POST …/uploads instead. Returns the import.
Permission
import.manage (Owner, Admin)
Risk
write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
One of DRAFT, QUEUED, RUNNING, COMPLETED, FAILED, UNDONE.
lockHistory
boolean
progress
object
progress.phase
string
progress.done
number
progress.total
number
preview
object or null
The last dry run; null until previewed or after a change.
preview.counts
object
Per entity: customers, properties, jobs, visits, invoices, payments…
preview.problems
array of object
preview.problems[].fileId
string or null
preview.problems[].fileName
string or null
preview.problems[].row
integer or null
1-based line in the file (the header is line 1).
preview.problems[].column
string or null
preview.problems[].severity
enum
Errors skip the row; warnings are only reported. One of error, warning.
preview.problems[].message
string
preview.errors
integer
preview.warnings
integer
preview.samples
object
A few records as they will look.
preview.openingBalances
object
preview.openingBalances.payments
integer
"Opening balance (imported)" payments so invoice balances match the export.
preview.openingBalances.invoices
integer
Opening-balance invoices for account balances without open invoices.
preview.openingBalances.amountCents
integer
preview.needsPaymentMethod
integer
Customers who paid by card on file or autopay: to re-collect.
preview.files
integer
preview.rows
integer
previewedAt
string (date-time) or null
summary
object or null
What the applied run did, per entity.
problems
array of object
problems[].fileId
string or null
problems[].fileName
string or null
problems[].row
integer or null
1-based line in the file (the header is line 1).
problems[].column
string or null
problems[].severity
enum
Errors skip the row; warnings are only reported. One of error, warning.
problems[].message
string
queuedAt
string (date-time) or null
startedAt
string (date-time) or null
finishedAt
string (date-time) or null
error
string or null
undoUntil
string (date-time) or null
canUndo
boolean
undoneAt
string (date-time) or null
undoReport
object or null
files
array of object
files[].id
string
files[].uploadId
string
files[].fileName
string
files[].sheetName
string or null
files[].sizeBytes
integer
files[].status
enum
One of UPLOADING, READY, ERROR.
files[].error
string or null
files[].dataset
enum or null
What the rows are; null = not recognised (skipped until set). One of pricebook, customers, contacts, properties, equipment, memberships, quotes, jobs, visits, invoices, payments, notes.
files[].detectedDataset
enum or null
One of pricebook, customers, contacts, properties, equipment, memberships, quotes, jobs, visits, invoices, payments, notes.
files[].detectionConfidence
number or null
files[].headers
array of string
files[].rowCount
integer
files[].sampleRows
array of array of string
files[].mapping
object
files[].needsReview
array of string
Headers mapped by a guess below 0.7 confidence: confirm them.
POST /organizations/{organizationId}/imports/{importId}/uploads
Step 1 of a browser upload: a signed URL to PUT the file to (10 minutes, with the same Content-Type). Then POST …/uploads/{uploadId}/confirm to read and sniff it.
Permission
import.manage (Owner, Admin)
Risk
write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
One of DRAFT, QUEUED, RUNNING, COMPLETED, FAILED, UNDONE.
lockHistory
boolean
progress
object
progress.phase
string
progress.done
number
progress.total
number
preview
object or null
The last dry run; null until previewed or after a change.
preview.counts
object
Per entity: customers, properties, jobs, visits, invoices, payments…
preview.problems
array of object
preview.problems[].fileId
string or null
preview.problems[].fileName
string or null
preview.problems[].row
integer or null
1-based line in the file (the header is line 1).
preview.problems[].column
string or null
preview.problems[].severity
enum
Errors skip the row; warnings are only reported. One of error, warning.
preview.problems[].message
string
preview.errors
integer
preview.warnings
integer
preview.samples
object
A few records as they will look.
preview.openingBalances
object
preview.openingBalances.payments
integer
"Opening balance (imported)" payments so invoice balances match the export.
preview.openingBalances.invoices
integer
Opening-balance invoices for account balances without open invoices.
preview.openingBalances.amountCents
integer
preview.needsPaymentMethod
integer
Customers who paid by card on file or autopay: to re-collect.
preview.files
integer
preview.rows
integer
previewedAt
string (date-time) or null
summary
object or null
What the applied run did, per entity.
problems
array of object
problems[].fileId
string or null
problems[].fileName
string or null
problems[].row
integer or null
1-based line in the file (the header is line 1).
problems[].column
string or null
problems[].severity
enum
Errors skip the row; warnings are only reported. One of error, warning.
problems[].message
string
queuedAt
string (date-time) or null
startedAt
string (date-time) or null
finishedAt
string (date-time) or null
error
string or null
undoUntil
string (date-time) or null
canUndo
boolean
undoneAt
string (date-time) or null
undoReport
object or null
files
array of object
files[].id
string
files[].uploadId
string
files[].fileName
string
files[].sheetName
string or null
files[].sizeBytes
integer
files[].status
enum
One of UPLOADING, READY, ERROR.
files[].error
string or null
files[].dataset
enum or null
What the rows are; null = not recognised (skipped until set). One of pricebook, customers, contacts, properties, equipment, memberships, quotes, jobs, visits, invoices, payments, notes.
files[].detectedDataset
enum or null
One of pricebook, customers, contacts, properties, equipment, memberships, quotes, jobs, visits, invoices, payments, notes.
files[].detectionConfidence
number or null
files[].headers
array of string
files[].rowCount
integer
files[].sampleRows
array of array of string
files[].mapping
object
files[].needsReview
array of string
Headers mapped by a guess below 0.7 confidence: confirm them.
Confirms or corrects what a file holds (dataset; null skips the file; changing it re-maps the columns) and its column mapping (mapping: header → field key from GET /migration/sources, custom:<label> for a new custom field on customers or properties, or null to skip). Confirmed columns are remembered for the next upload of that kind of file. Clears the preview. Returns the import.
Permission
import.manage (Owner, Admin)
Risk
write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
One of DRAFT, QUEUED, RUNNING, COMPLETED, FAILED, UNDONE.
lockHistory
boolean
progress
object
progress.phase
string
progress.done
number
progress.total
number
preview
object or null
The last dry run; null until previewed or after a change.
preview.counts
object
Per entity: customers, properties, jobs, visits, invoices, payments…
preview.problems
array of object
preview.problems[].fileId
string or null
preview.problems[].fileName
string or null
preview.problems[].row
integer or null
1-based line in the file (the header is line 1).
preview.problems[].column
string or null
preview.problems[].severity
enum
Errors skip the row; warnings are only reported. One of error, warning.
preview.problems[].message
string
preview.errors
integer
preview.warnings
integer
preview.samples
object
A few records as they will look.
preview.openingBalances
object
preview.openingBalances.payments
integer
"Opening balance (imported)" payments so invoice balances match the export.
preview.openingBalances.invoices
integer
Opening-balance invoices for account balances without open invoices.
preview.openingBalances.amountCents
integer
preview.needsPaymentMethod
integer
Customers who paid by card on file or autopay: to re-collect.
preview.files
integer
preview.rows
integer
previewedAt
string (date-time) or null
summary
object or null
What the applied run did, per entity.
problems
array of object
problems[].fileId
string or null
problems[].fileName
string or null
problems[].row
integer or null
1-based line in the file (the header is line 1).
problems[].column
string or null
problems[].severity
enum
Errors skip the row; warnings are only reported. One of error, warning.
problems[].message
string
queuedAt
string (date-time) or null
startedAt
string (date-time) or null
finishedAt
string (date-time) or null
error
string or null
undoUntil
string (date-time) or null
canUndo
boolean
undoneAt
string (date-time) or null
undoReport
object or null
files
array of object
files[].id
string
files[].uploadId
string
files[].fileName
string
files[].sheetName
string or null
files[].sizeBytes
integer
files[].status
enum
One of UPLOADING, READY, ERROR.
files[].error
string or null
files[].dataset
enum or null
What the rows are; null = not recognised (skipped until set). One of pricebook, customers, contacts, properties, equipment, memberships, quotes, jobs, visits, invoices, payments, notes.
files[].detectedDataset
enum or null
One of pricebook, customers, contacts, properties, equipment, memberships, quotes, jobs, visits, invoices, payments, notes.
files[].detectionConfidence
number or null
files[].headers
array of string
files[].rowCount
integer
files[].sampleRows
array of array of string
files[].mapping
object
files[].needsReview
array of string
Headers mapped by a guess below 0.7 confidence: confirm them.
One of DRAFT, QUEUED, RUNNING, COMPLETED, FAILED, UNDONE.
lockHistory
boolean
progress
object
progress.phase
string
progress.done
number
progress.total
number
preview
object or null
The last dry run; null until previewed or after a change.
preview.counts
object
Per entity: customers, properties, jobs, visits, invoices, payments…
preview.problems
array of object
preview.problems[].fileId
string or null
preview.problems[].fileName
string or null
preview.problems[].row
integer or null
1-based line in the file (the header is line 1).
preview.problems[].column
string or null
preview.problems[].severity
enum
Errors skip the row; warnings are only reported. One of error, warning.
preview.problems[].message
string
preview.errors
integer
preview.warnings
integer
preview.samples
object
A few records as they will look.
preview.openingBalances
object
preview.openingBalances.payments
integer
"Opening balance (imported)" payments so invoice balances match the export.
preview.openingBalances.invoices
integer
Opening-balance invoices for account balances without open invoices.
preview.openingBalances.amountCents
integer
preview.needsPaymentMethod
integer
Customers who paid by card on file or autopay: to re-collect.
preview.files
integer
preview.rows
integer
previewedAt
string (date-time) or null
summary
object or null
What the applied run did, per entity.
problems
array of object
problems[].fileId
string or null
problems[].fileName
string or null
problems[].row
integer or null
1-based line in the file (the header is line 1).
problems[].column
string or null
problems[].severity
enum
Errors skip the row; warnings are only reported. One of error, warning.
problems[].message
string
queuedAt
string (date-time) or null
startedAt
string (date-time) or null
finishedAt
string (date-time) or null
error
string or null
undoUntil
string (date-time) or null
canUndo
boolean
undoneAt
string (date-time) or null
undoReport
object or null
files
array of object
files[].id
string
files[].uploadId
string
files[].fileName
string
files[].sheetName
string or null
files[].sizeBytes
integer
files[].status
enum
One of UPLOADING, READY, ERROR.
files[].error
string or null
files[].dataset
enum or null
What the rows are; null = not recognised (skipped until set). One of pricebook, customers, contacts, properties, equipment, memberships, quotes, jobs, visits, invoices, payments, notes.
files[].detectedDataset
enum or null
One of pricebook, customers, contacts, properties, equipment, memberships, quotes, jobs, visits, invoices, payments, notes.
files[].detectionConfidence
number or null
files[].headers
array of string
files[].rowCount
integer
files[].sampleRows
array of array of string
files[].mapping
object
files[].needsReview
array of string
Headers mapped by a guess below 0.7 confidence: confirm them.
POST /organizations/{organizationId}/imports/{importId}/files/{fileId}/suggest-mapping
Columns the preset and the saved mapping do not know go to Claude (headers and up to three sample values each), which proposes a field, a custom field or skip with a confidence; anything below 0.7 is listed in needsReview. Never changes columns the owner set. Uses AI credits. Without AI configured the name heuristic answers (mode HEURISTIC). Returns the file.
Permission
import.manage (Owner, Admin)
Risk
write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
What the rows are; null = not recognised (skipped until set). One of pricebook, customers, contacts, properties, equipment, memberships, quotes, jobs, visits, invoices, payments, notes.
file.detectedDataset
enum or null
One of pricebook, customers, contacts, properties, equipment, memberships, quotes, jobs, visits, invoices, payments, notes.
file.detectionConfidence
number or null
file.headers
array of string
file.rowCount
integer
file.sampleRows
array of array of string
file.mapping
object
file.needsReview
array of string
Headers mapped by a guess below 0.7 confidence: confirm them.
POST /organizations/{organizationId}/imports/{importId}/preview
The dry run: counts per entity (to create, to update, duplicates, kept because edited in ServFlo), every problem with its file, row, column and severity, sample records, opening balances to write and customers who will need a card. Writes no records (only the preview on the import). Required before applying.
Permission
import.manage (Owner, Admin)
Risk
write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
POST /organizations/{organizationId}/imports/{importId}/apply
Writes customer, job and money records: runs the previewed import in the background in dependency order (pricebook → customers → contacts → properties → memberships → quotes → jobs and visits → invoices → payments → notes). Sends nothing to customers: imported records emit no events and are held back from automations, reminders, membership billing and dunning until cutover (POST /migration/cutover/release); webhooks get one import.completed. Invoices keep their numbers, issue dates, tax as charged and balances (an opening-balance payment where only a balance was exported); counters move past the highest imported number. Poll GET /imports/{importId}. Undo within 7 days.
Permission
import.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
imports_apply (toolset settings)
Approval
Over MCP, this tool asks for your OK first (in the AI app when it supports it, otherwise in ServFlo). See Approvals.
One of DRAFT, QUEUED, RUNNING, COMPLETED, FAILED, UNDONE.
lockHistory
boolean
progress
object
progress.phase
string
progress.done
number
progress.total
number
preview
object or null
The last dry run; null until previewed or after a change.
preview.counts
object
Per entity: customers, properties, jobs, visits, invoices, payments…
preview.problems
array of object
preview.problems[].fileId
string or null
preview.problems[].fileName
string or null
preview.problems[].row
integer or null
1-based line in the file (the header is line 1).
preview.problems[].column
string or null
preview.problems[].severity
enum
Errors skip the row; warnings are only reported. One of error, warning.
preview.problems[].message
string
preview.errors
integer
preview.warnings
integer
preview.samples
object
A few records as they will look.
preview.openingBalances
object
preview.openingBalances.payments
integer
"Opening balance (imported)" payments so invoice balances match the export.
preview.openingBalances.invoices
integer
Opening-balance invoices for account balances without open invoices.
preview.openingBalances.amountCents
integer
preview.needsPaymentMethod
integer
Customers who paid by card on file or autopay: to re-collect.
preview.files
integer
preview.rows
integer
previewedAt
string (date-time) or null
summary
object or null
What the applied run did, per entity.
problems
array of object
problems[].fileId
string or null
problems[].fileName
string or null
problems[].row
integer or null
1-based line in the file (the header is line 1).
problems[].column
string or null
problems[].severity
enum
Errors skip the row; warnings are only reported. One of error, warning.
problems[].message
string
queuedAt
string (date-time) or null
startedAt
string (date-time) or null
finishedAt
string (date-time) or null
error
string or null
undoUntil
string (date-time) or null
canUndo
boolean
undoneAt
string (date-time) or null
undoReport
object or null
files
array of object
files[].id
string
files[].uploadId
string
files[].fileName
string
files[].sheetName
string or null
files[].sizeBytes
integer
files[].status
enum
One of UPLOADING, READY, ERROR.
files[].error
string or null
files[].dataset
enum or null
What the rows are; null = not recognised (skipped until set). One of pricebook, customers, contacts, properties, equipment, memberships, quotes, jobs, visits, invoices, payments, notes.
files[].detectedDataset
enum or null
One of pricebook, customers, contacts, properties, equipment, memberships, quotes, jobs, visits, invoices, payments, notes.
files[].detectionConfidence
number or null
files[].headers
array of string
files[].rowCount
integer
files[].sampleRows
array of array of string
files[].mapping
object
files[].needsReview
array of string
Headers mapped by a guess below 0.7 confidence: confirm them.
POST /organizations/{organizationId}/imports/{importId}/undo
DELETES what this import created (within 7 days of finishing), in reverse order. Records edited in ServFlo since, or used by work added since (a new job, a payment), are kept and listed in undoReport. Records the import only updated stay as they are. Returns the import (status UNDONE).
Permission
import.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
imports_undo (toolset settings)
Approval
Over MCP, this tool asks for your OK first (in the AI app when it supports it, otherwise in ServFlo). See Approvals.
One of DRAFT, QUEUED, RUNNING, COMPLETED, FAILED, UNDONE.
lockHistory
boolean
progress
object
progress.phase
string
progress.done
number
progress.total
number
preview
object or null
The last dry run; null until previewed or after a change.
preview.counts
object
Per entity: customers, properties, jobs, visits, invoices, payments…
preview.problems
array of object
preview.problems[].fileId
string or null
preview.problems[].fileName
string or null
preview.problems[].row
integer or null
1-based line in the file (the header is line 1).
preview.problems[].column
string or null
preview.problems[].severity
enum
Errors skip the row; warnings are only reported. One of error, warning.
preview.problems[].message
string
preview.errors
integer
preview.warnings
integer
preview.samples
object
A few records as they will look.
preview.openingBalances
object
preview.openingBalances.payments
integer
"Opening balance (imported)" payments so invoice balances match the export.
preview.openingBalances.invoices
integer
Opening-balance invoices for account balances without open invoices.
preview.openingBalances.amountCents
integer
preview.needsPaymentMethod
integer
Customers who paid by card on file or autopay: to re-collect.
preview.files
integer
preview.rows
integer
previewedAt
string (date-time) or null
summary
object or null
What the applied run did, per entity.
problems
array of object
problems[].fileId
string or null
problems[].fileName
string or null
problems[].row
integer or null
1-based line in the file (the header is line 1).
problems[].column
string or null
problems[].severity
enum
Errors skip the row; warnings are only reported. One of error, warning.
problems[].message
string
queuedAt
string (date-time) or null
startedAt
string (date-time) or null
finishedAt
string (date-time) or null
error
string or null
undoUntil
string (date-time) or null
canUndo
boolean
undoneAt
string (date-time) or null
undoReport
object or null
files
array of object
files[].id
string
files[].uploadId
string
files[].fileName
string
files[].sheetName
string or null
files[].sizeBytes
integer
files[].status
enum
One of UPLOADING, READY, ERROR.
files[].error
string or null
files[].dataset
enum or null
What the rows are; null = not recognised (skipped until set). One of pricebook, customers, contacts, properties, equipment, memberships, quotes, jobs, visits, invoices, payments, notes.
files[].detectedDataset
enum or null
One of pricebook, customers, contacts, properties, equipment, memberships, quotes, jobs, visits, invoices, payments, notes.
files[].detectionConfidence
number or null
files[].headers
array of string
files[].rowCount
integer
files[].sampleRows
array of array of string
files[].mapping
object
files[].needsReview
array of string
Headers mapped by a guess below 0.7 confidence: confirm them.
GET /organizations/{organizationId}/migration/cutover
What is left after importing: imported records still held back from automations (heldRecords), customers to ask for a card (customersNeedingCard), active technicians and automations, and the last import. Read-only.
POST /organizations/{organizationId}/migration/cutover/release
Customer-visible from now on: imported customers, visits, invoices and memberships join automations, reminders, dunning and membership billing. Do it once the old system has stopped sending (cutover day). Sends nothing by itself. Returns how many records were released.
Permission
import.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
imports_release (toolset settings)
Approval
Over MCP, this tool asks for your OK first (in the AI app when it supports it, otherwise in ServFlo). See Approvals.
GET /organizations/{organizationId}/migration/needs-card
Customers who paid by card on file or autopay in the old system (needsPaymentMethod): saved cards are not copied, so they are sent the update-card link. The flag clears when they save a card. Read-only.
POST /organizations/{organizationId}/migration/update-card-links
Sends to customers: emails or texts each customer flagged needsPaymentMethod (or only customerIds) a link to their portal to add a card for automatic payments (Stripe Checkout in setup mode; nothing is charged). Consent, quiet hours and the message log apply; batchKey makes a retry send nothing twice. Needs online payments (Settings → Payments): 409 otherwise.
Permission
import.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
imports_sendUpdateCardLinks (toolset settings)
Approval
Over MCP, this tool always waits for your approval in ServFlo. See Approvals.