DevelopersAPI reference

Requests API

REST endpoints for requests in SKUFlow: 9 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 requestsGET /organizations/{organizationId}/requestsread
Create a requestPOST /organizations/{organizationId}/requestswrite
Get a request with its customer and quotesGET /organizations/{organizationId}/requests/{requestId}read
Update a requestPATCH /organizations/{organizationId}/requests/{requestId}write
Delete a requestDELETE /organizations/{organizationId}/requests/{requestId}sensitive
Make the request's contact a customerPOST /organizations/{organizationId}/requests/{requestId}/customerwrite
Convert a request to a draft quotePOST /organizations/{organizationId}/requests/{requestId}/quotewrite
Online request form and portal settingsGET /organizations/{organizationId}/booking-settingsread
Turn the online request form or customer sign-in on or offPATCH /organizations/{organizationId}/booking-settingssensitive

List requests

GET /organizations/{organizationId}/requests

Requests (REQ-n, leads) newest first: from the online request form, the website, the customer portal or entered by staff. Filter by text, status, source or customer; paged with a total. Read-only.

Permissionrequests.read (Owner, Admin, Staff, Member)
Riskread, OAuth scope skuflow.read. Read: reads only.
MCP toolrequests_list (toolset sales, in the default set)

Parameters

NameInTypeRequiredDescription
queryquerystringNoFree-text search over the list's names, numbers and contact details. Up to 200 characters.
statusqueryenumNoOne of NEW, QUOTED, CONVERTED, ARCHIVED.
sourcequeryenumNoManual: entered by staff; ONLINE_BOOKING: the public request form (/book/{slug}), the website or a widget; PORTAL: sent from the customer portal. One of MANUAL, ONLINE_BOOKING, PORTAL, DESIGN_STUDIO.
customerIdquerystringNo
businessUnitIdquerystringNoOnly this business unit (GET /business-units), or "none" for records without one. Up to 100 characters.
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/requests" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
itemsarray of object
items[].idstringRequest id.
items[].organizationIdstring
items[].identifierstringREQ-n, unique per organization.
items[].customerIdstring or nullNull while the request is from a new contact.
items[].contactNamestring or null
items[].contactCompanystring or null
items[].contactPhonestring or null
items[].contactEmailstring or null
items[].propertyIdstring or null
items[].addressstring or null
items[].descriptionstringWhat the customer asked for.
items[].preferredDatestring or nullWhen they need it (in-hands date), YYYY-MM-DD.
items[].alternateDatestring or nullYYYY-MM-DD
items[].sourceenumWhere it came from: MANUAL (staff), ONLINE_BOOKING (the online request form, website or a widget) or PORTAL (the customer portal). One of MANUAL, ONLINE_BOOKING, PORTAL, DESIGN_STUDIO.
items[].statusenumNEW → QUOTED → CONVERTED (its quote was invoiced), or ARCHIVED. One of NEW, QUOTED, CONVERTED, ARCHIVED.
items[].internalNotesstring or null
items[].convertedAtstring (date-time) or null
items[].archivedAtstring (date-time) or null
items[].businessUnitIdstring or null
items[].adCampaignIdstring or nullThe ad campaign that brought it; null when not from an ad.
items[].createdAtstring (date-time)
items[].updatedAtstring (date-time)
items[].customerobject or null
items[].customer.idstring
items[].customer.namestring
items[].propertyobject or null
items[].property.idstringProperty id.
items[].property.namestring or null
items[].property.addressstring or null
items[].property.citystring or null
items[].businessUnitobject or nullThe business unit.
items[].businessUnit.idstring
items[].businessUnit.namestring
totalintegerHow many match the filters, across all pages.

Create a request

POST /organizations/{organizationId}/requests

Records a NEW request (REQ-n). Name an existing customerId (search GET /customers first), or give contactName (and phone/email) for a new contact; no customer is created until POST /requests/{requestId}/customer. Nothing is sent to anyone.

Permissionrequests.write (Owner, Admin, Staff)
Riskwrite, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolrequests_create (toolset sales, in the default set)

Request body

