Skip to main content
The Vori REST API lets grocers pull and manage data like store products programmatically. All requests go to https://api.vori.com.
Download the OpenAPI specification to generate a client in your language or load every endpoint into an API tool like Postman or Insomnia.

Authentication

Every API request must include a bearer token in the Authorization header. Authenticate with an API key: a long-lived credential you create and manage yourself, scoped to whatever roles you assign it.
There’s no token exchange and nothing to refresh — the key works as-is until you delete it.

Create a key

1

Open API clients

Go to app.vori.com/retail/api-keys. If you can’t access this page, contact Support to get access.
2

Create a client

Give it a name and assign the roles it needs. Roles determine which resources and actions the key can reach — the same role model used for user accounts.
3

Copy the secret immediately

The full secret (sk_live_...) is shown exactly once, at creation. Vori stores only a hash of it, so if you lose the secret, there’s no way to recover it — delete the key and create a new one.
If a key only needs to read data, assign it a Read-only role instead of a full-access one. This avoids errors from write attempts you didn’t anticipate needing, and limits the blast radius if the secret is mishandled.

Keys don’t expire

API keys have no built-in expiration or rotation. To replace a key, create a new one, migrate your integration to it, confirm the old key is no longer being used, then delete the old key.

Rate limits

Requests are rate-limited per API key. Each response includes headers describing your current standing:
  • X-RateLimit-Limit — the maximum number of requests allowed in the current window
  • X-RateLimit-Remaining — how many requests you have left in the current window
If you exceed the limit, you’ll receive a 429 response with a Retry-After header telling you how many seconds to wait before retrying.

Pagination

List endpoints use cursor-based pagination:
  • limit sets the page size. Each endpoint documents its own default and maximum.
  • starting_after and ending_before take the id of a record in the result set, and page forward or backward from it.
Results are always ordered by id descending. This order isn’t configurable per request. Responses use one envelope across all list endpoints:
has_more tells you whether another page is available.

Filtering

Filterable fields are real, typed query parameters — not a single opaque filter object. Which fields are filterable, and which operators they support, is documented per endpoint. The value types you’ll see: Range operators are [gt], [gte], [lt], and [lte]. Multiple parameters combine with AND; there’s no OR across different fields. Matching multiple values (IN) — repeat the key rather than passing a comma list:
Repeated values for the same key combine with OR. This only applies to identifier fields — repeating store_department_id narrows to any of those departments; boolean and timestamp fields take a single value. Each endpoint caps how many values you can repeat for a given key; exceeding the cap returns an error rather than silently truncating. Example: active products in a specific department, with inventory included: