DevelopersAPI reference

Imports API

REST endpoints for imports in SKUFlow: 18 operations with parameters, request and response fields, permissions and curl examples.

Base URL: https://app.skuflow.ai/api. Every call needs Authorization: Bearer skf_… (Authentication); {organizationId} ($ORGANIZATION_ID in the examples) is your business's id.

OperationEndpointRisk
Import sources and fieldsGET /organizations/{organizationId}/migration/sourcesread
List importsGET /organizations/{organizationId}/importsread
Start an importPOST /organizations/{organizationId}/importswrite
Get an importGET /organizations/{organizationId}/imports/{importId}read
Delete a draft importDELETE /organizations/{organizationId}/imports/{importId}sensitive
Add a file (content in the request)POST /organizations/{organizationId}/imports/{importId}/fileswrite
Get an upload URLPOST /organizations/{organizationId}/imports/{importId}/uploadswrite
Confirm an uploadPOST /organizations/{organizationId}/imports/{importId}/uploads/{uploadId}/confirmwrite
Set a file's dataset or mappingPATCH /organizations/{organizationId}/imports/{importId}/files/{fileId}write
Remove a file from an importDELETE /organizations/{organizationId}/imports/{importId}/files/{fileId}sensitive
AI column mappingPOST /organizations/{organizationId}/imports/{importId}/files/{fileId}/suggest-mappingwrite
Preview an import (dry run)POST /organizations/{organizationId}/imports/{importId}/previewwrite
Apply an importPOST /organizations/{organizationId}/imports/{importId}/applysensitive
Undo an importPOST /organizations/{organizationId}/imports/{importId}/undosensitive
Cutover checklistGET /organizations/{organizationId}/migration/cutoverread
Release imported records (cutover)POST /organizations/{organizationId}/migration/cutover/releasesensitive
Customers to ask for a cardGET /organizations/{organizationId}/migration/needs-cardread
Send update-card linksPOST /organizations/{organizationId}/migration/update-card-linkssensitive

Import sources and fields

GET /organizations/{organizationId}/migration/sources

What can be imported: the sources (DECONETWORK, SPREADSHEET = "Other spreadsheet": any other tool such as Printavo or InkSoft, or a hand-made sheet), each with the steps to export every dataset it has a preset for, and the SKUFlow fields of each dataset (mapping targets). DecoNetwork's presets (customers, the order items export as invoices, the payments export) were checked against real exports (verified); unknown columns go to AI mapping. Read-only. Next: POST /imports.

Permissionimport.manage (Owner, Admin)
Riskread, OAuth scope skuflow.read. Read: reads only.
MCP toolimports_sources (toolset settings)

Example

curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/migration/sources" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
maxFileBytesinteger
sourcesarray of object
sources[].sourceenumOne of DECONETWORK, SPREADSHEET.
sources[].labelstring
sources[].verifiedbooleanEvery preset of the source was checked against a real export file.
sources[].datasetsarray of object
sources[].datasets[].datasetenumOne of pricebook, customers, contacts, properties, quotes, invoices, payments, notes.
sources[].datasets[].howToExportarray of string
sources[].datasets[].verifiedbooleanThis preset was checked against a real export file of that system.
datasetsarray of object
datasets[].datasetenumOne of pricebook, customers, contacts, properties, quotes, invoices, payments, notes.
datasets[].fieldsarray of object
datasets[].fields[].keystring
datasets[].fields[].labelstring
datasets[].fields[].typestring
datasets[].fields[].descriptionstring

List imports

GET /organizations/{organizationId}/imports

The business's imports, newest first (the last 50), with files, progress, results and whether undo is still possible. Read-only.

Permissionimport.manage (Owner, Admin)
Riskread, OAuth scope skuflow.read. Read: reads only.
MCP toolimports_list (toolset settings)

Example

curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/imports" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields

An array of objects:

FieldTypeDescription
idstring
sourceenumOne of DECONETWORK, SPREADSHEET.
statusenumOne of DRAFT, QUEUED, RUNNING, COMPLETED, FAILED, UNDONE.
lockHistoryboolean
progressobject
progress.phasestring
progress.donenumber
progress.totalnumber
previewobject or nullThe last dry run; null until previewed or after a change.
preview.countsobjectPer entity: customers, properties, quotes, invoices, payments…
preview.problemsarray of object
preview.problems[].fileIdstring or null
preview.problems[].fileNamestring or null
preview.problems[].rowinteger or null1-based line in the file (the header is line 1).
preview.problems[].columnstring or null
preview.problems[].severityenumErrors skip the row; warnings are only reported. One of error, warning.
preview.problems[].messagestring
preview.errorsinteger
preview.warningsinteger
preview.samplesobjectA few records as they will look.
preview.openingBalancesobject
preview.openingBalances.paymentsinteger"Opening balance (imported)" payments so invoice balances match the export.
preview.openingBalances.invoicesintegerOpening-balance invoices for account balances without open invoices.
preview.openingBalances.amountCentsinteger
preview.needsPaymentMethodintegerCustomers who paid by card on file or autopay: to re-collect.
preview.filesinteger
preview.rowsinteger
previewedAtstring (date-time) or null
summaryobject or nullWhat the applied run did, per entity.
problemsarray of object
problems[].fileIdstring or null
problems[].fileNamestring or null
problems[].rowinteger or null1-based line in the file (the header is line 1).
problems[].columnstring or null
problems[].severityenumErrors skip the row; warnings are only reported. One of error, warning.
problems[].messagestring
queuedAtstring (date-time) or null
startedAtstring (date-time) or null
finishedAtstring (date-time) or null
errorstring or null
undoUntilstring (date-time) or null
canUndoboolean
undoneAtstring (date-time) or null
undoReportobject or null
filesarray of object
files[].idstring
files[].uploadIdstring
files[].fileNamestring
files[].sheetNamestring or null
files[].sizeBytesinteger
files[].statusenumOne of UPLOADING, READY, ERROR.
files[].errorstring or null
files[].datasetenum or nullWhat the rows are; null = not recognised (skipped until set). One of pricebook, customers, contacts, properties, quotes, invoices, payments, notes.
files[].detectedDatasetenum or nullOne of pricebook, customers, contacts, properties, quotes, invoices, payments, notes.
files[].detectionConfidencenumber or null
files[].headersarray of string
files[].rowCountinteger
files[].sampleRowsarray of array of string
files[].mappingobject
files[].needsReviewarray of stringHeaders mapped by a guess below 0.7 confidence: confirm them.
files[].createdAtstring (date-time)
createdAtstring (date-time)

Start an import

POST /organizations/{organizationId}/imports

Creates a draft import from one source. Nothing is written to customers, quotes or invoices 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.

Permissionimport.manage (Owner, Admin)
Riskwrite, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolimports_create (toolset settings)

Request body

FieldTypeRequiredDescription
sourceenumYesDECONETWORK or SPREADSHEET (any other tool or a hand-made sheet). One of DECONETWORK, SPREADSHEET.
lockHistorybooleanNoImported paid or void invoices are read-only (default true).

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/imports" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"source":"DECONETWORK"}'

Response

200: the answer's fields
FieldTypeDescription
idstring
sourceenumOne of DECONETWORK, SPREADSHEET.
statusenumOne of DRAFT, QUEUED, RUNNING, COMPLETED, FAILED, UNDONE.
lockHistoryboolean
progressobject
progress.phasestring
progress.donenumber
progress.totalnumber
previewobject or nullThe last dry run; null until previewed or after a change.
preview.countsobjectPer entity: customers, properties, quotes, invoices, payments…
preview.problemsarray of object
preview.problems[].fileIdstring or null
preview.problems[].fileNamestring or null
preview.problems[].rowinteger or null1-based line in the file (the header is line 1).
preview.problems[].columnstring or null
preview.problems[].severityenumErrors skip the row; warnings are only reported. One of error, warning.
preview.problems[].messagestring
preview.errorsinteger
preview.warningsinteger
preview.samplesobjectA few records as they will look.
preview.openingBalancesobject
preview.openingBalances.paymentsinteger"Opening balance (imported)" payments so invoice balances match the export.
preview.openingBalances.invoicesintegerOpening-balance invoices for account balances without open invoices.
preview.openingBalances.amountCentsinteger
preview.needsPaymentMethodintegerCustomers who paid by card on file or autopay: to re-collect.
preview.filesinteger
preview.rowsinteger
previewedAtstring (date-time) or null
summaryobject or nullWhat the applied run did, per entity.
problemsarray of object
problems[].fileIdstring or null
problems[].fileNamestring or null
problems[].rowinteger or null1-based line in the file (the header is line 1).
problems[].columnstring or null
problems[].severityenumErrors skip the row; warnings are only reported. One of error, warning.
problems[].messagestring
queuedAtstring (date-time) or null
startedAtstring (date-time) or null
finishedAtstring (date-time) or null
errorstring or null
undoUntilstring (date-time) or null
canUndoboolean
undoneAtstring (date-time) or null
undoReportobject or null
filesarray of object
files[].idstring
files[].uploadIdstring
files[].fileNamestring
files[].sheetNamestring or null
files[].sizeBytesinteger
files[].statusenumOne of UPLOADING, READY, ERROR.
files[].errorstring or null
files[].datasetenum or nullWhat the rows are; null = not recognised (skipped until set). One of pricebook, customers, contacts, properties, quotes, invoices, payments, notes.
files[].detectedDatasetenum or nullOne of pricebook, customers, contacts, properties, quotes, invoices, payments, notes.
files[].detectionConfidencenumber or null
files[].headersarray of string
files[].rowCountinteger
files[].sampleRowsarray of array of string
files[].mappingobject
files[].needsReviewarray of stringHeaders mapped by a guess below 0.7 confidence: confirm them.
files[].createdAtstring (date-time)
createdAtstring (date-time)

Get an import

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.

Permissionimport.manage (Owner, Admin)
Riskread, OAuth scope skuflow.read. Read: reads only.
MCP toolimports_get (toolset settings)

Parameters

NameInTypeRequiredDescription
importIdpathstringYesThe import run (from POST /imports or GET /imports).

Example

curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/imports/{importId}" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
idstring
sourceenumOne of DECONETWORK, SPREADSHEET.
statusenumOne of DRAFT, QUEUED, RUNNING, COMPLETED, FAILED, UNDONE.
lockHistoryboolean
progressobject
progress.phasestring
progress.donenumber
progress.totalnumber
previewobject or nullThe last dry run; null until previewed or after a change.
preview.countsobjectPer entity: customers, properties, quotes, invoices, payments…
preview.problemsarray of object
preview.problems[].fileIdstring or null
preview.problems[].fileNamestring or null
preview.problems[].rowinteger or null1-based line in the file (the header is line 1).
preview.problems[].columnstring or null
preview.problems[].severityenumErrors skip the row; warnings are only reported. One of error, warning.
preview.problems[].messagestring
preview.errorsinteger
preview.warningsinteger
preview.samplesobjectA few records as they will look.
preview.openingBalancesobject
preview.openingBalances.paymentsinteger"Opening balance (imported)" payments so invoice balances match the export.
preview.openingBalances.invoicesintegerOpening-balance invoices for account balances without open invoices.
preview.openingBalances.amountCentsinteger
preview.needsPaymentMethodintegerCustomers who paid by card on file or autopay: to re-collect.
preview.filesinteger
preview.rowsinteger
previewedAtstring (date-time) or null
summaryobject or nullWhat the applied run did, per entity.
problemsarray of object
problems[].fileIdstring or null
problems[].fileNamestring or null
problems[].rowinteger or null1-based line in the file (the header is line 1).
problems[].columnstring or null
problems[].severityenumErrors skip the row; warnings are only reported. One of error, warning.
problems[].messagestring
queuedAtstring (date-time) or null
startedAtstring (date-time) or null
finishedAtstring (date-time) or null
errorstring or null
undoUntilstring (date-time) or null
canUndoboolean
undoneAtstring (date-time) or null
undoReportobject or null
filesarray of object
files[].idstring
files[].uploadIdstring
files[].fileNamestring
files[].sheetNamestring or null
files[].sizeBytesinteger
files[].statusenumOne of UPLOADING, READY, ERROR.
files[].errorstring or null
files[].datasetenum or nullWhat the rows are; null = not recognised (skipped until set). One of pricebook, customers, contacts, properties, quotes, invoices, payments, notes.
files[].detectedDatasetenum or nullOne of pricebook, customers, contacts, properties, quotes, invoices, payments, notes.
files[].detectionConfidencenumber or null
files[].headersarray of string
files[].rowCountinteger
files[].sampleRowsarray of array of string
files[].mappingobject
files[].needsReviewarray of stringHeaders mapped by a guess below 0.7 confidence: confirm them.
files[].createdAtstring (date-time)
createdAtstring (date-time)

Delete a draft import

DELETE /organizations/{organizationId}/imports/{importId}

DELETES the draft import and its uploaded files. Only an import never applied (DRAFT); an applied one is undone instead (POST …/undo).

Permissionimport.manage (Owner, Admin)
Risksensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access.
MCP toolimports_delete (toolset settings)
ApprovalOver MCP, this tool always waits for your approval in SKUFlow. See Approvals.

Parameters

NameInTypeRequiredDescription
importIdpathstringYesThe import run (from POST /imports or GET /imports).

Example

curl -X DELETE "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/imports/{importId}" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
deletedtrue

Add a file (content in the request)

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, contacts, properties, pricebook, quotes, invoices, payments, notes) and the mapping from the source's preset, the saved mapping and the name heuristic. Several files may hold one dataset (a list split into several exports). The browser uses POST …/uploads instead. Returns the import.

Permissionimport.manage (Owner, Admin)
Riskwrite, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolimports_addFile (toolset settings)

Parameters

NameInTypeRequiredDescription
importIdpathstringYesThe import run (from POST /imports or GET /imports).

Request body

FieldTypeRequiredDescription
fileNamestringYesThe file's name, with its extension (.csv, .tsv or .xlsx). Up to 255 characters.
textstringNoThe CSV/TSV text.
contentBase64stringNoThe file's bytes as base64 (required for .xlsx).

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/imports/{importId}/files" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"fileName":"string"}'

Response

200: the answer's fields
FieldTypeDescription
idstring
sourceenumOne of DECONETWORK, SPREADSHEET.
statusenumOne of DRAFT, QUEUED, RUNNING, COMPLETED, FAILED, UNDONE.
lockHistoryboolean
progressobject
progress.phasestring
progress.donenumber
progress.totalnumber
previewobject or nullThe last dry run; null until previewed or after a change.
preview.countsobjectPer entity: customers, properties, quotes, invoices, payments…
preview.problemsarray of object
preview.problems[].fileIdstring or null
preview.problems[].fileNamestring or null
preview.problems[].rowinteger or null1-based line in the file (the header is line 1).
preview.problems[].columnstring or null
preview.problems[].severityenumErrors skip the row; warnings are only reported. One of error, warning.
preview.problems[].messagestring
preview.errorsinteger
preview.warningsinteger
preview.samplesobjectA few records as they will look.
preview.openingBalancesobject
preview.openingBalances.paymentsinteger"Opening balance (imported)" payments so invoice balances match the export.
preview.openingBalances.invoicesintegerOpening-balance invoices for account balances without open invoices.
preview.openingBalances.amountCentsinteger
preview.needsPaymentMethodintegerCustomers who paid by card on file or autopay: to re-collect.
preview.filesinteger
preview.rowsinteger
previewedAtstring (date-time) or null
summaryobject or nullWhat the applied run did, per entity.
problemsarray of object
problems[].fileIdstring or null
problems[].fileNamestring or null
problems[].rowinteger or null1-based line in the file (the header is line 1).
problems[].columnstring or null
problems[].severityenumErrors skip the row; warnings are only reported. One of error, warning.
problems[].messagestring
queuedAtstring (date-time) or null
startedAtstring (date-time) or null
finishedAtstring (date-time) or null
errorstring or null
undoUntilstring (date-time) or null
canUndoboolean
undoneAtstring (date-time) or null
undoReportobject or null
filesarray of object
files[].idstring
files[].uploadIdstring
files[].fileNamestring
files[].sheetNamestring or null
files[].sizeBytesinteger
files[].statusenumOne of UPLOADING, READY, ERROR.
files[].errorstring or null
files[].datasetenum or nullWhat the rows are; null = not recognised (skipped until set). One of pricebook, customers, contacts, properties, quotes, invoices, payments, notes.
files[].detectedDatasetenum or nullOne of pricebook, customers, contacts, properties, quotes, invoices, payments, notes.
files[].detectionConfidencenumber or null
files[].headersarray of string
files[].rowCountinteger
files[].sampleRowsarray of array of string
files[].mappingobject
files[].needsReviewarray of stringHeaders mapped by a guess below 0.7 confidence: confirm them.
files[].createdAtstring (date-time)
createdAtstring (date-time)

Get an upload URL

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.

Permissionimport.manage (Owner, Admin)
Riskwrite, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolimports_createUpload (toolset settings)

Parameters

NameInTypeRequiredDescription
importIdpathstringYesThe import run (from POST /imports or GET /imports).

Request body

FieldTypeRequiredDescription
fileNamestringYesThe file's name, with its extension (.csv, .tsv or .xlsx). Up to 255 characters.
contentTypestringYesUp to 200 characters.
sizeBytesintegerYes1–26214400.

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/imports/{importId}/uploads" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"fileName":"string","contentType":"string","sizeBytes":1}'

Response

200: the answer's fields
FieldTypeDescription
uploadIdstring
uploadUrlstring

Confirm an upload

POST /organizations/{organizationId}/imports/{importId}/uploads/{uploadId}/confirm

Step 2 of a browser upload: reads the uploaded file, sniffs each sheet and maps its columns. Returns the import.

Permissionimport.manage (Owner, Admin)
Riskwrite, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolimports_confirmUpload (toolset settings)

Parameters

NameInTypeRequiredDescription
importIdpathstringYesThe import run (from POST /imports or GET /imports).
uploadIdpathstringYesFrom POST …/uploads.

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/imports/{importId}/uploads/{uploadId}/confirm" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
idstring
sourceenumOne of DECONETWORK, SPREADSHEET.
statusenumOne of DRAFT, QUEUED, RUNNING, COMPLETED, FAILED, UNDONE.
lockHistoryboolean
progressobject
progress.phasestring
progress.donenumber
progress.totalnumber
previewobject or nullThe last dry run; null until previewed or after a change.
preview.countsobjectPer entity: customers, properties, quotes, invoices, payments…
preview.problemsarray of object
preview.problems[].fileIdstring or null
preview.problems[].fileNamestring or null
preview.problems[].rowinteger or null1-based line in the file (the header is line 1).
preview.problems[].columnstring or null
preview.problems[].severityenumErrors skip the row; warnings are only reported. One of error, warning.
preview.problems[].messagestring
preview.errorsinteger
preview.warningsinteger
preview.samplesobjectA few records as they will look.
preview.openingBalancesobject
preview.openingBalances.paymentsinteger"Opening balance (imported)" payments so invoice balances match the export.
preview.openingBalances.invoicesintegerOpening-balance invoices for account balances without open invoices.
preview.openingBalances.amountCentsinteger
preview.needsPaymentMethodintegerCustomers who paid by card on file or autopay: to re-collect.
preview.filesinteger
preview.rowsinteger
previewedAtstring (date-time) or null
summaryobject or nullWhat the applied run did, per entity.
problemsarray of object
problems[].fileIdstring or null
problems[].fileNamestring or null
problems[].rowinteger or null1-based line in the file (the header is line 1).
problems[].columnstring or null
problems[].severityenumErrors skip the row; warnings are only reported. One of error, warning.
problems[].messagestring
queuedAtstring (date-time) or null
startedAtstring (date-time) or null
finishedAtstring (date-time) or null
errorstring or null
undoUntilstring (date-time) or null
canUndoboolean
undoneAtstring (date-time) or null
undoReportobject or null
filesarray of object
files[].idstring
files[].uploadIdstring
files[].fileNamestring
files[].sheetNamestring or null
files[].sizeBytesinteger
files[].statusenumOne of UPLOADING, READY, ERROR.
files[].errorstring or null
files[].datasetenum or nullWhat the rows are; null = not recognised (skipped until set). One of pricebook, customers, contacts, properties, quotes, invoices, payments, notes.
files[].detectedDatasetenum or nullOne of pricebook, customers, contacts, properties, quotes, invoices, payments, notes.
files[].detectionConfidencenumber or null
files[].headersarray of string
files[].rowCountinteger
files[].sampleRowsarray of array of string
files[].mappingobject
files[].needsReviewarray of stringHeaders mapped by a guess below 0.7 confidence: confirm them.
files[].createdAtstring (date-time)
createdAtstring (date-time)

