DevelopersAPI reference

Integrations API

REST endpoints for integrations 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
List integrationsGET /organizations/{organizationId}/integrationsread
Start connecting QuickBooksPOST /organizations/{organizationId}/integrations/quickbooks/connectsensitive
Disconnect QuickBooksPOST /organizations/{organizationId}/integrations/quickbooks/disconnectsensitive
QuickBooks mappingsGET /organizations/{organizationId}/integrations/quickbooks/settingsread
Set the QuickBooks mappingsPATCH /organizations/{organizationId}/integrations/quickbooks/settingswrite
QuickBooks sync logGET /organizations/{organizationId}/integrations/quickbooks/sync-logread
Push a record to QuickBooks nowPOST /organizations/{organizationId}/integrations/quickbooks/resyncwrite
Run the QuickBooks sync nowPOST /organizations/{organizationId}/integrations/quickbooks/syncwrite
A record's QuickBooks statusGET /organizations/{organizationId}/integrations/quickbooks/records/{entityType}/{entityId}read
Start connecting XeroPOST /organizations/{organizationId}/integrations/xero/connectsensitive
Choose the Xero organisationPOST /organizations/{organizationId}/integrations/xero/tenantsensitive
Disconnect XeroPOST /organizations/{organizationId}/integrations/xero/disconnectsensitive
Xero mappingsGET /organizations/{organizationId}/integrations/xero/settingsread
Set the Xero mappingsPATCH /organizations/{organizationId}/integrations/xero/settingswrite
Xero sync logGET /organizations/{organizationId}/integrations/xero/sync-logread
Push a record to Xero nowPOST /organizations/{organizationId}/integrations/xero/resyncwrite
Run the Xero sync nowPOST /organizations/{organizationId}/integrations/xero/syncwrite
A record's Xero statusGET /organizations/{organizationId}/integrations/xero/records/{entityType}/{entityId}read

List integrations

GET /organizations/{organizationId}/integrations

The accounting integrations, QuickBooks Online and Xero: for each, whether the server is configured for it and in which mode (mock, sandbox / production or live), the variables still missing, the connection, mappings, sync counts and records synced; blockedBy names the other one when it is connected (one accounting system at a time). Xero also lists pendingTenants while a consent that connected several Xero organisations waits for the choice. Start with POST /integrations/quickbooks/connect or POST /integrations/xero/connect. Read-only.

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

Example

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

Response

200: the answer's fields
FieldTypeDescription
quickbooksobject
quickbooks.configobject
quickbooks.config.modeenumOne of mock, live, unconfigured.
quickbooks.config.configuredboolean
quickbooks.config.missingarray of stringEnvironment variables the server still needs.
quickbooks.config.redirectUristring
quickbooks.config.environmentstring
quickbooks.connectionobject or null
quickbooks.connection.idstring
quickbooks.connection.statusenumOne of CONNECTED, DISCONNECTED, ERROR.
quickbooks.connection.environmentstring or null
quickbooks.connection.companyIdstring or nullThe QuickBooks realm id.
quickbooks.connection.companyNamestring or null
quickbooks.connection.connectedAtstring or null
quickbooks.connection.disconnectedAtstring or null
quickbooks.connection.lastSyncAtstring or null
quickbooks.connection.lastErrorstring or null
quickbooks.connection.mappingobject
quickbooks.tasksobject
quickbooks.tasks.PENDINGinteger
quickbooks.tasks.SUCCEEDEDinteger
quickbooks.tasks.FAILEDinteger
quickbooks.tasks.DEADinteger
quickbooks.tasks.SKIPPEDinteger
quickbooks.syncedobject
quickbooks.synced.CUSTOMERinteger
quickbooks.synced.INVOICEinteger
quickbooks.synced.PAYMENTinteger
quickbooks.synced.REFUNDinteger
quickbooks.blockedByenum or nullXero is connected: disconnect it before connecting QuickBooks. One of XERO.
xeroobject
xero.configobject
xero.config.modeenumOne of mock, live, unconfigured.
xero.config.configuredboolean
xero.config.missingarray of stringEnvironment variables the server still needs.
xero.config.redirectUristring
xero.config.scopesstringThe OAuth scopes SKUFlow asks Xero for.
xero.connectionobject or null
xero.connection.idstring
xero.connection.statusenumDISCONNECTED with pendingTenants = waiting for the organisation choice. One of CONNECTED, DISCONNECTED, ERROR.
xero.connection.environmentstring or null
xero.connection.tenantIdstring or nullThe Xero organisation (tenant) id.
xero.connection.tenantNamestring or null
xero.connection.connectedAtstring or null
xero.connection.disconnectedAtstring or null
xero.connection.lastSyncAtstring or null
xero.connection.lastErrorstring or null
xero.connection.mappingobject
xero.pendingTenantsarray of objectXero organisations waiting for the choice (POST /integrations/xero/tenant).
xero.pendingTenants[].tenantIdstring
xero.pendingTenants[].tenantNamestring
xero.blockedByenum or nullQuickBooks is connected: disconnect it before connecting Xero. One of QUICKBOOKS.
xero.tasksobject
xero.tasks.PENDINGinteger
xero.tasks.SUCCEEDEDinteger
xero.tasks.FAILEDinteger
xero.tasks.DEADinteger
xero.tasks.SKIPPEDinteger
xero.syncedobject
xero.synced.CUSTOMERinteger
xero.synced.INVOICEinteger
xero.synced.PAYMENTinteger
xero.synced.REFUNDinteger

