SYSTEM
REFERENCE
Headless CMS API. Public reads, private writes.
One token. Multiple projects. Zero complexity.
QUICK START
Generate your token
One-time setup. Requires init secret. Save the token - it cannot be recovered.
curl -X POST https://oliphaunt.ai/api/auth/token \ -H "X-Init-Secret: YOUR_INIT_SECRET"
Create a post
Use your token to create content. SEO metadata is auto-generated.
curl -X POST https://oliphaunt.ai/api/posts \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"Hello World","content":"# Welcome","published":true}'Fetch it publicly
Published posts are readable without auth.
curl https://oliphaunt.ai/api/posts/hello-world?render=1
AUTHENTICATION
How it works
- •
INIT_SECRETrequired to generate tokens - • Token generated once, stored as SHA-256 hash
- • Pass via
Authorization: Bearer TOKEN - • Lost token? Rotate it with auth endpoint
Public vs Private
- PUBLIC: GET posts (published only)
- PRIVATE: Create, update, delete, drafts
- PRIVATE: Upload, projects, AI cover
PROJECTS (MULTI-BLOG)
Run multiple blogs from one API. Each project has isolated content.
Set project via header:
X-Project: myblog
Or via query param:
?project=myblog
Projects are created implicitly when you create your first post with a new project name.
ENDPOINTS: AUTH
/api/auth/tokenINIT-SECRETGenerate API token (one-time, requires init secret)
curl -X POST https://oliphaunt.ai/api/auth/token \ -H "X-Init-Secret: YOUR_INIT_SECRET"
/api/auth/token/rotateAUTHRotate token (invalidates old one)
curl -X POST https://oliphaunt.ai/api/auth/token/rotate \ -H "Authorization: Bearer YOUR_TOKEN"
ENDPOINTS: PROJECTS
/api/projectsAUTHList all projects with optional counts
curl -H "Authorization: Bearer YOUR_TOKEN" \ "https://oliphaunt.ai/api/projects?includeCounts=1"
ENDPOINTS: POSTS
/api/postsList posts (public: published only)
curl "https://oliphaunt.ai/api/posts?project=myblog&page=1&limit=10&render=1"
/api/postsAUTHCreate new post
curl -X POST https://oliphaunt.ai/api/posts \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-H "X-Project: myblog" \
-d '{"title":"My Post","content":"# Hello","tags":["tech"],"published":true}'/api/posts/[slug]Get single post
curl "https://oliphaunt.ai/api/posts/my-post?project=myblog&render=1"
/api/posts/[slug]AUTHUpdate post
curl -X PUT https://oliphaunt.ai/api/posts/my-post \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-H "X-Project: myblog" \
-d '{"title":"Updated Title","published":true}'/api/posts/[slug]AUTHDelete post
curl -X DELETE https://oliphaunt.ai/api/posts/my-post \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "X-Project: myblog"
/api/posts/searchSearch posts
curl "https://oliphaunt.ai/api/posts/search?q=hello&project=myblog&render=1"
/api/posts/tagsList all unique tags
curl "https://oliphaunt.ai/api/posts/tags?project=myblog"
/api/posts/authorsList all unique authors
curl "https://oliphaunt.ai/api/posts/authors?project=myblog"
/api/posts/bulkAUTHBulk delete posts (max 100)
curl -X DELETE https://oliphaunt.ai/api/posts/bulk \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-H "X-Project: myblog" \
-d '{"slugs":["post-1","post-2","post-3"]}'ENDPOINTS: MEDIA
/api/uploadsAUTHList all uploaded media
curl -H "Authorization: Bearer YOUR_TOKEN" \ "https://oliphaunt.ai/api/uploads?limit=50"
/api/uploadAUTHUpload image (jpeg, png, webp, gif)
curl -X POST "https://oliphaunt.ai/api/upload?filename=photo.jpg" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: image/jpeg" \ --data-binary @photo.jpg
/api/uploadAUTHDelete uploaded image
curl -X DELETE "https://oliphaunt.ai/api/upload?url=https://..." \ -H "Authorization: Bearer YOUR_TOKEN"
ENDPOINTS: AI COVER
/api/posts/[slug]/coverAUTHGenerate AI cover image
# With your own prompt:
curl -X POST https://oliphaunt.ai/api/posts/my-post/cover \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-H "X-Project: myblog" \
-d '{"prompt":"Minimalist cover: geometric shapes, black ink on white, bold red accents. No text or typography.","aspectRatio":"21:9"}'
# Or auto-generate prompt with Haiku:
curl -X POST "https://oliphaunt.ai/api/posts/my-post/cover?autoprompt=1" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-H "X-Project: myblog" \
-d '{}'QUERY PARAMETERS
| Param | Description |
|---|---|
| project | Filter by project (default: 'default') |
| page | Page number for pagination |
| limit | Items per page (max 100) |
| published | Filter by publish status |
| includeDrafts | Include drafts (auth required) |
| render | Include rendered HTML |
| tag | Filter by tag |
| author | Filter by author |
| includeCounts | Include post counts (projects) |
| autoprompt | Auto-generate cover prompt |
SCHEDULED PUBLISHING
Schedule posts to publish automatically at a future date/time using the publishAt field.
Create scheduled post:
curl -X POST https://oliphaunt.ai/api/posts \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Future Post",
"content": "# Coming Soon",
"publishAt": "2025-12-01T09:00:00Z"
}'Clear scheduled time:
curl -X PUT https://oliphaunt.ai/api/posts/future-post \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"publishAt": null}'How it works: A cron job runs every minute, checking for posts where publishAt has passed. When triggered, the post is automatically published and publishedAt is set to the current time.
AUTO SEO METADATA
SEO metadata (metaTitle and metaDescription) is automatically generated using AI when you create or update a post.
Auto-generated (default):
// Just create a post - SEO is generated automatically
{
"title": "My Post",
"content": "..."
}
// Response includes:
{
"metaTitle": "AI-optimized title (50-60 chars)",
"metaDescription": "AI-optimized desc (150-155 chars)"
}Override with custom SEO:
{
"title": "My Post",
"content": "...",
"metaTitle": "Custom SEO Title",
"metaDescription": "Custom meta description for search engines."
}Regeneration: SEO is regenerated when title or content changes (unless you explicitly provide metaTitle/metaDescription). Set to null to clear and regenerate.
AI COVER: PROMPT TIPS
Best Practices
- • Always include
"no text, no typography" - • Use specific hex colors from the palette
- • Request: "minimalist, black ink line art, flat color blocks"
- • Specify aspect ratio (default: 21:9)
Color Palette
Example Prompt
Minimalist scientific editorial illustration. High-contrast black ink line art on off-white background (#F8F9FA) with bold flat color blocks. Swiss design aesthetic: clean, precise, geometric composition, sharp boundaries, no gradients. Limited palette: pure black + bold red (#E63946). Abstract conceptual representation of cellular biology. No text, no letters, no words, no typography.
199 LABS
LONDON / MIAMI / SINGAPORE
Built by Boris Djordjevic