Set a file's dataset or mapping

PATCH /organizations/{organizationId}/imports/{importId}/files/{fileId}

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.

Permissionimport.manage (Owner, Admin)
Riskwrite, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolimports_updateFile (toolset settings)

Parameters

NameInTypeRequiredDescription
importIdpathstringYesThe import run (from POST /imports or GET /imports).
fileIdpathstringYesA file of the import (one per CSV, or per sheet of a workbook).

Request body

FieldTypeRequiredDescription
datasetenum or nullNoOne of pricebook, customers, contacts, properties, quotes, invoices, payments, notes.
mappingobjectNo

Example

curl -X PATCH "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/imports/{importId}/files/{fileId}" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"dataset":"pricebook","mapping":{}}'

Response

200: the answer's fields
FieldTypeDescription
idstring
sourceenumOne of DECONETWORK, SPREADSHEET.
statusenumOne of DRAFT, QUEUED, RUNNING, COMPLETED, FAILED, UNDONE.
lockHistoryboolean
progressobject
progress.phasestring
progress.donenumber
progress.totalnumber
previewobject or nullThe last dry run; null until previewed or after a change.
preview.countsobjectPer entity: customers, properties, quotes, invoices, payments…
preview.problemsarray of object
preview.problems[].fileIdstring or null
preview.problems[].fileNamestring or null
preview.problems[].rowinteger or null1-based line in the file (the header is line 1).
preview.problems[].columnstring or null
preview.problems[].severityenumErrors skip the row; warnings are only reported. One of error, warning.
preview.problems[].messagestring
preview.errorsinteger
preview.warningsinteger
preview.samplesobjectA few records as they will look.
preview.openingBalancesobject
preview.openingBalances.paymentsinteger"Opening balance (imported)" payments so invoice balances match the export.
preview.openingBalances.invoicesintegerOpening-balance invoices for account balances without open invoices.
preview.openingBalances.amountCentsinteger
preview.needsPaymentMethodintegerCustomers who paid by card on file or autopay: to re-collect.
preview.filesinteger
preview.rowsinteger
previewedAtstring (date-time) or null
summaryobject or nullWhat the applied run did, per entity.
problemsarray of object
problems[].fileIdstring or null
problems[].fileNamestring or null
problems[].rowinteger or null1-based line in the file (the header is line 1).
problems[].columnstring or null
problems[].severityenumErrors skip the row; warnings are only reported. One of error, warning.
problems[].messagestring
queuedAtstring (date-time) or null
startedAtstring (date-time) or null
finishedAtstring (date-time) or null
errorstring or null
undoUntilstring (date-time) or null
canUndoboolean
undoneAtstring (date-time) or null
undoReportobject or null
filesarray of object
files[].idstring
files[].uploadIdstring
files[].fileNamestring
files[].sheetNamestring or null
files[].sizeBytesinteger
files[].statusenumOne of UPLOADING, READY, ERROR.
files[].errorstring or null
files[].datasetenum or nullWhat the rows are; null = not recognised (skipped until set). One of pricebook, customers, contacts, properties, quotes, invoices, payments, notes.
files[].detectedDatasetenum or nullOne of pricebook, customers, contacts, properties, quotes, invoices, payments, notes.
files[].detectionConfidencenumber or null
files[].headersarray of string
files[].rowCountinteger
files[].sampleRowsarray of array of string
files[].mappingobject
files[].needsReviewarray of stringHeaders mapped by a guess below 0.7 confidence: confirm them.
files[].createdAtstring (date-time)
createdAtstring (date-time)

Remove a file from an import

DELETE /organizations/{organizationId}/imports/{importId}/files/{fileId}

DELETES the file (sheet) from the draft import; its stored upload goes when no sheet uses it. Returns the import.

Permissionimport.manage (Owner, Admin)
Risksensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access.
MCP toolimports_deleteFile (toolset settings)
ApprovalOver MCP, this tool always waits for your approval in SKUFlow. See Approvals.

Parameters

NameInTypeRequiredDescription
importIdpathstringYesThe import run (from POST /imports or GET /imports).
fileIdpathstringYesA file of the import (one per CSV, or per sheet of a workbook).

Example

curl -X DELETE "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/imports/{importId}/files/{fileId}" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
idstring
sourceenumOne of DECONETWORK, SPREADSHEET.
statusenumOne of DRAFT, QUEUED, RUNNING, COMPLETED, FAILED, UNDONE.
lockHistoryboolean
progressobject
progress.phasestring
progress.donenumber
progress.totalnumber
previewobject or nullThe last dry run; null until previewed or after a change.
preview.countsobjectPer entity: customers, properties, quotes, invoices, payments…
preview.problemsarray of object
preview.problems[].fileIdstring or null
preview.problems[].fileNamestring or null
preview.problems[].rowinteger or null1-based line in the file (the header is line 1).
preview.problems[].columnstring or null
preview.problems[].severityenumErrors skip the row; warnings are only reported. One of error, warning.
preview.problems[].messagestring
preview.errorsinteger
preview.warningsinteger
preview.samplesobjectA few records as they will look.
preview.openingBalancesobject
preview.openingBalances.paymentsinteger"Opening balance (imported)" payments so invoice balances match the export.
preview.openingBalances.invoicesintegerOpening-balance invoices for account balances without open invoices.
preview.openingBalances.amountCentsinteger
preview.needsPaymentMethodintegerCustomers who paid by card on file or autopay: to re-collect.
preview.filesinteger
preview.rowsinteger
previewedAtstring (date-time) or null
summaryobject or nullWhat the applied run did, per entity.
problemsarray of object
problems[].fileIdstring or null
problems[].fileNamestring or null
problems[].rowinteger or null1-based line in the file (the header is line 1).
problems[].columnstring or null
problems[].severityenumErrors skip the row; warnings are only reported. One of error, warning.
problems[].messagestring
queuedAtstring (date-time) or null
startedAtstring (date-time) or null
finishedAtstring (date-time) or null
errorstring or null
undoUntilstring (date-time) or null
canUndoboolean
undoneAtstring (date-time) or null
undoReportobject or null
filesarray of object
files[].idstring
files[].uploadIdstring
files[].fileNamestring
files[].sheetNamestring or null
files[].sizeBytesinteger
files[].statusenumOne of UPLOADING, READY, ERROR.
files[].errorstring or null
files[].datasetenum or nullWhat the rows are; null = not recognised (skipped until set). One of pricebook, customers, contacts, properties, quotes, invoices, payments, notes.
files[].detectedDatasetenum or nullOne of pricebook, customers, contacts, properties, quotes, invoices, payments, notes.
files[].detectionConfidencenumber or null
files[].headersarray of string
files[].rowCountinteger
files[].sampleRowsarray of array of string
files[].mappingobject
files[].needsReviewarray of stringHeaders mapped by a guess below 0.7 confidence: confirm them.
files[].createdAtstring (date-time)
createdAtstring (date-time)

AI column mapping

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.

Permissionimport.manage (Owner, Admin)
Riskwrite, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolimports_suggestMapping (toolset settings)

Parameters

NameInTypeRequiredDescription
importIdpathstringYesThe import run (from POST /imports or GET /imports).
fileIdpathstringYesA file of the import (one per CSV, or per sheet of a workbook).

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/imports/{importId}/files/{fileId}/suggest-mapping" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
modeenumOne of AI, HEURISTIC.
aiAvailableboolean
fileobject
file.idstring
file.uploadIdstring
file.fileNamestring
file.sheetNamestring or null
file.sizeBytesinteger
file.statusenumOne of UPLOADING, READY, ERROR.
file.errorstring or null
file.datasetenum or nullWhat the rows are; null = not recognised (skipped until set). One of pricebook, customers, contacts, properties, quotes, invoices, payments, notes.
file.detectedDatasetenum or nullOne of pricebook, customers, contacts, properties, quotes, invoices, payments, notes.
file.detectionConfidencenumber or null
file.headersarray of string
file.rowCountinteger
file.sampleRowsarray of array of string
file.mappingobject
file.needsReviewarray of stringHeaders mapped by a guess below 0.7 confidence: confirm them.
file.createdAtstring (date-time)

Preview an import (dry run)

POST /organizations/{organizationId}/imports/{importId}/preview

The dry run: counts per entity (to create, to update, duplicates, kept because edited in SKUFlow), 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.

Permissionimport.manage (Owner, Admin)
Riskwrite, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolimports_preview (toolset settings)

Parameters

