Your headless front end is only as fast as the API behind it. Code and Core Headless Fast API gives your Next.js, Nuxt, Astro, Gatsby, SvelteKit, React Native or Flutter app a WordPress API built for speed. It does not run the whole of WordPress on every request.
Each request to the built-in WordPress REST API starts the full WordPress stack: every active plugin, the theme, init, the REST server, its controllers and WP_Query. On a typical site with 20 to 40 plugins, most of that work has nothing to do with the JSON you asked for. This plugin cuts that work out:
init, the REST API and WP_Query load.Your front end gets the familiar REST-style data, including ACF fields, Yoast SEO metadata and resolved relationships, with far less work on the server. The result is lower response times, less CPU and database load, and quicker static builds and server-side rendering.
The built-in REST API is not changed or disabled. This plugin adds its own read-only namespace, /code-and-core-headless-fast-api/v1/, next to it, so you can switch over one endpoint at a time.
title.rendered, content.rendered, featured_media, …), so existing front-end code needs only small changes.GET only, prepared SQL, an allowlist of entities, and capability and nonce checks on every admin action.init: REST API: loaded. Headless Fast API: skipped.WP_Query and REST controllers. Headless Fast API: direct, batched, prepared SQL.HIT/MISS header._fields on each request. Headless Fast API: saved per endpoint in the admin, including nested ACF fields and flexible-content layouts.X-WP-Total headers. Headless Fast API: total and total_pages in the JSON body.plugins_loaded, before the theme, init, the REST API and WP_Query run.id, title.rendered, content.rendered, excerpt.rendered, featured_media, _links and so on), so existing front-end code needs few changes.acf, including repeaters, groups, flexible content and image fields. ACF options pages get their own endpoint.yoast_head and yoast_head_json are built from Yoast’s own indexable data, ready for your front end’s <head>.index.php. No rewrite rules, no separate entry point./code-and-core-headless-fast-api/v1/... is recognised from the URL with a simple string check. All other requests continue as normal and pay almost nothing.On sites with many plugins, most of a request’s time is spent loading those plugins. Fast Mode answers API requests before any regular plugin loads.
Fast Mode is off until an administrator turns it on. After activation the plugin asks once, in a popup on its Dashboard screen, and nothing is installed unless the administrator clicks “Enable Fast Mode”. It can be turned on or off at any time under Advanced.
Turning it on writes one small file, wp-content/mu-plugins/0-cachfa-fast-path.php, using the WordPress filesystem API. That file:
/code-and-core-headless-fast-api/v1/... and does nothing on any other request;Because other plugins do not run on API requests in Fast Mode, output they add through filters at runtime is not included in API responses. Data they save to the database is included.
All endpoints are GET only and start with:
https://example.com/code-and-core-headless-fast-api/v1/
home: the static front page (Settings > Reading), or the latest posts if the front page shows posts.posts, posts/{id_or_slug}: posts.pages, pages/{id_or_slug}: pages.media, media/{id_or_slug}: attachments.{post_type}s, {post_type}s/{id_or_slug}: any public custom post type you enable (for example products, products/blue-shirt).categories, categories/{id_or_slug}: categories.tags, tags/{id_or_slug}: tags.{taxonomy}s, {taxonomy}s/{id_or_slug}: any public custom taxonomy you enable.users, users/{id_or_slug}: users (can be turned off under Entities).options/{options_page_slug}: fields from an ACF options page (needs ACF with options pages).The Dashboard screen lists the exact URL of every active endpoint on your site.
Endpoints are available only for the post types and taxonomies you enable under Entities. Any other type returns a 404 with a JSON error.
Posts, pages, media and custom post types
page: page number (default 1).per_page: items per page, 1 to 100 (default 10). Other values return 400 rest_invalid_param, as in the REST API.offset: number of items to skip; overrides page.search: search title, content and excerpt.slug: one or more slugs, comma-separated.include, exclude: IDs, comma-separated.author, author_exclude: author IDs, comma-separated.parent, parent_exclude: parent IDs, comma-separated.menu_order: exact menu order.after, before: published after or before a date (any format strtotime() accepts, for example 2026-01-01T00:00:00).modified_after, modified_before: modified after or before a date.sticky: true for only sticky posts, false to leave them out.categories, categories_exclude, tags, tags_exclude: term IDs, comma-separated.{taxonomy}, {taxonomy}_exclude: term IDs for any enabled custom taxonomy.tax_relation: AND (default) or OR between taxonomy filters.media_type: image, video, audio, application, … (media only).mime_type: exact MIME type, for example image/png (media only).password: password for a password-protected post. Without it, content and excerpt are empty.orderby: date (default), title, id, modified, author, parent, slug, menu_order, include (the order of include) or include_slugs (the order of slug).order: DESC (default) or ASC.Categories, tags and custom taxonomies
page, per_page, search, slug, include, exclude.parent: parent term ID (0 for top-level terms).hide_empty: 1 to leave out terms with no posts.post: only terms assigned to this post ID.orderby: name (default), id, count or slug.order: ASC (default) or DESC.Users
page, per_page (1 to 100), offset, search, slug, include, exclude.roles, capabilities: comma-separated.who=authors: only users with published posts.has_published_posts: 1, or a comma-separated list of post types.orderby: name (default), id, registered_date, slug, url or include.order: ASC (default) or DESC.Array values such as include[]=1&include[]=2 are accepted and treated as include=1,2.
A single item (/posts/hello-world) returns the item object, in the WordPress REST API format. Single posts also contain pagination.previous_post and pagination.next_post (id, title, slug) to make “previous / next” links easy.
A list (/posts?per_page=5) returns a wrapper object instead of a bare array, so you get the totals without reading headers:
{ "type": "post", "count": 5, "total": 42, "total_pages": 9, "data": [ ... ] }
Errors are JSON with the matching HTTP status, for example { "code": "rest_post_invalid_id", "message": "Invalid post ID.", "data": { "status": 404 } }.
Every response includes:
Content-Type: application/json; charset=UTF-8Access-Control-Allow-Origin: * and Access-Control-Allow-Methods: GET, OPTIONS, so the API can be called from a browser on any domain. OPTIONS preflight requests are answered straight away.X-HeadlessFastAPI-Cache: HIT or MISS, to show whether the disk cache was used.const res = await fetch('https://example.com/code-and-core-headless-fast-api/v1/posts?per_page=6&categories=3');
const json = await res.json();
json.data.forEach(post => console.log(post.title.rendered));
const page = await fetch('https://example.com/code-and-core-headless-fast-api/v1/pages/about').then(r => r.json());
// Next.js (App Router): revalidate every 60 seconds
const API = 'https://example.com/code-and-core-headless-fast-api/v1';
const posts = await fetch(API + '/posts?per_page=10', { next: { revalidate: 60 } }).then(r => r.json());
content on list endpoints that only show cards.GET requests, so they cache well at the edge.per_page small and paginate with page and total_pages.X-HeadlessFastAPI-Cache header in your browser’s network tab to see whether the disk cache answered.The plugin adds a Code and Core Headless Fast API menu with five screens:
Press Save & Sync Schemas to save. Saving also scans for new post types, taxonomies and ACF fields again.
When Enable Disk Caching is on (Advanced screen), each response is stored as a JSON file. The key is the full request URL, so every combination of path and query string is cached separately.
GET API, which makes it easy to cache at the edge.With the ACF integration on, each item has an acf object built from the stored field values and a field map generated from your field groups. The map is rebuilt when you save the settings, when you press Force Sync, and whenever an ACF …