Start connecting QuickBooks

POST /organizations/{organizationId}/integrations/quickbooks/connect

Grants access: returns the Intuit consent URL to open (in mock mode, the callback URL directly). After consent Intuit redirects to /integrations/quickbooks/callback with code, state and realmId; finish with POST /integrations/quickbooks/callback. 400 when the server is not configured (see GET /integrations); 409 while Xero is connected (one accounting system at a time).

Permissionintegrations.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 toolintegrations_quickbooksConnect (toolset settings)
PlanQuickBooks Online or Xero sync: the Connect plan and up.
ApprovalWaits for your approval in SKUFlow when called with an API key or a connected app: the first call answers 428 APPROVAL_REQUIRED; once you approve it, repeat the call with the X-SKUFlow-Approval header. See Approvals.

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/integrations/quickbooks/connect" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
authorizeUrlstring
modeenumOne of mock, live, unconfigured.

Disconnect QuickBooks

POST /organizations/{organizationId}/integrations/quickbooks/disconnect

Revokes access: revokes and forgets the QuickBooks tokens; nothing more is pushed and waiting syncs are skipped. The mappings of synced records are kept, so reconnecting the same company updates them rather than creating duplicates.

Permissionintegrations.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 toolintegrations_quickbooksDisconnect (toolset settings)
ApprovalOver MCP, this tool always waits for your approval in SKUFlow. See Approvals.

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/integrations/quickbooks/disconnect" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
idstring
statusenumOne of CONNECTED, DISCONNECTED, ERROR.
environmentstring or null
companyIdstring or nullThe QuickBooks realm id.
companyNamestring or null
connectedAtstring or null
disconnectedAtstring or null
lastSyncAtstring or null
lastErrorstring or null
mappingobject
mapping.itemIdstring or null
mapping.itemNamestring or null
mapping.incomeAccountIdstring or null
mapping.incomeAccountNamestring or null
mapping.taxCodeIdstring or null
mapping.taxCodeNamestring or null
mapping.depositAccountIdstring or null
mapping.depositAccountNamestring or null

QuickBooks mappings

GET /organizations/{organizationId}/integrations/quickbooks/settings

The current mappings and the choices from the connected company: income accounts, items, tax codes and deposit accounts. Invoices need the default item before they can be pushed. 409 when not connected. Read-only.

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

Example

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

Response

