If you want a flexible, API-driven changelog for your product, changes.page offers a simple, headless backend that you can integrate into any custom UI. This guide will walk you through the available APIs and how to use them to power your own changelog frontend.
Why Use changes.page as a Headless Backend?
- Separation of content and presentation: Manage your changelog content in changes.page, but display it however you want in your app or website.
- Easy integration: Simple REST APIs return JSON, making it easy to fetch and display changelog data in any frontend framework.
- No lock-in: You control the UI/UX, while changes.page handles the backend and content management.
Setting Up Your Changelog Page
- Create a changelog page at changes.page.
- Add your posts, pin important updates, and organize your changelog as needed.
API Overview
changes.page provides several endpoints for fetching changelog data:
- Get latest post:
/latest.json
- Get pinned post:
/pinned.json
- Get all posts:
/changes.json
- Get post by ID:
/changes.json/:id
Replace yourpage
in the URLs below with your actual changes.page subdomain.
1. Fetch the Latest Post
Endpoint:
GET https://yourpage.changes.page/latest.json
Example Response:
{
"id": "b0cb4fde-8f17-4ee2-b292-196a6f2e748e",
"title": "New UI, pinned post & more!",
"content": "We've made several tweaks to the UI across the app and the most important change is the new editor.",
"type": "announcement",
"created_at": "2022-11-01T11:46:25.719707+00:00"
}
Usage:
Display the most recent update in your app, e.g., as a banner or notification.
2. Fetch the Pinned Post
Endpoint:
GET https://yourpage.changes.page/pinned.json
Example Response:
{
"id": "b0cb4fde-8f17-4ee2-b292-196a6f2e748e",
"title": "New UI, pinned post & more!",
"content": "We've made several tweaks to the UI across the app and the most important change is the new editor.",
"type": "announcement",
"created_at": "2022-11-01T11:46:25.719707+00:00"
}
Usage:
Highlight a key update at the top of your changelog page.
3. Fetch All Posts (with Pagination)
Endpoint:
GET https://yourpage.changes.page/changes.json
Optional Query Parameter:
offset
(for pagination, defaults to 0)
Example Request:
GET https://yourpage.changes.page/changes.json?offset=10
Example Response:
[
{
"id": "cf8c52a9-27b3-47df-9f22-0c0af15cfaca",
"title": "Unlock Teamwork with Our Latest Feature Update",
"content": "We're kicking off 2025 by introducing one of our most highly requested features!",
"tags": ["announcement", "new"],
"publication_date": "2025-02-14T12:22:16.571+00:00",
"updated_at": "2025-02-14T12:22:17.887817+00:00",
"created_at": "2025-02-14T09:42:52.934045+00:00",
"url": "https://hey.changes.page/post/cf8c52a9-27b3-47df-9f22-0c0af15cfaca/unlock-teamwork-with-our-latest-feature-update",
"plain_text_content": "We're kicking off 2025 by introducing one of our most highly requested features!"
}
]
Usage:
Render a list of all changelog entries in your custom UI, with support for pagination.
4. Fetch a Post by ID
Endpoint:
GET https://yourpage.changes.page/changes.json/:id
Example Request:
GET https://yourpage.changes.page/changes.json/cf8c52a9-27b3-47df-9f22-0c0af15cfaca
Example Response:
{
"id": "cf8c52a9-27b3-47df-9f22-0c0af15cfaca",
"title": "Unlock Teamwork with Our Latest Feature Update",
"content": "We're kicking off 2025 by introducing one of our most highly requested features!",
"tags": ["announcement", "new"],
"publication_date": "2025-02-14T12:22:16.571+00:00",
"updated_at": "2025-02-14T12:22:17.887817+00:00",
"created_at": "2025-02-14T09:42:52.934045+00:00",
"url": "https://hey.changes.page/post/cf8c52a9-27b3-47df-9f22-0c0af15cfaca/unlock-teamwork-with-our-latest-feature-update",
"plain_text_content": "We're kicking off 2025 by introducing one of our most highly requested features!"
}
Usage:
Show a detailed view of a single changelog entry, e.g., when a user clicks on a post.
Example: Fetching and Displaying Posts in JavaScript
async function fetchChangelogPosts() {
const response = await fetch('https://yourpage.changes.page/changes.json');
const posts = await response.json();
// Render posts in your UI
posts.forEach(post => {
// Example: create a card for each post
console.log(post.title, post.content);
});
}
Tips for Building Your Custom UI
- Cache responses for performance, especially if your changelog doesn't change often.
- Handle null responses (e.g., if there is no pinned post).
- Paginate if you have many posts (use the
offset
parameter). - Use the
plain_text_content
field for simple rendering, orcontent
for rich formatting.
References
With these APIs, you can build a fully custom changelog experience in your app, while letting changes.page handle the backend and content management. Happy building!
Let me know if you want a code sample for a specific frontend framework or more advanced integration tips!