API Documentation
Autofocus provides REST API endpoints for content delivery, integration, and automation. Access user profiles, pages, and blocks programmatically for custom applications and external integrations.
🌐 API Overview
Base URL
https://autofoc.us/api
All API endpoints are accessed via this base URL with RESTful patterns.
Response Format
Content-Type: application/json
All responses are returned in JSON format with consistent error handling.
📦 Content Delivery API
Get User Profile
GET /api/user/[username]
Retrieve public profile information for a user.
Example Request
curl https://autofoc.us/api/user/nate -H "Accept: application/json"
Example Response
{
"id": "uuid",
"username": "nate",
"display_name": "Nate",
"bio": "Creator bio text",
"avatar_url": "https://...",
"social_links": {...},
"created_at": "2024-01-01T00:00:00Z"
}Get Page Content
GET /[username]/[page]?api=1
Retrieve all blocks for a specific page in JSON format.
Example Request
curl https://autofoc.us/nate/portfolio?api=1 -H "Accept: application/json"
Example Response
[
{
"id": "uuid",
"type": "markdown",
"content": {
"text": "# Welcome to my page"
},
"order_index": 0,
"created_at": "2024-01-01T00:00:00Z"
},
{
"id": "uuid",
"type": "image",
"content": {
"url": "https://...",
"alt": "Photo description"
},
"order_index": 1
}
]🔐 Authentication & Verification
Verify Redirect Password
POST /api/verify-redirect-password
Verify password for protected redirect pages.
Request Body
{
"username": "nate",
"pageSlug": "private-page",
"password": "secret123"
}Response
{
"success": true
}
// Or on failure:
{
"success": false,
"error": "Invalid password"
}🧩 Block Types API Reference
Each block type has a consistent structure but different content schemas. Here are the main block types and their API formats:
Text/Markdown Block
{
"type": "markdown",
"content": {
"text": "# Heading\n\nParagraph text"
}
}Image Block
{
"type": "image",
"content": {
"url": "https://example.com/image.jpg",
"alt": "Image description",
"caption": "Optional caption"
}
}Link Block
{
"type": "link",
"content": {
"url": "https://example.com",
"title": "Link Title",
"description": "Description text"
}
}Checklist Block
{
"type": "checklist",
"content": {
"items": [
{"text": "Task 1", "completed": false},
{"text": "Task 2", "completed": true}
]
}
}Code Block
{
"type": "code",
"content": {
"code": "console.log('Hello');",
"language": "javascript",
"theme": "dark"
}
}Audio Block
{
"type": "audio",
"content": {
"url": "https://example.com/audio.mp3",
"title": "Audio Title",
"duration": 180
}
}Location Block
{
"type": "location",
"content": {
"latitude": 40.7128,
"longitude": -74.0060,
"title": "Location Name",
"description": "Details"
}
}Kanban Block
{
"type": "kanban",
"content": {
"columns": [
{
"title": "To Do",
"cards": [
{"title": "Task", "description": "Details"}
]
}
]
}
}⚠️ Error Handling & Status Codes
HTTP Status Codes
200Success
400Bad Request
404Not Found
500Server Error
Error Response Format
{
"error": "Profile not found",
"code": "PROFILE_NOT_FOUND",
"message": "The requested user profile does not exist.",
"timestamp": "2024-01-01T00:00:00Z"
}🚦 Rate Limiting & Best Practices
Rate Limits
• Public API: 100 requests per minute
• Authenticated API: 1000 requests per minute
• Bulk operations: 10 requests per minute
• Rate limit headers included in responses
Best Practices
• Cache responses when possible
• Use pagination for large datasets
• Implement exponential backoff for retries
• Monitor rate limit headers
• Use webhook subscriptions for real-time updates
🔌 Integration Examples
JavaScript/Node.js
// Fetch user profile
const response = await fetch('https://autofoc.us/api/user/nate');
const profile = await response.json();
// Get page blocks
const pageResponse = await fetch('https://autofoc.us/nate/portfolio?api=1');
const blocks = await pageResponse.json();
// Filter for specific block types
const imageBlocks = blocks.filter(block => block.type === 'image');
const textBlocks = blocks.filter(block => block.type === 'markdown');Python
import requests
# Get user profile
response = requests.get('https://autofoc.us/api/user/nate')
profile = response.json()
# Get page content
page_response = requests.get('https://autofoc.us/nate/portfolio?api=1')
blocks = page_response.json()
# Process blocks by type
for block in blocks:
if block['type'] == 'image':
print(f"Image: {block['content']['url']}")
elif block['type'] == 'markdown':
print(f"Text: {block['content']['text'][:100]}...")