ProcessWire Headless CMS: REST API and GraphQL Guide

Building a Headless CMS API with ProcessWire

Development and maintenance of all types of websites:

Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Our competencies:

Frequently Asked Questions

Latest works

  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1281
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1237
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    977
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    1026
  • image_website-sbh_0.webp
    Website development for SBH Partners
    1103
  • image_website-_0.webp
    Website development for Red Pear
    550

Building a Headless CMS API with ProcessWire

Organizing Content Delivery via ProcessWire API

A ProcessWire project has been running for several years, with dozens of templates accumulated. Then the client demands a React SPA or mobile app. Standard PHP rendering won't work—they need clean JSON. You could hack together something with direct DB access, but that breaks permission logic and caching. The right solution is to add an HTTP API on top of the existing templates. We do this in 2–4 days using built-in tools: a template router or the GraphQL module. No rewriting—just a new endpoint.

We have completed over 30 such projects. The most loaded configuration handles up to 100,000 requests per day on a budget VPS. The API has been running without issues for over two years. Below we break down the implementation options.

Built-in PHP API

ProcessWire exposes $pages, $page, $user, and $config as global variables in templates:

// templates/blog.php // Selection with filters and pagination $limit = 12; $start = ($input->pageNum - 1) * $limit; $posts = $pages->find("template=blog-post, status=published, sort=-date, limit=$limit, start=$start"); $totalPosts = $pages->count("template=blog-post, status=published"); // Selection with field conditions $featuredPosts = $pages->find(" template=blog-post, featured=1, date>=today, category.name%=Web Development, sort=-date, limit=3 "); // Single item $post = $pages->get("template=blog-post, slug=my-post-slug"); if (!$post->id) wire404(); 

For a full ProcessWire JSON API, we create custom REST endpoints using ProcessWire API templates, enabling seamless headless ProcessWire SPA development.

Selector String — Query Language

// Text search $pages->find("template=product, title*=laptop, sort=title"); // Numeric conditions $pages->find("template=product, price>=1000, price<=5000"); // Date $pages->find("template=event, event_date>=today, sort=event_date"); // OR conditions $pages->find("template=post, (category=tech|category=science)"); // Related pages $pages->find("template=product, categories.id={$category->id}"); // Full-text search $pages->find("title|body~=search query, template=post"); // Sort by custom field $pages->find("template=product, sort=-rating, sort=title"); 

REST API via ProCache or Custom Module

ProcessWire does not ship with a built-in REST API. We create one using a template router:

// site/templates/api.php // URL: /api/blog/?page=1&limit=10 header('Content-Type: application/json'); header('Access-Control-Allow-Origin: ' . $config->httpHost); // Simple key-based authorization $apiKey = $input->get->text('key'); if ($apiKey !== $config->apiKey) { http_response_code(401); echo json_encode(['error' => 'Unauthorized']); return; } $page_num = (int) $input->get->int('page') ?: 1; $limit = min((int) $input->get->int('limit') ?: 10, 100); $start = ($page_num - 1) * $limit; $posts = $pages->find(" template=blog-post, status=published, sort=-date, limit=$limit, start=$start "); $result = [ 'data' => array_map(fn($post) => [ 'id' => $post->id, 'title' => $post->title, 'slug' => $post->name, 'url' => $post->url, 'date' => $post->date->format('Y-m-d'), 'excerpt' => $post->excerpt, 'image' => $post->image ? [ 'url' => $post->image->width(800)->url, 'width' => 800, 'height' => (int) round(800 / $post->image->ratio), ] : null, ], $posts->getArray()), 'total' => $posts->getTotal(), 'page' => $page_num, 'limit' => $limit, ]; echo json_encode($result); 

ProcessWire GraphQL Module

Install via ProcessWire modules. Download from processwire.com/modules/processwire-graphql/ and add settings to config.php:

$config->graphql = [ 'templateFilters' => ['blog-post', 'product', 'category'], 'fieldFilters' => ['title', 'body', 'date', 'image', 'category'], 'maxLimit' => 100, ]; query { blogPost(s: "status=published, sort=-date, limit=10") { list { id title date body image { url(width: 800) } category { title url } } total } } 

Response Caching

// Caching via WireCache $cacheKey = "api_posts_page{$page_num}"; $cached = $cache->get($cacheKey); if ($cached) { echo $cached; return; } // ... build $result ... $json = json_encode($result); $cache->save($cacheKey, $json, 3600); // 1 hour echo $json; 

Building a basic REST API on ProcessWire (5–7 endpoints) takes 2–4 days. Typical investment: a basic REST API starts at $2,500, including caching and documentation. GraphQL integration adds $500–$1,500. Cost is determined after analyzing the project scope. Typical costs range from $3,000 to $5,000, and our approach saves you 30–40% compared to alternative CMS migrations.

REST vs GraphQL for ProcessWire

Criterion Custom REST ProcessWire GraphQL
Implementation complexity Medium (template router) Low (module + config)
Development speed 2–4 days 1–2 days
Control over response Full Limited by settings
Typing No Yes (via GraphQL schema)
Caching level Endpoint Query (via persisted queries)

REST is better when you need minimal response and full control. GraphQL is preferable if clients need flexible field selection.

ProcessWire as a Headless CMS: Advantages

Unlike WordPress (where an API is a bolt-on hack) or Strapi (heavy), ProcessWire provides a single source of truth for both PHP templates and external clients. You write templates once, and the JSON output is just a second template with different headers. According to our estimates, this reduces maintenance costs by 30–40%.

ProcessWire API documentation confirms that selectors work identically in templates and API.

What Is Included in ProcessWire API Setup

Stage Duration Description
Design 0.5 day Endpoint schema, data types
REST implementation 1–2 days Template router, auth, CORS
Or GraphQL 0.5–1 day Module, config, tests
Caching 0.5 day WireCache + Redis
Documentation 0.5 day Postman or Swagger
Testing & deployment 1 day Load tests, monitoring

Deliverables:

  • API documentation (Postman/OpenAPI)
  • Access to staging environment
  • 1-hour training session for your developers
  • 30 days of post-deployment support
  • Source code and deployment scripts
Common mistakes when doing it yourself
  • Incorrect CORS headers (not all methods allowed)
  • Missing request limits (security vulnerability)
  • Serializing the entire $page object (leaks extra data, slow response)
  • No caching — every request hits the DB

We account for all of this from day one.

How We Do It: Phases

  1. Analysis: Study the template and field structure; determine required endpoints.
  2. Design: Map the data schema and decide what to expose to the client.
  3. Implementation: Write the template router or configure GraphQL; set up caching.
  4. Testing: Verify all endpoints; perform load testing (100 concurrent requests).
  5. Deployment: Push to production server; set up monitoring.

We guarantee the result: if the API is not working after 4 days, we finish it free of charge. Experience: 30+ ProcessWire projects.

A ProcessWire REST API is developed 2–3 times faster than on WordPress with plugins, thanks to the unified selector syntax.

Our Edge: 30+ ProcessWire API Projects

With 7+ years of ProcessWire expertise, 30+ projects, and 5+ years on the market, we have proven experience. Over the years of working with ProcessWire, we have built APIs for e-commerce platforms, SaaS services, and content portals. We know the non-obvious constraints: PermissionManager behavior in headless mode, ProCache nuances with Bearer tokens, and fieldgroup peculiarities when serializing nested objects. The most loaded configuration from our practice handles 100,000 requests per day on a 4 GB RAM server without degradation. We are ready to take on any complexity: from a basic REST API with five endpoints to GraphQL with persisted queries and real-time subscriptions. Send us a description of your project—we will propose the optimal stack and estimate the work within one business day.

With over 7 years of ProcessWire development experience and 30+ completed API projects, we ensure reliable delivery. Get a consultation for your project—contact us and we will provide an estimate within one day.