FieldTypeRequiredDescription
customerIdstring or nullNo
contactNamestring or nullNoUp to 200 characters.
contactCompanystring or nullNoUp to 200 characters.
contactPhonestring or nullNoUp to 50 characters.
contactEmailempty string or string (email) or nullNo
propertyIdstring or nullNo
addressstring or nullNoUp to 500 characters.
descriptionstringYes
preferredDateempty string or string or nullNoWhen the customer would like it (an in-hands date).
alternateDateempty string or string or nullNo
sourceenumNoManual: entered by staff; ONLINE_BOOKING: the public request form (/book/{slug}), the website or a widget; PORTAL: sent from the customer portal. One of MANUAL, ONLINE_BOOKING, PORTAL, DESIGN_STUDIO.
internalNotesstring or nullNo
businessUnitIdstring or nullNoBusiness unit (GET /business-units); null = none. Omitted on create: the business's default unit, if any. Up to 100 characters.

Example

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

Response

201: the answer's fields
FieldTypeDescription
idstringRequest id.
organizationIdstring
identifierstringREQ-n, unique per organization.
customerIdstring or nullNull while the request is from a new contact.
contactNamestring or null
contactCompanystring or null
contactPhonestring or null
contactEmailstring or null
propertyIdstring or null
addressstring or null
descriptionstringWhat the customer asked for.
preferredDatestring or nullWhen they need it (in-hands date), YYYY-MM-DD.
alternateDatestring or nullYYYY-MM-DD
sourceenumWhere it came from: MANUAL (staff), ONLINE_BOOKING (the online request form, website or a widget) or PORTAL (the customer portal). One of MANUAL, ONLINE_BOOKING, PORTAL, DESIGN_STUDIO.
statusenumNEW → QUOTED → CONVERTED (its quote was invoiced), or ARCHIVED. One of NEW, QUOTED, CONVERTED, ARCHIVED.
internalNotesstring or null
convertedAtstring (date-time) or null
archivedAtstring (date-time) or null
businessUnitIdstring or null
adCampaignIdstring or nullThe ad campaign that brought it; null when not from an ad.
createdAtstring (date-time)
updatedAtstring (date-time)
customerobject or null
customer.idstring
customer.namestring
propertyobject or null
property.idstringProperty id.
property.namestring or null
property.addressstring or null
property.citystring or null
businessUnitobject or nullThe business unit.
businessUnit.idstring
businessUnit.namestring

Get a request with its customer and quotes

GET /organizations/{organizationId}/requests/{requestId}

One request with its customer, address and quotes. matchingCustomers lists existing customers with the contact's email or phone, when no customer is linked: link one with PATCH (customerId) rather than creating a duplicate. Read-only.

Permissionrequests.read (Owner, Admin, Staff, Member)
Riskread, OAuth scope skuflow.read. Read: reads only.
MCP toolrequests_get (toolset sales, in the default set)

Parameters

NameInTypeRequiredDescription
requestIdpathstringYes

Example

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

Response

200: the answer's fields
FieldTypeDescription
idstringRequest id.
organizationIdstring
identifierstringREQ-n, unique per organization.
customerIdstring or nullNull while the request is from a new contact.
contactNamestring or null
contactCompanystring or null
contactPhonestring or null
contactEmailstring or null
propertyIdstring or null
addressstring or null
descriptionstringWhat the customer asked for.
preferredDatestring or nullWhen they need it (in-hands date), YYYY-MM-DD.
alternateDatestring or nullYYYY-MM-DD
sourceenumWhere it came from: MANUAL (staff), ONLINE_BOOKING (the online request form, website or a widget) or PORTAL (the customer portal). One of MANUAL, ONLINE_BOOKING, PORTAL, DESIGN_STUDIO.
statusenumNEW → QUOTED → CONVERTED (its quote was invoiced), or ARCHIVED. One of NEW, QUOTED, CONVERTED, ARCHIVED.
internalNotesstring or null
convertedAtstring (date-time) or null
archivedAtstring (date-time) or null
businessUnitIdstring or null
adCampaignIdstring or nullThe ad campaign that brought it; null when not from an ad.
createdAtstring (date-time)
updatedAtstring (date-time)
customerobject or null
customer.idstring
customer.namestring
customer.emailstring or null
customer.phonestring or null
customer.statusenumLEAD until the first sale, then ACTIVE; ARCHIVED customers leave the lists. One of LEAD, ACTIVE, INACTIVE, ARCHIVED.
propertyobject or null
property.idstringProperty id.
property.namestring or null
property.addressstring or null
property.citystring or null
property.statestring or null
property.zipstring or null
businessUnitobject or nullThe business unit.
businessUnit.idstring
businessUnit.namestring
quotesarray of object
quotes[].idstring
quotes[].identifierstringQ-n
quotes[].statusenumDRAFT → SENT (customer can answer at /q/{publicToken}) → APPROVED / CHANGES_REQUESTED / DECLINED; APPROVED → CONVERTED (invoice made). SENT past validUntil becomes EXPIRED. One of DRAFT, SENT, APPROVED, CHANGES_REQUESTED, DECLINED, CONVERTED, EXPIRED, ARCHIVED.
quotes[].titlestring
matchingCustomersarray of objectExisting customers with the contact's email or phone (up to 3) while the request has no customer.
matchingCustomers[].idstring
matchingCustomers[].namestring
matchingCustomers[].emailstring or null
matchingCustomers[].phonestring or null
designsarray of objectThe design sent with it from the online designer; converting the request quotes it.
designs[].idstringThe design (GET /designs/{designId}).
designs[].namestring
designs[].productIdstring
designs[].productNamestring
designs[].colorNamesarray of string
designs[].submittedAtstring (date-time) or null
designs[].mockupsarray of object
designs[].mockups[].viewstring
designs[].mockups[].urlstring or null

