generated: '2026-08-22'
method: derived
source: >-
openapi/_original/iggenix-content-openapi.yml (derived from https://iggenix.com/wp-json/) plus live
anonymous requests against https://iggenix.com/wp-json/wp/v2/*, 2026-08-22. Cross-cutting behaviour is
WordPress core REST behaviour, observed on this host rather than assumed.
summary: >-
This is a WordPress core REST API, so every cross-cutting convention below is WordPress's, not a
design IgGenix authored. It is a well-behaved read surface — offset/page pagination with the count in
response headers, a consistent JSON error envelope, field selection via _fields, embedded relations via
_embed — and a poor write surface for agents: no idempotency keys, no dry-run, no request-id header,
and no reversal semantics beyond WordPress's own trash-and-restore.
authentication:
style: HTTP Basic (WordPress Application Passwords)
anonymous_read: true
note: >-
The whole content read surface answers anonymously. Writes, and the authenticated-read routes
(/wp/v2/settings, /wp-abilities/v1/*), require an application password. Advertised by the host's own
route index under authentication.application-passwords.
authorization_endpoint: https://iggenix.com/wp-admin/authorize-application.php
see: authentication/iggenix-authentication.yml
versioning:
style: uri-namespace
current: wp/v2
note: >-
The version is a namespace segment in the path (/wp-json/wp/v2/...). The route index at /wp-json/
enumerates every registered namespace, so a client can discover a version change. IgGenix publishes
no versioning policy of its own — the version tracks whatever WordPress core the site runs.
discovery: https://iggenix.com/wp-json/
pagination:
style: page-and-per-page
params:
- name: page
default: 1
minimum: 1
- name: per_page
default: 10
minimum: 1
maximum: 100
- name: offset
note: Alternative to page; skips a fixed number of items.
response_headers:
- name: X-WP-Total
description: Total items in the unpaginated collection. Observed as 20 on pressreleases, 9 on publications, 14 on abstracts, 76 on media.
- name: X-WP-TotalPages
description: Total pages available at the current per_page.
- name: Link
description: RFC 8288 next/prev links.
cors_exposed: true
cors_note: 'The host sets access-control-expose-headers: X-WP-Total, X-WP-TotalPages, Link — so a browser client can read them.'
field_selection:
sparse_fields:
param: _fields
description: Comma-separated list of top-level fields to return. Verified live — _fields=id,date,slug,link,title returns exactly those keys.
expansion:
param: _embed
description: Inlines linked resources (author, featured media, terms) into an _embedded block, resolving the _links graph in one round trip.
envelope:
param: _envelope
description: Wraps body, status and headers into a single JSON object for clients that cannot read response headers.
context:
param: context
values: [view, embed, edit]
default: view
description: Controls which fields are present. edit requires authentication.
ordering_and_filtering:
order_params: [order, orderby]
filter_params: [search, after, before, modified_after, modified_before, include, exclude, slug, status, author, categories, tags]
note: Parameter names and allowed values are taken verbatim from the route index; see the per-operation parameters in openapi/.
hypermedia:
style: HAL-like _links
description: >-
Every resource carries a _links object with self, collection, about (the post-type descriptor),
wp:attachment, curies and, on search results, an embeddable self href with a targetHints.allow array
naming the methods the caller may use. This is the most agent-useful property of the surface: a
search hit tells an agent exactly which route to follow next and which verbs are permitted.
discovery_header: 'Link: ; rel="https://api.w.org/" is returned on every HTML page.'
error_envelope:
format: wordpress-wp-error
rfc9457: false
content_type: application/json
shape: '{ "code": "", "message": "", "data": { "status": } }'
observed: '{"code":"rest_post_invalid_id","message":"Invalid post ID.","data":{"status":404}}'
note: >-
Not RFC 9457 problem+json. The HTTP status is duplicated inside data.status, and code is a stable
machine-readable slug. See errors/iggenix-problem-types.yml.
request_tracing:
request_id_header: none
note: >-
No X-Request-Id, X-Correlation-Id or equivalent is returned. Responses do carry WP Engine cache
headers (x-cache, x-cache-group, x-cacheable) which are operational, not correlational. An agent
that needs to report a failing call back to IgGenix has no identifier to quote.
caching:
headers:
- 'cache-control: max-age=600, must-revalidate'
- 'vary: Accept-Encoding,Cookie'
- 'x-cacheable: SHORT'
- 'x-cache: HIT/MISS'
etag: false
conditional_requests: false
note: Edge-cached at WP Engine for ten minutes. No ETag or Last-Modified, so no conditional GET.
idempotency:
supported: false
header: null
note: >-
WordPress core has no idempotency-key mechanism. A retried POST to /wp/v2/pressreleases creates a
second post. No Idempotency pointer is emitted in apis.yml because there is nothing to point at —
asserting one would be a false claim on IgGenix's behalf.
dry_run_mode:
supported: false
note: No preview, validate-only or simulate parameter exists on any write operation.
reversibility:
grade: documented
na: false
note: >-
The write surface is authenticated-only, so no reversal path could be exercised; everything below is
read out of the route index's own parameter set on this host, not out of IgGenix documentation —
IgGenix publishes none. The reversal path exists and is discoverable; the WINDOW is not stated
anywhere by IgGenix, so this grades `documented` rather than `verified`. Nothing here asserts a
retention period, because no IgGenix page states one.
write_surfaces:
- surface: Content deletion (pressreleases, publications, abstracts, careers, posts, pages, media, comments)
destructive_operation: 'DELETE /wp/v2/{type}/{id}'
reversal: soft-delete to trash, then restore by setting status back to publish
reversal_operation: 'POST /wp/v2/{type}/{id} with {"status":"publish"}'
window: unstated
window_note: >-
DELETE without force=true moves the item to trash and it can be restored; DELETE with force=true is
permanent and has no reversal. How long a trashed item survives is governed by the site's
EMPTY_TRASH_DAYS configuration, which is not exposed on any anonymous endpoint and is not
documented by IgGenix, so no window is asserted here.
evidence: 'The force parameter is declared on every DELETE endpoint in the route index served at https://iggenix.com/wp-json/ with the description "Whether to bypass Trash and force deletion."'
- surface: Media deletion
destructive_operation: 'DELETE /wp/v2/media/{id}'
reversal: none
window: none
window_note: >-
Attachments are force-deleted by WordPress; the route index declares force as required on this
endpoint. There is no undo. This is the one write on the surface an agent cannot take back.
- surface: Settings mutation
destructive_operation: 'POST|PUT|PATCH /wp/v2/settings'
reversal: re-submit the previous values
window: unbounded
window_note: >-
Settings are last-write-wins with no history, so reversal is only possible if the caller captured
the prior state first. GET /wp/v2/settings is 401 anonymously, so an unauthenticated agent cannot
capture it.
read_only_surfaces:
- Search API
- Discovery API
- oEmbed API
rate_limit_signaling:
headers: none
note: >-
No X-RateLimit-*, RateLimit-* or Retry-After header was returned on any observed response. See
rate-limits/iggenix-rate-limits.yml.
cross_links:
errors: errors/iggenix-problem-types.yml
lifecycle: lifecycle/iggenix-lifecycle.yml
authentication: authentication/iggenix-authentication.yml
rate_limits: rate-limits/iggenix-rate-limits.yml
data_model: data-model/iggenix-data-model.yml