API Reference
Base URL: https://dish-embed.latimal.com
Authentication
All endpoints except /health require an API key in the X-API-Key header:
curl -X POST https://dish-embed.latimal.com/embed \
-H "X-API-Key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"items": ["Chicken Biryani"]}'Keys are issued per-customer. Contact us to get yours.
Plans and rate limits
Access is sold as monthly plans. One HTTP request counts as one API call against your plan's monthly quota, no matter how many items it carries. Plans also set a per-second rate limit and gate which endpoints are available:
| Plan | API calls/mo | Rate limit | Endpoints |
|---|---|---|---|
| Starter | 10,000 | 20 req/sec | /search, /classify, /match |
| Pro | 100,000 | 60 req/sec | + /suggest, /report |
| Scale | 1,000,000 | 150 req/sec | + /dedup |
The Endpoints column lists what each tier adds over the one below it. The utility endpoints /embed, /embed/batch, /health, and /balance are available on every plan.
Every plan starts with a 14-day free trial. Reaching your monthly quota returns 402 with no overage billing. Bursting past your rate limit, or running too many requests at once, returns 429. See latimal.com/pricing for current rates.
Common patterns
- All endpoints accept and return JSON
- Per-item text limit: 500 characters
- All text is automatically preprocessed (noise removal, spelling normalization) before processing
- Embeddings are L2-normalized
Error codes
| Code | Meaning |
|---|---|
| 200 | Success |
| 400 | Bad request (malformed JSON, invalid parameters) |
| 401 | Missing or invalid API key |
| 402 | Monthly quota reached (no overage billing; upgrade or wait for the next cycle) |
| 422 | Validation error (item too long, exceeds max count, etc.) |
| 429 | Rate limit exceeded (your plan's per-second limit, or too many simultaneous in-flight requests) |
| 503 | Model not loaded or server starting up |
Latency (p50, production)
| Endpoint | Items | Latency |
|---|---|---|
| POST /embed | 100 | ~50ms |
| POST /embed/batch | 1000 | ~400ms |
| POST /search | 100 corpus | ~80ms |
| POST /match | 10 pairs | ~120ms |
| POST /dedup | 100 items | ~200ms |
| POST /classify | 100 items | ~60ms |
| POST /report | 500 items | ~1.5s |
| POST /suggest | 50 cart + 200 menu | ~150ms |
Endpoints
| Endpoint | Description | Plans |
|---|---|---|
| POST /embed | Generate embeddings for menu items | All plans |
| POST /embed/batch | Batch embedding for large catalogs (up to 5K items) | All plans |
| POST /match | Check if pairs of items are the same dish | All plans |
| POST /dedup | Find duplicate items in a menu | Scale |
| POST /classify | Classify items by cuisine | All plans |
| POST /search | Semantic menu search | All plans |
| POST /report | Full menu health report | Pro, Scale |
| POST /suggest | Cart upsell suggestions | Pro, Scale |
| GET /health | Server status check | All plans |
| GET /balance | Check remaining quota | All plans |
Authentication
Authenticate dish-embed API requests with the X-API-Key header. Covers key format, Python and curl examples, and 401 error responses for invalid keys.
POST /embed
POST /embed generates dense vector embeddings for up to 512 menu items per call. Supports 128, 256, and 384 dimensions with built-in noise stripping.