generated: '2026-08-11' method: probed source: live responses from https://cruzfoam.com/wp-json/ + openapi/ derived parameters description: >- Cross-cutting request/response semantics for the WordPress REST content API behind cruzfoam.com. Cruz Foam publishes no API documentation, so every convention below was read off live responses and the server's own OPTIONS schema documents on 2026-08-11, or is the documented WordPress core behaviour the surface inherits. authentication: style: none for reads detail: >- Anonymous read. No key, token or account. Writes require a WordPress application password (Basic over TLS) that has no public issuance path. artifact: authentication/cruz-foam-authentication.yml idempotency: supported: false idempotency_key_header: null detail: >- There is no idempotency contract. No Idempotency-Key header, parameter or replay window is accepted or documented anywhere on this surface. The public operations are all GET and are therefore idempotent by HTTP method semantics alone, which is not the same thing as an idempotency guarantee for retried writes. pagination: style: page-number with offset alternative params: page: 1-based page number. Default 1. per_page: Records per page. Default 10, minimum 1, maximum 100 — exceeding it returns 400 rest_invalid_param. offset: Alternative to page; skip N records. order: asc or desc. orderby: Sort field; varies per resource (date, id, title, slug, relevance, ...). response_headers: X-WP-Total: Total records matching the query. X-WP-TotalPages: Total pages available at the current per_page. Link: RFC 8288 rel="next" / rel="prev" links. detail: >- Verified live: GET /wp/v2/posts?per_page=2 returned X-WP-Total 139, X-WP-TotalPages 70 and a Link header carrying rel="next". Both counter headers are listed in Access-Control-Expose-Headers, so they are readable from a browser. cursor: false field_selection: supported: true params: _fields: Comma-separated allowlist of top-level response fields — a real sparse-fieldset control. _embed: Inline embeddable linked resources (author, featured media, terms) under _embedded. _links: HAL-style link relations are present on every record by default. detail: >- Combining _fields with _embed is the difference between a 33KB and a 2KB response on this surface; a single post record is roughly 16KB unfiltered. filtering: detail: >- Per-resource query parameters are declared in the OPTIONS document for each route and carried into the derived OpenAPI. Common across post types: search, slug, include, exclude, after, before, modified_after, modified_before, status, categories, tags, order, orderby. taxonomy_filters: - 'GET /wp/v2/posts?categories=' - 'GET /wp/v2/posts?tags=' - 'GET /wp/v2/customers?portfolio-categories=' context_parameter: param: context values: [view, embed, edit] default: view detail: >- `view` is the full public record, `embed` a trimmed subset for embedding. `edit` requires authentication and returns 401 anonymously. Field visibility per context is declared in each property of the published schemas. request_tracing: request_id_header: null detail: No correlation or request-id header is returned. There is nothing to quote in a support ticket, and no support channel for the API either. versioning: scheme: uri-path namespace current: wp/v2 detail: >- The version is a namespace segment in the path. 18 namespaces are registered at capture (wp/v2, oembed/1.0, yoast/v1, wpcom/v2, wpcom/v3, jetpack/v4, elementor/v1, ...). Cruz Foam publishes no versioning or deprecation policy of its own; the version moves when the site's WordPress core and plugins are upgraded, with no announcement. artifact: lifecycle/cruz-foam-lifecycle.yml error_envelope: format: wp-rest-error rfc9457: false shape: '{code, message, data:{status, params?, details?}}' detail: Match on `code`, never on `message`. Full catalog in errors/cruz-foam-problem-types.yml. artifact: errors/cruz-foam-problem-types.yml rate_limiting: documented: false response_headers: [] detail: >- No RateLimit-*, X-RateLimit-* or Retry-After header appeared on any observed response, and no limits are published. An agent has no runtime signal here and must self-throttle. artifact: rate-limits/cruz-foam-rate-limits.yml caching: observed_headers: Cache-Control: 'max-age=0, s-maxage=2592000' detail: >- Observed on GET /wp/v2/posts. Browsers are told not to cache, while a shared/edge cache is told to hold the response for 30 days. Freshness of any read is therefore an edge-cache property, not a contract — a record updated on the site may be served stale for up to 30 days. conditional_requests: not observed cors: access_control_expose_headers: [X-WP-Total, X-WP-TotalPages, Link] access_control_allow_headers: [Authorization, X-WP-Nonce, Content-Disposition, Content-MD5, Content-Type] indexing: x_robots_tag: noindex detail: >- Every API response carries `X-Robots-Tag: noindex`. The data is public and machine-readable but the provider signals it should not be indexed as content. content_type: request: application/json response: application/json; charset=UTF-8 evidence: - url: https://cruzfoam.com/wp-json/wp/v2/posts?per_page=2 http_status: 200 headers_observed: [x-wp-total, x-wp-totalpages, link, allow, cache-control, x-robots-tag, access-control-expose-headers] - url: https://cruzfoam.com/wp-json/wp/v2/posts?per_page=999 http_status: 400 - url: https://cruzfoam.com/wp-json/ http_status: 200