Dino Discover exposes its admin and storefront surfaces through a
single REST namespace: /wp-json/dino-discover/v1/. The Builder, the
Coverage page, the Settings page, and the storefront quiz all talk
to the plugin through this API. This page is the route catalogue.
For the architectural picture (the published-only invariant, the
two-tier auth model, the optimistic-locking pattern), see
Architecture.
- Base URL:
/wp-json/dino-discover/v1/.
- Admin routes require the
manage_dino_discover capability plus
a valid X-WP-Nonce header.
- Storefront routes are unauthenticated but rate-limited. After
the initial
POST /storefront/sessions, subsequent calls carry
the X-DD-Variant-Token header.
- Optimistic locking: every mutating admin route on a quiz
carries an
expected_draft_version integer; mismatch returns
409 dd_draft_version_mismatch.
- Idempotency: mutating storefront routes (
/events, /recommend,
/lead) accept an idempotency key.
- Errors use the WordPress REST error envelope (
code, message,
data.status).
Admin endpoints require the manage_dino_discover capability. The
capability is filterable via dino_discover_capability. All requests
need a valid X-WP-Nonce from wpApiSettings.nonce (or
@wordpress/api-fetch’s middleware).
| Method | Path | Purpose |
|---|
| GET | /quizzes | List quizzes. |
| POST | /quizzes | Create quiz. |
| GET | /quizzes/{id} | Fetch the draft tree (questions, answers, upvotes, variants). |
| PATCH | /quizzes/{id} | Update; gated by expected_draft_version. |
| DELETE | /quizzes/{id} | Soft-delete. |
| POST | /quizzes/{id}/publish | Publish a snapshot; gated by expected_draft_version. |
| POST | /quizzes/{id}/duplicate | Duplicate the quiz (draft only; doesn’t copy snapshots). |
| GET | /quizzes/{id}/export | Export the quiz as JSON. |
| POST | /quizzes/import | Import a quiz from a JSON payload. |
| PUT | /quizzes/{id}/answers/{answer_id}/upvotes | Set the upvote mapping for an answer. |
| GET | /quizzes/{id}/catalogue | Catalogue picker payload (products available to upvote against). |
| GET | /quizzes/{id}/share/sample-completion | Most-recent completion’s anonymous ID for the Share tab “preview a recent completion” feature. |
| Method | Path | Purpose |
|---|
| GET | /quizzes/{id}/snapshots | List snapshots for the quiz (newest first). |
| PATCH | /quizzes/{id}/snapshots/{sid} | Rename the snapshot (update the publish note). |
| POST | /quizzes/{id}/snapshots/{sid}/restore | Restore the snapshot back to draft. |
| Method | Path | Purpose |
|---|
| POST | /quizzes/{id}/variants | Clone an existing variant into a new one (requires a source_variant_id). |
| PATCH | /quizzes/{id}/variants/{vid} | Update a variant. |
| DELETE | /quizzes/{id}/variants/{vid} | Delete a variant. |
| POST | /quizzes/{id}/variants/{vid}/archive | Archive a variant (exclude from traffic). |
| PUT | /quizzes/{id}/variant-weights | Bulk-edit the traffic-weight distribution. |
| POST | /quizzes/{id}/instances/{iid}/detach | DD-11 detach a session instance from its variant. |
| POST | /quizzes/{id}/instances/{iid}/relink | DD-11 relink. |
| Method | Path | Purpose |
|---|
| GET | /coverage | Aggregate coverage report (the scatter chart data). |
| GET | /coverage/products/{pid} | Per-product paths and score. |
| POST | /coverage/refresh | Schedule an immediate Coverage refresh. |
| Method | Path | Purpose |
|---|
| GET | /analytics/aggregate | Funnel / topline metrics for a quiz over a date range. |
| GET | /analytics/aggregate/variants | A/B variant comparison. |
| Method | Path | Purpose |
|---|
| GET | /leads | List captured leads (admin-only). |
| GET | /leads/export.csv | Stream a CSV export of leads. Required query params: quiz_id, from, to. |
| Method | Path | Purpose |
|---|
| GET | /settings | Read settings. |
| PUT | /settings | Update settings (validated against SettingsSchema). |
| POST | /settings/regenerate-salt | Rotate every per-quiz experiment salt (reshuffles variant assignment for every active experiment). |
| GET | /settings/privacy/quizzes | Per-quiz retention listing. |
Per-quiz configuration for the three shipped integrations.
| Method | Path | Purpose |
|---|
| GET | /quizzes/{quiz_id}/integrations | List integration statuses for the quiz. |
| GET / PUT | /quizzes/{quiz_id}/integrations/webhook | Webhook config. |
| POST | /quizzes/{quiz_id}/integrations/webhook/test | Test the webhook. |
| GET / PUT | /quizzes/{quiz_id}/integrations/klaviyo | Klaviyo config. |
| POST | /quizzes/{quiz_id}/integrations/klaviyo/test | Test the Klaviyo key. |
| GET / PUT | /quizzes/{quiz_id}/integrations/mailchimp | Mailchimp config. |
| POST | /quizzes/{quiz_id}/integrations/mailchimp/test | Test the Mailchimp key. |
| Method | Path | Purpose |
|---|
| GET | /licence | Read licence state. |
| PUT | /licence | Save a licence key. |
| DELETE | /licence | Clear the saved key. |
The licence client runs without a key during Beta — these endpoints
are wired forward for the 1.0 release.
| Method | Path | Purpose |
|---|
| GET | /setup-checklist | Dashboard checklist completion counts. |
Storefront routes are unauthenticated but rate-limited. The default
limit is 60 requests/minute per client IP, configurable via the
dino_discover_rate_limit filter. The client IP derivation is
filterable via dino_discover_client_ip for CDN passthrough.
| Method | Path | Purpose |
|---|
| GET | /storefront/quizzes/{slug}/bootstrap | Return the bootstrap payload for a published quiz. Returns 404 if published_snapshot_id IS NULL. |
| POST | /storefront/sessions | Start a new session. Returns the session ID and the X-DD-Variant-Token to use on subsequent calls. |
| POST | /storefront/sessions/{sid}/events | Submit a batch of storefront events. Requires X-DD-Variant-Token. Idempotent on the event-key. |
| POST | /storefront/sessions/{sid}/recommend | Compute the recommendation set for the session. Requires X-DD-Variant-Token. Idempotent. |
| GET | /storefront/sessions/{sid}/results | Re-read the recommendation result. Cache-warmed by the most recent recommend call. |
| POST | /storefront/sessions/{sid}/lead | Capture a lead for the session. Requires X-DD-Variant-Token. Idempotent. |
| GET | /storefront/quizzes/{slug}/draft-preview-bootstrap | Admin-only draft-preview endpoint. Requires the Builder-minted nonce. Single exception to the published-only invariant. |
| Method | Path | Purpose |
|---|
| POST | /storefront/cart/bulk-add | Add multiple recommended products to the WooCommerce cart in one round-trip. |
AbstractController::permissions_admin() is the admin gate. It
applies the dino_discover_capability filter to resolve the required
capability (default manage_dino_discover), checks
current_user_can(), and enforces the X-WP-Nonce header — returning
a WP_Error on any failure rather than a bare boolean.
permissions_storefront() is the public gate: it runs the rate
limiter (filterable via dino_discover_rate_limit) and, for routes
that need session continuity, the Variant\Assignor validates the
X-DD-Variant-Token header against the session record. Mismatch
returns 403.
A few routes are catalogued in the technical design but do not
exist in code as of 0.1.0. Watch the register_route() callsites
before you depend on them:
/quizzes/{id}/lock, /quizzes/{id}/declare-winner.
/analytics/topline, /analytics/sankey, /analytics/export.csv.
/placements*, /jobs/{id}.
/storefront/sessions/{sid}/resume,
/storefront/share/{token}, /storefront/share/{token}/event.
The shipped analytics endpoints in 0.1.0 are
/analytics/aggregate and /analytics/aggregate/variants.