Update a request

PATCH /organizations/{organizationId}/requests/{requestId}

Changes the fields sent. status: ARCHIVED archives it; NEW reopens an archived request. To quote it use POST /requests/{requestId}/quote.

Permissionrequests.write (Owner, Admin, Staff)
Riskwrite, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolrequests_update (toolset sales)

Parameters

NameInTypeRequiredDescription
requestIdpathstringYes

Request body

FieldTypeRequiredDescription
customerIdstring or nullNo
contactNamestring or nullNoUp to 200 characters.
contactCompanystring or nullNoUp to 200 characters.
contactPhonestring or nullNoUp to 50 characters.
contactEmailempty string or string (email) or nullNo
propertyIdstring or nullNo
addressstring or nullNoUp to 500 characters.
descriptionstringNo
preferredDateempty string or string or nullNoWhen the customer would like it (an in-hands date).
alternateDateempty string or string or nullNo
sourceenumNoManual: entered by staff; ONLINE_BOOKING: the public request form (/book/{slug}), the website or a widget; PORTAL: sent from the customer portal. One of MANUAL, ONLINE_BOOKING, PORTAL, DESIGN_STUDIO.
internalNotesstring or nullNo
businessUnitIdstring or nullNoBusiness unit (GET /business-units); null = none. Omitted on create: the business's default unit, if any. Up to 100 characters.
statusenumNoOne of NEW, QUOTED, CONVERTED, ARCHIVED.

Example

curl -X PATCH "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/requests/{requestId}" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"customerId":"customer_id","contactName":"string","contactCompany":"string"}'

Response

200: the answer's fields
FieldTypeDescription
idstringRequest id.
organizationIdstring
identifierstringREQ-n, unique per organization.
customerIdstring or nullNull while the request is from a new contact.
contactNamestring or null
contactCompanystring or null
contactPhonestring or null
contactEmailstring or null
propertyIdstring or null
addressstring or null
descriptionstringWhat the customer asked for.
preferredDatestring or nullWhen they need it (in-hands date), YYYY-MM-DD.
alternateDatestring or nullYYYY-MM-DD
sourceenumWhere it came from: MANUAL (staff), ONLINE_BOOKING (the online request form, website or a widget) or PORTAL (the customer portal). One of MANUAL, ONLINE_BOOKING, PORTAL, DESIGN_STUDIO.
statusenumNEW → QUOTED → CONVERTED (its quote was invoiced), or ARCHIVED. One of NEW, QUOTED, CONVERTED, ARCHIVED.
internalNotesstring or null
convertedAtstring (date-time) or null
archivedAtstring (date-time) or null
businessUnitIdstring or null
adCampaignIdstring or nullThe ad campaign that brought it; null when not from an ad.
createdAtstring (date-time)
updatedAtstring (date-time)
customerobject or null
customer.idstring
customer.namestring
propertyobject or null
property.idstringProperty id.
property.namestring or null
property.addressstring or null
property.citystring or null
businessUnitobject or nullThe business unit.
businessUnit.idstring
businessUnit.namestring

