Skip to content

Instantly share code, notes, and snippets.

@simplistik
Last active March 4, 2026 02:12
Show Gist options
  • Select an option

  • Save simplistik/3e2747280a4c09f31978b7c3e2ad83dc to your computer and use it in GitHub Desktop.

Select an option

Save simplistik/3e2747280a4c09f31978b7c3e2ad83dc to your computer and use it in GitHub Desktop.
HPT Articles REST API

HPT Articles REST API

Endpoint

GET /wp-json/hpt/v1/articles

Public endpoint — no authentication required. Returns both post and triage post types, sorted by date descending.

Parameters

Param Type Default Description
topic string Filter by topic taxonomy slug (e.g. disparities)
search string Search articles by keyword, minimum 3 characters (matches title and content)
per_page integer 12 Number of results per request (1–100)
before string Return results older than this datetime (Y-m-d H:i:s)
after string Return results newer than this datetime (Y-m-d H:i:s)

Response Headers

Header Description
X-WP-Total Total number of matching results (stable across pages)
X-WP-Remaining Number of results remaining past the current cursor
X-Cursor-First Datetime of the newest item in the current response
X-Cursor-Last Datetime of the oldest item in the current response

These headers are exposed via CORS and accessible from JavaScript fetch responses.

Response Shape

Every item in the response array has the same shape regardless of post type:

{
  "type": "post",
  "title": "Calling Out a \"Silent Killer\"",
  "link": "https://example.com/2023/05/12/calling-out-a-silent-killer/",
  "date": "2023-05-12 04:20:00",
  "image_url": "https://example.com/wp-content/uploads/2023/05/image.jpeg",
  "topics": ["Health Disparities", "Patient Access"],
  "categories": ["Blog"],
  "tags": ["Biologics", "Rare Disease"],
  "author": "Jullia Machado",
  "excerpt": null,
  "partner": null
}

For triage items, link points to the external resource (URL or file), and excerpt/partner are populated:

{
  "type": "triage",
  "title": "Addressing Unmet Needs for Patients with Rare Vision Conditions",
  "link": "https://example.org/whitepaper.pdf",
  "date": "2023-08-18 09:15:00",
  "image_url": "https://example.com/wp-content/uploads/2023/09/image.png",
  "topics": ["Health Disparities", "Patient Access"],
  "categories": [],
  "tags": [],
  "author": "Erin Fedorchak",
  "excerpt": "White Paper",
  "partner": "Vision Health Advocacy Coalition"
}

Field Reference

Field Type Description
type string "post" or "triage"
title string Post title
link string Permalink for posts, external URL for triage
date string Publish datetime (Y-m-d H:i:s)
image_url string Featured image URL (falls back to site placeholder if none set)
topics string[] Topic taxonomy terms assigned to the post
categories string[] WordPress categories (typically empty for triage)
tags string[] WordPress post tags
author string Author display name
excerpt string? Triage description (e.g. "White Paper"). null for posts
partner string? Triage partner organization name. null for posts

Cursor-Based Pagination

This API uses datetime-based cursor pagination instead of page numbers. The cursor is the date field from the response items.

How It Works

Results are always sorted newest-first. The before and after params slice the timeline:

  • before=2023-05-26 10:31:31 → "give me articles older than this moment"
  • after=2025-08-20 13:55:39 → "give me articles newer than this moment"

Use the response headers as cursors for subsequent requests.

"Load More" Pattern (example usage)

Use this for infinite scroll or load-more-button flows. Paginate forward through older content.

First request — no cursor needed:

GET /wp-json/hpt/v1/articles?topic=disparities

Response (12 items):

X-WP-Total: 46
X-WP-Remaining: 46
X-Cursor-First: 2025-10-02 10:09:16
X-Cursor-Last: 2023-05-26 10:31:31

Second request — pass X-Cursor-Last as the before param:

GET /wp-json/hpt/v1/articles?topic=disparities&before=2023-05-26 10:31:31

Response (12 items):

X-WP-Total: 46
X-WP-Remaining: 34
X-Cursor-First: 2023-05-12 04:20:00
X-Cursor-Last: 2023-01-19 11:31:14

Third request — pass the new X-Cursor-Last:

GET /wp-json/hpt/v1/articles?topic=disparities&before=2023-01-19 11:31:14

Repeat until X-WP-Remaining is less than or equal to per_page (no more pages).

Checking for More Results

Compare X-WP-Remaining to per_page after each response. If X-WP-Remaining <= per_page, there are no more results to load.

  • X-WP-Total — stable total across all pages (ignores cursor filters)
  • X-WP-Remaining — how many items match the current cursor-filtered query

Search Examples

Search across all articles:

GET /wp-json/hpt/v1/articles?search=cancer

Response (12 items):

X-WP-Total: 132
X-WP-Remaining: 132
X-Cursor-First: 2026-02-20 14:45:45
X-Cursor-Last: 2025-04-15 13:44:48

Search within a topic:

GET /wp-json/hpt/v1/articles?search=cancer&topic=disparities

Response (4 items):

X-WP-Total: 4
X-WP-Remaining: 4
X-Cursor-First: 2025-08-20 13:55:39
X-Cursor-Last: 2022-03-03 04:18:00

Search combines with all other params. Add before/after to paginate search results.

Using after for Refresh / New Content

Check for newer content published since the last fetch by passing X-Cursor-First as the after param:

GET /wp-json/hpt/v1/articles?topic=disparities&after=2025-10-02 10:09:16

An empty response means no new content.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment