API Reference
Auth & Users
POST /api/auth/change-password Session

Allows a logged-in user to change their password. Requires the current password and a new password, which must be at least 6 characters long. Sends a security notification email upon successful change.

FieldDetails
current_password (string
required)
new_password (string
required)

Response

Response
message (on success); error (on missing fields, short password, incorrect current password, or general failure)
POST /api/auth/forgot-password Public

No description provided.

Response

Response
varies
POST /api/auth/forgot-username Public

No description provided.

Response

Response
varies
POST /api/auth/phone/lookup-username Public

Returns a masked username for a customer using a verified phone session token. The session token is consumed after use.

FieldDetails
phone_session_token (string
required)

Response

Response
error, username
POST /api/auth/phone/reset-password Public

Resets the password for a customer using a verified phone session token. The new password must be at least 6 characters long.

FieldDetails
phone_session_token (string
required)
password (string
required)

Response

Response
message, error
POST /api/auth/reset-password Public

Resets the password for a customer user using a valid reset token. The new password must be at least 6 characters long.

FieldDetails
token (string
required)
password (string
required)

Response

Response
message, error
POST /api/customer/forgot-password Public

Allows customer users to request a password reset link. It sends an email with a reset token if the account exists.

FieldDetails
identifier (string
required)

Response

Response
message, email_sent, debug_token
POST /api/customer/forgot-username Public

Allows customer users to recover their username. It sends an email containing the username if the email is registered.

FieldDetails
email (string
required)

Response

Response
message, email_sent
GET /api/customers/<int:customer_id>/score Staff

GET /api/customers/{id}/score - single customer score.

FieldDetails
N/A for GET

Response

Response
varies (customer score dict)
GET /api/customers/scores Staff

GET /api/customers/scores

ParamDetails
tier (str
None)
min_p_alive (float
None)
max_p_alive (float
None)
search (str
'')
page (int
1)
per_page (int
50)
ordering (str
'-expected_orders_90d')
FieldDetails
N/A for GET

Response

Response
results (list of dicts), total, page, pages, tier_counts, last_computed
POST /api/login Public

Authenticates a user with a username and password. If successful and the email is verified, it establishes a user session. Otherwise, it returns an error for invalid credentials or unverified email.

FieldDetails
username (string
required)
password (string
required)

Response

Response
message, user (on success); error, email_verification_required (on unverified email); error (on invalid credentials or general failure)
GET /api/me Session

Retrieves the profile information of the currently logged-in user.

FieldDetails
N/A for GET

Response

Response
user (username, email, company_name, phone, etc.)
POST /api/payments/confirm Public

Called after Stripe payment succeeds on the frontend. Updates the order's payment_status and stores the payment_intent_id.

FieldDetails
order_number (string
required)
payment_intent_id (string
required)

Response

Response
success, message
POST /api/payments/create-intent Public

Create a Stripe PaymentIntent for a given order total. Called from the frontend checkout when customer selects credit card.

FieldDetails
amount (float
required)
order_number (string
optional)
customer_name (string
optional)
customer_email (string
optional)

Response

Response
success, client_secret, payment_intent_id
POST /api/payments/create-link Staff

Generates a Stripe Payment Link for an order. Can be called by staff, the voice agent, or the customer dashboard.

FieldDetails
order_number (string
required)
expires_in_hours (integer
optional)

Response

Response
success, payment_url, order_number, amount, expires_at, error, fallback_url
POST /api/payments/upload-check Staff

Accepts front and back check image uploads for an order. Requires staff authentication — check images are sensitive financial documents.

FieldDetails
order_number (string
required)
check_front (file
required)
check_image (file
optional)
check_back (file
optional)

Response

Response
success, message, front_filename, back_filename
GET /api/procurement/vendors Staff

List all vendors, active by default. Can include inactive vendors with a query parameter.

ParamDetails
all (string
default '0')

Response

Response
id, name, website, phone, email, contact_name, address, notes, active
POST /api/procurement/vendors Staff + Admin

Create a new vendor. Requires admin or manager staff role.

FieldDetails
name (string
required)
website (string
optional)
phone (string
optional)
email (string
optional)
contact_name (string
optional)
address (string
optional)
notes (string
optional)
active (boolean
optional)

Response

Response
id, name, website, phone, email, contact_name, address, notes, active
GET /api/procurement/vendors/<int:vendor_id> Staff

Retrieve details for a single vendor, including all associated products.

Response

Response
id, name, website, phone, email, contact_name, address, notes, active, products (list of product objects)
PUT /api/procurement/vendors/<int:vendor_id> Staff + Admin

Update an existing vendor's details. Requires admin or manager staff role.

FieldDetails
name (string
optional)
website (string
optional)
phone (string
optional)
email (string
optional)
contact_name (string
optional)
address (string
optional)
notes (string
optional)
active (boolean
optional)

Response

Response
id, name, website, phone, email, contact_name, address, notes, active
DELETE /api/procurement/vendors/<int:vendor_id> Staff + Admin

Delete a vendor and all its associated products. Requires admin staff role.

FieldDetails
N/A for GET

Response

Response
success
POST /api/register Public

Registers a new user, checking for existing accounts by username, email, or phone. It creates a new user, hashes the password, generates an email verification token, and sends a verification email. The user must verify their email before logging in.

FieldDetails
username (string
required)
email (string
optional)
company_name (string
optional)
phone (string
optional)
business_type (string
optional)
business_ein (string
optional)
resale_certificate (string
optional)
state_of_operation (string
optional)
password (string
required)

Response

Response
message, email_verification_required, user (on success); error, duplicate_field, hint (on duplicate); error (on general failure)
POST /api/save-me-money Public

Handles the "Save Me Money" form submission, collecting contact and restaurant details, and an optional invoice file. It then sends an email with the submission information.

FieldDetails
name (string
required)
restaurant_name (string
required)
address (string
required)
city (string
required)
state (string
required)
phone (string
required)
email (string
required)
rd_customer_number (string
optional)
invoice (file
optional)

Response

Response
success (boolean), message (string), error (string)
GET /api/users Session

Retrieves the record for the currently logged-in user. Note: This endpoint is intended for customers to see only their own record, not all users.

FieldDetails
N/A for GET

Response

Response
user (username, email, company_name, phone, etc.)
GET /api/users/<int:user_id> Session

Retrieves a specific user's profile by ID. Access is restricted to the currently logged-in user's own record.

FieldDetails
N/A for GET

Response

Response
user (username, email, company_name, phone, etc.)
PUT /api/users/<int:user_id> Session

Updates the profile information for a specific user. Only the logged-in user can update their own record, and only safe profile fields are allowed to be modified.

FieldDetails
email (string
optional)
company_name (string
optional)
phone (string
optional)
shipping_address (string
optional)
billing_address (string
optional)

Response

Response
user (updated username, email, company_name, phone, etc.)
DELETE /api/users/<int:user_id> Session

Deletes a specific user account. Only the logged-in user can delete their own account.

FieldDetails
N/A for GET

Response

Response
(empty response with 204 status code)
Orders
POST /api/orders Public

Place a new order for either logged-in users or guests, including delivery details and order items.

FieldDetails
items (list of dicts
required)
delivery_name (string
required)
delivery_address (string
required)
delivery_city (string
required)
delivery_state (string
required)
delivery_zip (string
required)
delivery_first_name (string
optional)
delivery_last_name (string
optional)
delivery_email (string
optional)
delivery_company (string
optional)
delivery_phone (string
optional)
special_notes (string
optional)
payment_method (string
optional
default 'net30')
billing_address (string
optional)

Response

Response
success, message, order (id, order_number, user_id, status, delivery_name, delivery_first_name, delivery_last_name, delivery_email, delivery_company, delivery_address, delivery_city, delivery_state, delivery_zip, delivery_phone, special_notes, subtotal, discount_amount, delivery_fee, total_amount, payment_method, payment_status, items (product_id, product_name, product_sku, product_brand, product_unit_size, quantity, unit_price, is_bulk_price, line_total))
GET /api/orders Session

Retrieve all orders associated with the currently logged-in customer.

FieldDetails
N/A for GET

Response

Response
list of orders (id, order_number, user_id, status, created_at, total_amount, delivery_name, item_count, tracking_number, carrier, items (product_id, product_name, product_sku, product_brand, product_unit_size, quantity, unit_price, is_bulk_price, line_total))
GET /api/orders/<string:order_number> Public

Retrieve a specific order by its order number. Allows guest tracking if no user is logged in, or if the order belongs to the logged-in user.

FieldDetails
N/A for GET

Response

Response
order (id, order_number, user_id, status, created_at, total_amount, delivery_name, item_count, tracking_number, carrier, items (product_id, product_name, product_sku, product_brand, product_unit_size, quantity, unit_price, is_bulk_price, line_total))
POST /api/orders/<string:order_number>/reorder Session

Return the items from a previous order for quick reordering by the customer.

FieldDetails
N/A for GET

Response

Response
success, items (product_id, product_name, product_sku, quantity, unit_price, bulk_price, bulk_quantity)
GET /api/orders/by-phone/<string:phone> Public

Look up orders by phone number for guest tracking. Returns a slimmed-down list of recent orders.

FieldDetails
N/A for GET

Response

Response
list of orders (order_number, status, created_at, total_amount, delivery_name, item_count, tracking_number, carrier)
POST /api/orders/create-account Public

Create a customer account at checkout, converting a guest to a registered user. Links an existing order if provided.

FieldDetails
email (string
required)
password (string
required)
delivery_name (string
required)
delivery_address (string
required)
delivery_city (string
required)
delivery_state (string
required)
delivery_zip (string
required)
delivery_phone (string
optional)
delivery_company (string
optional)
order_number (string
optional)

Response

Response
success, message, user (id, username, email, first_name, last_name, company_name, phone, shipping_address, email_verified)
Products & Inventory
POST /api/admin/products Session

Creates a new product entry.

FieldDetails
name (string
required)
description (string
optional)
category_id (int
required)
sku (string
required)
unit_price (float
required)
bulk_price (float
optional)
bulk_quantity (int
optional)
unit_size (string
optional)
brand (string
optional)
image_url (string
optional)

Response

Response
id, name, description, category_id, sku, unit_price, bulk_price, bulk_quantity, unit_size, brand, image_url
GET /api/procurement/products Staff

List all procurement products across all vendors. Can filter by category and include inactive products.

ParamDetails
all (string
default '0')
category (string
optional)

Response

