Overview

Smooth API Accelerator generates JSON outputs from a source system and publishes them to Smooth CDN for faster delivery and lower origin load.

The source system remains the content and API source of truth. API Accelerator is responsible for scanning routes, deciding which ones should be synced, generating JSON files, and serving them through CDN URLs.

The current production integration is WordPress. The same model can be extended to other source systems later, but this documentation page describes the current WordPress plugin behavior.

Core model

  • Discover routes that can be synced.
  • Keep synced routes in a dedicated group separate from the rest of detected endpoints.
  • Generate one or more JSON files per synced route.
  • Serve those files from https://cdn.smoothcdn.com/<user-slug>/<project-slug>/....
  • Optionally upload synced JSONs as protected assets.
WordPress

The WordPress plugin Smooth API Accelerator turns selected WP REST API endpoints into JSON files hosted on Smooth CDN.

Installation

  1. Download the plugin from Smooth API Accelerator.
  2. Install and activate it in WordPress.
  3. Open Smooth API Accelerator -> Settings in wp-admin.

Login and connection

The plugin supports two connection modes: an existing Smooth CDN account or guest mode.

  1. Choose the connection mode in Settings.
  2. Use Log in to Smooth CDN for account mode, or switch to guest mode and accept the policy.
  3. After connection, the plugin stores the API key and creates or attaches a Smooth CDN project of type api_accelerator.

If the status payload does not return another value, guest mode falls back to a default limit of50 JSON files.

Endpoint discovery and route selection

The endpoint screen keeps two tables:

  • Synced endpoints
  • Other endpoints

The current flow is:

  1. Run scan now discovers GET endpoints and refreshes the local endpoint registry.
  2. Newly detected endpoints appear in Other endpoints.
  3. Sync selected moves selected entries into the synced group and queues an immediate background sync for those routes.
  4. After that selection, the routes appear in Synced endpoints.
  5. Sync endpoints now runs a full sync for all currently synced endpoints.
  6. Unsync selected removes selected entries from the synced group and removes their remote JSON files from Smooth CDN.

Sync selected does not wait for the normal hourly schedule. The plugin queues a fast single WP-Cron event for the selected routes, usually with a short delay. Execution still depends on WP-Cron and the next request that triggers it, but it does not wait for the regular hourly cron.

Automatic refresh after content changes

The plugin automatically scans and syncs related routes after content changes affecting:

  • posts
  • terms and taxonomies

When a post changes, the plugin can refresh:

  • the endpoint for that specific post
  • the collection endpoint for that post type
  • related taxonomy collection endpoints
  • related term item endpoints

When a term changes, the plugin can refresh:

  • the taxonomy collection endpoint
  • the specific term endpoint
  • related post collection endpoints
  • related single post endpoints

These refreshes are also scheduled through WP-Cron with short-delay single events instead of waiting for the standard automatic scan interval.

Settings

The current WordPress plugin exposes these settings:

  • Add blocks field — adds a normalized blocks field when block parsing is possible.
  • Remove content field — appears only when Add blocks field is enabled and removes content only if blocks was actually added.
  • Protected assets — uploads synced JSON files as protected assets instead of public assets.
  • Collection sync page size — available values: 10, 25, 50, 100; default: 50.
  • Auto scan and sync — schedules the automatic full scan and sync recurrence: hourly, daily, or weekly.

Changing any of these settings forces sync invalidation and a faster full refresh:

  • Protected assets
  • Add blocks field
  • Remove content field
  • Collection sync page size

After such a change, the plugin clears sync markers for previously synced routes and queues a faster full scan + sync through an immediate single WP-Cron event instead of waiting for the regular schedule.

Blocking original WordPress REST API

In Settings you can configure whether original WordPress REST GET endpoints should remain available:

  • No — do not block original wp-json GET routes.
  • Yes — block all eligible REST GET routes for non-logged-in users.
  • Only synced ones — block only routes that are already synced to Smooth CDN.

Blocks output

When Add blocks field is enabled, the plugin adds a normalized blocks field to supported post-like payloads. The current block shape uses:

  • block_name
  • attrs
  • innerContent
  • inner_blocks

The synced JSON does not use the old output shape with blockName, innerBlocks, orinnerHTML.

{
  "id": 42,
  "title": { "rendered": "Example page" },
  "blocks": [
    {
      "block_name": "core/paragraph",
      "attrs": {},
      "innerContent": [
        "<p>Hello world</p>"
      ],
      "inner_blocks": []
    }
  ]
}

Practical note for core/navigation: if the block contains ref or legacynavigationMenuId, the plugin expands inner_blocks from the referenced wp_navigation post to avoid syncing an empty core/navigation wrapper.

Protected JSONs and file limits

Enable Protected assets when synced JSONs should not be exposed as public files. In that mode use a token-aware consumer to read them.

File limits are counted as physical JSON files. Paginated collections count as multiple files: one metadata file plus every page file.

Filtering requested JSONs

Synced JSON files can be filtered at request time with the _fields query parameter. Array payloads can also be filtered with normal query params such as id, slug, or other top-level keys.

Return only selected fields
https://cdn.smoothcdn.com/<user-slug>/<project-slug>/wp/v2/posts/page-1.json?_fields=id,slug,title
Filter array items and select fields
GET https://cdn.smoothcdn.com/<user-slug>/<project-slug>/wp/v2/posts/page-1.json?slug=hello-world&_fields=id,slug,title

Field filtering works on top-level keys. Dot notation is normalized to the root field.

Pre-send hook

Use scdn_api_accelerator_pre_send_json to adjust payloads right before JSON encoding and upload. Returning WP_Error stops sync for the current output file.