200: the answer's fields
FieldTypeDescription
mappingobject
mapping.itemIdstring or null
mapping.itemNamestring or null
mapping.incomeAccountIdstring or null
mapping.incomeAccountNamestring or null
mapping.taxCodeIdstring or null
mapping.taxCodeNamestring or null
mapping.depositAccountIdstring or null
mapping.depositAccountNamestring or null
optionsobject
options.incomeAccountsarray of object
options.incomeAccounts[].idstring
options.incomeAccounts[].namestring
options.incomeAccounts[].kindstring or null
options.depositAccountsarray of object
options.depositAccounts[].idstring
options.depositAccounts[].namestring
options.depositAccounts[].kindstring or null
options.itemsarray of object
options.items[].idstring
options.items[].namestring
options.items[].kindstring or null
options.taxCodesarray of object
options.taxCodes[].idstring
options.taxCodes[].namestring
options.taxCodes[].kindstring or null

Set the QuickBooks mappings

PATCH /organizations/{organizationId}/integrations/quickbooks/settings

Choose the QuickBooks item invoice lines are booked to (required), the income account (for reference), the tax code for taxed invoices (default TAX) and the account payments are deposited to (default Undeposited Funds). Ids from GET /integrations/quickbooks/settings; null clears.

Permissionintegrations.manage (Owner, Admin)
Riskwrite, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolintegrations_quickbooksUpdateSettings (toolset settings)
PlanQuickBooks Online or Xero sync: the Connect plan and up.

Request body

FieldTypeRequiredDescription
itemIdstring or nullNoUp to 100 characters.
incomeAccountIdstring or nullNoUp to 100 characters.
taxCodeIdstring or nullNoUp to 100 characters.
depositAccountIdstring or nullNoUp to 100 characters.

Example

curl -X PATCH "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/integrations/quickbooks/settings" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"itemId":"item_id","incomeAccountId":"incomeAccount_id","taxCodeId":"taxCode_id"}'

Response

200: the answer's fields
FieldTypeDescription
itemIdstring or null
itemNamestring or null
incomeAccountIdstring or null
incomeAccountNamestring or null
taxCodeIdstring or null
taxCodeNamestring or null
depositAccountIdstring or null
depositAccountNamestring or null

QuickBooks sync log

GET /organizations/{organizationId}/integrations/quickbooks/sync-log

Every push to QuickBooks, newest first: the record (customer, invoice, payment, refund), what triggered it (an event or a manual resync), status (PENDING, SUCCEEDED, FAILED = will retry, DEAD, SKIPPED with the reason), attempts, the QuickBooks id and the error. Filter by status or record. Read-only.

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

Parameters

NameInTypeRequiredDescription
statusqueryenumNoOne of PENDING, SUCCEEDED, FAILED, DEAD, SKIPPED.
entityTypequeryenumNoOne of CUSTOMER, INVOICE, PAYMENT, REFUND.
entityIdquerystringNo
limitqueryintegerNoPage size, 1–200. Default 50.
offsetqueryintegerNoRows to skip; the answer's total counts every match. Default 0.

Example

curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/integrations/quickbooks/sync-log" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
itemsarray of object
items[].idstring
items[].triggerenumOne of EVENT, MANUAL.
items[].eventIdstring or null
items[].eventTypestring or null
items[].entityTypeenumOne of CUSTOMER, INVOICE, PAYMENT, REFUND.
items[].entityIdstring
items[].statusenumOne of PENDING, SUCCEEDED, FAILED, DEAD, SKIPPED.
items[].attemptCountinteger
items[].nextAttemptAtstring or null
items[].completedAtstring or null
items[].remoteIdstring or nullThe record's id in QuickBooks.
items[].errorstring or null
items[].createdAtstring
items[].updatedAtstring
items[].labelstring or null
totalinteger

Push a record to QuickBooks now

POST /organizations/{organizationId}/integrations/quickbooks/resync

