API Documentation
Use the REST API to programmatically manage your helpdesk content
Create a category and article in 3 steps
const API_KEY = "hdh_your_api_key";
const BASE_URL = "https://helpdesky.io/api/v1";
const headers = {
"X-API-Key": API_KEY,
"Content-Type": "application/json",
};
// 1. Create a category
const catRes = await fetch(`${BASE_URL}/categories`, {
method: "POST",
headers,
body: JSON.stringify({
name: "Getting Started",
description: "Help users get set up",
}),
});
const { data: category } = await catRes.json();
// 2. Create an article in that category
const articleRes = await fetch(`${BASE_URL}/articles`, {
method: "POST",
headers,
body: JSON.stringify({
title: "How to create your first project",
content: "## Welcome\n\nFollow these steps to get started:\n\n1. Click **New Project**\n2. Enter a name\n3. Choose a template\n\nThat's it!",
categoryId: category.id,
published: true,
}),
});
const { data: article } = await articleRes.json();
console.log("Created:", article.title);
All API requests require an API key sent via the X-API-Key header.
Generate your API key from your dashboard under Settings > API Integration.
curl -X GET https://helpdesky.io/api/v1/categories \ -H "X-API-Key: hdh_your_api_key_here"
Base URL: https://helpdesky.io/api/v1
Content Type: application/json
CRUD operations for organising articles into categories
/api/v1/categories
List all categories in your helpdesk
Example
curl -X GET https://helpdesky.io/api/v1/categories \ -H "X-API-Key: hdh_your_api_key"
Response
{
"data": [
{
"id": "abc123",
"name": "Getting Started",
"slug": "getting-started",
"description": "Introductory guides",
"icon": "folder",
"order": 0
}
]
}
/api/v1/categories
Create a new category
Request Body
{
"name": "Getting Started", // required
"description": "Intro guides", // optional
"icon": "book-open" // optional, default: "folder"
}
Example
curl -X POST https://helpdesky.io/api/v1/categories \
-H "X-API-Key: hdh_your_api_key" \
-H "Content-Type: application/json" \
-d '{"name": "Getting Started", "description": "Introductory guides"}'
Response
{
"data": {
"id": "abc123",
"name": "Getting Started",
"slug": "getting-started",
"description": "Introductory guides",
"icon": "folder",
"order": 0
}
}
/api/v1/categories/:id
Update a category. Only include the fields you want to change.
Request Body
{
"name": "New Name", // optional
"description": "Updated desc", // optional
"icon": "star", // optional
"order": 1 // optional
}
Example
curl -X PATCH https://helpdesky.io/api/v1/categories/CATEGORY_ID \
-H "X-API-Key: hdh_your_api_key" \
-H "Content-Type: application/json" \
-d '{"name": "Updated Name"}'
Response
{
"data": {
"id": "abc123",
"name": "Updated Name",
"slug": "getting-started",
"description": "Introductory guides",
"icon": "folder",
"order": 0
}
}
/api/v1/categories/:id
Delete a category and all its articles
Example
curl -X DELETE https://helpdesky.io/api/v1/categories/CATEGORY_ID \ -H "X-API-Key: hdh_your_api_key"
Response
{
"data": {
"success": true
}
}
CRUD operations for managing helpdesk articles
/api/v1/articles
List all articles. Optionally filter by category using the categoryId query parameter.
Example
curl -X GET "https://helpdesky.io/api/v1/articles?categoryId=CATEGORY_ID" \ -H "X-API-Key: hdh_your_api_key"
Response
{
"data": [
{
"id": "def456",
"title": "How to reset your password",
"slug": "how-to-reset-your-password",
"content": "## Steps\n\n1. Click **Forgot Password**...",
"excerpt": "Learn how to reset your password",
"published": true,
"categoryId": "abc123",
"order": 0
}
]
}
/api/v1/articles
Create a new article. Content should be in Markdown format.
Request Body
{
"title": "How to reset your password", // required
"content": "## Steps\n\n1. Click...", // required, Markdown
"slug": "reset-password", // optional, auto-generated from title if omitted
"excerpt": "Short summary", // optional
"categoryId": "abc123", // optional
"published": true, // optional, default: false
"numberHeadings": true // optional, default: false — numbers H2 headings
}
Example
curl -X POST https://helpdesky.io/api/v1/articles \
-H "X-API-Key: hdh_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"title": "How to reset your password",
"content": "## Steps\n\n1. Click **Forgot Password**\n2. Enter your email\n3. Check your inbox",
"categoryId": "CATEGORY_ID",
"published": true
}'
Response
{
"data": {
"id": "def456",
"title": "How to reset your password",
"slug": "reset-password",
"content": "## Steps\n\n1. Click **Forgot Password**...",
"excerpt": null,
"published": true,
"numberHeadings": false,
"categoryId": "abc123",
"order": 0
}
}
/api/v1/articles/:id
Update an article. Only include the fields you want to change. Changing the slug on a published article automatically creates a 301 redirect from the old URL.
Request Body
{
"title": "Updated Title", // optional
"content": "New content...", // optional, Markdown
"slug": "new-url-handle", // optional — auto-redirect created for published articles
"excerpt": "Updated summary", // optional
"categoryId": "abc123", // optional
"published": true, // optional
"numberHeadings": true, // optional — numbers H2 headings
"order": 2 // optional
}
Example
curl -X PATCH https://helpdesky.io/api/v1/articles/ARTICLE_ID \
-H "X-API-Key: hdh_your_api_key" \
-H "Content-Type: application/json" \
-d '{"published": true}'
Response
{
"data": {
"id": "def456",
"title": "How to reset your password",
"slug": "new-url-handle",
"content": "## Steps...",
"published": true,
"numberHeadings": true,
"categoryId": "abc123",
"order": 0
}
}
/api/v1/articles/:id
Delete an article permanently
Example
curl -X DELETE https://helpdesky.io/api/v1/articles/ARTICLE_ID \ -H "X-API-Key: hdh_your_api_key"
Response
{
"data": {
"success": true
}
}
Upload images to use in article content
/api/v1/images
Upload an image file. Returns a URL you can embed in article content using HTML or Markdown (see format options below). Maximum file size is 5MB. Allowed types: JPG, PNG, GIF, WebP, SVG.
Request
Send a multipart/form-data request with the image in a field named image.
Example
curl -X POST https://helpdesky.io/api/v1/images \ -H "X-API-Key: hdh_your_api_key" \ -F "image=@/path/to/screenshot.png"
Response
{
"url": "/api/images/uploads/USER_ID/abc123-screenshot.png",
"filename": "screenshot.png",
"size": 245760,
"contentType": "image/png"
}
Use the returned url in your article content. There are two formats you can use:
Option 1: HTML (recommended)
Use an HTML <img> tag to control the display size with width and/or height attributes. This is the same format used by the dashboard visual editor.
<img src="/api/images/uploads/USER_ID/abc123-screenshot.png" width="400" />
Option 2: Markdown
Standard Markdown image syntax. Simple, but the image always displays at its full original size — there is no way to set dimensions.