Response
id, vendor_id, name, category, description, model_number, est_price_min, est_price_max, lead_time_days, notes, active
PUT /api/procurement/products/<int:product_id> Staff + Admin

Update an existing procurement product. Requires admin or manager staff role.

FieldDetails
name (string
optional)
category (string
optional)
description (string
optional)
model_number (string
optional)
est_price_min (number
optional)
est_price_max (number
optional)
lead_time_days (number
optional)
notes (string
optional)
active (boolean
optional)
vendor_id (integer
optional)

Response

Response
id, vendor_id, name, category, description, model_number, est_price_min, est_price_max, lead_time_days, notes, active
DELETE /api/procurement/products/<int:product_id> Staff + Admin

Delete a procurement product. Requires admin or manager staff role.

FieldDetails
N/A for GET

Response

Response
success
GET /api/procurement/vendors/<int:vendor_id>/products Staff

List all products for a specific vendor. Can include inactive products with a query parameter.

ParamDetails
all (string
default '0')

Response

Response
id, vendor_id, name, category, description, model_number, est_price_min, est_price_max, lead_time_days, notes, active
POST /api/procurement/vendors/<int:vendor_id>/products Staff + Admin

Add a new product to a specified vendor. Requires admin or manager staff role.

FieldDetails
name (string
required)
category (string
optional)
description (string
optional)
model_number (string
optional)
est_price_min (number
optional)
est_price_max (number
optional)
lead_time_days (number
optional)
notes (string
optional)
active (boolean
optional)

Response

Response
id, vendor_id, name, category, description, model_number, est_price_min, est_price_max, lead_time_days, notes, active
GET /api/products Public

Returns a paginated list of products, with optional filtering by category and search terms.

ParamDetails
category_id (int
optional)
search (string
optional)
page (int
1)
per_page (int
100)
category (string
optional)
FieldDetails
N/A for GET

Response

Response
products (list of id, name, sku, brand, unit_price, bulk_price, bulk_quantity, unit_size, in_stock), total, pages, current_page, per_page
GET /api/products/<int:product_id> Public

Returns details for a single product identified by its ID.

FieldDetails
N/A for GET

Response

Response
id, name, description, category_id, sku, unit_price, bulk_price, bulk_quantity, unit_size, brand, image_url, in_stock
GET /api/products/<int:product_id>/thumbnail Public

Serves a compressed and resized JPEG thumbnail for a product's primary image.

FieldDetails
N/A for GET

Response

Response
image/jpeg (binary data)
GET /api/products/sku/<string:sku> Public

Returns details for a single product identified by its SKU.

FieldDetails
N/A for GET

Response

Response
id, name, description, category_id, sku, unit_price, bulk_price, bulk_quantity, unit_size, brand, image_url, in_stock
GET /api/v1/products API Key

List all products with optional filtering.

ParamDetails
category_id (int
none)
search (str
'')
in_stock (bool
none)
page (int
1)
per_page (int
50)
FieldDetails
N/A for GET

Response

Response
total, page, per_page, pages, products
GET /api/v1/products/<identifier> API Key

Get a single product by ID (integer) or SKU (string).

FieldDetails
N/A for GET

Response

Response
product, error
PUT /api/v1/products/<identifier> API Key

Full or partial update of any product fields.

FieldDetails
name (str
optional)
description (str
optional)
category_id (int
optional)
sku (str
optional)
unit_price (float
optional)
bulk_price (float
optional)
bulk_quantity (int
optional)
unit_size (str
optional)
brand (str
optional)
in_stock (bool
optional)
image_url (str
optional)

Response

Response
success, product, error
POST /api/v1/products/<identifier>/image API Key

Upload a product image (multipart/form-data).

FieldDetails
image (file
required)

Response

Response
success, image_url, product, error
PATCH /api/v1/products/<identifier>/inventory API Key

Update inventory/stock status for a product.

FieldDetails
in_stock (bool
required)

Response

Response
success, product, error
PATCH /api/v1/products/<identifier>/price API Key

Update pricing for a product.

FieldDetails
unit_price (float
required)
bulk_price (float
optional)
bulk_quantity (int
optional)

Response

Response
success, product, error
POST /api/v1/products/bulk-update API Key

Bulk update multiple products in a single request.

FieldDetails
products (list
required) - id (int
required) OR sku (str
required)
unit_price (float
optional)
bulk_price (float
optional)
bulk_quantity (int
optional)
in_stock (bool
optional)
name (str
optional)
description (str
optional)
brand (str
optional)
unit_size (str
optional)
image_url (str
optional)

Response

Response
success, updated_count, skipped_count, error_count, updated, skipped, errors
Staff Portal
GET /api/staff/categories Staff

Retrieves a list of all product categories, ordered by name.

FieldDetails
N/A for GET

Response

Response
varies
POST /api/staff/categories Staff

Adds a new product category to the system.

FieldDetails
name (string
required)
description (string
optional)

Response

Response
success, category
GET /api/staff/checks/<string:order_number> Staff

Serve the check front image for staff review. Requires staff auth.

FieldDetails
N/A for GET

Response

Response
varies
POST /api/staff/checks/<string:order_number>/approve Staff

Staff approves a check payment and confirms the order. Requires staff auth (JWT or session).

FieldDetails
N/A for POST

Response

Response
success, message
GET /api/staff/checks/<string:order_number>/back Staff

Serve the check back image for staff review. Requires staff auth.

FieldDetails
N/A for GET

Response

Response
varies
POST /api/staff/checks/<string:order_number>/reject Staff

Staff rejects a check payment — resets order to pending so Pay options reappear.

FieldDetails
N/A for POST

Response

Response
success, message
GET /api/staff/customers Staff

Retrieve a paginated list of customers with optional search, sorting, and filtering.

ParamDetails
page (integer
optional
default 1)
per_page (integer
optional
default 50)
search (string
optional)
sort_by (string
optional
default 'created_at')
sort_dir (string
optional
default 'desc')
FieldDetails
N/A for GET

Response

Response
customers (list of customer objects), total, page, per_page, pages
GET /api/staff/customers/<int:user_id> Staff

Retrieve details for a single customer by ID.

FieldDetails
N/A for GET

Response

Response
id, username, first_name, last_name, email, company_name, phone, phone2, shipping_address, billing_address, preferred_language, do_not_call, created_at, is_active
PUT /api/staff/customers/<int:user_id> Staff

Update details for a single customer by ID. Allows partial updates.

FieldDetails
first_name (string
optional)
last_name (string
optional)
email (string
optional)
company_name (string
optional)
phone (string
optional)
phone2 (string
optional)
shipping_address (string
optional)
billing_address (string
optional)
preferred_language (string
optional)
do_not_call (boolean
optional)

Response

Response
success, id, username, first_name, last_name, email, company_name, phone, phone2, shipping_address, billing_address, preferred_language, do_not_call
DELETE /api/staff/customers/<int:user_id> Staff + Admin

Permanently delete a customer account. Associated orders are preserved but unlinked.

FieldDetails
N/A for GET

Response

Response
success, deleted_id
GET /api/staff/customers/<int:user_id>/orders Staff

Return all orders linked to a customer by user_id, sorted newest-first with full item details.

FieldDetails
N/A for GET

Response

Response
orders, total
POST /api/staff/customers/bulk-delete Staff

Delete multiple customers at once.

FieldDetails
ids (array of integers
required)

Response

Response
success, deleted
GET /api/staff/customers/csv-template Staff

Return a blank CSV template with the correct headers.

FieldDetails
N/A for GET

Response

Response
first_name, last_name, company_name, email, phone, orders, total_spent, joined, shipping_street, shipping_city, shipping_state, shipping_zip, billing_street, billing_city, billing_state, billing_zip, same_as_shipping
GET /api/staff/customers/duplicate-phones Staff

Find customers sharing the same primary phone number. Returns groups of customers with matching phones.

FieldDetails
N/A for GET

Response

Response
duplicate_groups, total_groups
GET /api/staff/customers/export-csv Staff

Download all customers as a CSV file.

FieldDetails
N/A for GET

Response

Response
first_name, last_name, company_name, email, phone, orders, total_spent, joined, shipping_street, shipping_city, shipping_state, shipping_zip, billing_street, billing_city, billing_state, billing_zip, same_as_shipping
POST /api/staff/customers/import-csv Staff

Bulk-import customers from a CSV file. Deduplication by email or phone. Creates new customers or skips existing ones.

FieldDetails
file (file
required) - CSV file containing customer data

Response

Response
success, total_rows, created, skipped, errors
POST /api/staff/customers/merge Staff

Full merge of two customer accounts. Transfers orders and allows choosing fields for the kept customer.

FieldDetails
keep_id (integer
required)
merge_id (integer
required)
chosen (object
optional) - fields to override (first_name
last_name
company_name
email)

Response

Response
success, kept_id, merged_id, orders_moved, combined_order_count, combined_total_spent, kept_customer
POST /api/staff/forgot-password Public

Allows staff users to request a password reset link. It sends an email with a reset token if the account exists.

FieldDetails
identifier (string
required)

Response

Response
message, email_sent, debug_token
POST /api/staff/forgot-username Public

Allows staff users to recover their username. It sends an email containing the username if the email is registered.

FieldDetails
email (string
required)

Response

Response
message, email_sent, debug_username
GET /api/staff/inventory Staff

Retrieve a paginated list of inventory items with optional search and filtering.

ParamDetails
page (integer
optional
default 1)
per_page (integer
optional
default 50)
search (string
optional)
category (string
optional)
in_stock (boolean
optional)
FieldDetails
N/A for GET

Response

Response
products (list of product objects), total, page, per_page, pages
PUT /api/staff/inventory/<int:product_id> Staff

Update details for a specific product in the inventory, including stock levels and pricing.

FieldDetails
in_stock (boolean
optional)
unit_price (float
optional)
bulk_price (float
optional)
stock_quantity (integer
optional)

Response

Response
success, product (id, name, sku, brand, unit_size, in_stock, unit_price, bulk_price, stock_quantity)
POST /api/staff/login Public

Authenticate staff users and issue a JWT token for cross-domain authentication.

FieldDetails
username (string
required)
password (string
required)

Response

Response
success, staff (id, username, email, first_name, last_name, role), token
POST /api/staff/logout Public

Log out the current staff user by clearing their session.

Response

Response
success
GET /api/staff/me Staff

Retrieve the profile information of the currently authenticated staff user.

FieldDetails
N/A for GET

Response

Response
staff (id, username, email, first_name, last_name, role)
GET /api/staff/orders Staff

Retrieve a list of all orders, with optional filtering by status, date range, and sales rep. Sales reps only see their own orders.

ParamDetails
status (string
optional)
from_date (string
optional)
to_date (string
optional)
rep_id (integer
optional)
page (integer
optional
default 1)
per_page (integer
optional
default 50)
search (string
optional)
FieldDetails
N/A for GET

Response

Response
orders (list of orders), total, page, pages
POST /api/staff/orders Staff

Manually create a new order from the staff portal. Allows for custom order details and customer upsertion.

FieldDetails
items (list of dicts
required)
delivery_name (string
required)
delivery_address (string
required)
delivery_city (string
required)
delivery_state (string
required)
delivery_zip (string
required)
discount_amount (float
optional
default 0.0)
delivery_fee (float
optional
default 0.0)
order_number (string
optional)
created_at (string
optional)
sales_rep_id (integer
optional)
status (string
optional
default 'pending')
delivery_first_name (string
optional)
delivery_last_name (string
optional)
delivery_email (string
optional)
delivery_company (string
optional)
delivery_phone (string
optional)
special_notes (string
optional)
payment_method (string
optional
default 'net30')
payment_status (string
optional
default 'paid')
staff_notes (string
optional
default 'Manually entered by staff')
assigned_to (string
optional)
upsert_customer (boolean
optional)

Response

Response
success, order (id, order_number, user_id, status, sales_rep_id, delivery_name, delivery_first_name, delivery_last_name, delivery_email, delivery_company, delivery_address, delivery_city, delivery_state, delivery_zip, delivery_phone, special_notes, subtotal, discount_amount, delivery_fee, total_amount, payment_method, payment_status, staff_notes, assigned_to, created_at, confirmed_at, shipped_at, delivered_at, items)
DELETE /api/staff/orders/<int:order_id> Staff

Delete an order. This action is restricted to admin and manager roles.

FieldDetails
N/A for DELETE

Response

Response
success
PUT /api/staff/orders/<int:order_id>/address Staff

Update the delivery address details for a specific order. Returns the updated order and a list of fields that were changed.

FieldDetails
delivery_name (string
optional)
delivery_first_name (string
optional)
delivery_last_name (string
optional)
delivery_company (string
optional)
delivery_address (string
optional)
delivery_city (string
optional)
delivery_state (string
optional)
delivery_zip (string
optional)
delivery_phone (string
optional)
delivery_email (string
optional)

Response

Response
success, order (id, delivery_name, delivery_first_name, delivery_last_name, delivery_company, delivery_address, delivery_city, delivery_state, delivery_zip, delivery_phone, delivery_email), updated_fields (list of strings)
POST /api/staff/orders/<int:order_id>/credit/apply Staff

Apply some or all of a user's store credit to reduce an order's balance. The order must be linked to a registered user.

FieldDetails
amount (float
required)

Response

Response
success, credit_applied, new_order_total, credit_balance, transaction
POST /api/staff/orders/<int:order_id>/mark-paid Staff

Manually mark an order as paid. Requires admin, manager, or staff role. Handles overpayments by crediting the customer's account.

FieldDetails
payment_method (string
optional
default 'cash')
note (string
optional)
amount_received (float
optional
default 0)

Response

Response
success, order (id, payment_status, payment_method, staff_notes), overpayment_credited
PUT /api/staff/orders/<int:order_id>/notes Staff

Update staff notes, assigned staff, and tracking number for an order. Automatically updates order status to 'shipped' if a tracking number is added.

FieldDetails
staff_notes (string
optional)
assigned_to (string
optional)
tracking_number (string
optional)

Response

Response
success, order (id, staff_notes, assigned_to, tracking_number, status, shipped_at)
PUT /api/staff/orders/<int:order_id>/status Staff

Update the status of a specific order. Handles stock deduction/restoration and Stripe refunds for cancellations.

FieldDetails
status (string
required)
staff_notes (string
optional)
assigned_to (string
optional)

Response

Response
success, order (id, order_number, status, payment_status, staff_notes, assigned_to, items), refund (refund_id, amount, status, error) (optional, for cancellations)
GET /api/staff/products Staff

Retrieves a paginated list of all products for admin, including inactive ones, with optional filtering by category and search terms.

ParamDetails
category_id (int
optional)
search (string
optional)
page (int
default 1)
per_page (int
default 50)
FieldDetails
N/A for GET

Response

Response
products, total, pages, current_page, per_page
POST /api/staff/products Staff

Adds a new product to the system. Only admins and managers can add products.

FieldDetails
name (string
required)
sku (string
required)
unit_price (float
required)
category_id (int
required)
description (string
optional)
bulk_price (float
optional)
bulk_quantity (int
optional)
unit_size (string
optional)
brand (string
optional)
in_stock (boolean
optional)
stock_quantity (int
optional)
image_url (string
optional)
cost_per_item (float
optional)
ship_weight_oz (float
optional)
ship_box_name (string
optional)
ship_box_length (float
optional)
ship_box_width (float
optional)
ship_box_height (float
optional)
is_customizable (boolean
optional)

Response

Response
success, product
PUT /api/staff/products/<int:product_id> Staff

Updates an existing product's details. Only admins and managers can update products.

FieldDetails
name (string
optional)
description (string
optional)
category_id (int
optional)
sku (string
optional)
unit_price (float
optional)
bulk_price (float
optional)
bulk_quantity (int
optional)
unit_size (string
optional)
brand (string
optional)
in_stock (boolean
optional)
stock_quantity (int
optional)
image_url (string
optional)
cost_per_item (float
optional)
ship_weight_oz (float
optional)
ship_box_name (string
optional)
ship_box_length (float
optional)
ship_box_width (float
optional)
ship_box_height (float
optional)
is_customizable (boolean
optional)

Response

Response
success, product
DELETE /api/staff/products/<int:product_id> Staff

Deletes a product from the system. Only admins and managers can delete products.

FieldDetails
N/A for GET

Response

Response
success, message
POST /api/staff/products/<int:product_id>/image Staff

Upload or replace the display image for a product. Stores the image as a base64 data URL in the database so it persists across container restarts and redeploys (no filesystem dependency).

FieldDetails
image (file
required)

Response

Response
success, image_url, product
DELETE /api/staff/products/<int:product_id>/image Staff

Remove the image from a product.

FieldDetails
N/A for GET

Response

Response
success, product
GET /api/staff/products/<int:product_id>/images Staff

Retrieves all gallery images for a specific product.

FieldDetails
N/A for GET

Response

Response
images
POST /api/staff/products/<int:product_id>/images Staff

Uploads an additional image to a product's gallery. Stores the image as a base64 data URL.

FieldDetails
image (file
required)

Response

Response
success, image, product
DELETE /api/staff/products/<int:product_id>/images/<int:image_id> Staff

Removes a specific image from a product's gallery.

FieldDetails
N/A for GET

Response

Response
success, product
POST /api/staff/products/<int:product_id>/images/<int:image_id>/set-primary Staff

Sets a gallery image as the primary display image for a product.

FieldDetails
N/A for GET

Response

Response
success, product
POST /api/staff/products/<int:product_id>/images/reorder Staff

Updates the sort order for all images in a product's gallery.

FieldDetails
order (array of int
required)

Response

Response
success, product
POST /api/staff/products/bulk-save Staff

Saves multiple product edits in a single request. Returns a summary of saved and errored products.

FieldDetails
products (array of objects
required) - each object contains product fields like id (int
required)
name (string
optional)
description (string
optional)
category_id (int
optional)
sku (string
optional)
unit_price (float
optional)
bulk_price (float
optional)
bulk_quantity (int
optional)
unit_size (string
optional)
brand (string
optional)
in_stock (boolean
optional)
stock_quantity (int
optional)
image_url (string
optional)
cost_per_item (float
optional)
ship_weight_oz (float
optional)
ship_box_name (string
optional)
ship_box_length (float
optional)
ship_box_width (float
optional)
ship_box_height (float
optional)
is_customizable (boolean
optional)

Response

Response
saved, errors
POST /api/staff/products/upload-image Staff

Pre-upload an image before the product record exists. Returns a base64 data URL that the caller includes in the create-product payload.

FieldDetails
image (file
required)

Response

Response
success, image_url
GET /api/staff/profile Staff

Returns the profile information of the currently logged-in staff member.

FieldDetails
N/A for GET

Response

Response
id, username, email, full_name, first_name, last_name, role, is_active, created_at, updated_at
POST /api/staff/profile/change-password Staff

Allows a logged-in staff member to change their own password.

FieldDetails
current_password (string
required)
new_password (string
required)
confirm_password (string
required)

Response

Response
message
POST /api/staff/profile/update-email Staff

Allows a logged-in staff member to update their own email address.

FieldDetails
new_email (string
required)

Response

Response
success, email
GET /api/staff/profit-dashboard Staff + Admin

Retrieves monthly profit dashboard aggregates including sales, delivery fees, cost of goods, shipping costs, and gross profit for a specified period. Requires staff with admin or manager roles.

ParamDetails
period (int
default: 6)
FieldDetails
N/A for GET

Response

Response
period, monthly (year, month, month_label, order_count, total_sales, delivery_fees, cost_of_goods, shipping_cost, gross_profit, avg_order_value), totals (total_sales, delivery_fees, cost_of_goods, shipping_cost, gross_profit, order_count)
POST /api/staff/reset-password Public

Resets the password for a staff user using a valid reset token. The new password must be at least 6 characters long.

FieldDetails
token (string
required)
password (string
required)

Response

Response
message, error
POST /api/staff/smtp-debug Staff

Perform a synchronous SMTP connection test to debug configuration issues. Returns exact error messages.

Response

Response
success, ehlo, starttls, login, error, error_type, smtp_user, smtp_pass_len
GET /api/staff/stats Staff

Retrieve dashboard statistics for the staff portal, including order counts and total revenue. Supports various date ranges.

ParamDetails
range (string
optional
default 'all'
options: '7d'
'30d'
'month'
'all')
FieldDetails
N/A for GET

Response

Response
total_orders, pending, confirmed, packed, shipped, delivered, cancelled, total_revenue, needs_attention
GET /api/staff/subscriptions Staff

List all subscriptions with optional filters.

ParamDetails
status (string
optional)
user_id (int
optional)
FieldDetails
N/A for GET

Response

Response
list of subscription objects (id, user_id, product_sku, quantity, interval_days, discount_pct, next_renewal_date, status, customer_name, customer_email, customer_phone, customer_company, last_renewal)
POST /api/staff/subscriptions Staff

Enroll a customer in a subscription.

FieldDetails
user_id (int
required)
product_sku (string
required)
quantity (int
required
min 4)
interval_days (int
required)
discount_pct (float
required)
stripe_customer_id (string
required)
stripe_payment_method_id (string
required)
payment_type (string
required)
delivery_name (string
required)
delivery_phone (string
optional)
delivery_email (string
required
must not be placeholder)
delivery_address (string
required)
delivery_city (string
required)
delivery_state (string
required)
delivery_zip (string
required)
delivery_company (string
optional)
notes (string
optional)
start_date (ISO string
optional)

Response

Response
subscription object (id, user_id, product_sku, quantity, interval_days, discount_pct, next_renewal_date, status, customer_name, customer_email, customer_phone, customer_company, last_renewal)
GET /api/staff/subscriptions/<int:sub_id> Staff

Get a single subscription with full renewal history and customer order history.

FieldDetails
N/A for GET

Response

Response
subscription object (id, user_id, product_sku, quantity, interval_days, discount_pct, next_renewal_date, status, customer_name, customer_email, customer_phone, customer_company, renewals, order_history, product_history)
PUT /api/staff/subscriptions/<int:sub_id> Staff

Update interval, quantity, discount, notes, next_renewal_date, and delivery information for a subscription.

FieldDetails
interval_days (int
optional)
quantity (int
optional
min 4)
discount_pct (float
optional)
notes (string
optional)
next_renewal_date (ISO string
optional)
delivery_name (string
optional)
delivery_address (string
optional)
delivery_city (string
optional)
delivery_state (string
optional)
delivery_zip (string
optional)

Response

Response
subscription object (id, user_id, product_sku, quantity, interval_days, discount_pct, next_renewal_date, status, customer_name, customer_email, customer_phone, customer_company, last_renewal)
POST /api/staff/subscriptions/<int:sub_id>/cancel Staff

Cancel a subscription.

FieldDetails
N/A for POST

Response

Response
success (boolean), status (string)
POST /api/staff/subscriptions/<int:sub_id>/pause Staff

Pause a subscription.

FieldDetails
N/A for POST

Response

Response
success (boolean), status (string)
POST /api/staff/subscriptions/<int:sub_id>/renew-now Staff

Manually trigger a renewal for a subscription (charge + create order).

FieldDetails
N/A for POST

Response

Response
success (boolean), renewal (object), next_renewal_date (ISO string)
POST /api/staff/subscriptions/<int:sub_id>/resume Staff

Resume a paused subscription.

FieldDetails
N/A for POST

Response

Response
success (boolean), status (string), next_renewal_date (ISO string)
POST /api/staff/subscriptions/process-renewals API Key

Internal cron endpoint to process all due renewals.

FieldDetails
N/A for POST

Response

Response
processed (int), results (list of objects with subscription_id, status, order or error)
POST /api/staff/subscriptions/setup-intent Staff

Create a Stripe SetupIntent so the frontend can collect and save a card or ACH payment method for a customer.

FieldDetails
user_id (int
optional)
customer_email (string
optional)
customer_name (string
optional)
payment_type (string
required
'card' or 'ach')

Response

Response
client_secret, stripe_customer_id, setup_intent_id
GET /api/staff/subscriptions/suggest/<int:user_id> Staff

Analyze product order history and suggest a renewal interval.

ParamDetails
sku (string
optional)
FieldDetails
N/A for GET

Response

Response
order_count, order_dates, avg_interval_days, suggested_interval_days, last_order_date, confidence
POST /api/staff/test-email Staff

Send a test email to verify SMTP configuration. Reports SMTP configuration status.

FieldDetails
to (string
optional
default SMTP_USER)

Response

Response
success, queued, config (SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASSWORD, sending_to), message
GET /api/staff/users Staff + Admin

Lists all staff users in the system.

FieldDetails
N/A for GET

Response

Response
id, username, email, full_name, first_name, last_name, role, is_active, created_at, updated_at
POST /api/staff/users Staff + Admin

Creates a new staff user with the provided details.

FieldDetails
username (string
required)
email (string
optional)
password (string
required)
role (string
optional)
first_name (string
optional)
last_name (string
optional)
full_name (string
optional)

Response

Response
id, username, email, full_name, first_name, last_name, role, is_active, created_at, updated_at
GET /api/staff/users Staff

Returns a paginated list of website-registered user accounts. This includes users who registered via email verification or OAuth, excluding imported contacts who never self-registered.

ParamDetails
page (int
1)
per_page (int
50)
search (str
none)
FieldDetails
N/A for GET

Response

Response
users, total, page, per_page, pages
PUT /api/staff/users/<int:user_id> Staff + Admin

Updates an existing staff user's details by ID.

FieldDetails
full_name (string
optional)
first_name (string
optional)
last_name (string
optional)
email (string
optional)
role (string
optional)
is_active (boolean
optional)
password (string
optional)

Response

Response
id, username, email, full_name, first_name, last_name, role, is_active, created_at, updated_at
DELETE /api/staff/users/<int:user_id> Staff + Admin

Deletes a staff user by ID. An admin cannot delete their own account.

FieldDetails
N/A for GET

Response

Response
message
GET /api/staff/users/<int:user_id>/credit Staff

Return the user's current credit balance and full transaction history.

FieldDetails
N/A for GET

Response

Response
user_id, username, company_name, credit_balance, history
POST /api/staff/users/<int:user_id>/credit/issue Staff

Manually issue, adjust, or deduct store credit for a user. Amount can be negative to deduct credit.

FieldDetails
amount (float
required)
note (string
optional)

Response

Response
success, credit_balance, transaction
Sales Rep Portal
GET /api/products/sales-catalog Public

Returns all products grouped by category, optimized for the sales catalog view with slim product details.

FieldDetails
N/A for GET

Response

Response
id, name, products (list of id, name, sku, unit_price, bulk_price, bulk_quantity, brand, unit_size, in_stock)
GET /api/sales/call-list Staff

Returns customers with phone numbers, sorted by last order date (oldest first).

ParamDetails
page (int
1)
per_page (int
100)
search (str
'')
FieldDetails
N/A for GET

Response

Response
customers (list of dicts with id, name, first_name, last_name, company, phone, email, shipping_address, order_count, total_spend, last_order_date, last_order_amount, last_order_items), total, page, pages
GET /api/sales/calling-list Staff

Return calling list entries with pagination (prospects + registered customers).

ParamDetails
sort (str
'priority_score')
dir (str
'desc')
status (str
'')
q (str
'')
assignee (str
'')
page (int
1)
per_page (int
50)
purchased_skus (str
'')
segment (str
'priority')
score_min (float
CALLING_MIN)
score_max (float
CALLING_MAX)
FieldDetails
N/A for GET

Response

Response
varies (list of dicts)
POST /api/sales/calling-list Staff

Add a single prospect to the calling list.

FieldDetails
phone (str
required)
company_name (str
optional)
contact_name (str
optional)
email (str
optional)
address (str
optional)
notes (str
optional)
priority_score (float
optional)
status (str
optional)

Response

Response
success, entry (dict)
PUT /api/sales/calling-list/<int:entry_id> Staff

Update a calling list entry.

FieldDetails
customer_id (int
optional)
first_name (str
optional)
last_name (str
optional)
contact_name (str
optional)
company_name (str
optional)
email (str
optional)
phone (str
optional)
phone2 (str
optional)
address (str
optional)
notes (str
optional)
assigned_to (int
optional)
status (str
optional)
priority_score (float
optional)
mark_called (bool
optional)
last_called (str
optional)

Response

Response
success, entry (dict)
PATCH /api/sales/calling-list/<int:entry_id> Staff

Update a calling list entry.

FieldDetails
customer_id (int
optional)
first_name (str
optional)
last_name (str
optional)
contact_name (str
optional)
company_name (str
optional)
email (str
optional)
phone (str
optional)
phone2 (str
optional)
address (str
optional)
notes (str
optional)
assigned_to (int
optional)
status (str
optional)
priority_score (float
optional)
mark_called (bool
optional)
last_called (str
optional)

Response

Response
success, entry (dict)
DELETE /api/sales/calling-list/<int:entry_id> Staff

Delete a calling list entry.

Response

Response
success
POST /api/sales/calling-list/backfill-customer-info Staff + Admin

One-time backfill (safe to re-run).

Response

Response
linked, already_linked, no_match, total, message
POST /api/sales/calling-list/batch-assign Staff + Admin

Assign a list of entry IDs to a specific staff user (or unassign if assignee_id is null).

FieldDetails
ids (list
optional)
assignee_id (int
optional)

Response

Response
success, updated
POST /api/sales/calling-list/batch-mark-called Staff

Batch-update last_called for a list of entry IDs in a single request.

FieldDetails
ids (list
optional)

Response

Response
success, updated
GET /api/sales/calling-list/purchased-products Staff

Return distinct product SKUs and names ever purchased, for the call list filter.

FieldDetails
N/A for GET

Response

Response
products (list of dicts with sku, name, purchase_count)
POST /api/sales/calling-list/run-decay Staff + Admin

Admin/manager endpoint: recalculate and persist decayed scores for all non-DNC entries.

Response

Response
success, updated, total
POST /api/sales/calling-list/score-event Staff + Admin

Trigger a score event for a calling list entry matched by phone or email.

FieldDetails
phone (str
optional)
email (str
optional)
event (str
optional)

Response

Response
success, id, new_score, reason
GET /api/sales/calling-list/segment-counts Staff

Return counts for each segment tab + todays KPI stats for the logged-in rep.

FieldDetails
N/A for GET

Response

Response
segments (dict with priority, window, lapsed, called, all), kpi (dict with calls_today, orders_placed, revenue_today, conversion)
GET /api/sales/calling-list/staff-list Staff

Return all active sales_rep and admin staff for the assign dropdown.

FieldDetails
N/A for GET

Response

Response
varies (list of dicts with id, full_name, username, role)
POST /api/sales/calling-list/upload-csv Staff

Bulk-upload prospects from CSV.

FieldDetails
file (file
required)

Response

Response
success, created, skipped, dupes, errors (list)
POST /api/sales/commission/<string:order_number>/toggle Staff + Admin

Toggle commission_paid on a single order.

FieldDetails
paid (bool
optional)

Response

Response
success, order_number, commission_paid, commission_paid_at, commission_amount
POST /api/sales/commission/bulk-toggle Staff + Admin

Mark multiple orders commission as paid or unpaid at once.

FieldDetails
order_numbers (list
optional)
paid (bool
optional)

