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 option velvetpress_settings as the api_key array entry. Nothing else is stored in that option today.
  • How it's sanitized. On save, the value is passed through sanitize_text_field() and trim(). 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:

  1. The API Key field is rendered readonly and shows the description "Set via wp-config.php constant."
  2. The Save Changes button is hidden — by design, so the wp-config.php value can't be silently overridden through the UI.
  3. 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:

  1. Site registration. The plugin POSTs to <api_url>/register with the effective API key, the site's domain (from home_url()), the active theme slug and version, the site name, and the WordPress version. The call has a 10-second timeout.
  2. Products cache invalidation. The cached /products response (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:

  1. Activate the plugin. Plugins → Add New → Upload Plugin, pick velvetpress.zip, Install Now, Activate Plugin.
  2. Open the settings screen. Settings → VelvetPress.
  3. Paste the API key. Drop the key the developer gave you into the API Key field. Whitespace is fine — it'll be trimmed.
  4. Save Changes. The page reloads. The badge next to VelvetPress flips to Checking... and then to one of the three resolved states.
  5. 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.
  6. Optional: install other managed products. Scroll to Available Products and click Install on anything else the developer has shared with you.

What's next