generated: '2026-08-09' method: searched source: https://www.nutrientsdb.com/api/docs + openapi/nutrientsdb-sample-api-openapi.yml + live response headers summary: >- Cross-cutting request/response semantics for the NutrientsDB Sample API, captured from the published docs page, the OpenAPI 3.1.0 definition, and live response headers. This is a deliberately small surface: one GET operation, no authentication, no write path, no pagination cursor, and no documented idempotency-key mechanism (none is needed — every operation is a safe GET). Read it as the contract for a read-only reference dataset, not a transactional API. authentication: styles: [] required: false see: authentication/nutrientsdb-authentication.yml transport: https_only: true hsts: true hsts_max_age: 63072000 http_methods: [GET, HEAD, OPTIONS] cors: enabled: true allow_origin: '*' allow_methods: GET, HEAD, OPTIONS allow_headers: Content-Type idempotency: idempotency_key_header: null documented: false safe_by_method: true notes: >- There is no Idempotency-Key header or parameter, and none is required: the API exposes a single GET operation with no side effects, so retries are safe by HTTP method semantics (RFC 9110 safe + idempotent). Agents may retry freely on transport failure. Do NOT read this as an idempotency-key contract — the provider ships no write path that would need one. pagination: style: limit-only cursor: false offset: false params: limit: default: 10 maximum: 20 behavior: Values above 20 are capped at 20 rather than rejected. response_fields: count: Number of foods returned in this response. total_matches: Total foods in the sample matching the query, which may exceed count. limit: The effective limit actually applied after capping. notes: >- There is no way to page past the first `limit` matches — no offset, cursor, or page parameter exists. total_matches tells a client how many it did not receive, not how to fetch them. For a 1,000-food sample this is a deliberate ceiling; the full dataset is licensed for local query. query_interfaces: - style: rest base_url: https://www.nutrientsdb.com/api operations: 1 notes: Single endpoint /api/foods; q and id are mutually exclusive selectors. filtering: search: param: q match: case-insensitive substring on food name min_length: 2 max_length: 100 exact_lookup: param: id match: exact public_id notes: Use instead of q, not alongside it. field_selection: supported: false notes: >- Every response carries all 86 nutrient keys on every food record. There is no sparse-fieldset or expansion parameter, so a caller wanting one nutrient still receives the full schema. Plan payload size accordingly — a 2-food search response is ~5.5 KB. data_semantics: basis: All nutrient values are per 100 g of the food. null_means: The source did not report that nutrient. It does not mean zero. stable_identifier: public_id see: vocabulary/nutrientsdb-nutrient-schema.yml metadata: sample_block: >- Every response — success AND error — carries a `sample` object with food_count and nutrient_count. Its presence is not a success signal; branch on the HTTP status instead. error_envelope: content_type: application/json rfc9457: false shape: '{sample: {...}, error: ""}' machine_readable_code: false see: errors/nutrientsdb-problem-types.yml caching: cache_control: public etag: true etag_form: weak conditional_requests: >- Weak ETags are returned on 200 responses, so If-None-Match revalidation is available to well-behaved clients. Observed served through Vercel's edge (x-vercel-cache header present). notes: 'No max-age directive is set — `cache-control: public` alone.' request_tracing: request_id_header: null notes: >- No first-party correlation id is returned. The upstream platform emits x-vercel-id, which is an infrastructure trace identifier, not a documented API contract — do not depend on it. rate_limiting: documented: false headers: [] observed: >- Ten rapid sequential requests all returned 200 with no 429 and no RateLimit-* or X-RateLimit-* headers. Absence of a published limit is not a guarantee of no limit — treat unbounded polling as unsupported. versioning: scheme: none-in-path current: 1.0.0 location: OpenAPI info.version only notes: >- The version appears in the OpenAPI document, not in the URL path, a header, or a date. There is no negotiation mechanism, so a breaking change would arrive unannounced at the same URL. see: lifecycle/nutrientsdb-lifecycle.yml cross_links: authentication: authentication/nutrientsdb-authentication.yml errors: errors/nutrientsdb-problem-types.yml lifecycle: lifecycle/nutrientsdb-lifecycle.yml vocabulary: vocabulary/nutrientsdb-nutrient-schema.yml examples: examples/_index.yml x-evidence: fetched: '2026-08-09' probes: - url: https://www.nutrientsdb.com/api/docs http_status: 200 - url: https://www.nutrientsdb.com/api/foods?id=2923506 http_status: 200 note: Response headers captured for cache/ETag/CORS/HSTS findings. - url: https://www.nutrientsdb.com/api/foods?q=rice&limit=1 http_status: 200 note: Repeated 10x in rapid succession; no 429 and no rate-limit headers observed.