Getting started with the API
The OrderUp REST API is the same surface our own management and POS apps use, exposed for partners and integrators who need to read or write tenant data programmatically. This page is the orientation. The full route reference (auto-generated from our OpenAPI spec) follows in the sidebar.
Who this is for
Use the API if you're:
- An ISV building a value-added product on top of OrderUp data (custom reports, loyalty, KDS hardware, accounting sync).
- A franchisee corporate office consolidating data across multiple tenants.
- An internal IT team building automation around your own restaurants.
If you're a manager or staff member just running your restaurant, you don't need the API — the management app and POS cover the day-to-day. Stick to those.
Base URL
https://api.letsorderup.com
All API paths are versioned and prefixed:
https://api.letsorderup.com/api/v1/{resource}
For example, listing orders for a restaurant:
GET https://api.letsorderup.com/api/v1/restaurants/{restaurantGuid}/orders
A staging environment is available on request for partners actively building against us. Contact your integration manager for credentials and a separate base URL.
Versioning policy
The API is currently on v1. Our versioning rules:
- Major versions (
v1,v2) ship rarely and only for breaking changes. We'll publish a migration guide and run versions in parallel for at least 12 months before we sunset an old major. - Minor changes (additive: new fields, new optional parameters, new endpoints) ship continuously inside
v1. They're backward-compatible — clients should ignore unknown fields. - Deprecations are announced in this site's changelog and via email to registered API consumers at least 90 days before removal, with a
Deprecationresponse header pointing at the replacement.
Treat the API as semver: pin nothing, but tolerate additive changes.
Rate limits
Default rate limit:
- 100 requests per minute per authenticated identity (per user, per API key).
- Identified by user ID when you authenticate as a user, or by API key when you authenticate with a key.
Every response includes the rate-limit headers so you can pace yourself:
x-ratelimit-limit: 100
x-ratelimit-remaining: 87
x-ratelimit-reset: 1714150260
When you exceed the limit you'll get a 429 with this body:
{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests. Limit: 100 requests per 60 seconds",
"details": {
"limit": 100,
"remaining": 0,
"resetTime": "2026-04-26T18:11:00.000Z"
}
}
}
If your integration legitimately needs more headroom (bulk syncs, large multi-location operators), reach out — we can issue API keys with higher quotas.
Error envelope
Every error response — 4xx and 5xx — uses the same shape:
{
"success": false,
"error": {
"code": "RESOURCE_NOT_FOUND",
"message": "Order not found",
"correlationId": "01HXY7..."
},
"meta": {
"timestamp": "2026-04-26T18:09:13.412Z",
"correlationId": "01HXY7...",
"version": "1.0.0"
}
}
The code is a stable string you can branch on. The message is human-readable and may change between versions. The correlationId matches the same ID in our server logs — include it in any support ticket and we can find your exact request.
Common error codes:
| Code | HTTP | Meaning |
|---|---|---|
UNAUTHORIZED | 401 | Missing, expired, or invalid credentials. |
FORBIDDEN | 403 | Authenticated, but not allowed for this resource. |
RESOURCE_NOT_FOUND | 404 | The thing you asked for doesn't exist. |
VALIDATION_ERROR | 400 | Request body or query failed schema validation. The details field lists the offending fields. |
CONFLICT | 409 | The resource already exists, or a concurrent edit lost a race. |
RATE_LIMIT_EXCEEDED | 429 | Slow down. Wait until resetTime. |
INTERNAL_ERROR | 500 | Our problem. Retry with backoff; persistent issues should be reported with the correlationId. |
Successful responses
Successful responses generally follow:
{
"success": true,
"data": { /* the resource or collection */ },
"meta": {
"timestamp": "2026-04-26T18:09:13.412Z",
"correlationId": "01HXY7...",
"version": "1.0.0"
}
}
Some endpoints (especially streaming or download endpoints) return raw payloads — the OpenAPI spec is the canonical reference for any given route.
Idempotency
Mutating endpoints (POST, PATCH, PUT, DELETE) accept an optional Idempotency-Key header. Send a unique value (a UUID is fine) per logical operation. If a network glitch causes you to retry the same request with the same key, the server detects it and returns the result of the original call rather than duplicating the operation.
POST /api/v1/restaurants/{restaurantGuid}/orders
Idempotency-Key: 8d0dafa3-9d16-4f91-9b89-3bcd6d7e7c44
Content-Type: application/json
Keys are scoped to the authenticated identity and retained for 24 hours.
Pagination
Collection endpoints paginate with cursor-style:
GET /api/v1/restaurants/{restaurantGuid}/orders?limit=50&cursor=eyJpZCI6...
Responses include a nextCursor (or null when you've reached the end). Don't try to construct cursors yourself — they're opaque.
What's next
- Set up authentication: see Authentication.
- Browse the auto-generated route reference in the sidebar.
- Try the interactive API explorer (linked at the top of each route page).