Headless example
Pro
This example reads and updates a Book from a Node.js or browser front end, using an Application Password. It assumes the Book post type is in the REST API and its fields are exposed.
Reading a book
js
const SITE = "https://example.com";
const auth = "Basic " + btoa("api-user:xxxx xxxx xxxx xxxx xxxx xxxx");
async function getBook(id) {
const res = await fetch(`${SITE}/wp-json/wp/v2/books/${id}?_fields=id,title,vx`, {
headers: { Authorization: auth },
});
if (!res.ok) {
const err = await res.json().catch(() => ({}));
throw new Error(err.message || res.statusText);
}
const book = await res.json();
const vx = book.vx || {};
return {
id: book.id,
title: book.title?.rendered ?? "",
tagline: vx.tagline ?? null,
priceRange: vx.price_range?.label ?? null, // choice: { value, label }
cover: vx.photos?.[0]?.url ?? null, // media object
writers: (vx.writers || []).map((s) => ({ id: s.id, title: s.title, url: s.url })),
};
}Fields the user can't read are simply missing from vx, so always allow for a missing key.
Listing books
js
const res = await fetch(`${SITE}/wp-json/wp/v2/books?per_page=20&page=1&_fields=id,title,vx`, {
headers: { Authorization: auth },
});
const books = await res.json(); // each item has its own vx
const totalPages = Number(res.headers.get("X-WP-TotalPages"));Updating a book
js
async function updateBook(id, values) {
const res = await fetch(`${SITE}/wp-json/wp/v2/books/${id}`, {
method: "POST",
headers: { Authorization: auth, "Content-Type": "application/json" },
body: JSON.stringify({ vx: values }),
});
const body = await res.json();
if (!res.ok) {
const details = body.data?.errors?.map((e) => `${e.path}: ${e.message}`).join("; ");
throw new Error(details || body.message);
}
if (body.vx_warnings?.length) {
console.warn("Saved with warnings:", body.vx_warnings);
}
return body.vx;
}
await updateBook(123, {
tagline: "A novel of lost catalogues",
price_range: "$$", // write the value, not { value, label }
photos: [88, 91], // attachment IDs
});The user behind the Application Password needs permission to edit the book. Writes are merged: only the keys you send change.
Technical details for LLMs
- Read
vxdefensively: absent key = not readable or not exposed. Choices read{ value, label }, write the value. Media reads objects, writes ids. See Field formats for every type. - Pagination: WordPress core headers
X-WP-Total/X-WP-TotalPages;per_page≤ 100. - Add
?vx_strict=1to fail on warnings instead of logging them.