Writing values
Pro
Send a vx object in the body of a normal WordPress create or update request, and VX validates and saves it through the same process as the editor:
bash
curl -X POST "https://example.com/wp-json/wp/v2/books/123" \
-u "editor:xxxx xxxx xxxx xxxx xxxx xxxx" \
-H "Content-Type: application/json" \
-d '{ "vx": { "tagline": "A novel of lost catalogues", "author_name": "Elena Voss" } }'This works on every exposed post type, taxonomy (/wp/v2/regions/10) and on users (/wp/v2/users/9, or /wp/v2/users/me for yourself). The response is the updated entry, with its fresh vx values.
Who can write
Writing depends only on capabilities, not on access tiers: you need to be allowed to edit that post, term or user (or to create posts of that type). An editor can write a Private field, because editors can already read it. Users can always update their own profile's fields.
Password fields, layout fields, Area shapes and Clone placeholders can't be written over the API, and neither can a Group or Repeater that contains a password field.
How a write is applied
- Only the fields you send change. Fields you leave out keep their values.
- An empty value clears a field:
"",[],{}ornull.nullalso clears a Switcher, whichfalsedoesn't:falsesaves it off. - Containers are written whole. Sending a Group replaces all its sub-fields, and sending a Repeater replaces all its rows.
- Unknown keys are refused with an
unknown_fieldserror, so a typo never disappears silently. - Fields hidden by conditional logic are skipped, just like in the editor.
- Several fieldsets are saved together: if any part fails, nothing is saved.
Warnings and strict mode
Like the editor, the API saves values that break a soft rule, such as a maximum length, and reports them in a vx_warnings list in the response. Relation rules never block a write either: extra items are dropped, and links a field wouldn't allow are removed.
Only hard errors, such as an attachment that doesn't exist or a file type the field doesn't allow, stop the write.
To reject anything that isn't perfectly valid, add ?vx_strict=1 to the request (or "vx_strict": true to the body). Any warning then fails the whole write, and nothing is saved.
Uploading media
Media fields take attachment IDs, not files. Upload the file to WordPress's media endpoint first, then send its ID:
bash
curl -X POST "https://example.com/wp-json/wp/v2/media" \
-u "editor:xxxx xxxx xxxx xxxx xxxx xxxx" \
-H "Content-Disposition: attachment; filename=cup.jpg" \
-H "Content-Type: image/jpeg" \
--data-binary @cup.jpg
# → { "id": 88, ... }
curl -X POST "https://example.com/wp-json/wp/v2/books/123" \
-u "editor:xxxx xxxx xxxx xxxx xxxx xxxx" \
-H "Content-Type: application/json" \
-d '{ "vx": { "photos": [88] } }'The field's rules (allowed types, sizes, number of files) are checked when you reference the ID.
Errors
Errors use WordPress's usual error format, with details for each field:
json
{
"code": "validation_error",
"message": "The submitted data is invalid.",
"data": { "status": 422, "errors": [ { "path": "photos", "message": "Attachment not found." } ] }
}| Code | Status | Meaning |
|---|---|---|
unknown_fields | 422 | A key matches no exposed field |
not_writable | 401, 403 or 422 | You can't edit this entry, or a field can't be written |
validation_error | 422 | A hard error, or any problem in strict mode |
write_failed | 500 | The values were valid but couldn't be saved; nothing was changed |
Warning
When you create an entry, WordPress creates it before VX processes vx. If the vx part fails, you get an error, but the new draft already exists. When that matters, create the entry first, then write vx in a second request.
Technical details for LLMs
- Capabilities: posts
edit_post(create: post typecreate_posts); termsedit_term; usersedit_user(always own record via/users/me). User writes don't depend on the per-role read opt-in.vxframework/rest/can_writehas the final say except for sensitive types. - Semantics: partial merge by key (
rest_keyaliases accepted); empty clears (nullfor any type, a Switcher included); containers replace whole; hidden-by-condition skipped; multi-fieldset writes in one transaction (rolled back on failure). - Strict:
vx_strict(query or body) dry-runs every partition; any error or warning → 422, nothing persisted. - Response: core entity with re-serialized
vx, plusvx_warnings: [ { path, message } ]when applicable. - Input shapes differ from read shapes for several types; see Field formats.
- Equivalent abilities (no REST exposure needed,
manage_options):vx-framework/set-post-values,vx-framework/set-term-values,vx-framework/set-user-values.