REST API

Grid Panda exposes a full REST API under /wp-json/gridpanda/v1/. All endpoints use standard WordPress REST API conventions, authentication, and error formats.

Authentication & Permissions

public

No authentication required. Open to all visitors. Used for grid render, facet choices, and autocomplete — the read-only endpoints that the frontend JavaScript calls on every filter interaction.

admin

Requires manage_options WordPress capability. Used for CRUD operations on grids, cards, facets, settings, and index management. Authenticate with Application Passwords or cookie auth from the admin.

# Application password authentication
curl -u "username:xxxx xxxx xxxx xxxx xxxx xxxx" \
     https://example.com/wp-json/gridpanda/v1/settings

# Cookie auth (from within WP admin JS)
wp.apiFetch({ path: '/gridpanda/v1/settings' })

Rate Limiting & Caching

The public render endpoint has rate limiting enabled by default (60 requests/minute/IP). Authenticated requests have a higher limit (configurable). Rate limiting can be adjusted via thegridpanda/rest/rate_limit filter.

Cacheable responses include Cache-Control andETag headers when ETag is enabled. Clients that send If-None-Match with the correct ETag receive a 304 Not Modified response.

Batch

Base path: /wp-json/gridpanda/v1/

POST
/batchpublic

Execute up to 25 requests in a single HTTP call. Body: { requests: [{ method, path, body }] }. Returns array of { index, status, body }.

Grids

Base path: /wp-json/gridpanda/v1/grids

GET
/gridspublic

List all grids. Public users see active grids only; admins see all.

GET
/grids/{id}public

Get a single grid by numeric ID.

POST
/grids/{id}/renderpublic

Render grid HTML with facet filters applied. Body: { facets: {slug: [values]}, page, per_page, orderby, order }. Returns { html, total, total_pages, facet_counts, pagination_html }.

GET
/query-optionsadmin

Get available taxonomies, meta keys, authors, and post statuses for a post_type. Query param: post_type.

POST
/grids/previewadmin

Preview grid config without saving. Body: { post_type, card_id, layout, columns, gap, per_page, facet_ids, orderby, order, page }.

POST
/grids/preview-layoutadmin

Preview a composed layout tree. Body: { layout_tree, elements, post_type, orderby, order, page, per_page }.

POST
/gridsadmin

Create a new grid. Body: { name, slug, layout, post_type, facet_ids, card_id, per_page, active, config }.

PUT
/grids/{id}admin

Update an existing grid. Supports partial updates.

DELETE
/grids/{id}admin

Delete a grid. Returns { deleted: true }.

Facets

Base path: /wp-json/gridpanda/v1/facets

GET
/facetspublic

List all facets. Public sees active only; admin sees all.

GET
/facets/{id}public

Get a single facet by ID.

GET
/facets/{id}/choicespublic

Get choices with counts for a facet. Query params: post_ids (array), selected (array), post_type, context.

GET
/facets/{id}/autocompletepublic

Fetch autocomplete suggestions. Query params: q (required), post_ids (array), limit.

GET
/taxonomy-terms/{taxonomy}admin

List terms for a taxonomy. Used by the builder to populate source options.

POST
/facetsadmin

Create a facet. Body: { name, slug, type, source, post_type, active, config }.

PUT
/facets/{id}admin

Update a facet. Supports partial updates including config.

DELETE
/facets/{id}admin

Delete a facet and its index rows.

POST
/facets/{id}/reindexadmin

Queue a reindex for a single facet. Returns { message, facet_id }.

Cards

Base path: /wp-json/gridpanda/v1/cards

GET
/cardsadmin

List all card templates.

GET
/cards/{id}admin

Get a single card by ID.

POST
/cardsadmin

Create a card. Body: { name, template (JSON block tree), styles (CSS string) }.

PUT
/cards/{id}admin

Update a card.

DELETE
/cards/{id}admin

Delete a card.

GET
/cards/sample-postadmin

Get sample post data for card builder preview. Query params: post_type, post_id.

GET
/cards/search-postsadmin

Search posts for card preview. Query params: s, post_type, per_page (max 20).

GET
/cards/acf-fieldsadmin

List ACF field groups and fields. Requires ACF.

GET
/cards/meta-keysadmin

List distinct post meta keys (limit 500).

GET
/cards/product-attributesadmin

List WooCommerce product attributes. Requires WooCommerce.

Index

Base path: /wp-json/gridpanda/v1/index

GET
/index/statusadmin

Get index statistics: per-facet row counts, queue stats (pending, processing, failed), last index timestamp.

POST
/index/reindex-alladmin

Queue a full site reindex. Returns { message, status: 'completed' }.

POST
/index/reindex/{facet_id}admin

Queue a per-facet reindex. Returns { message, facet_id, status }.

DELETE
/index/purgeadmin

Delete all rows from wp_gridpanda_index. Returns { message, status: 'purged' }.

POST
/index/canceladmin

Cancel all pending queue jobs. Returns { message, cancelled: int, status }.

Settings

Base path: /wp-json/gridpanda/v1/settings

GET
/settingsadmin

Get all plugin settings as a flat object.

PUT
/settingsadmin

Update settings. Supports partial updates — only keys included in the request body are changed.

GET
/settings/schemaadmin

Get settings JSON schema for form generation.

POST
/settings/purge-cacheadmin

Clear all cached REST API responses. Returns { success: true, message }.

POST
/settings/exportadmin

Export all settings plus grid/facet/card counts. Returns { settings, counts, version }.

POST
/settings/importadmin

Import a settings bundle. Body: { settings: {...} }. Returns { success, imported: int, keys: [...] }.

Dashboard

Base path: /wp-json/gridpanda/v1/dashboard

GET
/dashboard/statsadmin

Get dashboard statistics: facet/grid/card counts, index status, integration flags, WP/PHP versions.

GET
/support/diagnosticsadmin

Get full system diagnostics for support: server info, WP config, DB row counts, recent error log entries.

Fonts

Base path: /wp-json/gridpanda/v1/fonts

GET
/fontsadmin

List all registered fonts with their configurations.

POST
/fonts/googleadmin

Add a Google Font. Body: { family (required), category, weights (array), variable (bool) }.

POST
/fonts/uploadadmin

Add an uploaded/self-hosted font. Body: { family, category, files: { weight: attachment_id } }.

DELETE
/fonts/{family}admin

Remove a font by family name (URL-encoded).

GET
/fonts/settingsadmin

Get font loading settings.

PUT
/fonts/settingsadmin

Update font loading mode: { loading_mode: 'cdn' | 'disabled' }.

Error Format

All errors use the standard WordPress REST API error envelope:

// 404 Not Found
HTTP/1.1 404 Not Found
{
  "code":    "gridpanda_not_found",
  "message": "Grid not found",
  "data":    { "status": 404 }
}

// 422 Validation Error
HTTP/1.1 422 Unprocessable Entity
{
  "code":    "gridpanda_validation_error",
  "message": "Invalid config: step must be greater than 0",
  "data":    { "status": 422, "field": "step" }
}

// 429 Rate Limited
HTTP/1.1 429 Too Many Requests
{
  "code":    "gridpanda_rate_limited",
  "message": "Too many requests. Retry after 60 seconds.",
  "data":    { "status": 429, "retry_after": 60 }
}