generated: '2026-08-25' method: derived source: >- openapi/ documents in this repo + live response headers and error bodies observed against https://leafforlife.com/wp-json on 2026-08-25. note: >- Cross-cutting request/response semantics of the LEAF4Life content API. LEAF4Life publishes no API conventions documentation of its own; everything below is the WordPress REST contract as it is actually deployed here, derived from the route index and confirmed against live anonymous responses. Idempotency is deliberately NOT claimed — this deployment exposes no idempotency key, no request-deduplication contract and no anonymous write surface at all, so no `Idempotency` pointer is emitted in apis.yml. authentication: style: none detail: >- No credentials required for any catalogued operation. The route index advertises WordPress application passwords for the site's own editors; they are not obtainable by a third party. See authentication/leaf4life-authentication.yml. idempotency: supported: false header: null detail: >- No Idempotency-Key header, no client-supplied request identifier and no documented replay semantics. Every catalogued operation is a GET and therefore idempotent by HTTP method alone, which is not an idempotency contract. pagination: style: page-number params: page: Current page of the collection (1-based, default 1). per_page: Items per page. Minimum 1, maximum 100, default 10. offset: Absolute offset into the result set, as an alternative to page. response_headers: X-WP-Total: Total number of matching items. X-WP-TotalPages: Total number of pages available at the current per_page. link_header: >- RFC 8288 Link header carrying rel="next" and rel="prev". Observed verbatim on /wp/v2/pages?per_page=1 as ; rel="next". cors_exposure: >- Access-Control-Expose-Headers advertises "X-WP-Total, X-WP-TotalPages, Link", so a browser client can read the pagination headers cross-origin. bounds_error: >- per_page above 100 returns 400 rest_invalid_param with a per-parameter details block carrying the nested code rest_out_of_bounds — it is rejected, not clamped. field_selection: supported: true params: _fields: Comma-separated allow-list of top-level response fields. _embed: Inline embeddable resources (author, featured media, terms) under _embedded. _envelope: Wrap body, status and headers in a single JSON envelope. context: param: context values: [view, embed, edit] detail: >- Anonymously only `view` and `embed` return data. `edit` returns 401 rest_forbidden_context. sorting_and_filtering: order: asc | desc orderby: Per-collection enum — date, id, title, slug, modified, author, include, relevance, menu_order, parent. date_windows: after, before, modified_after, modified_before (ISO 8601). identity: include / exclude / slug / parent. full_text: >- search, with search_columns (post_title, post_content, post_excerpt) and search_semantics. Verified ineffective on this deployment — see the caveat under content_availability below. taxonomy: categories, categories_exclude, tags, tags_exclude, tax_relation (AND | OR). content_availability: caveat: >- THE CENTRAL LIMITATION OF THIS SURFACE, verified 2026-08-25. `content.rendered` and `excerpt.rendered` are the empty string on all 8 published pages. Every page uses the theme template `template-modular.php` and its body is assembled by a page builder that stores blocks in postmeta rather than in `post_content`. The API therefore returns page identity — id, slug, title.rendered, link, date, modified, template — and nothing else. As a direct consequence /wp/v2/search and ?search= return X-WP-Total: 0 for every site term, because WordPress searches post_content and post_content is empty. consequence_for_agents: >- An agent that needs LEAF4Life's science, pipeline or leadership narrative must fetch the HTML at the `link` field of each page and parse it. The API is a reliable index of what pages exist and when they changed; it is not a source of the text on them. metadata: field: meta detail: >- A `meta` object is present on page objects but carries only the WordPress core `footnotes` key. No custom or SEO metadata is exposed — this deployment registers no Yoast/RankMath REST fields, so there is no structured description, canonical URL or schema.org graph on the API surface. request_tracing: request_id_header: null detail: >- No provider request identifier and no correlation id. Cache and edge trace tokens (X-Nitro-Cache, x-nitro-rev, X-Webcom-Cache-Status, cf-edge-cache) are infrastructure signals, not application-level correlation ids. versioning: scheme: uri-path-namespace current: wp/v2 detail: >- The version is carried in the route namespace. Namespaces registered on 2026-08-25: oembed/1.0, akismet/v1, wp-super-cache/v1, wp/v2, wp-site-health/v1, wp-block-editor/v1, wp-abilities/v1. LEAF4Life does not version this surface itself; it moves when WordPress core and the installed plugins move. See lifecycle/leaf4life-lifecycle.yml. error_envelope: format: wordpress-rest rfc9457: false content_type: application/json shape: '{ code: string, message: string, data: { status: int, params?: object, details?: object } }' detail: >- Not RFC 9457 problem+json — no `type` URI, no title/detail split, no application/problem+json media type. See errors/leaf4life-problem-types.yml. rate_limiting: signaled: false headers: [] detail: >- No RateLimit-*, X-RateLimit-* or Retry-After headers were returned on any /wp-json response during this pass, and no limit is published. See rate-limits/leaf4life-rate-limits.yml. caching: cache_control: 'no-cache on /wp-json responses; page HTML is served from a NitroPack edge cache (X-Nitro-Cache: HIT)' headers_observed: [cf-edge-cache, X-Nitro-Cache, X-Nitro-Cache-From, x-nitro-rev, X-Webcom-Cache-Status, Vary] detail: >- API responses are explicitly uncached (Cache-Control: no-cache, cf-edge-cache: no-cache, Vary: Accept-Encoding,Cookie,Origin) and carry X-Robots-Tag: noindex. HTML pages are cached and optimized by NitroPack in front of an openresty/1.25.3.1 origin. reversibility: applicable: false grade: na dry_run_mode: na idempotency: na detail: >- There is no anonymous write surface on this API — every catalogued operation is a GET, and every POST/PUT/PATCH/DELETE route in the index requires an authenticated WordPress user of the site itself. With no action an agent can take, there is nothing to reverse, nothing to rehearse and nothing to de-duplicate. Recorded as `na` rather than absent so that a read-only provider is not scored as if it shipped an irreversible write surface. reversal_operations: [] windows: [] cross_links: authentication: authentication/leaf4life-authentication.yml errors: errors/leaf4life-problem-types.yml lifecycle: lifecycle/leaf4life-lifecycle.yml data_model: data-model/leaf4life-data-model.yml conformance: conformance/leaf4life-conformance.yml rate_limits: rate-limits/leaf4life-rate-limits.yml