Delete a request

DELETE /organizations/{organizationId}/requests/{requestId}

Destructive: deletes the request. Quotes made from it stay. Prefer archiving (PATCH status: ARCHIVED).

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

Parameters

NameInTypeRequiredDescription
requestIdpathstringYes

Example

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

Response

200: the answer's fields
FieldTypeDescription
oktrue

Make the request's contact a customer

POST /organizations/{organizationId}/requests/{requestId}/customer

Creates a LEAD customer (and an address record from the address) from the request's contact when the request has none, and links it; returns the request. Check matchingCustomers on GET /requests/{requestId} first to avoid duplicates.

Permissionrequests.write (Owner, Admin, Staff)
Riskwrite, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolrequests_ensureCustomer (toolset sales)

Parameters

NameInTypeRequiredDescription
requestIdpathstringYes

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/requests/{requestId}/customer" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
idstringRequest id.
organizationIdstring
identifierstringREQ-n, unique per organization.
customerIdstring or nullNull while the request is from a new contact.
contactNamestring or null
contactCompanystring or null
contactPhonestring or null
contactEmailstring or null
propertyIdstring or null
addressstring or null
descriptionstringWhat the customer asked for.
preferredDatestring or nullWhen they need it (in-hands date), YYYY-MM-DD.
alternateDatestring or nullYYYY-MM-DD
sourceenumWhere it came from: MANUAL (staff), ONLINE_BOOKING (the online request form, website or a widget) or PORTAL (the customer portal). One of MANUAL, ONLINE_BOOKING, PORTAL, DESIGN_STUDIO.
statusenumNEW → QUOTED → CONVERTED (its quote was invoiced), or ARCHIVED. One of NEW, QUOTED, CONVERTED, ARCHIVED.
internalNotesstring or null
convertedAtstring (date-time) or null
archivedAtstring (date-time) or null
businessUnitIdstring or null
adCampaignIdstring or nullThe ad campaign that brought it; null when not from an ad.
createdAtstring (date-time)
updatedAtstring (date-time)
customerobject or null
customer.idstring
customer.namestring
customer.emailstring or null
customer.phonestring or null
customer.statusenumLEAD until the first sale, then ACTIVE; ARCHIVED customers leave the lists. One of LEAD, ACTIVE, INACTIVE, ARCHIVED.
propertyobject or null
property.idstringProperty id.
property.namestring or null
property.addressstring or null
property.citystring or null
property.statestring or null
property.zipstring or null
businessUnitobject or nullThe business unit.
businessUnit.idstring
businessUnit.namestring
quotesarray of object
quotes[].idstring
quotes[].identifierstringQ-n
quotes[].statusenumDRAFT → SENT (customer can answer at /q/{publicToken}) → APPROVED / CHANGES_REQUESTED / DECLINED; APPROVED → CONVERTED (invoice made). SENT past validUntil becomes EXPIRED. One of DRAFT, SENT, APPROVED, CHANGES_REQUESTED, DECLINED, CONVERTED, EXPIRED, ARCHIVED.
quotes[].titlestring
matchingCustomersarray of objectExisting customers with the contact's email or phone (up to 3) while the request has no customer.
matchingCustomers[].idstring
matchingCustomers[].namestring
matchingCustomers[].emailstring or null
matchingCustomers[].phonestring or null
designsarray of objectThe design sent with it from the online designer; converting the request quotes it.
designs[].idstringThe design (GET /designs/{designId}).
designs[].namestring
designs[].productIdstring
designs[].productNamestring
designs[].colorNamesarray of string
designs[].submittedAtstring (date-time) or null
designs[].mockupsarray of object
designs[].mockups[].viewstring
designs[].mockups[].urlstring or null

Convert a request to a draft quote

POST /organizations/{organizationId}/requests/{requestId}/quote

Creates a DRAFT quote for the request (and the customer, if the request is from a new contact); the request becomes QUOTED. Fill the quote with PATCH /quotes/{quoteId}; nothing is sent.

Permissionrequests.write (Owner, Admin, Staff)
Riskwrite, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolrequests_convertToQuote (toolset sales, in the default set)

Parameters

NameInTypeRequiredDescription
requestIdpathstringYes

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/requests/{requestId}/quote" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

201: the answer's fields
FieldTypeDescription
idstringQuote id.
organizationIdstring
identifierstringQ-n, unique per organization.
customerIdstring
propertyIdstring or null
requestIdstring or nullThe request it was made from.
titlestring
messagestring or nullShown to the customer.
validUntilstring or nullYYYY-MM-DD; a sent quote expires after it.
statusenumDRAFT → SENT (customer can answer at /q/{publicToken}) → APPROVED / CHANGES_REQUESTED / DECLINED; APPROVED → CONVERTED (invoice made). SENT past validUntil becomes EXPIRED. One of DRAFT, SENT, APPROVED, CHANGES_REQUESTED, DECLINED, CONVERTED, EXPIRED, ARCHIVED.
taxRatenumberTax rate in percent.
taxClothingRatenumber or nullPercent on CLOTHING lines; null = taxRate (some states tax apparel less).
taxShippingRatenumber or nullPercent on SHIPPING lines; null = taxRate (0 where shipping is not taxed).
taxDetailsanyHow the rate was decided: source EXEMPT (tax-exempt customer), MANUAL (typed), ADDRESS (the address's own rate), RULES (the business's tax rules for the ship-to address; rules lists them), UNIT, DEFAULT or NONE. Null on older records.
depositPercentnumber or nullDeposit asked, as a percent of the total.
depositCentsinteger or nullDeposit asked, as a fixed amount in cents.
internalNotesstring or null
publicTokenstringThe customer link token: the quote page is /q/{publicToken}.
sentAtstring (date-time) or null
approvedAtstring (date-time) or null
approvedOptionIdstring or null
approvedLineIdsarray of stringThe optional lines the customer kept.
approvedTotalCentsinteger or nullApproved total in cents, with tax.
approvedDepositCentsinteger or nullApproved deposit in cents.
signatureNamestring or null
approvedByStaffbooleanStaff recorded the approval for the customer.
changesRequestedAtstring (date-time) or null
changesRequestedNotestring or null
declinedAtstring (date-time) or null
declineReasonstring or null
invoiceIdstring or nullThe invoice it was converted to.
convertedAtstring (date-time) or null
soldByUserIdstring or nullThe team member who sold it.
financingDisabledboolean
businessUnitIdstring or null
customFieldsanyCustom field values by key (definitions: GET /custom-fields?entity=QUOTE).
createdAtstring (date-time)
updatedAtstring (date-time)

Online request form and portal settings

GET /organizations/{organizationId}/booking-settings

Whether the public request form (/book/{slug}) takes requests and whether customers can sign in to their portal (/c/{slug}). Read-only.

Permissionsettings.read (Owner, Admin, Staff)
Riskread, OAuth scope skuflow.read. Read: reads only.
MCP toolbookingSettings_get (toolset settings)

Example

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

Response

200: the answer's fields
FieldTypeDescription
slugstringThe request form is at /book/{slug}.
bookingEnabledbooleanWhether the online request form takes requests.
customerSignInEnabledbooleanWhether customers can sign in to their portal at /c/{slug} with a code sent to their email or phone (default on).

Turn the online request form or customer sign-in on or off

PATCH /organizations/{organizationId}/booking-settings

customerSignInEnabled off REVOKES ACCESS: every customer is signed out of their portal at once and /c/{slug} stops offering sign-in (portal links keep working). bookingEnabled off: the public request form and /api/public/book/{slug} answer 404 and take no requests; on: anyone with the link can send a request. Send either or both. Needs settings.manage (owners and admins).

Permissionsettings.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 toolbookingSettings_update (toolset settings)
ApprovalOver MCP, this tool asks for your OK first (in the AI app when it supports it, otherwise in SKUFlow). See Approvals.

Request body

FieldTypeRequiredDescription
bookingEnabledbooleanNo
customerSignInEnabledbooleanNoLet customers sign in to their portal with a code (on by default). Off signs every customer out at once.

Example

curl -X PATCH "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/booking-settings" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"bookingEnabled":true,"customerSignInEnabled":true}'

Response

200: the answer's fields
FieldTypeDescription
slugstringThe request form is at /book/{slug}.
bookingEnabledbooleanWhether the online request form takes requests.
customerSignInEnabledbooleanWhether customers can sign in to their portal at /c/{slug} with a code sent to their email or phone (default on).

On this page