Response

Response
success, updated, paid
GET /api/sales/customer/<int:customer_id>/ach Staff

Return the ACH info on file for a customer (masked account number).

FieldDetails
N/A for GET

Response

Response
customer_id, has_ach, ach_bank_name, ach_account_name, ach_routing_number, ach_account_number_masked, ach_account_type, ach_authorized_at
PUT /api/sales/customer/<int:customer_id>/ach Staff

Save or update ACH bank info for a customer.

FieldDetails
bank_name (str
optional)
account_name (str
optional)
routing_number (str
required)
account_number (str
required)
account_type (str
optional)

Response

Response
success, has_ach, ach_bank_name, ach_account_name, ach_routing_number, ach_account_number_masked, ach_account_type, ach_authorized_at
GET /api/sales/customer/<int:customer_id>/profile Staff

Returns full customer profile with order stats and recent order history.

FieldDetails
N/A for GET

Response

Response
id, first_name, last_name, full_name, company_name, email, phone, shipping_address, payment_terms, created_at, order_count, total_spent, orders (list of dicts with order_number, created_at, total_amount, status, payment_status, payment_method, item_count, items_preview)
PUT /api/sales/customer/<int:customer_id>/profile Staff

Update a customer's profile fields.

FieldDetails
first_name (str
optional)
last_name (str
optional)
company_name (str
optional)
email (str
optional)
phone (str
optional)
phone2 (str
optional)
shipping_address (str
optional)
billing_address (str
optional)
preferred_language (str
optional)

Response

Response
success, id, first_name, last_name, full_name, company_name, email, phone, phone2, shipping_address, billing_address, preferred_language, updated_orders
GET /api/sales/customer/by-phone/profile Staff

Returns profile and order history for a guest customer looked up by phone number.

ParamDetails
phone (str
'')
FieldDetails
N/A for GET

Response

Response
id, first_name, last_name, full_name, company_name, email, phone, phone2, shipping_address, billing_address, payment_terms, created_at, order_count, total_spent, orders (list of dicts with order_number, created_at, total_amount, status, payment_status, payment_method, item_count, items_preview) | varies if guest (no_account: True)
GET /api/sales/history Staff

Full past-sales history for the logged-in rep (or all reps for admin/manager).

ParamDetails
rep_id (int
None)
from_date (str
'')
to_date (str
'')
status (str
'')
search (str
'')
group_by (str
'')
format (str
'')
page (int
1)
per_page (int
50)
FieldDetails
N/A for GET

Response

Response
varies (csv file or json with group_by, groups, total_orders, total_revenue or json with page, per_page, total, pages, summary, orders)
GET /api/sales/import-status/<job_id> Staff

Poll the status of an async import job.

FieldDetails
N/A for GET

Response

Response
varies (job dict)
GET /api/sales/import-template Staff

Return a sample CSV template for the import feature.

FieldDetails
N/A for GET

Response

Response
varies (csv file)
POST /api/sales/import-transactions Staff

Bulk-import historical orders from a CSV upload (async background job).

FieldDetails
file (file
required)

Response

Response
success, job_id, message
GET /api/sales/my-sales Staff

Returns the logged-in reps attributed orders and summary stats.

ParamDetails
days (int
30)
FieldDetails
N/A for GET

Response

Response
rep (dict with id, name, role), period_days, period_orders, period_revenue, all_time_orders, all_time_revenue, orders (list of dicts)
POST /api/sales/order/<int:order_id>/cancel Staff

Allow a sales rep to cancel their own order if it is still pending or confirmed.

Response

Response
success, order_id, order_number, status
GET /api/sales/performance Staff + Admin

Returns a full performance breakdown for all sales reps (or a single rep).

ParamDetails
rep_id (int
None)
days (int
90)
period (str
'month')
FieldDetails
N/A for GET

Response

Response
period_days, period_label, team_revenue, team_orders, reps (list of dicts)
POST /api/sales/place-order Staff

Place an order on behalf of a customer, attributed to the logged-in sales rep.

FieldDetails
customer_id (int
required)
items (list of dicts
required)
notes (str
optional)
payment_method (str
optional)
ach (dict
optional)
discount_amount (float
optional)
delivery_fee (float
optional)

Response

Response
success, order (dict)
GET /api/sales/script Staff

Returns the current call script.

FieldDetails
N/A for GET

Response

Response
content, updated_by, updated_at
POST /api/sales/script Staff + Admin

Admin/manager: update the call script.

FieldDetails
content (str
required)

Response

Response
success, message
PUT /api/staff/orders/<int:order_id>/assign-sales-rep Staff

Assign or reassign an order to a sales representative. Restricted to admin and manager roles.

FieldDetails
sales_rep_id (integer
required)

Response

Response
success, order (id, sales_rep_id)
GET /api/staff/sales-reps Staff

Returns a list of staff users with the 'sales_rep' role.

FieldDetails
N/A for GET

Response

Response
id, username, full_name
Shipping Portal
GET /api/shipping/box-recommendations Staff

Retrieves a list of all existing box recommendation rules.

FieldDetails
N/A for GET

Response

Response
box_recommendations
POST /api/shipping/box-recommendations Staff

Creates a new box recommendation rule.

FieldDetails
product_id (int
required)
qty_per_box (int
optional)
box_name (string
optional)
length_in (float
optional)
width_in (float
optional)
height_in (float
optional)
notes (string
optional)

Response

Response
success, box_recommendation
PUT /api/shipping/box-recommendations/<int:rule_id> Staff

Updates an existing box recommendation rule by its ID.

FieldDetails
product_id (int
optional)
qty_per_box (int
optional)
box_name (string
optional)
length_in (float
optional)
width_in (float
optional)
height_in (float
optional)
notes (string
optional)

Response

Response
success, box_recommendation
DELETE /api/shipping/box-recommendations/<int:rule_id> Staff

Deletes a box recommendation rule by its ID.

FieldDetails
N/A for DELETE

Response

Response
success
POST /api/shipping/box-recommendations/for-order Staff

Suggests box recommendations for products in a given order.

FieldDetails
items (list of dicts
each dict has product_id (int
required)
quantity (int
required))

Response

Response
rules
GET /api/shipping/box-recommendations/products Staff

Searches for products based on a query string for use in box recommendations.

ParamDetails
q (string
default: '')
limit (int
default: 20)
FieldDetails
N/A for GET

Response

Response
products
POST /api/shipping/discord-shipment-summary API Key

Triggers a Discord notification summarizing all orders that still need to be shipped. Protected by an internal secret header.

Response

Response
success, message
POST /api/shipping/login Public

Handles staff login, authenticating users and returning a JWT token and staff details upon successful login.

FieldDetails
username (string
required)
password (string
required)

Response

Response
success, staff (id, username, role, is_active), token
POST /api/shipping/logout Public

Logs out the current staff user by clearing their session.

Response

Response
success
GET /api/shipping/me Staff

Returns the details of the currently authenticated staff user.

FieldDetails
N/A for GET

Response

Response
id, username, role, is_active
GET /api/shipping/orders Staff

Returns orders that need warehouse action, with filtering, searching, and sorting capabilities.

ParamDetails
status (string
default: active)
q (string
default: '')
sort (string
default: created_at)
dir (string
default: asc)
FieldDetails
N/A for GET

Response

Response
orders (list of order objects)
GET /api/shipping/orders/<order_number> Staff

Returns a single order's details for shipping based on its order number.

FieldDetails
N/A for GET

Response

Response
order (order object)
POST /api/shipping/orders/<order_number>/confirm Staff

Marks an order as confirmed, indicating it has been picked and is ready to ship.

Response

Response
success, order (order object)
POST /api/shipping/orders/<order_number>/deliver Staff

Marks an order as delivered.

Response

Response
success, order (order object)
POST /api/shipping/orders/<order_number>/label Staff

Purchases a shipping label for an order using EasyPost, saves label details, and updates the order.

FieldDetails
carrier (string
required)
service (string
required)
from_address (object
required)
to_address (object
required)
parcels (list of objects
required)
customs_info (object
optional)
insurance (float
optional)

Response

Response
label_url, tracking_num, carrier, service, rate, shipment_id, tracker_id, label_id
GET /api/shipping/orders/<order_number>/labels Staff

Returns all EasyPost labels purchased for a given order.

FieldDetails
N/A for GET

Response

Response
labels (list of label objects)
DELETE /api/shipping/orders/<order_number>/labels/<int:label_id> Staff

Hard-deletes a label record without an EasyPost refund (intended for admin use).

Response

Response
success
POST /api/shipping/orders/<order_number>/labels/<int:label_id>/void Staff

Voids/refunds an EasyPost shipping label, deletes the label record, and removes its tracking number from the order.

Response

Response
success, voided_tracking, ep_refund_status, ep_error, remaining_tracking
GET /api/shipping/orders/<order_number>/packing-slip Staff

Returns packing slip data for a specific order, excluding pricing information.

FieldDetails
N/A for GET

Response

Response
slip (order object)
POST /api/shipping/orders/<order_number>/ship Staff

Marks an order as shipped, optionally recording tracking number and carrier, and sends an SMS notification.

FieldDetails
tracking_number (string
optional)
carrier (string
optional)

Response

Response
success, order (order object)
GET /api/shipping/orders/<order_number>/tracking-status Staff

Fetches live tracking status for an order from EasyPost, falling back to direct carrier tracking if necessary.

FieldDetails
N/A for GET

Response

Response
success, tracking_number, carrier, status, status_label, est_delivery_date, public_url, tracking_details (list of objects), last_updated
GET /api/shipping/stats Staff

Provides quick counts for the dashboard header, including shipped today, in transit, and delivered in the last 7 days.

FieldDetails
N/A for GET

Response

Response
shipped_today, in_transit, delivered_7d
Voice AI
GET /api/invoices Staff

Retrieves a list of all invoices, optionally filtered by status. Requires staff authentication.

ParamDetails
status (string
optional)
FieldDetails
N/A for GET

Response

Response
id, invoice_number, status, customer_name, customer_company, customer_email, customer_phone, customer_address, customer_city, customer_state, customer_zip, subtotal, discount_amount, shipping_fee, tax_rate, tax_amount, total_amount, payment_method, payment_terms, due_date, notes, internal_notes, created_by, created_at, updated_at, sent_at, paid_at, items
POST /api/invoices Staff

Creates a new invoice. Requires staff authentication.

FieldDetails
customer_name (string
required)
items (list of dicts
required)
status (string
optional)
customer_company (string
optional)
customer_email (string
optional)
customer_phone (string
optional)
customer_address (string
optional)
customer_city (string
optional)
customer_state (string
optional)
customer_zip (string
optional)
discount_amount (float
optional)
shipping_fee (float
optional)
tax_rate (float
optional)
payment_method (string
optional)
payment_terms (string
optional)
due_date (string
optional)
notes (string
optional)
internal_notes (string
optional)

Response

Response
id, invoice_number, status, customer_name, customer_company, customer_email, customer_phone, customer_address, customer_city, customer_state, customer_zip, subtotal, discount_amount, shipping_fee, tax_rate, tax_amount, total_amount, payment_method, payment_terms, due_date, notes, internal_notes, created_by, created_at, updated_at, sent_at, paid_at, items
GET /api/invoices/<int:invoice_id> Staff

Retrieves details for a single invoice by its ID. Requires staff authentication.

FieldDetails
N/A for GET

Response

Response
id, invoice_number, status, customer_name, customer_company, customer_email, customer_phone, customer_address, customer_city, customer_state, customer_zip, subtotal, discount_amount, shipping_fee, tax_rate, tax_amount, total_amount, payment_method, payment_terms, due_date, notes, internal_notes, created_by, created_at, updated_at, sent_at, paid_at, items
PUT /api/invoices/<int:invoice_id> Staff

Updates an existing invoice by its ID. Requires staff authentication.

FieldDetails
customer_name (string
optional)
customer_company (string
optional)
customer_email (string
optional)
customer_phone (string
optional)
customer_address (string
optional)
customer_city (string
optional)
customer_state (string
optional)
customer_zip (string
optional)
payment_method (string
optional)
payment_terms (string
optional)
due_date (string
optional)
notes (string
optional)
internal_notes (string
optional)
items (list of dicts
optional)
discount_amount (float
optional)
shipping_fee (float
optional)
tax_rate (float
optional)
status (string
optional)

Response

Response
id, invoice_number, status, customer_name, customer_company, customer_email, customer_phone, customer_address, customer_city, customer_state, customer_zip, subtotal, discount_amount, shipping_fee, tax_rate, tax_amount, total_amount, payment_method, payment_terms, due_date, notes, internal_notes, created_by, created_at, updated_at, sent_at, paid_at, items
DELETE /api/invoices/<int:invoice_id> Staff

Deletes an invoice by its ID. Requires staff authentication.

FieldDetails
N/A for GET

Response

Response
message (string)
GET /api/invoices/<int:invoice_id>/pdf Staff

Downloads the PDF for a specific invoice. Generates the PDF if it doesn't exist. Requires staff authentication.

FieldDetails
N/A for GET

Response

Response
file (application/pdf)
GET /api/sales/customer/<int:customer_id>/invoices Staff

Returns the order history (invoices) for a specific customer.

FieldDetails
N/A for GET

Response

Response
orders (list of dicts)
GET /api/staff/voice/performance Staff

Returns aggregated performance data for the staff portal voice dashboard.

ParamDetails
agent_id (int
optional)
date_from (str
optional
default 30 days ago)
date_to (str
optional
default today)
granularity (str
optional
default daily)
FieldDetails
N/A for GET

Response

Response
summary (total_calls, total_orders, total_revenue, total_cost, avg_score, resolution_rate, hallucination_rate, roi), date_from, date_to | rows (varies), date_from, date_to
POST /api/voice/log_outbound_call_outcome API Key

Logs the outcome of an outbound sales call. Persists to outbound_call_log for cooldown tracking and call-queue filtering. Special outcomes: dnc_requested permanently sets do_not_call=true on the customer record (excluded from /api/staff/call-queue forever). checker_verdict=fail automatically creates a review queue entry in call_log with call_type=outbound_sales, surfacing the call in /api/staff/voice/review-queue for staff review.

MethodHeaderNotes
API KeyX-API-Key: <key>For n8n / automated callers
Staff sessionCookieFor staff portal manual logging
FieldTypeRequiredDescription
phonestringYesCustomer phone number (E.164 format)
outcomestringYessale_made | interested_callback | busy_callback | not_interested | no_answer | wrong_number | dnc_requested
customer_namestringNoCustomer display name
order_numberstringNoOrder number if sale_made
callback_datestringNoISO date for callback (YYYY-MM-DD)
notesstringNoFree-text call notes
items_discussedstringNoProducts discussed during the call
procurement_interestbooleanNotrue if customer expressed sourcing/procurement interest
checker_verdictstringNopass or fail — verdict from the Checker sub-agent. If fail, a review queue entry is created automatically.
checker_reasonslist[str]NoFail reasons from the Checker sub-agent (e.g. ["Promised discount not authorized"]). Only meaningful when checker_verdict=fail.
transcript_urlstringNoURL to the stored call transcript. Attached to the review queue entry when checker_verdict=fail.

Response

Response · 200
{
  "success": true,
  "message": "Acme Restaurant placed an order. Great work!",
  "review_queue_id": null
}

// When checker_verdict=fail:
{
  "success": true,
  "message": "Call outcome 'sale_made' logged for Acme Restaurant.",
  "review_queue_id": 42
}
GET /api/staff/voice/review-queue Staff

Returns calls that need manual staff review — both inbound ordering calls with low eval scores and outbound sales calls where the Checker sub-agent returned checker_verdict=fail. Use the call_type filter to separate the two queues.

ParamTypeDefaultDescription
agent_idintegerFilter to a specific ElevenLabs agent ID
statusstringcompleteEval status: complete | reviewed | flagged
limitinteger100Max results to return
call_typestringallFilter by type: inbound_order | outbound_sales

Response

Response · 200
{
  "calls": [
    {
      "id": 42,
      "call_type": "outbound_sales",
      "direction": "outbound",
      "caller_phone": "+13125550101",
      "customer_id": 88,
      "sub_agent_name": "LLD Outbound Sales",
      "eval_status": "complete",
      "eval_score": 0,
      "eval_hallucination": true,
      "eval_escalation_needed": false,
      "eval_reviewed_by": null,
      "eval_reviewed_at": null,
      "checker_verdict": "fail",
      "checker_reasons": [
        "Promised discount not authorized",
        "Incorrect product availability stated"
      ],
      "transcript_url": "https://storage.example.com/transcripts/call-42.txt",
      "created_at": "2026-07-01T14:22:00Z"
    }
  ]
}
POST /api/staff/voice/review-queue/<int:call_id>/approve Staff

Mark a call evaluation as reviewed and approved (no retraining needed).

Response

Response
success, call_log_id, status
POST /api/staff/voice/review-queue/<int:call_id>/reject Staff

Mark a call as flagged for retraining.

FieldDetails
notes (str
optional)

Response

Response
success, call_log_id, status
POST /api/voice/cancel_order API Key

Cancel an order. Only pending or confirmed orders can be cancelled via voice.

FieldDetails
order_number (str
required)
phone_number (str
optional)
phone (str
optional)
confirmed (bool
required)

Response

Response
success, order_number, message
POST /api/voice/check_account_standing API Key

Determine whether a customer is approved for Net 30 payment terms and whether they have any overdue invoices. The voice agent calls this before placing an order to decide the payment flow: Net 30 (frictionless), Stripe link, or check upload.

FieldDetails
phone_number (string
required)

Response

Response
success, approved_for_terms, payment_terms, has_overdue, overdue_amount, overdue_invoice_count, credit_limit, available_credit, customer_id, company_name, current_balance, account_status, overdue_orders
POST /api/voice/check_order_status API Key

Look up the status of an order by order number OR by phone number (returns most recent).

FieldDetails
order_number (str
optional)
phone_number (str
optional)
phone (str
optional)

Response

Response
success, order (order_number, status, total, subtotal, delivery_fee, payment_method, payment_status, item_count, created_at, special_notes, items (sku, name, quantity, unit_price, line_total))
GET /api/voice/db_stats API Key

Temporary diagnostic: count users and phone numbers in DB.

FieldDetails
N/A for GET

Response

Response
success, total_users, users_with_phone, sample_phones, sample_usernames
POST /api/voice/evaluate Staff

Trigger or re-trigger LLM evaluation for a specific call.

FieldDetails
call_log_id (int
required)
async (bool
optional
default True)

Response

Response
success, message, call_log_id | success, call (varies)
POST /api/voice/get_customer API Key

Look up a registered customer by phone number.

FieldDetails
phone_number (str
required)
phone (str
required)

Response

Response
success, found, customer (id, name, company, email, phone, payment_terms, approved_for_terms, recent_orders (order_number, status, total, date, item_count))
POST /api/voice/get_customer_order_history API Key

Outbound Sales Agent tool — retrieve a customer's full order history by phone.

FieldDetails
phone_number (str
required)
phone (str
required)
limit (int
optional
default 10
max 20)

Response

Response
success, customer_name, company, order_count, orders (order_number, date, status, payment_status, total, items (sku, name, quantity, unit_price, line_total), special_notes), top_categories, reorder_candidates, message
POST /api/voice/get_order_history API Key

ElevenLabs tool webhook — look up a customer's past orders by phone number.

FieldDetails
phone (str
required)
phone_number (str
required)
limit (int
optional
default 5
max 20)
status_filter (str
optional
default 'all')

Response

Response
success, customer_name, order_count, orders (order_number, date, status, payment_status, total, items, tracking_number), message
POST /api/voice/get_products API Key

Search or list available products.

FieldDetails
query (str
optional)
category (str
optional)
in_stock_only (bool
optional)

Response

Response
success, count, products (sku, name, brand, unit_size, unit_price, bulk_price, bulk_quantity, in_stock, stock_quantity)
POST /api/voice/optimize-agent/<int:agent_id> Staff

Analyze worst-performing calls for an agent and suggest prompt improvements.

FieldDetails
min_calls (int
optional
default 10)
score_threshold (float
optional
default 60.0)
date_from (str
optional)
date_to (str
optional)

Response

Response
analysis, suggested_system_prompt, changes_made, expected_improvement
POST /api/voice/place_order API Key

Place a new order on behalf of a customer identified by phone number. Supports both registered customers and guest callers.

FieldDetails
phone_number (str
required)
phone (str
required)
items (list
required)
confirmed (bool
required)
special_notes (str
optional)
payment_method (str
optional)
delivery_name (str
required for guest)
delivery_company (str
required for guest)
delivery_address (str
required for guest)
delivery_city (str
required for guest)
delivery_state (str
required for guest)
delivery_zip (str
required for guest)

Response

