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
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.
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/
/batchpublicExecute 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
/gridspublicList all grids. Public users see active grids only; admins see all.
/grids/{id}publicGet a single grid by numeric ID.
/grids/{id}/renderpublicRender grid HTML with facet filters applied. Body: { facets: {slug: [values]}, page, per_page, orderby, order }. Returns { html, total, total_pages, facet_counts, pagination_html }.
/query-optionsadminGet available taxonomies, meta keys, authors, and post statuses for a post_type. Query param: post_type.
/grids/previewadminPreview grid config without saving. Body: { post_type, card_id, layout, columns, gap, per_page, facet_ids, orderby, order, page }.
/grids/preview-layoutadminPreview a composed layout tree. Body: { layout_tree, elements, post_type, orderby, order, page, per_page }.
/gridsadminCreate a new grid. Body: { name, slug, layout, post_type, facet_ids, card_id, per_page, active, config }.
/grids/{id}adminUpdate an existing grid. Supports partial updates.
/grids/{id}adminDelete a grid. Returns { deleted: true }.
Facets
Base path: /wp-json/gridpanda/v1/facets
/facetspublicList all facets. Public sees active only; admin sees all.
/facets/{id}publicGet a single facet by ID.
/facets/{id}/choicespublicGet choices with counts for a facet. Query params: post_ids (array), selected (array), post_type, context.
/facets/{id}/autocompletepublicFetch autocomplete suggestions. Query params: q (required), post_ids (array), limit.
/taxonomy-terms/{taxonomy}adminList terms for a taxonomy. Used by the builder to populate source options.
/facetsadminCreate a facet. Body: { name, slug, type, source, post_type, active, config }.
/facets/{id}adminUpdate a facet. Supports partial updates including config.
/facets/{id}adminDelete a facet and its index rows.
/facets/{id}/reindexadminQueue a reindex for a single facet. Returns { message, facet_id }.
Cards
Base path: /wp-json/gridpanda/v1/cards
/cardsadminList all card templates.
/cards/{id}adminGet a single card by ID.
/cardsadminCreate a card. Body: { name, template (JSON block tree), styles (CSS string) }.
/cards/{id}adminUpdate a card.
/cards/{id}adminDelete a card.
/cards/sample-postadminGet sample post data for card builder preview. Query params: post_type, post_id.
/cards/search-postsadminSearch posts for card preview. Query params: s, post_type, per_page (max 20).
/cards/acf-fieldsadminList ACF field groups and fields. Requires ACF.
/cards/meta-keysadminList distinct post meta keys (limit 500).
/cards/product-attributesadminList WooCommerce product attributes. Requires WooCommerce.
Index
Base path: /wp-json/gridpanda/v1/index
/index/statusadminGet index statistics: per-facet row counts, queue stats (pending, processing, failed), last index timestamp.
/index/reindex-alladminQueue a full site reindex. Returns { message, status: 'completed' }.
/index/reindex/{facet_id}adminQueue a per-facet reindex. Returns { message, facet_id, status }.
/index/purgeadminDelete all rows from wp_gridpanda_index. Returns { message, status: 'purged' }.
/index/canceladminCancel all pending queue jobs. Returns { message, cancelled: int, status }.
Settings
Base path: /wp-json/gridpanda/v1/settings
/settingsadminGet all plugin settings as a flat object.
/settingsadminUpdate settings. Supports partial updates — only keys included in the request body are changed.
/settings/schemaadminGet settings JSON schema for form generation.
/settings/purge-cacheadminClear all cached REST API responses. Returns { success: true, message }.
/settings/exportadminExport all settings plus grid/facet/card counts. Returns { settings, counts, version }.
/settings/importadminImport a settings bundle. Body: { settings: {...} }. Returns { success, imported: int, keys: [...] }.
Dashboard
Base path: /wp-json/gridpanda/v1/dashboard
/dashboard/statsadminGet dashboard statistics: facet/grid/card counts, index status, integration flags, WP/PHP versions.
/support/diagnosticsadminGet full system diagnostics for support: server info, WP config, DB row counts, recent error log entries.
Fonts
Base path: /wp-json/gridpanda/v1/fonts
/fontsadminList all registered fonts with their configurations.
/fonts/googleadminAdd a Google Font. Body: { family (required), category, weights (array), variable (bool) }.
/fonts/uploadadminAdd an uploaded/self-hosted font. Body: { family, category, files: { weight: attachment_id } }.
/fonts/{family}adminRemove a font by family name (URL-encoded).
/fonts/settingsadminGet font loading settings.
/fonts/settingsadminUpdate 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 }
}