Pushes one customer, invoice, payment or refund to the connected QuickBooks now (creating it, or updating the copy already there: never a duplicate), with what it depends on (an invoice's customer first). Answers the sync task. Drafts and cancelled invoices are skipped.

Permissionintegrations.manage (Owner, Admin)
Riskwrite, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolintegrations_quickbooksResync (toolset settings)
PlanQuickBooks Online or Xero sync: the Connect plan and up.

Request body

FieldTypeRequiredDescription
entityTypeenumYesOne of CUSTOMER, INVOICE, PAYMENT, REFUND.
entityIdstringYes

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/integrations/quickbooks/resync" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"entityType":"CUSTOMER","entityId":"entity_id"}'

Response

200: the answer's fields
FieldTypeDescription
idstring
triggerenumOne of EVENT, MANUAL.
eventIdstring or null
eventTypestring or null
entityTypeenumOne of CUSTOMER, INVOICE, PAYMENT, REFUND.
entityIdstring
statusenumOne of PENDING, SUCCEEDED, FAILED, DEAD, SKIPPED.
attemptCountinteger
nextAttemptAtstring or null
completedAtstring or null
remoteIdstring or nullThe record's id in QuickBooks.
errorstring or null
createdAtstring
updatedAtstring

Run the QuickBooks sync now

POST /organizations/{organizationId}/integrations/quickbooks/sync

Processes this organization's waiting pushes now instead of on the next scheduler run (it also runs every few seconds in the API service). Answers how many were attempted, succeeded, failed, died or were skipped.

Permissionintegrations.manage (Owner, Admin)
Riskwrite, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolintegrations_quickbooksSyncNow (toolset settings)
PlanQuickBooks Online or Xero sync: the Connect plan and up.

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/integrations/quickbooks/sync" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
attemptedinteger
succeededinteger
failedinteger
deadinteger
skippedinteger
deferredintegerWaiting for a rate-limit pause to end (Xero); no attempt used.

A record's QuickBooks status

GET /organizations/{organizationId}/integrations/quickbooks/records/{entityType}/{entityId}

Whether a customer, invoice, payment or refund is in QuickBooks: SYNCED (with its QuickBooks id and when), PENDING, ERROR (with the reason), SKIPPED (why), NOT_SYNCED, or NOT_CONNECTED when the organization has no QuickBooks. For the badge on invoices and customers. Read-only.

Permissioninvoices.read (Owner, Admin, Staff, Member)
Riskread, OAuth scope skuflow.read. Read: reads only.
MCP toolintegrations_syncStatus (toolset settings)

Parameters

NameInTypeRequiredDescription
entityTypepathenumYesOne of CUSTOMER, INVOICE, PAYMENT, REFUND.
entityIdpathstringYes

Example

curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/integrations/quickbooks/records/{entityType}/{entityId}" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
stateenumOne of SYNCED, PENDING, ERROR, SKIPPED, NOT_SYNCED, NOT_CONNECTED.
remoteIdstring or null
syncedAtstring or null
errorstring or null
taskIdstring or null

Start connecting Xero

POST /organizations/{organizationId}/integrations/xero/connect

Grants access: returns Xero's consent URL to open (in mock mode, the callback URL directly). After consent Xero redirects to /integrations/xero/callback with code and state; finish with POST /integrations/xero/callback. 400 when the server is not configured (see GET /integrations); 409 while QuickBooks is connected (one accounting system at a time).

Permissionintegrations.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 toolintegrations_xeroConnect (toolset settings)
PlanQuickBooks Online or Xero sync: the Connect plan and up.
ApprovalWaits for your approval in SKUFlow when called with an API key or a connected app: the first call answers 428 APPROVAL_REQUIRED; once you approve it, repeat the call with the X-SKUFlow-Approval header. See Approvals.

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/integrations/xero/connect" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
authorizeUrlstring
modeenumOne of mock, live, unconfigured.

Choose the Xero organisation

POST /organizations/{organizationId}/integrations/xero/tenant

Grants access: connects SKUFlow to one of the Xero organisations the last consent connected (pendingTenants of GET /integrations). Choosing a different organisation than before starts with empty mappings. 409 when nothing waits for a choice (connect again) or QuickBooks is connected.

Permissionintegrations.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 toolintegrations_xeroSelectTenant (toolset settings)
PlanQuickBooks Online or Xero sync: the Connect plan and up.
ApprovalWaits for your approval in SKUFlow when called with an API key or a connected app: the first call answers 428 APPROVAL_REQUIRED; once you approve it, repeat the call with the X-SKUFlow-Approval header. See Approvals.

Request body

FieldTypeRequiredDescription
tenantIdstringYesA tenantId from pendingTenants (Xero's organisation id, external). Up to 100 characters.

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/integrations/xero/tenant" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"tenantId":"tenant_id"}'

Response

200: the answer's fields
FieldTypeDescription
idstring
statusenumDISCONNECTED with pendingTenants = waiting for the organisation choice. One of CONNECTED, DISCONNECTED, ERROR.
environmentstring or null
tenantIdstring or nullThe Xero organisation (tenant) id.
tenantNamestring or null
connectedAtstring or null
disconnectedAtstring or null
lastSyncAtstring or null
lastErrorstring or null
mappingobject
mapping.salesAccountCodestring or null
mapping.salesAccountNamestring or null
mapping.taxTypestring or null
mapping.taxTypeNamestring or null
mapping.noTaxTypestring or null
mapping.noTaxTypeNamestring or null
mapping.taxRatesarray of object or null
mapping.taxRates[].ratenumber
mapping.taxRates[].taxTypestring
mapping.taxRates[].taxTypeNamestring or null
mapping.paymentAccountIdstring or null
mapping.paymentAccountNamestring or null
mapping.itemCodestring or null
mapping.itemNamestring or null
mapping.trackingCategoryIdstring or null
mapping.trackingCategoryNamestring or null
mapping.trackingOptionIdstring or null
mapping.trackingOptionNamestring or null

Disconnect Xero

POST /organizations/{organizationId}/integrations/xero/disconnect

Revokes access: removes the connection at Xero and forgets the tokens; nothing more is pushed and waiting syncs are skipped. The ids of synced records are kept, so reconnecting the same Xero organisation updates them rather than creating duplicates. Also cancels a connection waiting for the organisation choice.

Permissionintegrations.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 toolintegrations_xeroDisconnect (toolset settings)
ApprovalOver MCP, this tool always waits for your approval in SKUFlow. See Approvals.

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/integrations/xero/disconnect" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
idstring
statusenumDISCONNECTED with pendingTenants = waiting for the organisation choice. One of CONNECTED, DISCONNECTED, ERROR.
environmentstring or null
tenantIdstring or nullThe Xero organisation (tenant) id.
tenantNamestring or null
connectedAtstring or null
disconnectedAtstring or null
lastSyncAtstring or null
lastErrorstring or null
mappingobject
mapping.salesAccountCodestring or null
mapping.salesAccountNamestring or null
mapping.taxTypestring or null
mapping.taxTypeNamestring or null
mapping.noTaxTypestring or null
mapping.noTaxTypeNamestring or null
mapping.taxRatesarray of object or null
mapping.taxRates[].ratenumber
mapping.taxRates[].taxTypestring
mapping.taxRates[].taxTypeNamestring or null
mapping.paymentAccountIdstring or null
mapping.paymentAccountNamestring or null
mapping.itemCodestring or null
mapping.itemNamestring or null
mapping.trackingCategoryIdstring or null
mapping.trackingCategoryNamestring or null
mapping.trackingOptionIdstring or null
mapping.trackingOptionNamestring or null

Xero mappings

GET /organizations/{organizationId}/integrations/xero/settings

The current mappings and the choices from the connected Xero organisation: revenue accounts (by code), bank accounts for payments, tax rates (TaxType with its rate), items and tracking categories with their options; ratesInUse lists the tax rates on this organization's invoices, for per-rate tax mapping. Invoices need the sales account (and a tax rate when taxed), payments and refunds the bank account. 409 when not connected. Read-only.

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

Example

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

Response

200: the answer's fields
FieldTypeDescription
mappingobject
mapping.salesAccountCodestring or null
mapping.salesAccountNamestring or null
mapping.taxTypestring or null
mapping.taxTypeNamestring or null
mapping.noTaxTypestring or null
mapping.noTaxTypeNamestring or null
mapping.taxRatesarray of object or null
mapping.taxRates[].ratenumber
mapping.taxRates[].taxTypestring
mapping.taxRates[].taxTypeNamestring or null
mapping.paymentAccountIdstring or null
mapping.paymentAccountNamestring or null
mapping.itemCodestring or null
mapping.itemNamestring or null
mapping.trackingCategoryIdstring or null
mapping.trackingCategoryNamestring or null
mapping.trackingOptionIdstring or null
mapping.trackingOptionNamestring or null
optionsobject
options.salesAccountsarray of object
options.salesAccounts[].idstring
options.salesAccounts[].namestring
options.paymentAccountsarray of object
options.paymentAccounts[].idstring
options.paymentAccounts[].namestring
options.taxRatesarray of object
options.taxRates[].idstring
options.taxRates[].namestring
options.taxRates[].ratenumber
options.itemsarray of object
options.items[].idstring
options.items[].namestring
options.trackingCategoriesarray of object
options.trackingCategories[].idstring
options.trackingCategories[].namestring
options.trackingCategories[].optionsarray of object
ratesInUsearray of numberTax rates (percent) on this organization's invoices.

Set the Xero mappings

PATCH /organizations/{organizationId}/integrations/xero/settings

Choose the revenue account invoice lines are booked to (salesAccountCode, required), the Xero tax rate for taxed invoices (taxType, required when invoices carry tax) and for untaxed ones (noTaxType, default NONE), optional per-rate overrides (taxRates: SKUFlow rate → TaxType; replaces the list), the bank account payments go into and refunds come out of (paymentAccountId, required for payments and refunds), and optionally an item code and one tracking option for every line (category and option together). Values from GET /integrations/xero/settings; null clears.

Permissionintegrations.manage (Owner, Admin)
Riskwrite, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolintegrations_xeroUpdateSettings (toolset settings)
PlanQuickBooks Online or Xero sync: the Connect plan and up.

Request body

FieldTypeRequiredDescription
salesAccountCodestring or nullNoA Xero account Code, e.g. 200. Up to 50 characters.
taxTypestring or nullNoA Xero TaxType, e.g. OUTPUT. Up to 100 characters.
noTaxTypestring or nullNoA Xero TaxType, e.g. NONE. Up to 100 characters.
taxRatesarray of object or nullNoUp to 50 items.
taxRates[].ratenumberYesA SKUFlow tax rate in percent. 0–100.
taxRates[].taxTypestringYesA Xero TaxType. Up to 100 characters.
paymentAccountIdstring or nullNoA Xero bank AccountID (external). Up to 100 characters.
itemCodestring or nullNoA Xero item Code (external). Up to 100 characters.
trackingCategoryIdstring or nullNoA Xero TrackingCategoryID (external). Up to 100 characters.
trackingOptionIdstring or nullNoA TrackingOptionID of that category (external). Up to 100 characters.

Example

curl -X PATCH "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/integrations/xero/settings" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"salesAccountCode":"string","taxType":"string","noTaxType":"string"}'

Response

200: the answer's fields
FieldTypeDescription
salesAccountCodestring or null
salesAccountNamestring or null
taxTypestring or null
taxTypeNamestring or null
noTaxTypestring or null
noTaxTypeNamestring or null
taxRatesarray of object or null
taxRates[].ratenumber
taxRates[].taxTypestring
taxRates[].taxTypeNamestring or null
paymentAccountIdstring or null
paymentAccountNamestring or null
itemCodestring or null
itemNamestring or null
trackingCategoryIdstring or null
trackingCategoryNamestring or null
trackingOptionIdstring or null
trackingOptionNamestring or null

Xero sync log

GET /organizations/{organizationId}/integrations/xero/sync-log

Every push to Xero, newest first: the record (customer → Contact, invoice → ACCREC Invoice, payment → Payment, refund → CreditNote and its refund payment), what triggered it (an event or a manual push), status (PENDING, SUCCEEDED, FAILED = will retry, including a rate-limit pause, DEAD, SKIPPED with the reason), attempts, the Xero id and the error. Filter by status or record. Read-only.

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

Parameters

NameInTypeRequiredDescription
statusqueryenumNoOne of PENDING, SUCCEEDED, FAILED, DEAD, SKIPPED.
entityTypequeryenumNoOne of CUSTOMER, INVOICE, PAYMENT, REFUND.
entityIdquerystringNo
limitqueryintegerNoPage size, 1–200. Default 50.
offsetqueryintegerNoRows to skip; the answer's total counts every match. Default 0.

Example

curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/integrations/xero/sync-log" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
itemsarray of object
items[].idstring
items[].triggerenumOne of EVENT, MANUAL.
items[].eventIdstring or null
items[].eventTypestring or null
items[].entityTypeenumOne of CUSTOMER, INVOICE, PAYMENT, REFUND.
items[].entityIdstring
items[].statusenumOne of PENDING, SUCCEEDED, FAILED, DEAD, SKIPPED.
items[].attemptCountinteger
items[].nextAttemptAtstring or null
items[].completedAtstring or null
items[].remoteIdstring or nullThe record's id in QuickBooks.
items[].errorstring or null
items[].createdAtstring
items[].updatedAtstring
items[].labelstring or null
totalinteger

Push a record to Xero now

POST /organizations/{organizationId}/integrations/xero/resync

Pushes one customer, invoice, payment or refund to the connected Xero organisation now (creating it, or updating the copy already there: never a duplicate; a first contact push links an existing Xero contact of the same name), with what it depends on (an invoice's contact first). Answers the sync task. Drafts and cancelled invoices are skipped; an invoice already paid in Xero is not changed (Xero locks it).

Permissionintegrations.manage (Owner, Admin)
Riskwrite, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolintegrations_xeroResync (toolset settings)
PlanQuickBooks Online or Xero sync: the Connect plan and up.

Request body

FieldTypeRequiredDescription
entityTypeenumYesOne of CUSTOMER, INVOICE, PAYMENT, REFUND.
entityIdstringYes

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/integrations/xero/resync" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"entityType":"CUSTOMER","entityId":"entity_id"}'

Response

200: the answer's fields
FieldTypeDescription
idstring
triggerenumOne of EVENT, MANUAL.
eventIdstring or null
eventTypestring or null
entityTypeenumOne of CUSTOMER, INVOICE, PAYMENT, REFUND.
entityIdstring
statusenumOne of PENDING, SUCCEEDED, FAILED, DEAD, SKIPPED.
attemptCountinteger
nextAttemptAtstring or null
completedAtstring or null
remoteIdstring or nullThe record's id in QuickBooks.
errorstring or null
createdAtstring
updatedAtstring

Run the Xero sync now

POST /organizations/{organizationId}/integrations/xero/sync

Processes this organization's waiting pushes now instead of on the next scheduler run. Pushes pause when Xero's rate limit (60 calls a minute, 5,000 a day) is reached and resume after the pause Xero asks for. Answers how many were attempted, succeeded, failed, died, were skipped or deferred.

Permissionintegrations.manage (Owner, Admin)
Riskwrite, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolintegrations_xeroSyncNow (toolset settings)
PlanQuickBooks Online or Xero sync: the Connect plan and up.

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/integrations/xero/sync" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
attemptedinteger
succeededinteger
failedinteger
deadinteger
skippedinteger
deferredintegerWaiting for a rate-limit pause to end (Xero); no attempt used.

A record's Xero status

GET /organizations/{organizationId}/integrations/xero/records/{entityType}/{entityId}

Whether a customer, invoice, payment or refund is in Xero: SYNCED (with its Xero id and when), PENDING, ERROR (with the reason), SKIPPED (why), NOT_SYNCED, or NOT_CONNECTED when the organization has no Xero. For the badge on invoices and customers. Read-only.

Permissioninvoices.read (Owner, Admin, Staff, Member)
Riskread, OAuth scope skuflow.read. Read: reads only.
MCP toolintegrations_xeroSyncStatus (toolset settings)

Parameters

NameInTypeRequiredDescription
entityTypepathenumYesOne of CUSTOMER, INVOICE, PAYMENT, REFUND.
entityIdpathstringYes

Example

curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/integrations/xero/records/{entityType}/{entityId}" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
stateenumOne of SYNCED, PENDING, ERROR, SKIPPED, NOT_SYNCED, NOT_CONNECTED.
remoteIdstring or null
syncedAtstring or null
errorstring or null
taskIdstring or null

On this page