The hook runs for regular endpoint JSONs and also for collection-specific outputs:

  • collection metadata files
  • individual collection page files

The context array can contain:

  • trigger
  • http_status
  • route_template
  • handler_args
  • repository_item
  • sync_file_kind for collection outputs
  • page_no for collection page files
  • total_pages for collection metadata and collection page files
  • per_page for collection metadata and collection page files
add_filter( 'scdn_api_accelerator_pre_send_json', function( $data, $route, $context ) {
    if ( '/wp/v2/posts' === $route && ( $context['sync_file_kind'] ?? '' ) === 'collection_page' && is_array( $data ) ) {
        foreach ( $data as $index => $item ) {
            if ( ! is_array( $item ) ) {
                continue;
            }

            unset( $data[ $index ]['class_list'], $data[ $index ]['meta'] );
        }
    }

    if ( '/wp/v2/posts' === $route && ( $context['sync_file_kind'] ?? '' ) === 'collection_manifest' ) {
        $data['generated_for'] = 'posts';
    }

    return $data;
}, 10, 3 );

Unsync selected

Unsync selected does more than removing a local flag.

  • It deletes synced JSON files from Smooth CDN.
  • For collections, this includes the metadata file and all paginated collection pages.
  • The local repository entry is reset to a detected state.

After unsync, the route goes back to Other endpoints instead of staying in the synced group.

Purge endpoints

Purge endpoints is a destructive maintenance action available in Settings.

  • It deletes synced JSON files from Smooth CDN.
  • Then it clears local endpoint data stored by the plugin.
  • It also clears plugin scheduling and stored plugin state.

Use this action only when you want to wipe synced endpoint data and start from a clean state.

JavaScript SDK

The JavaScript SDK is the recommended way to consume synced API Accelerator JSONs in apps that need route-aware resolution, field filtering, query filters, pagination, or protected asset access.

Installation

npm install @smoothcdn/api-accelerator-sdk

Basic usage

Create a client with your Smooth CDN slugs and fetch data by route:

import { createApiClient } from "@smoothcdn/api-accelerator-sdk";

const client = createApiClient({
  userSlug: "example-user",
  projectSlug: "my-project"
});

const posts = await client.fetch("/wp/v2/posts");

Fields, filtering, and pagination

Use fields to map to _fields, where to append top-level query filters, andpage when you want a specific collection page.

const postsPage2 = await client.fetch("/wp/v2/posts", {
  fields: ["id", "title", "slug"],
  where: {
    slug: "hello-world"
  },
  page: 2
});

Use page for paginated collection files.

Joins

Use join to concatenate JSON files into more dynamical collection.

const postsWithAuthors = await client.fetch("/wp/v2/posts", {
  join: {
    author: "/wp/v2/users/[author]"
  },
});

Query with token

For protected JSONs, pass a token when creating the client.

import { createApiClient } from "@smoothcdn/api-accelerator-sdk";

const client = createApiClient({
  userSlug: "example-user",
  projectSlug: "my-project",
  token: process.env.SMOOTHCDN_TOKEN
});

const privatePosts = await client.fetch("/wp/v2/posts", {
  page: 1,
});

Framework adapters

The SDK also provides framework-specific adapters for the most common frontend runtimes.

Next.js

import { createApiClient } from "@smoothcdn/api-accelerator-sdk/next";

const next = createApiClient({
  userSlug: "example-user",
  projectSlug: "my-project",
  token: process.env.SMOOTHCDN_TOKEN
});

export async function getStaticProps() {
  return next.createStaticProps("/wp/v2/pages", { revalidate: 60 });
}

export async function getFeaturedPost() {
  return next.getRouteData("/wp/v2/posts", {
    fields: ["id", "title"],
    where: { id: 123 },
    cache: "force-cache",
    next: {
      revalidate: 300,
      tags: ["posts", "featured-post"]
    }
  });
}

Nuxt

import { createApiClient } from "@smoothcdn/api-accelerator-sdk/nuxt";

const nuxt = createApiClient({
  userSlug: "example-user",
  projectSlug: "my-project",
  token: process.env.SMOOTHCDN_TOKEN
});

export default defineComponent({
  setup() {
    const requestFetch = useRequestFetch();
    return nuxt.useRouteDataWithAutoKey(useAsyncData, "/wp/v2/posts", {
      fetch: requestFetch,
      asyncData: {
        dedupe: "defer",
        lazy: true
      }
    });
  }
});

Astro

import { createApiClient } from "@smoothcdn/api-accelerator-sdk/astro";

const astro = createApiClient({
  userSlug: "example-user",
  projectSlug: "my-project"
});

const loadPosts = astro.createLoader("/wp/v2/posts", {
  fields: ["id", "title"]
});

const posts = await loadPosts({ fetch });

SvelteKit

import { createApiClient } from "@smoothcdn/api-accelerator-sdk/sveltekit";

const sveltekit = createApiClient({
  userSlug: "example-user",
  projectSlug: "my-project"
});

export const load = sveltekit.createLoad("/wp/v2/posts", {
  fields: ["id", "title"],
  depends: ["smooth:posts"],
  cacheControl: "public, max-age=60"
});

Remix

import { json } from "@remix-run/node";
import { createApiClient } from "@smoothcdn/api-accelerator-sdk/remix";

const remix = createApiClient({
  userSlug: "example-user",
  projectSlug: "my-project",
  token: process.env.SMOOTHCDN_TOKEN
});

export const loader = remix.createJsonLoader(json, "/wp/v2/posts", {
  fields: ["id", "title"],
  where: { id: 123 },
  useRequestSignal: true
});