Response
success, order_number, total, subtotal, items_placed, customer_type, payment_required, message
POST /api/voice/send_payment_sms API Key

Send an SMS to the customer after an order is placed. SMS content varies by payment_method: net30 (Confirms order on terms, no payment URL), credit_card (Generates Stripe Payment Link and texts it), check (Texts the check upload URL).

FieldDetails
phone_number (string
required)
order_number (string
required)
payment_method (string
required)

Response

Response
success, message, sms_type, payment_url, sms_body_preview
POST /api/voice/submit_special_order API Key

ElevenLabs tool webhook — submit a special/custom sourcing request. Creates an RFQ in the sourcing system and notifies the China team via Discord.

FieldDetails
phone (str
required)
phone_number (str
required)
item_description (str
required)
specifications (str
optional)
quantity (int
optional)
target_unit_price (float
optional)
quality_notes (str
optional)
timeline_weeks (int
optional)
delivery_address (str
optional)
additional_notes (str
optional)

Response

Response
success, rfq_number, message
POST /api/voice/webhook/call-complete hmac_sha256

ElevenLabs webhook to log call details and optionally sync customer data to the staff portal. Triggered after a voice agent call is complete.

FieldDetails
call_id (string
required)
status (string
required)
duration (integer
required)
start_time (string
required)
end_time (string
required)
phone_number (string
required)
transcript (string
optional)
order_placed (boolean
optional)
order_number (string
optional)
tool_outputs (list
optional)

Response

Response
success
GET /api/staff/call-queue Staff or API Key

Returns a prioritized, pre-filtered list of customers who are due for an outbound reorder call. Excludes customers with do_not_call=true (non-overridable by any query param), invalid/missing phone numbers, and customers within the cooldown window — unless they have a callback outcome with a callback_date on or before today. Priority score: (days_since_last_order / avg_reorder_cycle) × ltv_weight. All order aggregates are computed in bulk SQL (no N+1 queries). DNC note: do_not_call is set automatically when log_outbound_call_outcome is called with outcome=dnc_requested. Once set, the customer is permanently excluded from this endpoint regardless of any filter params.

MethodHeader / CookieUse Case
Staff JWTCookie: sessionorAuthorization: Bearer <token>Staff portal UI
API KeyX-API-Key: <key>n8n automation
ParamTypeDefaultDescription
min_days_since_orderint14Minimum days since last order to include customer
max_days_since_orderint180Maximum days since last order (excludes very old/inactive)
min_order_countint1Minimum lifetime order count to include customer
cooldown_daysint10Days to suppress a customer after any call outcome
limitint50Max results per page
pageint1Page number for pagination
sortstrprioritySort order:priority,days_desc,ltv_desc
credit_statusstrnoneFilter by credit standing. Valid values: good (approved terms, balance within limit), overdue (balance exceeds credit limit), no_terms (not approved for net terms). Use credit_status=good for upsell-focused campaigns.
FieldTypeDescription
customer_idintUser ID
phonestrCustomer phone number
customer_namestrFull name
company_namestr | nullBusiness name
days_since_last_orderintDays since most recent order
last_order_datestrISO date of last order
average_order_valuefloatAverage order total
lifetime_valuefloatSum of all order totals
order_countintTotal number of orders
reorder_candidateslist[str]Product names from last order likely to be reordered
top_categorieslist[str]Most frequently ordered product categories
suggested_upsellslist[str]Products frequently bought by similar customers
talking_pointslist[str]Pre-built call script bullets (reorder prompt, LTV note, etc.)
credit_statusstrCredit standing: good | overdue | no_terms
priority_scorefloatComputed priority: higher = call sooner
last_callobject | nullnullif never called. Otherwise:{date, outcome, callback_date, notes}

Response

Response Envelope
{
            "results": [ ... ],   // array of customer objects (see below)
            "total": 120,         // total matching customers (before pagination)
            "page": 1,
            "limit": 50,
            "generated_at": "2026-07-01T16:25:01.062044Z"
          }
Example Response
{
  "results": [
    {
      "customer_id": 42,
      "phone": "+13105550187",
      "customer_name": "Maria Chen",
      "company_name": "Golden Dragon Restaurant",
      "days_since_last_order": 21,
      "last_order_date": "2026-06-10",
      "average_order_value": 340.50,
      "lifetime_value": 4086.00,
      "order_count": 12,
      "reorder_candidates": ["Soy Sauce 1gal", "Oyster Sauce"],
      "top_categories": ["Sauces", "Dry Goods"],
      "suggested_upsells": ["Sesame Oil", "Rice Vinegar"],
      "talking_points": [
        "Last order was 21 days ago — may be running low on Soy Sauce 1gal",
        "Loyal customer with 12 orders — offer volume discount",
        "Top categories: Sauces, Dry Goods"
      ],
      "credit_status": "good",
      "priority_score": 3.42,
      "last_call": {
        "date": "2026-06-15",
        "outcome": "no_answer",
        "callback_date": null,
        "notes": null
      }
    },
    {
      "customer_id": 99,
      "phone": "+13235550042",
      "customer_name": "Tony Nguyen",
      "company_name": "Pho Palace",
      "days_since_last_order": 35,
      "last_order_date": "2026-05-27",
      "average_order_value": 210.00,
      "lifetime_value": 630.00,
      "order_count": 3,
      "reorder_candidates": ["Pho Broth Base"],
      "top_categories": ["Soups"],
      "suggested_upsells": [],
      "talking_points": [
        "Last order was 35 days ago — may be running low on Pho Broth Base",
        "Returning customer with 3 orders",
        "Average order $210 — suggest bundling to $300 for free delivery"
      ],
      "credit_status": "no_terms",
      "priority_score": 0.88,
      "last_call": null
    }
  ],
  "total": 87,
  "page": 1,
  "limit": 50,
  "generated_at": "2026-07-01T16:25:01.062044Z"
}
POST /api/voice/upload-transcript API Key

Uploads a call transcript to Cloudflare R2 object storage and returns a permanent public URL. Used by n8n immediately after an ElevenLabs call completes — the returned transcript_url is then passed to log_outbound_call_outcome. Accepts either a raw text body (JSON field transcript) or a multipart file upload. Requires R2_ACCOUNT_ID, R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY, R2_BUCKET_NAME, and R2_PUBLIC_URL environment variables on the Railway backend.

MethodHeaderNotes
API KeyX-API-Key: <key>n8n / automated callers only
FieldTypeRequiredDescription
transcriptstringYes*Full transcript text. *Required if not sending a multipart file.
call_idstringNoElevenLabs call ID — used in the storage key for traceability
phonestringNoCustomer phone — used in the storage key
FieldTypeDescription
filefileTranscript file (.txt or .json)
call_idstringOptional ElevenLabs call ID
phonestringOptional customer phone
StatusCondition
401Missing or invalid API key
400No transcript text or file provided
503R2 environment variables not configured
502R2 upload failed (boto3 error)

Response

Response · 200
{
  "success": true,
  "transcript_url": "https://transcripts.lldrestaurantsupply.com/transcripts/2026-07-01/+13125550101_call-abc123.txt",
  "key": "transcripts/2026-07-01/+13125550101_call-abc123.txt",
  "bucket": "lld-transcripts",
  "size_bytes": 4821
}

// Error — R2 not configured:
{
  "error": "Transcript storage not configured",
  "detail": "R2_ACCOUNT_ID environment variable is missing"
}
Sourcing
GET /api/sourcing/inventory-needs Staff

Retrieves a list of inventory needs, potentially filtered by product ID.

ParamDetails
product_id (int
optional)
FieldDetails
N/A for GET

Response

Response
list of inventory_need objects
POST /api/sourcing/orchestrate Staff

Generates a sub-agent configuration for a sourcing requirement using AI.

FieldDetails
requirement (str
required)
product_id (int
optional)
product_name (str
optional)
quantity (int
optional)
target_price (float
optional)
deadline (str
optional)
notes (str
optional)

Response

Response
success, config (dict)
GET /api/sourcing/payments Staff

Retrieves a list of supplier payments, with optional filtering by supplier ID and status.

ParamDetails
supplier_id (int
optional)
status (str
optional)
FieldDetails
N/A for GET

Response

Response
list of supplier_payment objects
POST /api/sourcing/payments Staff

Creates a new supplier payment record.

FieldDetails
supplier_id (int
required)
rfq_id (int
optional)
shipment_id (int
optional)
amount (float
required)
currency (str
optional
default 'USD')
payment_date (str
optional)
status (str
optional
default 'pending')
notes (str
optional)

Response

Response
success, supplier_payment
PUT /api/sourcing/payments/<int:pid> Staff

Updates an existing supplier payment record by ID.

FieldDetails
supplier_id (int
optional)
rfq_id (int
optional)
shipment_id (int
optional)
amount (float
optional)
currency (str
optional)
payment_date (str
optional)
status (str
optional)
notes (str
optional)

Response

Response
success, supplier_payment
POST /api/sourcing/qc/inspections Staff

Creates a new QC inspection record.

FieldDetails
shipment_id (int
optional)
supplier_id (int
optional)
product_id (int
optional)
product_name (str
optional)
inspection_date (str
optional)
inspector (str
optional)
result (str
optional
default 'pending')
notes (str
optional)
defects (list
optional)
images (list
optional)

Response

Response
success, qc_inspection
GET /api/sourcing/qc/inspections Staff

Retrieves a list of QC inspections, with optional filtering by status, shipment ID, and supplier ID.

ParamDetails
status (str
default '')
shipment_id (int
optional)
supplier_id (int
optional)
FieldDetails
N/A for GET

Response

Response
list of qc_inspection objects
PUT /api/sourcing/qc/inspections/<int:iid> Staff

Updates an existing QC inspection record by ID.

FieldDetails
shipment_id (int
optional)
supplier_id (int
optional)
product_id (int
optional)
product_name (str
optional)
inspection_date (str
optional)
inspector (str
optional)
result (str
optional)
notes (str
optional)
defects (list
optional)
images (list
optional)

Response

Response
success, qc_inspection
POST /api/sourcing/rfqs Staff

Creates a new Request for Quotation (RFQ).

FieldDetails
product_id (int
optional)
description (str
optional)
target_unit_price (float
optional)
quantity (int
optional)
status (str
optional
default 'draft')

Response

Response
success, rfq
GET /api/sourcing/rfqs Staff

Retrieves a list of RFQs, with optional filtering by status and product ID.

ParamDetails
status (str
default '')
product_id (int
optional)
FieldDetails
N/A for GET

Response