Tip: We recommend HTML for most use cases — it gives you full control over how large images appear in your articles. Both formats are supported anywhere in your article content and can be mixed freely.
All errors return a JSON object with an error field:
401 Missing or invalid API key
{
"error": "Missing X-API-Key header"
}
400 Missing required fields or invalid data
{
"error": "Title is required"
}
404 Resource not found or doesn't belong to your helpdesk
{
"error": "Category not found"
}
429 Rate limit exceeded (60 requests per minute per API key)
{
"error": "Rate limit exceeded. Please try again later."
}
500 Server error
{
"error": "Internal server error"
}
Supported syntax for article content
Article content uses Markdown. In addition to standard syntax (headings, bold, italic, lists, links, images, code blocks), we support:
Tables
Use pipe syntax to create tables. The first row becomes the header.
| Feature | Status | Notes | | ----------- | --------- | ----------------- | | Markdown | Supported | Full GFM syntax | | Tables | Supported | Auto-styled | | Callouts | Supported | info/warning/danger |
Callout Blocks
Highlight important information with callout blocks using blockquote syntax:
> [!info] > This is an informational note. > [!warning] > Be careful with this setting. > [!danger] > This action cannot be undone.
YouTube Embeds
Paste a YouTube URL on its own line to auto-embed the video:
https://www.youtube.com/watch?v=VIDEO_ID
Slugs
Slugs are auto-generated from the article title or category name if not provided, but you can set a custom slug when creating an article or category via POST. You can also change the slug later with PATCH. If you change the slug on a published article, a 301 redirect is automatically created from the old URL to the new one.
Public URLs
Article slugs determine the public URL of each article. The URL format depends on whether you use a custom domain:
Path-based (default): https://helpdesky.io/help/{helpdesk-slug}/{article-slug}
Custom domain: https://{your-domain}/{article-slug}
On custom domains, articles are served directly at the root. The /articles path (without a slug) is a separate page that lists all published articles.
Pagination
The API does not currently paginate results. All categories and articles are returned in a single response.
Filtering
Use the categoryId query parameter on GET /api/v1/articles to filter articles by category.
Rate Limiting
The API is limited to 60 requests per minute per API key. If you exceed this limit, you'll receive a 429 status code. Rate limit headers (RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset) are included in every response.
Category Icons
The following icon values are available for categories:
folder
file-text
book-open
lightbulb
help-circle
settings
zap
users
The default icon is folder if none is specified.