REST API
Every MealCP capability is a plain HTTPS GET that returns JSON - there are
no SDKs to install, webhooks to receive, or request bodies to sign. Point any
HTTP client at https://api.mealcp.com, send your API key in a header, and
read the response. This page covers the conventions shared by all endpoints:
authentication, the error envelope, pagination, and credit costs. The
endpoint-specific pages (search, prices,
taxonomy) document inputs and outputs in full.
Base URL: https://api.mealcp.com
A typical integration
Section titled “A typical integration”- Discover the scope once:
GET /v1/coveragelists countries, retailers, and catalogue sizes;GET /v1/categoriesandGET /v1/tagsgive you the filter vocabulary. All three are free and public. - Search per user query or on a schedule with
GET /v1/search- filters in, normalized product records out. - Drill into a product with
GET /v1/prices/{id}using theidfrom a hit, to show trend, volatility, or the raw observation log. - Check your balance with
GET /v1/mebefore long batch runs, so a job never dies halfway through a sweep.
Authentication
Section titled “Authentication”Authenticated endpoints expect your API key in the X-API-Key header:
curl -H "X-API-Key: $MEALCP_API_KEY" \ "https://api.mealcp.com/v1/search?q=hapanjuurileip%C3%A4&country=FI"Missing or invalid keys get a 401:
{ "error": { "code": "unauthorized", "message": "missing X-API-Key header" }}The key travels on every call to the search, product, price, and me
endpoints; the taxonomy and coverage endpoints are public and need none.
Treat the key as a server-side secret - anything shipped to a browser or a
mobile bundle can be extracted, so proxy requests through your backend
instead. Check your key and live credit balance any time with
GET /v1/me.
Endpoints
Section titled “Endpoints”| Endpoint | Auth | Description |
|---|---|---|
GET /v1/search |
key | Keyword search with faceted filtering |
GET /v1/products/{id} |
key | One product by id |
GET /v1/prices/{id} |
key | Aggregated price-history stats |
GET /v1/prices/{id}/observations |
key | Raw price observations |
GET /v1/categories |
- | Category tree (flat rows) |
GET /v1/tags |
- | Canonical tag vocabulary |
GET /v1/me |
key | Your identity, cap, and credit balance |
GET /v1/coverage |
- | Per-country catalogue coverage |
Product ids are opaque (rp_ + 32 hex chars). Take them verbatim from a
search hit - never construct them yourself.
Error handling
Section titled “Error handling”Every non-2xx response uses the same envelope, so one error handler covers the whole API. Match on the HTTP status:
| Status | Meaning | Client action |
|---|---|---|
401 |
Missing/invalid key | Check the X-API-Key header; rotate if lost |
402 |
Credits exhausted | Wait for the window reset or request a higher cap |
422 |
Invalid params | Fix each field named in error.details[] |
429 |
Rate limit exceeded | Honor the Retry-After header (seconds) |
Two further cases: search can answer 503 while the search service restarts
(retry with backoff), and 400 flags semantically impossible parameters such
as a min_price above max_price. A handler that logs the status, reads
error.message, and retries only on 429/503 is enough for production.
The full semantics are listed in Credits & limits.
Pagination
Section titled “Pagination”List endpoints paginate with page (1-based) and page_size. The response
carries found - the total match count - so walk pages by incrementing
page until page * page_size >= found:
curl -H "X-API-Key: $MEALCP_API_KEY" \ "https://api.mealcp.com/v1/search?q=oat%20milk&page=2&page_size=100"Credits are charged per request, not per result: sweeping 10 pages of
results costs 10 credits regardless of page size. If a batch needs the full
result set, use the largest page_size (100 on search) to minimize the
request count, and prefer narrower filters over long walks - a query scoped
with country or category usually needs far fewer pages.
Conventions
Section titled “Conventions”- All responses are JSON, including errors.
- All endpoints are read-only
GETs, so failed calls are always safe to retry exactly as issued. - Query parameters do not change the cost - a
page_size=100search costs the same 1 credit aspage_size=1. - Timestamps are RFC 3339 UTC (
latest_observed_at,window_resets_at); dates in price ranges are ISOYYYY-MM-DD. - Full machine-readable spec:
https://api.mealcp.com/openapi.json- generate a typed client from it instead of hand-writing request types.