Response
list of rfq objects
POST /api/sourcing/rfqs/<int:rfq_id>/award Staff

Awards an RFQ to a specific supplier.

FieldDetails
supplier_id (int
required)

Response

Response
success, rfq
PUT /api/sourcing/rfqs/<int:rfq_id>/quotes Staff

Appends a supplier quote to the RFQ's quotes JSON array and updates RFQ status if applicable.

FieldDetails
price (float
required)
supplier_id (int
optional)
moq (int
optional)
lead_time (str
optional)
notes (str
optional)

Response

Response
success, rfq
POST /api/sourcing/shipments Staff

Creates a new shipment record.

FieldDetails
supplier_id (int
optional)
rfq_id (int
optional)
tracking_number (str
optional)
carrier (str
optional)
status (str
optional
default 'production')
origin (str
optional)
destination (str
optional
default 'Chicago warehouse')
eta (str
optional)
items (list
optional)
documents (list
optional)
total_cost (float
optional)
currency (str
optional
default 'USD')
notes (str
optional)

Response

Response
success, shipment
GET /api/sourcing/shipments Staff

Retrieves a list of shipments, with optional filtering by status, supplier ID, and active status.

ParamDetails
status (str
default '')
supplier_id (int
optional)
active (str
default '')
FieldDetails
N/A for GET

Response

Response
list of shipment objects
PUT /api/sourcing/shipments/<int:sid>/status Staff

Updates a shipment's status and appends an event to its timeline.

FieldDetails
status (str
optional)
tracking_number (str
optional)
eta (str
optional)
event (str
optional)
notes (str
optional)
location (str
optional)
recorded_by (str
optional)

Response

Response
success, shipment
GET /api/sourcing/shipments/<int:sid>/timeline Staff

Retrieves the timeline of events for a specific shipment.

FieldDetails
N/A for GET

Response

Response
shipment_number, status, timeline
POST /api/sourcing/suppliers Staff

Creates a new supplier entry in the system.

FieldDetails
name (str
required)
name_cn (str
optional)
platform (str
optional)
location (str
optional)
contact_name (str
optional)
contact_wechat (str
optional)
contact_email (str
optional)
contact_phone (str
optional)
product_categories (list
optional)
rating (int
optional)
lead_time_days (int
optional)
moq_notes (str
optional)
payment_terms (str
optional)
is_active (bool
optional)
notes (str
optional)

Response

Response
success, supplier
GET /api/sourcing/suppliers Staff

Retrieves a list of suppliers, with optional filtering by active status, search terms, and platform.

ParamDetails
active (str
default 'true')
search (str
default '')
platform (str
default '')
FieldDetails
N/A for GET

Response

Response
list of supplier objects
GET /api/sourcing/suppliers/<int:sid> Staff

Retrieves details for a specific supplier by ID, including associated RFQ and shipment counts.

FieldDetails
N/A for GET

Response

Response
supplier object, rfq_count, shipment_count, active_shipments
PUT /api/sourcing/suppliers/<int:sid> Staff

Updates an existing supplier's details by ID.

FieldDetails
name (str
optional)
name_cn (str
optional)
platform (str
optional)
location (str
optional)
contact_name (str
optional)
contact_wechat (str
optional)
contact_email (str
optional)
contact_phone (str
optional)
product_categories (list
optional)
rating (int
optional)
lead_time_days (int
optional)
moq_notes (str
optional)
payment_terms (str
optional)
is_active (bool
optional)
notes (str
optional)

Response

Response
success, supplier
Bills & Invoices
GET /api/bills Staff

List all uploaded bills, newest first.

FieldDetails
N/A for GET

Response

Response
id, extraction_status, extraction_error, total_items, items_we_carry, potential_savings, supplier_name, bill_date, bill_number, bill_total, restaurant_name, restaurant_email, restaurant_phone, contact_name, notes, original_filename, file_path, file_type, uploaded_by, created_at, updated_at
POST /api/bills Staff

Upload a new supplier bill for analysis.

FieldDetails
file (file
required)
restaurant_name (string
required)
restaurant_email (string
optional)
restaurant_phone (string
optional)
contact_name (string
optional)
notes (string
optional)
supplier_name (string
optional)

Response

Response
success, bill (id, extraction_status, extraction_error, total_items, items_we_carry, potential_savings, supplier_name, bill_date, bill_number, bill_total, restaurant_name, restaurant_email, restaurant_phone, contact_name, notes, original_filename, file_path, file_type, uploaded_by, created_at, updated_at)
GET /api/bills/<int:bill_id> Staff

Get a single bill with all line items.

FieldDetails
N/A for GET

Response

Response
id, extraction_status, extraction_error, total_items, items_we_carry, potential_savings, supplier_name, bill_date, bill_number, bill_total, restaurant_name, restaurant_email, restaurant_phone, contact_name, notes, original_filename, file_path, file_type, uploaded_by, created_at, updated_at, line_items (description, sku, quantity, unit, unit_price, line_total, our_sku, our_name, our_price, our_unit, savings, savings_pct, match_confidence)
DELETE /api/bills/<int:bill_id> Staff

Delete a bill and its uploaded file.

FieldDetails
N/A for GET

Response

Response
success
PUT /api/bills/<int:bill_id>/notes Staff

Update staff notes on a bill.

FieldDetails
notes (string
optional)
restaurant_email (string
optional)
restaurant_phone (string
optional)
contact_name (string
optional)

Response

Response
success
POST /api/bills/<int:bill_id>/reprocess Staff

Re-run AI extraction on an existing bill.

Response

Response
success, message
GET /api/bills/<int:bill_id>/status Staff

Poll extraction status — used by frontend to check progress.

FieldDetails
N/A for GET

Response

Response
id, extraction_status, extraction_error, total_items, items_we_carry, potential_savings, supplier_name, bill_date, bill_number, bill_total
Utilities
POST /api/admin/categories Session

Creates a new product category.

FieldDetails
name (string
required)
description (string
optional)

Response

Response
id, name, description
GET /api/admin/keys Staff + Admin

Returns a list of all API keys, showing only previews and never the raw key values.

FieldDetails
N/A for GET

Response

Response
id, name, prefix, key_preview, description, is_active, created_at, created_by, expires_at, revoked_at, revoked_by, last_used_at, use_count
POST /api/admin/keys Staff + Admin

Creates a new API key. The raw key is returned once in the response and is not stored.

FieldDetails
name (string
required)
prefix (string
required)
description (string
optional)
expires_at (string
optional
YYYY-MM-DD)

Response

Response
id, name, prefix, key_preview, description, is_active, created_at, created_by, expires_at, revoked_at, revoked_by, last_used_at, use_count, raw_key, warning
DELETE /api/admin/keys/<int:key_id> Staff + Admin

Permanently removes an API key record from the database.

Response

Response
success
POST /api/admin/keys/<int:key_id>/activate Staff + Admin

Re-activates a previously revoked API key by setting is_active to True and clearing revoked_at and revoked_by.

Response

Response
success, key (id, name, prefix, key_preview, description, is_active, created_at, created_by, expires_at, revoked_at, revoked_by, last_used_at, use_count)
POST /api/admin/keys/<int:key_id>/revoke Staff + Admin

Deactivates an API key by setting is_active to False, revoked_at, and revoked_by. The key's audit record remains in the database.

Response

Response
success, key (id, name, prefix, key_preview, description, is_active, created_at, created_by, expires_at, revoked_at, revoked_by, last_used_at, use_count)
POST /api/admin/keys/verify Staff + Admin

Verifies if a raw API key is valid (active and not expired). Updates last_used_at and use_count for the key.

FieldDetails
raw_key (string
required)

Response

Response
valid, reason, key (id, name, prefix, key_preview, description, is_active, created_at, created_by, expires_at, revoked_at, revoked_by, last_used_at, use_count)
POST /api/auth/phone/send-code Public

Looks up a customer by phone number and sends a 6-digit OTP via Twilio SMS for password reset or username lookup. Returns a generic message to prevent phone enumeration.

FieldDetails
phone (string
required)

Response

Response
message, sms_sent, debug_otp
POST /api/auth/phone/verify-code Public

Verifies the 6-digit OTP sent to the customer's phone. On success, it returns a short-lived phone_session_token.

FieldDetails
phone (string
required)
code (string
required)

Response

Response
error, phone_session_token
POST /api/auth/resend-verification Session

Resends the email verification link to the currently logged-in customer user. A new verification token is generated and sent via email.

Response

Response
error, message, email_sent
GET /api/auth/verify-email/<token> Public

Verifies a customer's email address using a token from a verification email. Redirects to the frontend with a status.

FieldDetails
N/A for GET

Response

Response
redirect to frontend with email_verified status (invalid, expired, success)
GET /api/categories Public

Returns a list of all product categories.

FieldDetails
N/A for GET

Response

Response
id, name
POST /api/chat Public

Handles chat messages with OpenAI integration, allowing users to ask questions about products, pricing, and availability.

FieldDetails
message (string
required)
language (string
optional)
history (array
optional)

Response

Response
success, message, timestamp | error
POST /api/chat/session Public

Creates a new chat session and returns a unique session ID.

FieldDetails
N/A for GET

Response

Response
success, session_id
POST /api/logout Session

Logs out the currently authenticated user by clearing their session.

FieldDetails
N/A for GET

Response

Response
message
POST /api/scores/recompute Staff + Admin

POST /api/scores/recompute - admin-only, triggers BG/NBD recompute.

Response

Response
success, message
POST /api/search/ai Public

Provides AI-powered natural language product search, returning matching products and a suggestion.

FieldDetails
query (string
required)
language (string
optional)

Response

Response
success, products, suggestion, total | error
POST /api/sms-optin Public

Submits an SMS opt-in consent form, stores the record in the database, and optionally sends a confirmation SMS via Twilio.

FieldDetails
first_name (string
required)
last_name (string
optional)
phone (string
required)
email (string
optional)
consent (boolean
required)

Response

Response
success, message
POST /api/sms/status-callback Public

Receives Twilio message delivery status callbacks, logs the event, and returns a 204 No Content response.

FieldDetails
MessageSid (string
optional)
MessageStatus (string
optional)
To (string
optional)
From (string
optional)
ErrorCode (string
optional)
ErrorMessage (string
optional)

Response

Response
varies
GET /api/v1/categories API Key

List all product categories.

FieldDetails
N/A for GET

Response

Response
categories
GET /api/v1/health Public

Health check endpoint — no authentication required.

FieldDetails
N/A for GET

Response

Response
status, service, version