NameInTypeRequiredDescription
importIdpathstringYesThe import run (from POST /imports or GET /imports).

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/imports/{importId}/preview" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
countsobjectPer entity: customers, properties, quotes, invoices, payments…
problemsarray of object
problems[].fileIdstring or null
problems[].fileNamestring or null
problems[].rowinteger or null1-based line in the file (the header is line 1).
problems[].columnstring or null
problems[].severityenumErrors skip the row; warnings are only reported. One of error, warning.
problems[].messagestring
errorsinteger
warningsinteger
samplesobjectA few records as they will look.
openingBalancesobject
openingBalances.paymentsinteger"Opening balance (imported)" payments so invoice balances match the export.
openingBalances.invoicesintegerOpening-balance invoices for account balances without open invoices.
openingBalances.amountCentsinteger
needsPaymentMethodintegerCustomers who paid by card on file or autopay: to re-collect.
filesinteger
rowsinteger

Apply an import

POST /organizations/{organizationId}/imports/{importId}/apply

Writes customer and money records: runs the previewed import in the background in dependency order (pricebook → customers → contacts → properties → quotes → invoices → payments → notes). Sends nothing to customers: imported records emit no events and are held back from automations, reminders 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.

Permissionimport.manage (Owner, Admin)
Risksensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access.
MCP toolimports_apply (toolset settings)
ApprovalOver MCP, this tool asks for your OK first (in the AI app when it supports it, otherwise in SKUFlow). See Approvals.

Parameters

NameInTypeRequiredDescription
importIdpathstringYesThe import run (from POST /imports or GET /imports).

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/imports/{importId}/apply" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
idstring
sourceenumOne of DECONETWORK, SPREADSHEET.
statusenumOne of DRAFT, QUEUED, RUNNING, COMPLETED, FAILED, UNDONE.
lockHistoryboolean
progressobject
progress.phasestring
progress.donenumber
progress.totalnumber
previewobject or nullThe last dry run; null until previewed or after a change.
preview.countsobjectPer entity: customers, properties, quotes, invoices, payments…
preview.problemsarray of object
preview.problems[].fileIdstring or null
preview.problems[].fileNamestring or null
preview.problems[].rowinteger or null1-based line in the file (the header is line 1).
preview.problems[].columnstring or null
preview.problems[].severityenumErrors skip the row; warnings are only reported. One of error, warning.
preview.problems[].messagestring
preview.errorsinteger
preview.warningsinteger
preview.samplesobjectA few records as they will look.
preview.openingBalancesobject
preview.openingBalances.paymentsinteger"Opening balance (imported)" payments so invoice balances match the export.
preview.openingBalances.invoicesintegerOpening-balance invoices for account balances without open invoices.
preview.openingBalances.amountCentsinteger
preview.needsPaymentMethodintegerCustomers who paid by card on file or autopay: to re-collect.
preview.filesinteger
preview.rowsinteger
previewedAtstring (date-time) or null
summaryobject or nullWhat the applied run did, per entity.
problemsarray of object
problems[].fileIdstring or null
problems[].fileNamestring or null
problems[].rowinteger or null1-based line in the file (the header is line 1).
problems[].columnstring or null
problems[].severityenumErrors skip the row; warnings are only reported. One of error, warning.
problems[].messagestring
queuedAtstring (date-time) or null
startedAtstring (date-time) or null
finishedAtstring (date-time) or null
errorstring or null
undoUntilstring (date-time) or null
canUndoboolean
undoneAtstring (date-time) or null
undoReportobject or null
filesarray of object
files[].idstring
files[].uploadIdstring
files[].fileNamestring
files[].sheetNamestring or null
files[].sizeBytesinteger
files[].statusenumOne of UPLOADING, READY, ERROR.
files[].errorstring or null
files[].datasetenum or nullWhat the rows are; null = not recognised (skipped until set). One of pricebook, customers, contacts, properties, quotes, invoices, payments, notes.
files[].detectedDatasetenum or nullOne of pricebook, customers, contacts, properties, quotes, invoices, payments, notes.
files[].detectionConfidencenumber or null
files[].headersarray of string
files[].rowCountinteger
files[].sampleRowsarray of array of string
files[].mappingobject
files[].needsReviewarray of stringHeaders mapped by a guess below 0.7 confidence: confirm them.
files[].createdAtstring (date-time)
createdAtstring (date-time)

Undo an import

POST /organizations/{organizationId}/imports/{importId}/undo

DELETES what this import created (within 7 days of finishing), in reverse order. Records edited in SKUFlow since, or used by work added since (a new quote, invoice or payment), are kept and listed in undoReport. Records the import only updated stay as they are. Returns the import (status UNDONE).

Permissionimport.manage (Owner, Admin)
Risksensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access.
MCP toolimports_undo (toolset settings)
ApprovalOver MCP, this tool asks for your OK first (in the AI app when it supports it, otherwise in SKUFlow). See Approvals.

Parameters

NameInTypeRequiredDescription
importIdpathstringYesThe import run (from POST /imports or GET /imports).

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/imports/{importId}/undo" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
idstring
sourceenumOne of DECONETWORK, SPREADSHEET.
statusenumOne of DRAFT, QUEUED, RUNNING, COMPLETED, FAILED, UNDONE.
lockHistoryboolean
progressobject
progress.phasestring
progress.donenumber
progress.totalnumber
previewobject or nullThe last dry run; null until previewed or after a change.
preview.countsobjectPer entity: customers, properties, quotes, invoices, payments…
preview.problemsarray of object
preview.problems[].fileIdstring or null
preview.problems[].fileNamestring or null
preview.problems[].rowinteger or null1-based line in the file (the header is line 1).
preview.problems[].columnstring or null
preview.problems[].severityenumErrors skip the row; warnings are only reported. One of error, warning.
preview.problems[].messagestring
preview.errorsinteger
preview.warningsinteger
preview.samplesobjectA few records as they will look.
preview.openingBalancesobject
preview.openingBalances.paymentsinteger"Opening balance (imported)" payments so invoice balances match the export.
preview.openingBalances.invoicesintegerOpening-balance invoices for account balances without open invoices.
preview.openingBalances.amountCentsinteger
preview.needsPaymentMethodintegerCustomers who paid by card on file or autopay: to re-collect.
preview.filesinteger
preview.rowsinteger
previewedAtstring (date-time) or null
summaryobject or nullWhat the applied run did, per entity.
problemsarray of object
problems[].fileIdstring or null
problems[].fileNamestring or null
problems[].rowinteger or null1-based line in the file (the header is line 1).
problems[].columnstring or null
problems[].severityenumErrors skip the row; warnings are only reported. One of error, warning.
problems[].messagestring
queuedAtstring (date-time) or null
startedAtstring (date-time) or null
finishedAtstring (date-time) or null
errorstring or null
undoUntilstring (date-time) or null
canUndoboolean
undoneAtstring (date-time) or null
undoReportobject or null
filesarray of object
files[].idstring
files[].uploadIdstring
files[].fileNamestring
files[].sheetNamestring or null
files[].sizeBytesinteger
files[].statusenumOne of UPLOADING, READY, ERROR.
files[].errorstring or null
files[].datasetenum or nullWhat the rows are; null = not recognised (skipped until set). One of pricebook, customers, contacts, properties, quotes, invoices, payments, notes.
files[].detectedDatasetenum or nullOne of pricebook, customers, contacts, properties, quotes, invoices, payments, notes.
files[].detectionConfidencenumber or null
files[].headersarray of string
files[].rowCountinteger
files[].sampleRowsarray of array of string
files[].mappingobject
files[].needsReviewarray of stringHeaders mapped by a guess below 0.7 confidence: confirm them.
files[].createdAtstring (date-time)
createdAtstring (date-time)

Cutover checklist

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 automations, and the last import. Read-only.

Permissionimport.manage (Owner, Admin)
Riskread, OAuth scope skuflow.read. Read: reads only.
MCP toolimports_cutover (toolset settings)

Example

curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/migration/cutover" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
lastImportobject or null
lastImport.idstring
lastImport.sourceenumOne of DECONETWORK, SPREADSHEET.
lastImport.finishedAtstring (date-time) or null
heldRecordsinteger
customersNeedingCardinteger
automationsOninteger

Release imported records (cutover)

POST /organizations/{organizationId}/migration/cutover/release

Customer-visible from now on: imported customers, quotes and invoices join automations, reminders and dunning. Do it once the old system has stopped sending (cutover day). Sends nothing by itself. Returns how many records were released.

Permissionimport.manage (Owner, Admin)
Risksensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access.
MCP toolimports_release (toolset settings)
ApprovalOver MCP, this tool asks for your OK first (in the AI app when it supports it, otherwise in SKUFlow). See Approvals.

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/migration/cutover/release" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
releasedinteger

Customers to ask for a card

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.

Permissionimport.manage (Owner, Admin)
Riskread, OAuth scope skuflow.read. Read: reads only.
MCP toolimports_needsCard (toolset settings)

Example

curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/migration/needs-card" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
totalinteger
customersarray of object
customers[].idstring
customers[].namestring
customers[].emailstring or null
customers[].phonestring or null
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.

Permissionimport.manage (Owner, Admin)
Risksensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access.
MCP toolimports_sendUpdateCardLinks (toolset settings)
ApprovalOver MCP, this tool always waits for your approval in SKUFlow. See Approvals.

Request body

FieldTypeRequiredDescription
channelenumNoOne of EMAIL, SMS, EMAIL_OR_SMS. Default EMAIL_OR_SMS.
customerIdsarray of stringNoOnly these (from GET /migration/needs-card). Up to 2000 items.
batchKeystringNoReuse to retry without sending twice. Up to 100 characters.

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/migration/update-card-links" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"channel":"EMAIL_OR_SMS","customerIds":["customer_id"],"batchKey":"string"}'

Response

200: the answer's fields
FieldTypeDescription
batchKeystring
sentinteger
skippedinteger
resultsarray of object
results[].customerIdstring
results[].namestring
results[].outcomeenumOne of SENT, QUEUED, SKIPPED.
results[].reasonstring or null
results[].channelenum or nullOne of EMAIL, SMS.

On this page