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.
| Field | Details |
|---|---|
| current_password (string | |
| required) | |
| new_password (string | |
| required) |
Response
message (on success); error (on missing fields, short password, incorrect current password, or general failure)
No description provided.
Response
varies
No description provided.
Response
varies
Returns a masked username for a customer using a verified phone session token. The session token is consumed after use.
| Field | Details |
|---|---|
| phone_session_token (string | |
| required) |
Response
error, username
Resets the password for a customer using a verified phone session token. The new password must be at least 6 characters long.
| Field | Details |
|---|---|
| phone_session_token (string | |
| required) | |
| password (string | |
| required) |
Response
message, error
Resets the password for a customer user using a valid reset token. The new password must be at least 6 characters long.
| Field | Details |
|---|---|
| token (string | |
| required) | |
| password (string | |
| required) |
Response
message, error
Allows customer users to request a password reset link. It sends an email with a reset token if the account exists.
| Field | Details |
|---|---|
| identifier (string | |
| required) |
Response
message, email_sent, debug_token
Allows customer users to recover their username. It sends an email containing the username if the email is registered.
| Field | Details |
|---|---|
| email (string | |
| required) |
Response
message, email_sent
GET /api/customers/{id}/score - single customer score.
| Field | Details |
|---|---|
| N/A for GET |
Response
varies (customer score dict)
GET /api/customers/scores
| Param | Details |
|---|---|
| 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') |
| Field | Details |
|---|---|
| N/A for GET |
Response
results (list of dicts), total, page, pages, tier_counts, last_computed
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.
| Field | Details |
|---|---|
| username (string | |
| required) | |
| password (string | |
| required) |
Response
message, user (on success); error, email_verification_required (on unverified email); error (on invalid credentials or general failure)
Retrieves the profile information of the currently logged-in user.
| Field | Details |
|---|---|
| N/A for GET |
Response
user (username, email, company_name, phone, etc.)
Called after Stripe payment succeeds on the frontend. Updates the order's payment_status and stores the payment_intent_id.
| Field | Details |
|---|---|
| order_number (string | |
| required) | |
| payment_intent_id (string | |
| required) |
Response
success, message
Create a Stripe PaymentIntent for a given order total. Called from the frontend checkout when customer selects credit card.
| Field | Details |
|---|---|
| amount (float | |
| required) | |
| order_number (string | |
| optional) | |
| customer_name (string | |
| optional) | |
| customer_email (string | |
| optional) |
Response
success, client_secret, payment_intent_id
Generates a Stripe Payment Link for an order. Can be called by staff, the voice agent, or the customer dashboard.
| Field | Details |
|---|---|
| order_number (string | |
| required) | |
| expires_in_hours (integer | |
| optional) |
Response
success, payment_url, order_number, amount, expires_at, error, fallback_url
Accepts front and back check image uploads for an order. Requires staff authentication — check images are sensitive financial documents.
| Field | Details |
|---|---|
| order_number (string | |
| required) | |
| check_front (file | |
| required) | |
| check_image (file | |
| optional) | |
| check_back (file | |
| optional) |
Response
success, message, front_filename, back_filename
List all vendors, active by default. Can include inactive vendors with a query parameter.
| Param | Details |
|---|---|
| all (string | |
| default '0') |
Response
id, name, website, phone, email, contact_name, address, notes, active
Create a new vendor. Requires admin or manager staff role.
| Field | Details |
|---|---|
| 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
id, name, website, phone, email, contact_name, address, notes, active
Retrieve details for a single vendor, including all associated products.
Response
id, name, website, phone, email, contact_name, address, notes, active, products (list of product objects)
Update an existing vendor's details. Requires admin or manager staff role.
| Field | Details |
|---|---|
| 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
id, name, website, phone, email, contact_name, address, notes, active
Delete a vendor and all its associated products. Requires admin staff role.
| Field | Details |
|---|---|
| N/A for GET |
Response
success
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.
| Field | Details |
|---|---|
| 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
message, email_verification_required, user (on success); error, duplicate_field, hint (on duplicate); error (on general failure)
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.
| Field | Details |
|---|---|
| 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
success (boolean), message (string), error (string)
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.
| Field | Details |
|---|---|
| N/A for GET |
Response
user (username, email, company_name, phone, etc.)
Retrieves a specific user's profile by ID. Access is restricted to the currently logged-in user's own record.
| Field | Details |
|---|---|
| N/A for GET |
Response
user (username, email, company_name, phone, etc.)
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.
| Field | Details |
|---|---|
| email (string | |
| optional) | |
| company_name (string | |
| optional) | |
| phone (string | |
| optional) | |
| shipping_address (string | |
| optional) | |
| billing_address (string | |
| optional) |
Response
user (updated username, email, company_name, phone, etc.)
Deletes a specific user account. Only the logged-in user can delete their own account.
| Field | Details |
|---|---|
| N/A for GET |
Response
(empty response with 204 status code)
Place a new order for either logged-in users or guests, including delivery details and order items.
| Field | Details |
|---|---|
| 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
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))
Retrieve all orders associated with the currently logged-in customer.
| Field | Details |
|---|---|
| N/A for GET |
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))
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.
| Field | Details |
|---|---|
| N/A for GET |
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))
Return the items from a previous order for quick reordering by the customer.
| Field | Details |
|---|---|
| N/A for GET |
Response
success, items (product_id, product_name, product_sku, quantity, unit_price, bulk_price, bulk_quantity)
Look up orders by phone number for guest tracking. Returns a slimmed-down list of recent orders.
| Field | Details |
|---|---|
| N/A for GET |
Response
list of orders (order_number, status, created_at, total_amount, delivery_name, item_count, tracking_number, carrier)
Create a customer account at checkout, converting a guest to a registered user. Links an existing order if provided.
| Field | Details |
|---|---|
| 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
success, message, user (id, username, email, first_name, last_name, company_name, phone, shipping_address, email_verified)
Creates a new product entry.
| Field | Details |
|---|---|
| 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
id, name, description, category_id, sku, unit_price, bulk_price, bulk_quantity, unit_size, brand, image_url
List all procurement products across all vendors. Can filter by category and include inactive products.
| Param | Details |
|---|---|
| all (string | |
| default '0') | |
| category (string | |
| optional) |
Response
id, vendor_id, name, category, description, model_number, est_price_min, est_price_max, lead_time_days, notes, active
Update an existing procurement product. Requires admin or manager staff role.
| Field | Details |
|---|---|
| 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
id, vendor_id, name, category, description, model_number, est_price_min, est_price_max, lead_time_days, notes, active
Delete a procurement product. Requires admin or manager staff role.
| Field | Details |
|---|---|
| N/A for GET |
Response
success
List all products for a specific vendor. Can include inactive products with a query parameter.
| Param | Details |
|---|---|
| all (string | |
| default '0') |
Response
id, vendor_id, name, category, description, model_number, est_price_min, est_price_max, lead_time_days, notes, active
Add a new product to a specified vendor. Requires admin or manager staff role.
| Field | Details |
|---|---|
| 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
id, vendor_id, name, category, description, model_number, est_price_min, est_price_max, lead_time_days, notes, active
Returns a paginated list of products, with optional filtering by category and search terms.
| Param | Details |
|---|---|
| category_id (int | |
| optional) | |
| search (string | |
| optional) | |
| page (int | |
| 1) | |
| per_page (int | |
| 100) | |
| category (string | |
| optional) |
| Field | Details |
|---|---|
| N/A for GET |
Response
products (list of id, name, sku, brand, unit_price, bulk_price, bulk_quantity, unit_size, in_stock), total, pages, current_page, per_page
Returns details for a single product identified by its ID.
| Field | Details |
|---|---|
| N/A for GET |
Response
id, name, description, category_id, sku, unit_price, bulk_price, bulk_quantity, unit_size, brand, image_url, in_stock
Serves a compressed and resized JPEG thumbnail for a product's primary image.
| Field | Details |
|---|---|
| N/A for GET |
Response
image/jpeg (binary data)
Returns a limited list of featured products that are in stock, ordered by most recently updated.
| Field | Details |
|---|---|
| N/A for GET |
Response
list of id, name, sku, brand, unit_price, bulk_price, bulk_quantity, unit_size, in_stock
Returns details for a single product identified by its SKU.
| Field | Details |
|---|---|
| N/A for GET |
Response
id, name, description, category_id, sku, unit_price, bulk_price, bulk_quantity, unit_size, brand, image_url, in_stock
List all products with optional filtering.
| Param | Details |
|---|---|
| category_id (int | |
| none) | |
| search (str | |
| '') | |
| in_stock (bool | |
| none) | |
| page (int | |
| 1) | |
| per_page (int | |
| 50) |
| Field | Details |
|---|---|
| N/A for GET |
Response
total, page, per_page, pages, products
Get a single product by ID (integer) or SKU (string).
| Field | Details |
|---|---|
| N/A for GET |
Response
product, error
Full or partial update of any product fields.
| Field | Details |
|---|---|
| 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
success, product, error
Upload a product image (multipart/form-data).
| Field | Details |
|---|---|
| image (file | |
| required) |
Response
success, image_url, product, error
Update inventory/stock status for a product.
| Field | Details |
|---|---|
| in_stock (bool | |
| required) |
Response
success, product, error
Update pricing for a product.
| Field | Details |
|---|---|
| unit_price (float | |
| required) | |
| bulk_price (float | |
| optional) | |
| bulk_quantity (int | |
| optional) |
Response
success, product, error
Bulk update multiple products in a single request.
| Field | Details |
|---|---|
| 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
success, updated_count, skipped_count, error_count, updated, skipped, errors
Retrieves a list of all product categories, ordered by name.
| Field | Details |
|---|---|
| N/A for GET |
Response
varies
Adds a new product category to the system.
| Field | Details |
|---|---|
| name (string | |
| required) | |
| description (string | |
| optional) |
Response
success, category
Serve the check front image for staff review. Requires staff auth.
| Field | Details |
|---|---|
| N/A for GET |
Response
varies
Staff approves a check payment and confirms the order. Requires staff auth (JWT or session).
| Field | Details |
|---|---|
| N/A for POST |
Response
success, message
Serve the check back image for staff review. Requires staff auth.
| Field | Details |
|---|---|
| N/A for GET |
Response
varies
Staff rejects a check payment — resets order to pending so Pay options reappear.
| Field | Details |
|---|---|
| N/A for POST |
Response
success, message
Retrieve a paginated list of customers with optional search, sorting, and filtering.
| Param | Details |
|---|---|
| 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') |
| Field | Details |
|---|---|
| N/A for GET |
Response
customers (list of customer objects), total, page, per_page, pages
Retrieve details for a single customer by ID.
| Field | Details |
|---|---|
| N/A for GET |
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
Update details for a single customer by ID. Allows partial updates.
| Field | Details |
|---|---|
| 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
success, id, username, first_name, last_name, email, company_name, phone, phone2, shipping_address, billing_address, preferred_language, do_not_call
Permanently delete a customer account. Associated orders are preserved but unlinked.
| Field | Details |
|---|---|
| N/A for GET |
Response
success, deleted_id
Return all orders linked to a customer by user_id, sorted newest-first with full item details.
| Field | Details |
|---|---|
| N/A for GET |
Response
orders, total
Delete multiple customers at once.
| Field | Details |
|---|---|
| ids (array of integers | |
| required) |
Response
success, deleted
Return a blank CSV template with the correct headers.
| Field | Details |
|---|---|
| N/A for GET |
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
Find customers sharing the same primary phone number. Returns groups of customers with matching phones.
| Field | Details |
|---|---|
| N/A for GET |
Response
duplicate_groups, total_groups
Download all customers as a CSV file.
| Field | Details |
|---|---|
| N/A for GET |
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
Bulk-import customers from a CSV file. Deduplication by email or phone. Creates new customers or skips existing ones.
| Field | Details |
|---|---|
| file (file | |
| required) - CSV file containing customer data |
Response
success, total_rows, created, skipped, errors
Full merge of two customer accounts. Transfers orders and allows choosing fields for the kept customer.
| Field | Details |
|---|---|
| keep_id (integer | |
| required) | |
| merge_id (integer | |
| required) | |
| chosen (object | |
| optional) - fields to override (first_name | |
| last_name | |
| company_name | |
| email) |
Response
success, kept_id, merged_id, orders_moved, combined_order_count, combined_total_spent, kept_customer
Search for customers by name, company, or phone for autofill purposes. Includes both registered users and guest order history.
| Param | Details |
|---|---|
| q (string | |
| required) |
| Field | Details |
|---|---|
| N/A for GET |
Response
list of customers (id, source, name, first_name, last_name, full_name, username, company, company_name, phone, email, shipping_address, address, city, state, zip)
Allows staff users to request a password reset link. It sends an email with a reset token if the account exists.
| Field | Details |
|---|---|
| identifier (string | |
| required) |
Response
message, email_sent, debug_token
Allows staff users to recover their username. It sends an email containing the username if the email is registered.
| Field | Details |
|---|---|
| email (string | |
| required) |
Response
message, email_sent, debug_username
Retrieve a paginated list of inventory items with optional search and filtering.
| Param | Details |
|---|---|
| page (integer | |
| optional | |
| default 1) | |
| per_page (integer | |
| optional | |
| default 50) | |
| search (string | |
| optional) | |
| category (string | |
| optional) | |
| in_stock (boolean | |
| optional) |
| Field | Details |
|---|---|
| N/A for GET |
Response
products (list of product objects), total, page, per_page, pages
Update details for a specific product in the inventory, including stock levels and pricing.
| Field | Details |
|---|---|
| in_stock (boolean | |
| optional) | |
| unit_price (float | |
| optional) | |
| bulk_price (float | |
| optional) | |
| stock_quantity (integer | |
| optional) |
Response
success, product (id, name, sku, brand, unit_size, in_stock, unit_price, bulk_price, stock_quantity)
Authenticate staff users and issue a JWT token for cross-domain authentication.
| Field | Details |
|---|---|
| username (string | |
| required) | |
| password (string | |
| required) |
Response
success, staff (id, username, email, first_name, last_name, role), token
Log out the current staff user by clearing their session.
Response
success
Retrieve the profile information of the currently authenticated staff user.
| Field | Details |
|---|---|
| N/A for GET |
Response
staff (id, username, email, first_name, last_name, role)
Retrieve a list of all orders, with optional filtering by status, date range, and sales rep. Sales reps only see their own orders.
| Param | Details |
|---|---|
| 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) |
| Field | Details |
|---|---|
| N/A for GET |
Response
orders (list of orders), total, page, pages
Manually create a new order from the staff portal. Allows for custom order details and customer upsertion.
| Field | Details |
|---|---|
| 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
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 an order. This action is restricted to admin and manager roles.
| Field | Details |
|---|---|
| N/A for DELETE |
Response
success
Update the delivery address details for a specific order. Returns the updated order and a list of fields that were changed.
| Field | Details |
|---|---|
| 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
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)
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.
| Field | Details |
|---|---|
| amount (float | |
| required) |
Response
success, credit_applied, new_order_total, credit_balance, transaction
Manually mark an order as paid. Requires admin, manager, or staff role. Handles overpayments by crediting the customer's account.
| Field | Details |
|---|---|
| payment_method (string | |
| optional | |
| default 'cash') | |
| note (string | |
| optional) | |
| amount_received (float | |
| optional | |
| default 0) |
Response
success, order (id, payment_status, payment_method, staff_notes), overpayment_credited
Update staff notes, assigned staff, and tracking number for an order. Automatically updates order status to 'shipped' if a tracking number is added.
| Field | Details |
|---|---|
| staff_notes (string | |
| optional) | |
| assigned_to (string | |
| optional) | |
| tracking_number (string | |
| optional) |
Response
success, order (id, staff_notes, assigned_to, tracking_number, status, shipped_at)
Update the status of a specific order. Handles stock deduction/restoration and Stripe refunds for cancellations.
| Field | Details |
|---|---|
| status (string | |
| required) | |
| staff_notes (string | |
| optional) | |
| assigned_to (string | |
| optional) |
Response
success, order (id, order_number, status, payment_status, staff_notes, assigned_to, items), refund (refund_id, amount, status, error) (optional, for cancellations)
Retrieves a paginated list of all products for admin, including inactive ones, with optional filtering by category and search terms.
| Param | Details |
|---|---|
| category_id (int | |
| optional) | |
| search (string | |
| optional) | |
| page (int | |
| default 1) | |
| per_page (int | |
| default 50) |
| Field | Details |
|---|---|
| N/A for GET |
Response
products, total, pages, current_page, per_page
Adds a new product to the system. Only admins and managers can add products.
| Field | Details |
|---|---|
| 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
success, product
Updates an existing product's details. Only admins and managers can update products.
| Field | Details |
|---|---|
| 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
success, product
Deletes a product from the system. Only admins and managers can delete products.
| Field | Details |
|---|---|
| N/A for GET |
Response
success, message
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).
| Field | Details |
|---|---|
| image (file | |
| required) |
Response
success, image_url, product
Remove the image from a product.
| Field | Details |
|---|---|
| N/A for GET |
Response
success, product
Retrieves all gallery images for a specific product.
| Field | Details |
|---|---|
| N/A for GET |
Response
images
Uploads an additional image to a product's gallery. Stores the image as a base64 data URL.
| Field | Details |
|---|---|
| image (file | |
| required) |
Response
success, image, product
Removes a specific image from a product's gallery.
| Field | Details |
|---|---|
| N/A for GET |
Response
success, product
Sets a gallery image as the primary display image for a product.
| Field | Details |
|---|---|
| N/A for GET |
Response
success, product
Updates the sort order for all images in a product's gallery.
| Field | Details |
|---|---|
| order (array of int | |
| required) |
Response
success, product
Saves multiple product edits in a single request. Returns a summary of saved and errored products.
| Field | Details |
|---|---|
| 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
saved, errors
Pre-upload an image before the product record exists. Returns a base64 data URL that the caller includes in the create-product payload.
| Field | Details |
|---|---|
| image (file | |
| required) |
Response
success, image_url
Returns the profile information of the currently logged-in staff member.
| Field | Details |
|---|---|
| N/A for GET |
Response
id, username, email, full_name, first_name, last_name, role, is_active, created_at, updated_at
Allows a logged-in staff member to change their own password.
| Field | Details |
|---|---|
| current_password (string | |
| required) | |
| new_password (string | |
| required) | |
| confirm_password (string | |
| required) |
Response
message
Allows a logged-in staff member to update their own email address.
| Field | Details |
|---|---|
| new_email (string | |
| required) |
Response
success, email
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.
| Param | Details |
|---|---|
| period (int | |
| default: 6) |
| Field | Details |
|---|---|
| N/A for GET |
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)
Resets the password for a staff user using a valid reset token. The new password must be at least 6 characters long.
| Field | Details |
|---|---|
| token (string | |
| required) | |
| password (string | |
| required) |
Response
message, error
Perform a synchronous SMTP connection test to debug configuration issues. Returns exact error messages.
Response
success, ehlo, starttls, login, error, error_type, smtp_user, smtp_pass_len
Retrieve dashboard statistics for the staff portal, including order counts and total revenue. Supports various date ranges.
| Param | Details |
|---|---|
| range (string | |
| optional | |
| default 'all' | |
| options: '7d' | |
| '30d' | |
| 'month' | |
| 'all') |
| Field | Details |
|---|---|
| N/A for GET |
Response
total_orders, pending, confirmed, packed, shipped, delivered, cancelled, total_revenue, needs_attention
List all subscriptions with optional filters.
| Param | Details |
|---|---|
| status (string | |
| optional) | |
| user_id (int | |
| optional) |
| Field | Details |
|---|---|
| N/A for GET |
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)
Enroll a customer in a subscription.
| Field | Details |
|---|---|
| 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
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 a single subscription with full renewal history and customer order history.
| Field | Details |
|---|---|
| N/A for GET |
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)
Update interval, quantity, discount, notes, next_renewal_date, and delivery information for a subscription.
| Field | Details |
|---|---|
| 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
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)
Cancel a subscription.
| Field | Details |
|---|---|
| N/A for POST |
Response
success (boolean), status (string)
Pause a subscription.
| Field | Details |
|---|---|
| N/A for POST |
Response
success (boolean), status (string)
Manually trigger a renewal for a subscription (charge + create order).
| Field | Details |
|---|---|
| N/A for POST |
Response
success (boolean), renewal (object), next_renewal_date (ISO string)
Resume a paused subscription.
| Field | Details |
|---|---|
| N/A for POST |
Response
success (boolean), status (string), next_renewal_date (ISO string)
Internal cron endpoint to process all due renewals.
| Field | Details |
|---|---|
| N/A for POST |
Response
processed (int), results (list of objects with subscription_id, status, order or error)
Create a Stripe SetupIntent so the frontend can collect and save a card or ACH payment method for a customer.
| Field | Details |
|---|---|
| user_id (int | |
| optional) | |
| customer_email (string | |
| optional) | |
| customer_name (string | |
| optional) | |
| payment_type (string | |
| required | |
| 'card' or 'ach') |
Response
client_secret, stripe_customer_id, setup_intent_id
Analyze product order history and suggest a renewal interval.
| Param | Details |
|---|---|
| sku (string | |
| optional) |
| Field | Details |
|---|---|
| N/A for GET |
Response
order_count, order_dates, avg_interval_days, suggested_interval_days, last_order_date, confidence
Send a test email to verify SMTP configuration. Reports SMTP configuration status.
| Field | Details |
|---|---|
| to (string | |
| optional | |
| default SMTP_USER) |
Response
success, queued, config (SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASSWORD, sending_to), message
Lists all staff users in the system.
| Field | Details |
|---|---|
| N/A for GET |
Response
id, username, email, full_name, first_name, last_name, role, is_active, created_at, updated_at
Creates a new staff user with the provided details.
| Field | Details |
|---|---|
| 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
id, username, email, full_name, first_name, last_name, role, is_active, created_at, updated_at
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.
| Param | Details |
|---|---|
| page (int | |
| 1) | |
| per_page (int | |
| 50) | |
| search (str | |
| none) |
| Field | Details |
|---|---|
| N/A for GET |
Response
users, total, page, per_page, pages
Updates an existing staff user's details by ID.
| Field | Details |
|---|---|
| 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
id, username, email, full_name, first_name, last_name, role, is_active, created_at, updated_at
Deletes a staff user by ID. An admin cannot delete their own account.
| Field | Details |
|---|---|
| N/A for GET |
Response
message
Return the user's current credit balance and full transaction history.
| Field | Details |
|---|---|
| N/A for GET |
Response
user_id, username, company_name, credit_balance, history
Manually issue, adjust, or deduct store credit for a user. Amount can be negative to deduct credit.
| Field | Details |
|---|---|
| amount (float | |
| required) | |
| note (string | |
| optional) |
Response
success, credit_balance, transaction
Returns all products grouped by category, optimized for the sales catalog view with slim product details.
| Field | Details |
|---|---|
| N/A for GET |
Response
id, name, products (list of id, name, sku, unit_price, bulk_price, bulk_quantity, brand, unit_size, in_stock)
Returns customers with phone numbers, sorted by last order date (oldest first).
| Param | Details |
|---|---|
| page (int | |
| 1) | |
| per_page (int | |
| 100) | |
| search (str | |
| '') |
| Field | Details |
|---|---|
| N/A for GET |
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
Return calling list entries with pagination (prospects + registered customers).
| Param | Details |
|---|---|
| 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) |
| Field | Details |
|---|---|
| N/A for GET |
Response
varies (list of dicts)
Add a single prospect to the calling list.
| Field | Details |
|---|---|
| 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
success, entry (dict)
Update a calling list entry.
| Field | Details |
|---|---|
| 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
success, entry (dict)
Update a calling list entry.
| Field | Details |
|---|---|
| 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
success, entry (dict)
Delete a calling list entry.
Response
success
One-time backfill (safe to re-run).
Response
linked, already_linked, no_match, total, message
Assign a list of entry IDs to a specific staff user (or unassign if assignee_id is null).
| Field | Details |
|---|---|
| ids (list | |
| optional) | |
| assignee_id (int | |
| optional) |
Response
success, updated
Batch-update last_called for a list of entry IDs in a single request.
| Field | Details |
|---|---|
| ids (list | |
| optional) |
Response
success, updated
Return distinct product SKUs and names ever purchased, for the call list filter.
| Field | Details |
|---|---|
| N/A for GET |
Response
products (list of dicts with sku, name, purchase_count)
Admin/manager endpoint: recalculate and persist decayed scores for all non-DNC entries.
Response
success, updated, total
Trigger a score event for a calling list entry matched by phone or email.
| Field | Details |
|---|---|
| phone (str | |
| optional) | |
| email (str | |
| optional) | |
| event (str | |
| optional) |
Response
success, id, new_score, reason
Return counts for each segment tab + todays KPI stats for the logged-in rep.
| Field | Details |
|---|---|
| N/A for GET |
Response
segments (dict with priority, window, lapsed, called, all), kpi (dict with calls_today, orders_placed, revenue_today, conversion)
Return all active sales_rep and admin staff for the assign dropdown.
| Field | Details |
|---|---|
| N/A for GET |
Response
varies (list of dicts with id, full_name, username, role)
Bulk-upload prospects from CSV.
| Field | Details |
|---|---|
| file (file | |
| required) |
Response
success, created, skipped, dupes, errors (list)
Toggle commission_paid on a single order.
| Field | Details |
|---|---|
| paid (bool | |
| optional) |
Response
success, order_number, commission_paid, commission_paid_at, commission_amount
Mark multiple orders commission as paid or unpaid at once.
| Field | Details |
|---|---|
| order_numbers (list | |
| optional) | |
| paid (bool | |
| optional) |
Response
success, updated, paid
Return the ACH info on file for a customer (masked account number).
| Field | Details |
|---|---|
| N/A for GET |
Response
customer_id, has_ach, ach_bank_name, ach_account_name, ach_routing_number, ach_account_number_masked, ach_account_type, ach_authorized_at
Save or update ACH bank info for a customer.
| Field | Details |
|---|---|
| bank_name (str | |
| optional) | |
| account_name (str | |
| optional) | |
| routing_number (str | |
| required) | |
| account_number (str | |
| required) | |
| account_type (str | |
| optional) |
Response
success, has_ach, ach_bank_name, ach_account_name, ach_routing_number, ach_account_number_masked, ach_account_type, ach_authorized_at
Returns full customer profile with order stats and recent order history.
| Field | Details |
|---|---|
| N/A for GET |
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)
Update a customer's profile fields.
| Field | Details |
|---|---|
| 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
success, id, first_name, last_name, full_name, company_name, email, phone, phone2, shipping_address, billing_address, preferred_language, updated_orders
Returns profile and order history for a guest customer looked up by phone number.
| Param | Details |
|---|---|
| phone (str | |
| '') |
| Field | Details |
|---|---|
| N/A for GET |
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)
Full past-sales history for the logged-in rep (or all reps for admin/manager).
| Param | Details |
|---|---|
| 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) |
| Field | Details |
|---|---|
| N/A for GET |
Response
varies (csv file or json with group_by, groups, total_orders, total_revenue or json with page, per_page, total, pages, summary, orders)
Poll the status of an async import job.
| Field | Details |
|---|---|
| N/A for GET |
Response
varies (job dict)
Return a sample CSV template for the import feature.
| Field | Details |
|---|---|
| N/A for GET |
Response
varies (csv file)
Bulk-import historical orders from a CSV upload (async background job).
| Field | Details |
|---|---|
| file (file | |
| required) |
Response
success, job_id, message
Returns the logged-in reps attributed orders and summary stats.
| Param | Details |
|---|---|
| days (int | |
| 30) |
| Field | Details |
|---|---|
| N/A for GET |
Response
rep (dict with id, name, role), period_days, period_orders, period_revenue, all_time_orders, all_time_revenue, orders (list of dicts)
Allow a sales rep to cancel their own order if it is still pending or confirmed.
Response
success, order_id, order_number, status
Returns a full performance breakdown for all sales reps (or a single rep).
| Param | Details |
|---|---|
| rep_id (int | |
| None) | |
| days (int | |
| 90) | |
| period (str | |
| 'month') |
| Field | Details |
|---|---|
| N/A for GET |
Response
period_days, period_label, team_revenue, team_orders, reps (list of dicts)
Place an order on behalf of a customer, attributed to the logged-in sales rep.
| Field | Details |
|---|---|
| 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
success, order (dict)
Returns the current call script.
| Field | Details |
|---|---|
| N/A for GET |
Response
content, updated_by, updated_at
Admin/manager: update the call script.
| Field | Details |
|---|---|
| content (str | |
| required) |
Response
success, message
Assign or reassign an order to a sales representative. Restricted to admin and manager roles.
| Field | Details |
|---|---|
| sales_rep_id (integer | |
| required) |
Response
success, order (id, sales_rep_id)
Returns a list of staff users with the 'sales_rep' role.
| Field | Details |
|---|---|
| N/A for GET |
Response
id, username, full_name
Retrieves a list of all existing box recommendation rules.
| Field | Details |
|---|---|
| N/A for GET |
Response
box_recommendations
Creates a new box recommendation rule.
| Field | Details |
|---|---|
| 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
success, box_recommendation
Updates an existing box recommendation rule by its ID.
| Field | Details |
|---|---|
| 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
success, box_recommendation
Deletes a box recommendation rule by its ID.
| Field | Details |
|---|---|
| N/A for DELETE |
Response
success
Suggests box recommendations for products in a given order.
| Field | Details |
|---|---|
| items (list of dicts | |
| each dict has product_id (int | |
| required) | |
| quantity (int | |
| required)) |
Response
rules
Searches for products based on a query string for use in box recommendations.
| Param | Details |
|---|---|
| q (string | |
| default: '') | |
| limit (int | |
| default: 20) |
| Field | Details |
|---|---|
| N/A for GET |
Response
products
Triggers a Discord notification summarizing all orders that still need to be shipped. Protected by an internal secret header.
Response
success, message
Handles staff login, authenticating users and returning a JWT token and staff details upon successful login.
| Field | Details |
|---|---|
| username (string | |
| required) | |
| password (string | |
| required) |
Response
success, staff (id, username, role, is_active), token
Logs out the current staff user by clearing their session.
Response
success
Returns the details of the currently authenticated staff user.
| Field | Details |
|---|---|
| N/A for GET |
Response
id, username, role, is_active
Returns orders that need warehouse action, with filtering, searching, and sorting capabilities.
| Param | Details |
|---|---|
| status (string | |
| default: active) | |
| q (string | |
| default: '') | |
| sort (string | |
| default: created_at) | |
| dir (string | |
| default: asc) |
| Field | Details |
|---|---|
| N/A for GET |
Response
orders (list of order objects)
Returns a single order's details for shipping based on its order number.
| Field | Details |
|---|---|
| N/A for GET |
Response
order (order object)
Marks an order as confirmed, indicating it has been picked and is ready to ship.
Response
success, order (order object)
Marks an order as delivered.
Response
success, order (order object)
Purchases a shipping label for an order using EasyPost, saves label details, and updates the order.
| Field | Details |
|---|---|
| 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
label_url, tracking_num, carrier, service, rate, shipment_id, tracker_id, label_id
Returns all EasyPost labels purchased for a given order.
| Field | Details |
|---|---|
| N/A for GET |
Response
labels (list of label objects)
Hard-deletes a label record without an EasyPost refund (intended for admin use).
Response
success
Voids/refunds an EasyPost shipping label, deletes the label record, and removes its tracking number from the order.
Response
success, voided_tracking, ep_refund_status, ep_error, remaining_tracking
Returns packing slip data for a specific order, excluding pricing information.
| Field | Details |
|---|---|
| N/A for GET |
Response
slip (order object)
Marks an order as shipped, optionally recording tracking number and carrier, and sends an SMS notification.
| Field | Details |
|---|---|
| tracking_number (string | |
| optional) | |
| carrier (string | |
| optional) |
Response
success, order (order object)
Fetches live tracking status for an order from EasyPost, falling back to direct carrier tracking if necessary.
| Field | Details |
|---|---|
| N/A for GET |
Response
success, tracking_number, carrier, status, status_label, est_delivery_date, public_url, tracking_details (list of objects), last_updated
Provides quick counts for the dashboard header, including shipped today, in transit, and delivered in the last 7 days.
| Field | Details |
|---|---|
| N/A for GET |
Response
shipped_today, in_transit, delivered_7d
Retrieves a list of all invoices, optionally filtered by status. Requires staff authentication.
| Param | Details |
|---|---|
| status (string | |
| optional) |
| Field | Details |
|---|---|
| N/A for GET |
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
Creates a new invoice. Requires staff authentication.
| Field | Details |
|---|---|
| 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
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
Retrieves details for a single invoice by its ID. Requires staff authentication.
| Field | Details |
|---|---|
| N/A for GET |
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
Updates an existing invoice by its ID. Requires staff authentication.
| Field | Details |
|---|---|
| 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
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
Deletes an invoice by its ID. Requires staff authentication.
| Field | Details |
|---|---|
| N/A for GET |
Response
message (string)
Downloads the PDF for a specific invoice. Generates the PDF if it doesn't exist. Requires staff authentication.
| Field | Details |
|---|---|
| N/A for GET |
Response
file (application/pdf)
Searches for products to be used as line items in invoices. Requires staff authentication.
| Param | Details |
|---|---|
| q (string | |
| optional) |
| Field | Details |
|---|---|
| N/A for GET |
Response
id, name, sku, unit_price, bulk_price, unit_size, brand
Returns the order history (invoices) for a specific customer.
| Field | Details |
|---|---|
| N/A for GET |
Response
orders (list of dicts)
Returns aggregated performance data for the staff portal voice dashboard.
| Param | Details |
|---|---|
| agent_id (int | |
| optional) | |
| date_from (str | |
| optional | |
| default 30 days ago) | |
| date_to (str | |
| optional | |
| default today) | |
| granularity (str | |
| optional | |
| default daily) |
| Field | Details |
|---|---|
| N/A for GET |
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
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.
| Method | Header | Notes |
|---|---|---|
| API Key | X-API-Key: <key> | For n8n / automated callers |
| Staff session | Cookie | For staff portal manual logging |
| Field | Type | Required | Description |
|---|---|---|---|
phone | string | Yes | Customer phone number (E.164 format) |
outcome | string | Yes | sale_made | interested_callback | busy_callback | not_interested | no_answer | wrong_number | dnc_requested |
customer_name | string | No | Customer display name |
order_number | string | No | Order number if sale_made |
callback_date | string | No | ISO date for callback (YYYY-MM-DD) |
notes | string | No | Free-text call notes |
items_discussed | string | No | Products discussed during the call |
procurement_interest | boolean | No | true if customer expressed sourcing/procurement interest |
checker_verdict | string | No | pass or fail — verdict from the Checker sub-agent. If fail, a review queue entry is created automatically. |
checker_reasons | list[str] | No | Fail reasons from the Checker sub-agent (e.g. ["Promised discount not authorized"]). Only meaningful when checker_verdict=fail. |
transcript_url | string | No | URL to the stored call transcript. Attached to the review queue entry when checker_verdict=fail. |
Response
{
"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
}
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.
| Param | Type | Default | Description |
|---|---|---|---|
agent_id | integer | — | Filter to a specific ElevenLabs agent ID |
status | string | complete | Eval status: complete | reviewed | flagged |
limit | integer | 100 | Max results to return |
call_type | string | all | Filter by type: inbound_order | outbound_sales |
Response
{
"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"
}
]
}
Mark a call evaluation as reviewed and approved (no retraining needed).
Response
success, call_log_id, status
Mark a call as flagged for retraining.
| Field | Details |
|---|---|
| notes (str | |
| optional) |
Response
success, call_log_id, status
Cancel an order. Only pending or confirmed orders can be cancelled via voice.
| Field | Details |
|---|---|
| order_number (str | |
| required) | |
| phone_number (str | |
| optional) | |
| phone (str | |
| optional) | |
| confirmed (bool | |
| required) |
Response
success, order_number, message
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.
| Field | Details |
|---|---|
| phone_number (string | |
| required) |
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
Look up the status of an order by order number OR by phone number (returns most recent).
| Field | Details |
|---|---|
| order_number (str | |
| optional) | |
| phone_number (str | |
| optional) | |
| phone (str | |
| optional) |
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))
Temporary diagnostic: count users and phone numbers in DB.
| Field | Details |
|---|---|
| N/A for GET |
Response
success, total_users, users_with_phone, sample_phones, sample_usernames
Trigger or re-trigger LLM evaluation for a specific call.
| Field | Details |
|---|---|
| call_log_id (int | |
| required) | |
| async (bool | |
| optional | |
| default True) |
Response
success, message, call_log_id | success, call (varies)
Look up a registered customer by phone number.
| Field | Details |
|---|---|
| phone_number (str | |
| required) | |
| phone (str | |
| required) |
Response
success, found, customer (id, name, company, email, phone, payment_terms, approved_for_terms, recent_orders (order_number, status, total, date, item_count))
Outbound Sales Agent tool — retrieve a customer's full order history by phone.
| Field | Details |
|---|---|
| phone_number (str | |
| required) | |
| phone (str | |
| required) | |
| limit (int | |
| optional | |
| default 10 | |
| max 20) |
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
ElevenLabs tool webhook — look up a customer's past orders by phone number.
| Field | Details |
|---|---|
| phone (str | |
| required) | |
| phone_number (str | |
| required) | |
| limit (int | |
| optional | |
| default 5 | |
| max 20) | |
| status_filter (str | |
| optional | |
| default 'all') |
Response
success, customer_name, order_count, orders (order_number, date, status, payment_status, total, items, tracking_number), message
Search or list available products.
| Field | Details |
|---|---|
| query (str | |
| optional) | |
| category (str | |
| optional) | |
| in_stock_only (bool | |
| optional) |
Response
success, count, products (sku, name, brand, unit_size, unit_price, bulk_price, bulk_quantity, in_stock, stock_quantity)
Analyze worst-performing calls for an agent and suggest prompt improvements.
| Field | Details |
|---|---|
| min_calls (int | |
| optional | |
| default 10) | |
| score_threshold (float | |
| optional | |
| default 60.0) | |
| date_from (str | |
| optional) | |
| date_to (str | |
| optional) |
Response
analysis, suggested_system_prompt, changes_made, expected_improvement
Place a new order on behalf of a customer identified by phone number. Supports both registered customers and guest callers.
| Field | Details |
|---|---|
| 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
success, order_number, total, subtotal, items_placed, customer_type, payment_required, message
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).
| Field | Details |
|---|---|
| phone_number (string | |
| required) | |
| order_number (string | |
| required) | |
| payment_method (string | |
| required) |
Response
success, message, sms_type, payment_url, sms_body_preview
ElevenLabs tool webhook — submit a special/custom sourcing request. Creates an RFQ in the sourcing system and notifies the China team via Discord.
| Field | Details |
|---|---|
| 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
success, rfq_number, message
ElevenLabs webhook to log call details and optionally sync customer data to the staff portal. Triggered after a voice agent call is complete.
| Field | Details |
|---|---|
| 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
success
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.
| Method | Header / Cookie | Use Case |
|---|---|---|
| Staff JWT | Cookie: sessionorAuthorization: Bearer <token> | Staff portal UI |
| API Key | X-API-Key: <key> | n8n automation |
| Param | Type | Default | Description |
|---|---|---|---|
| min_days_since_order | int | 14 | Minimum days since last order to include customer |
| max_days_since_order | int | 180 | Maximum days since last order (excludes very old/inactive) |
| min_order_count | int | 1 | Minimum lifetime order count to include customer |
| cooldown_days | int | 10 | Days to suppress a customer after any call outcome |
| limit | int | 50 | Max results per page |
| page | int | 1 | Page number for pagination |
| sort | str | priority | Sort order:priority,days_desc,ltv_desc |
| credit_status | str | none | Filter 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. |
| Field | Type | Description |
|---|---|---|
| customer_id | int | User ID |
| phone | str | Customer phone number |
| customer_name | str | Full name |
| company_name | str | null | Business name |
| days_since_last_order | int | Days since most recent order |
| last_order_date | str | ISO date of last order |
| average_order_value | float | Average order total |
| lifetime_value | float | Sum of all order totals |
| order_count | int | Total number of orders |
| reorder_candidates | list[str] | Product names from last order likely to be reordered |
| top_categories | list[str] | Most frequently ordered product categories |
| suggested_upsells | list[str] | Products frequently bought by similar customers |
| talking_points | list[str] | Pre-built call script bullets (reorder prompt, LTV note, etc.) |
| credit_status | str | Credit standing: good | overdue | no_terms |
| priority_score | float | Computed priority: higher = call sooner |
| last_call | object | null | nullif never called. Otherwise:{date, outcome, callback_date, notes} |
Response
{
"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"
}
{
"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"
}
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.
| Method | Header | Notes |
|---|---|---|
| API Key | X-API-Key: <key> | n8n / automated callers only |
| Field | Type | Required | Description |
|---|---|---|---|
transcript | string | Yes* | Full transcript text. *Required if not sending a multipart file. |
call_id | string | No | ElevenLabs call ID — used in the storage key for traceability |
phone | string | No | Customer phone — used in the storage key |
| Field | Type | Description |
|---|---|---|
file | file | Transcript file (.txt or .json) |
call_id | string | Optional ElevenLabs call ID |
phone | string | Optional customer phone |
| Status | Condition |
|---|---|
| 401 | Missing or invalid API key |
| 400 | No transcript text or file provided |
| 503 | R2 environment variables not configured |
| 502 | R2 upload failed (boto3 error) |
Response
{
"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"
}