WordPress admin settings reference
The VelvetPress client plugin adds one screen to WordPress: Settings → VelvetPress. This page documents every field on it, what each one controls, and what happens when you click Save Changes. It's the reference companion to Installing on a customer WordPress site, which is the narrative walkthrough.
Where to find it
After activating the client plugin, the settings live at:
wp-admin → Settings → VelvetPress
The page is registered as a standard add_options_page, so it shows up
under the Settings menu — not as a top-level menu item. Only users
with the manage_options capability (administrators on a single site,
super-admins on multisite) can see or change anything on it.
The API Key field
The settings form has exactly one editable field: API Key.
- What it stores. The per-site API key the developer issued you when they added your site to VelvetPress. It's an opaque string — treat it like a password.
- Where it goes. Submitted as
velvetpress_settings[api_key]and saved into the WordPress optionvelvetpress_settingsas theapi_keyarray entry. Nothing else is stored in that option today. - How it's sanitized. On save, the value is passed through
sanitize_text_field()andtrim(). Leading/trailing whitespace from a copy-paste is stripped automatically; control characters and HTML are dropped. - How it's validated. The form itself doesn't validate the key —
it accepts whatever you paste in. Validation happens
asynchronously on the next page load: the page pings
/ping?api_key=<key>&domain=<host>and updates the status badge based on the response (see Status badge below). - What "wrong" looks like. A wrong, expired, or revoked key doesn't block the save — the value is stored as-is and the status badge flips to ✗ Error on reload. The full failure-mode catalogue is in Troubleshooting → Plugin says "Invalid API key".
To change the key, paste a new value over the old one and click Save Changes. To clear it, empty the field and save — the badge will disappear on reload and the diagnostic and product UI go with it.
Locking the key down with wp-config.php
If you'd rather not store the key in the WordPress database — useful on
multisite, in version-controlled wp-config.php, or anywhere you keep
secrets out of the DB — define it as a constant before the
/* That's all, stop editing! Happy publishing. */ line:
define( 'VELVETPRESS_API_KEY', 'your-api-key-here' );
When the constant is set, three things change on the settings screen:
- The API Key field is rendered
readonlyand shows the description "Set via wp-config.php constant." - The Save Changes button is hidden — by design, so the
wp-config.phpvalue can't be silently overridden through the UI. - The constant value always wins. Any value already stored in the database is ignored as long as the constant is defined.
There's a parallel VELVETPRESS_API_URL constant for pointing the
plugin at a non-production VelvetPress backend (e.g. a staging
deployment). It defaults to https://api.velvetpress.dev and is
not rendered as a field on the settings screen — define it in
wp-config.php or leave it at the default. You almost never need to
touch this.
define( 'VELVETPRESS_API_URL', 'https://api-staging.velvetpress.dev' );
The lookup order is: constant (if defined) → saved option → built-in
default. api_url skips the middle step — the settings form
intentionally drops it during sanitization, so it's effectively
constant → default. Constants are read every request, so deploying a
new wp-config.php value takes effect immediately with no re-save
needed.
What happens when you click Save Changes
Saving the form does more than write the option. Two side effects fire when you save a key that's different from what's currently stored:
- Site registration. The plugin POSTs to
<api_url>/registerwith the effective API key, the site's domain (fromhome_url()), the active theme slug and version, the site name, and the WordPress version. The call has a 10-second timeout. - Products cache invalidation. The cached
/productsresponse (a six-hour transient) is deleted, so the Available Products section below the form reflects the new key on the very next page load instead of waiting for the TTL.
A no-op save — clicking Save Changes without having actually edited the field — does nothing, because WordPress doesn't treat unchanged values as a save.
If the API Key field is read-only because VELVETPRESS_API_KEY
is defined in wp-config.php, the form has no submit button — by
design, so the constant value can't be overridden through the UI. A
constant-only install where the key is set for the first time will
still receive updates (/ping and /products succeed off the API
key alone), and the site appears on the developer's dashboard with
the metadata they already have. If you need to push fresh metadata
(WordPress version, theme version, site name) from a constant-only
install, ask your developer to refresh the registration on their
end.
Status badge
When the API key field is non-empty, the page header changes from
just VelvetPress to VelvetPress + a colored badge. The badge
starts as Checking... while the inline script makes a JSON GET
to <api_url>/ping?api_key=<key>&domain=<host>, then settles into
one of:
| Badge | Meaning |
|---|---|
| Checking... | The ping request is in flight. Should resolve in well under a second. |
| ✓ Connected | The backend accepted the key for this domain. The site is fully wired. |
| ✗ Error | The request reached the backend but the response was { "success": false }. The error message is shown in the Debug Info panel. Most often a key/domain mismatch. |
| ✗ Offline | The HTTP request itself failed — DNS, network, firewall, or CORS. The browser-level error is shown in the Debug Info panel. |
The badge is client-side, computed from a browser fetch. If
you've blocked outbound JS or the browser can't reach
api.velvetpress.dev, the badge will say ✗ Offline even though
WordPress's own server-to-server calls might still work. Use the
Update manifest reference curl examples to
test the backend from the server itself when the badge looks wrong.
Available Products
When an API key is saved, the settings screen also renders an Available Products section between the form and the Debug Info panel. It lists every plugin and theme your API key has access to, with one of three actions per row:
- Install — the product isn't on disk yet. Clicking installs it in-place from a short-lived download URL.
- Update to v<x.y.z> — the product is installed but a newer version is published.
- Installed (v<x.y.z>) — the local version matches or is newer than what the backend offers. No action.
For the full install flow and behavior (one-click install, no second confirmation, page reload on success), see Installing on a customer WordPress site → Installing a new plugin or theme via Available Products.
If the Available Products heading isn't there at all on a saved
settings screen, the /products call failed — the inline error
message right under the heading tells you why.
First-time setup walkthrough
The quickest path from a freshly activated plugin to a working update check:
- Activate the plugin. Plugins → Add New → Upload Plugin,
pick
velvetpress.zip, Install Now, Activate Plugin. - Open the settings screen. Settings → VelvetPress.
- Paste the API key. Drop the key the developer gave you into the API Key field. Whitespace is fine — it'll be trimmed.
- Save Changes. The page reloads. The badge next to VelvetPress flips to Checking... and then to one of the three resolved states.
- Confirm the badge says ✓ Connected. If it does, you're done — future updates will appear under Dashboard → Updates on WordPress's normal schedule. If it says ✗ Error or ✗ Offline, expand Debug Info and copy the domain string; that's almost always what your developer needs to resolve it.
- Optional: install other managed products. Scroll to Available Products and click Install on anything else the developer has shared with you.
What's next
- Installing on a customer WordPress site — the same flow as a narrative, with the customer-side context for why each step matters.
- Troubleshooting — failure modes cross-linked from the status badge and the Debug Info panel.
- Update manifest reference — wire-level
details of
/ping,/register, and/productsso you can reproduce what the plugin is doing from a terminal.