REST API
Programmatic access to your VoidForge CMS content via a RESTful JSON API.
Introduction
The VoidForge REST API provides full CRUD (Create, Read, Update, Delete) operations for posts, pages, media, users, and taxonomies. All requests and responses use JSON format.
Features
- Full CRUD operations for all content types
- API key authentication with granular permissions
- Pagination and filtering support
- JSON request and response format
- Consistent error handling
Authentication
All API requests require authentication using an API key and secret. Include these in your request headers:
X-API-Key: your_api_key_here
X-API-Secret: your_api_secret_here
Content-Type: application/json
Example Request
curl -X GET "https://yoursite.com/api/v1/posts" \
-H "X-API-Key: vf_abc123..." \
-H "X-API-Secret: vfs_xyz789..."
API Key Management
Create and manage API keys from the admin panel at Admin → Tools → API Keys.
Creating an API Key
- Go to Admin → Tools → API Keys
- Click "Generate New Key"
- Enter a descriptive name (e.g., "Mobile App", "External Service")
- Select permissions (Read, Write, Delete)
- Optionally set an expiration date
- Copy and securely store both the Key and Secret
Permissions
| Permission | Allows |
|---|---|
read | GET requests to retrieve content |
write | POST and PUT requests to create/update content |
delete | DELETE requests to remove content |
Base URL
All API endpoints are relative to the base URL:
https://yoursite.com/api/v1/
For example, to get all posts:
GET https://yoursite.com/api/v1/posts
Posts
Manage blog posts and custom post type content.
Retrieve a list of posts with optional filtering and pagination.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
per_page | integer | Items per page (default: 10, max: 100) |
page | integer | Page number (default: 1) |
status | string | Filter by status: published, draft, trash |
post_type | string | Filter by post type (default: post) |
orderby | string | Sort field: date, title, id |
order | string | Sort direction: asc, desc |
Example Request
curl "https://yoursite.com/api/v1/posts?per_page=5&status=published" \
-H "X-API-Key: your_key" \
-H "X-API-Secret: your_secret"
Response
{
"success": true,
"data": [
{
"id": 1,
"title": "Hello World",
"slug": "hello-world",
"content": "<p>Welcome to VoidForge!</p>",
"excerpt": "Welcome to VoidForge!",
"status": "published",
"post_type": "post",
"author_id": 1,
"created_at": "2024-12-15 10:30:00",
"updated_at": "2024-12-15 10:30:00",
"published_at": "2024-12-15 10:30:00",
"url": "https://yoursite.com/hello-world"
}
],
"pagination": {
"total": 25,
"per_page": 5,
"current_page": 1,
"total_pages": 5
}
}
Retrieve a single post by ID.
Create a new post. Requires write permission.
Request Body
{
"title": "My New Post",
"content": "<p>Post content here...</p>",
"excerpt": "A short summary",
"status": "published",
"post_type": "post"
}
Update an existing post. Requires write permission.
Delete a post (moves to trash). Requires delete permission.
Pages
Manage static pages. Pages use the same structure as posts with post_type: page.
Retrieve a list of pages.
Retrieve a single page by ID.
Create a new page.
Update an existing page.
Delete a page.
Media
Manage uploaded files and images.
Retrieve a list of media files.
Response
{
"success": true,
"data": [
{
"id": 1,
"filename": "photo.jpg",
"url": "https://yoursite.com/uploads/2024/12/photo.jpg",
"mime_type": "image/jpeg",
"size": 245678,
"width": 1920,
"height": 1080,
"alt_text": "A beautiful sunset",
"created_at": "2024-12-15 10:30:00"
}
]
}
Retrieve a single media item by ID.
Upload a new media file via base64 encoding.
Request Body
{
"filename": "photo.jpg",
"data": "base64_encoded_file_content...",
"alt_text": "Description of the image"
}
Delete a media file.
Users
Retrieve user information (read-only for security).
Retrieve a list of users (excludes sensitive data).
Response
{
"success": true,
"data": [
{
"id": 1,
"username": "admin",
"display_name": "Administrator",
"role": "admin",
"avatar_url": "https://gravatar.com/...",
"created_at": "2024-12-01 09:00:00"
}
]
}
Retrieve a single user by ID.
Taxonomies
Retrieve taxonomy terms (categories, tags, custom taxonomies).
Retrieve terms for a taxonomy type.
Taxonomy Types
category— Post categoriestag— Post tags{custom}— Any custom taxonomy slug
Example Request
curl "https://yoursite.com/api/v1/taxonomies/category" \
-H "X-API-Key: your_key" \
-H "X-API-Secret: your_secret"
Response
{
"success": true,
"data": [
{
"id": 1,
"name": "Technology",
"slug": "technology",
"description": "Tech-related posts",
"parent_id": 0,
"count": 15
}
]
}
Query Parameters
Common query parameters available on list endpoints:
| Parameter | Default | Description |
|---|---|---|
per_page | 10 | Number of items per page (max: 100) |
page | 1 | Page number for pagination |
status | published | Filter by status |
orderby | date | Field to sort by |
order | desc | Sort direction (asc/desc) |
post_type | post | Filter by post type |
Example with Multiple Parameters
GET /api/v1/posts?per_page=20&page=2&status=published&orderby=title&order=asc
Response Format
All API responses follow a consistent JSON structure:
Success Response
{
"success": true,
"data": { ... },
"pagination": {
"total": 100,
"per_page": 10,
"current_page": 1,
"total_pages": 10
}
}
Error Response
{
"success": false,
"error": "Error message here"
}
HTTP Status Codes
| Code | Description |
|---|---|
200 | Success |
201 | Created (POST requests) |
400 | Bad Request (invalid parameters) |
401 | Unauthorized (invalid or missing API key) |
403 | Forbidden (insufficient permissions) |
404 | Not Found |
500 | Server Error |
Error Handling
Handle API errors gracefully in your application:
// JavaScript example
async function getPosts() {
try {
const response = await fetch('https://yoursite.com/api/v1/posts', {
headers: {
'X-API-Key': 'your_key',
'X-API-Secret': 'your_secret'
}
});
const data = await response.json();
if (!data.success) {
throw new Error(data.error);
}
return data.data;
} catch (error) {
console.error('API Error:', error.message);
}
}
Common Errors
| Error | Cause | Solution |
|---|---|---|
Missing API credentials | Headers not included | Add X-API-Key and X-API-Secret headers |
Invalid API key | Key doesn't exist or is inactive | Check key in Admin → Tools → API Keys |
Permission denied | Key lacks required permission | Update key permissions in admin |
API key expired | Key past expiration date | Generate a new API key |
Code Examples
JavaScript (Fetch)
// Get all published posts
const response = await fetch('https://yoursite.com/api/v1/posts', {
headers: {
'X-API-Key': 'your_key',
'X-API-Secret': 'your_secret'
}
});
const posts = await response.json();
// Create a new post
const newPost = await fetch('https://yoursite.com/api/v1/posts', {
method: 'POST',
headers: {
'X-API-Key': 'your_key',
'X-API-Secret': 'your_secret',
'Content-Type': 'application/json'
},
body: JSON.stringify({
title: 'My New Post',
content: '<p>Hello World!</p>',
status: 'published'
})
});
PHP (cURL)
// Get all posts
$ch = curl_init('https://yoursite.com/api/v1/posts');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'X-API-Key: your_key',
'X-API-Secret: your_secret'
]);
$response = curl_exec($ch);
$posts = json_decode($response, true);
// Create a post
$ch = curl_init('https://yoursite.com/api/v1/posts');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'X-API-Key: your_key',
'X-API-Secret: your_secret',
'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'title' => 'My New Post',
'content' => '<p>Hello World!</p>',
'status' => 'published'
]));
$response = curl_exec($ch);
Python (Requests)
import requests
headers = {
'X-API-Key': 'your_key',
'X-API-Secret': 'your_secret'
}
# Get all posts
response = requests.get('https://yoursite.com/api/v1/posts', headers=headers)
posts = response.json()
# Create a post
response = requests.post(
'https://yoursite.com/api/v1/posts',
headers={**headers, 'Content-Type': 'application/json'},
json={
'title': 'My New Post',
'content': '<p>Hello World!</p>',
'status': 'published'
}
)