FLOW Catalog API (1.0.0)
Product catalog, catalog assignment by location, and storefront catalog endpoints for FLOW.
FLOW is the catalog ordering platform that Alfred Williams & Company (AWC) runs for Novant Health. This document describes the catalog part of the FLOW HTTP API: products and items, catalogs and their published versions, product images, bulk import, which catalog each location gets, and the read-only storefront catalog.
| Environment | Base URL | Use |
|---|---|---|
| Production | https://awcflow-prod.pages.dev | Live data. |
| Development | https://awcflow.pages.dev | Integration testing. Data is a copy and may be reset. |
All paths in this document are relative to the base URL. Use HTTPS only.
FLOW has two kinds of API caller. Both authenticate with cookies. There is no API-key or OAuth client-credentials flow yet. An integration account for a partner system is set up on request.
Every endpoint that is not under /api/public-store needs a staff session and a persona.
- Sign in.
POST /api/auth/sign-in/emailwith the email and password AWC issued to you. The response sets the session cookie__Secure-flow_app.session_token. - Load your persona.
POST /api/persona/autowith the session cookie. The response sets the signedff_personacookie. Your persona decides which capabilities you have. - Call the API. Send both cookies on every request.
Server-to-server clients must keep the cookies (a cookie jar) and send an Origin header set to the base URL on the sign-in request.
A request with no session gets a 302 redirect to /login, not a 401. Treat a 302 from any /api/* path as "session expired, sign in again". A request with a session whose persona lacks the needed capability gets a 403 with required set to the missing capability.
/api/public-store/{storeKey}/* endpoints that read the catalog, store configuration or prices need no authentication. Endpoints that submit data on behalf of a buyer need a storefront session, obtained with POST /api/store-auth/sign-in/email (cookie __Secure-flow_store.session_token).
| Capability | Grants | Personas that hold it |
|---|---|---|
manage_catalog | Read and change products, catalogs, images, location assignment. | Catalog, Account, Pricing, Admin |
modify_pricing | See cost prices and change any price field. | Pricing, Admin |
create_quote | Read the catalog a location is entitled to. | All personas |
view_admin_settings | Create locations; approve catalog publishes. | Admin |
Price fields need modify_pricing. A write that includes a list, cost or sell price from a persona without modify_pricing is refused with 403 and the fields (or skus) that caused it. Reads from such a persona leave the cost fields out of the response; the key is absent, not null.
- Format. Request and response bodies are JSON (
application/json) unless an operation saysmultipart/form-data(file uploads) or returns a file. - Errors. Every error body has an
errorstring. Some addcode,issues,fields,skusorblockers. See theErrorschema. - Status codes.
200read or update,201created,202accepted for approval,400invalid input,403missing capability or price permission,404not found,409conflict (duplicate name or SKU, still in use),413upload too large,429rate limited,500server error,503dependency unavailable. - Pagination. List endpoints take
page(1-based) andpageSizeand returntotal(andtotalPageswhere shown). Limits are given on each parameter. - Identifiers. Products have a string
id(32 hex characters or a UUID) and a uniquesku. Catalogs and locations have integer ids. Catalog versions have UUID string ids. - Money. Prices are numbers in US dollars.
listPriceis the manufacturer list price;sellPrice/unitPriceis the contract price for a catalog or location. - Images. Image URLs are paths on the same host (for example
/api/images/catalog-assets/…). Prefix them with the base URL./api/images/*needs no authentication. - Request tracing. Every response carries
x-request-id. Send your ownx-request-idto correlate logs; quote it when you report a problem. - CORS. The API does not send CORS headers. Call it from a server, not from a browser on another origin.
| Scope | Limit |
|---|---|
Sign-in (/api/auth/*, /api/store-auth/*) | 10 requests per minute per IP |
| Storefront pricing | 60 requests per minute per IP |
| Storefront writes (suggestions) | 30 requests per minute per IP |
Over the limit, the response is 429 with a retry-after header in seconds.
| Task | Endpoint |
|---|---|
| Get the products and contract prices a site (location) can order | GET /api/catalog/for-location/{locationId} |
| Get the full, unpaginated assortment of a location's published catalog | GET /api/locations/{locationId}/catalog |
| Find a location id from a name, city or ZIP | GET /api/catalog/locations |
| Get one product's full detail | GET /api/catalog/{sku} |
| Poll for catalog changes | GET /api/catalog/changes |
| Price a basket for a storefront | POST /api/public-store/{storeKey}/pricing |