Skip to main content
The ChatFeatured REST API allows you to query, create, and manage your articles programmatically. Use API keys to authenticate requests and build custom workflows, integrations, or applications on top of your ChatFeatured content. Status: Available | Complexity: Intermediate | Use cases: Custom automation, third-party integrations, mobile apps
The REST API is perfect for building custom integrations, automating publishing workflows, or syncing content to external platforms. It gives you full programmatic control over your articles.

Authentication

All API requests require authentication via API Key:

Headers

Authorization: Bearer YOUR_API_KEY
or
X-API-Key: YOUR_API_KEY

Create an API Key

  1. In ChatFeatured, go to Integrations → REST API
  2. Click Create API Key
  3. Name it descriptively (e.g., “Mobile App”, “Automation Script”)
  4. Copy the key immediately (only shown once)
Security: Treat API Keys like passwords. Never commit them to version control or expose in client-side code. Store them in environment variables instead.

Base URL

All API requests use:
https://api.chatfeatured.com/v1
Use HTTPS only. HTTP requests will be rejected for security.

Endpoints

List Articles

List all articles with optional filtering.
GET /articles
Query Parameters:
ParameterTypeDescription
statusstringFilter: published, draft, scheduled, review
limitnumberMax results per page (default: 20, max: 100)
offsetnumberPagination offset (default: 0)
Example with curl:
curl https://api.chatfeatured.com/v1/articles?status=published&limit=10 \
  -H "Authorization: Bearer YOUR_API_KEY"
Example with Python:
import requests

response = requests.get(
    'https://api.chatfeatured.com/v1/articles',
    params={'status': 'published', 'limit': 10},
    headers={'Authorization': 'Bearer YOUR_API_KEY'}
)
articles = response.json()
Example with JavaScript:
const response = await fetch(
  'https://api.chatfeatured.com/v1/articles?status=published&limit=10',
  {
    headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
  }
);
const articles = await response.json();
Response:
{
  "data": [
    {
      "id": "abc123",
      "title": "AI Trends in 2026",
      "slug": "ai-trends-2026",
      "status": "published",
      "excerpt": "What's new in AI this year...",
      "content": "<p>Full HTML content...</p>",
      "featuredImage": "https://...",
      "createdAt": "2026-05-20T10:00:00Z",
      "publishedAt": "2026-05-21T14:30:00Z"
    }
  ],
  "pagination": {
    "offset": 0,
    "limit": 10,
    "total": 42
  }
}

Get Single Article

Retrieve a specific article by ID or slug.
GET /articles/{id}
GET /articles/{slug}
Example with curl:
curl https://api.chatfeatured.com/v1/articles/ai-trends-2026 \
  -H "Authorization: Bearer YOUR_API_KEY"
Example with Python:
response = requests.get(
    'https://api.chatfeatured.com/v1/articles/ai-trends-2026',
    headers={'Authorization': 'Bearer YOUR_API_KEY'}
)
article = response.json()
Example with JavaScript:
const response = await fetch(
  'https://api.chatfeatured.com/v1/articles/ai-trends-2026',
  { headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }
);
const article = await response.json();

Publish Article

Publish a draft article or change publication status.
POST /articles/{id}/publish
Body:
{
  "status": "published",
  "publishedAt": "2026-05-22T14:00:00Z"
}
Example with curl:
curl -X POST https://api.chatfeatured.com/v1/articles/abc123/publish \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status": "published"}'
Example with Python:
response = requests.post(
    'https://api.chatfeatured.com/v1/articles/abc123/publish',
    json={'status': 'published'},
    headers={'Authorization': 'Bearer YOUR_API_KEY'}
)
Example with JavaScript:
const response = await fetch(
  'https://api.chatfeatured.com/v1/articles/abc123/publish',
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer YOUR_API_KEY'
    },
    body: JSON.stringify({ status: 'published' })
  }
);

Webhooks

Get notified when articles change status via webhooks.
Webhooks let your application react to events in real-time. For example, automatically sync articles to your CMS when they’re published, or send Slack notifications when articles are ready for review.

Configure Webhooks

  1. Go to Integrations → REST API
  2. Scroll to Webhooks section
  3. Enter your Webhook URL
  4. (Optional) Enter a Signing Secret for security
  5. Select which events to receive:
    • Article ready for review
    • Article published
  6. Save webhook settings

Webhook Events

Event: article.review Fires when an article finishes generating and is ready for review.
{
  "event": "article.review",
  "timestamp": "2026-03-20T12:00:00.000Z",
  "data": {
    "id": "abc123",
    "title": "Your Article Title",
    "slug": "your-article-title",
    "status": "review",
    "excerpt": "A brief excerpt...",
    "content": "<p>Full HTML content...</p>",
    "metadata": {
      "articleType": "guide",
      "description": "A brief excerpt..."
    }
  }
}
Event: article.published Fires when an article is published.
{
  "event": "article.published",
  "timestamp": "2026-03-20T12:00:00.000Z",
  "data": {
    "id": "abc123",
    "title": "Your Article Title",
    "slug": "your-article-title",
    "status": "published",
    "publishedAt": "2026-03-20T12:00:00.000Z"
  }
}

Webhook Security

If you configured a Signing Secret, each webhook includes an X-Webhook-Signature header:
X-Webhook-Signature: sha256=hex_encoded_signature
Verify the signature with Python:
import hmac
import hashlib

def verify_webhook(payload, signature, secret):
    expected = hmac.new(
        secret.encode(),
        payload.encode(),
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)
Verify the signature with JavaScript:
const crypto = require('crypto');

function verifyWebhook(payload, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  return crypto.timingSafeEqual(expected, signature);
}
Always verify webhook signatures to ensure requests are genuinely from ChatFeatured.

Error Handling

{
  "error": "unauthorized",
  "message": "Invalid or missing API key"
}
Cause: Invalid or missing API Key
Solution: Generate new API Key, verify header format (Authorization: Bearer KEY or X-API-Key: KEY)
{
  "error": "not_found",
  "message": "Article not found"
}
Cause: Article doesn’t exist or wrong ID/slug
Solution: Verify article ID or slug, check if article was deleted
{
  "error": "rate_limited",
  "message": "Too many requests. Retry after 60 seconds"
}
Cause: Too many requests in short time
Solution: Wait time in X-RateLimit-Reset header, implement exponential backoff, reduce frequency
{
  "error": "server_error",
  "message": "An internal error occurred"
}
Cause: Unexpected server error
Solution: Retry with exponential backoff, check status page, contact support if persists

Rate Limiting

API requests are rate limited per API Key:
  • Free tier: 100 requests/hour
  • Pro tier: 1,000 requests/hour
  • Enterprise: Custom limits
Response headers indicate your remaining quota:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1653313200
Check rate limit headers in every response. When you’re close to the limit, throttle requests or implement backoff.

Use Cases

Automated Publishing

import requests
import schedule

def publish_article():
    response = requests.post(
        'https://api.chatfeatured.com/v1/articles/article-123/publish',
        json={'status': 'published'},
        headers={'Authorization': f'Bearer {API_KEY}'}
    )
    print(f"Published: {response.json()}")

schedule.every().day.at("09:00").do(publish_article)

Sync to External CMS

def sync_to_wordpress(article_id):
    # Get article from ChatFeatured
    cf_response = requests.get(
        f'https://api.chatfeatured.com/v1/articles/{article_id}',
        headers={'Authorization': f'Bearer {CF_API_KEY}'}
    )
    article = cf_response.json()
    
    # Post to WordPress
    wp_response = requests.post(
        'https://yourwordpress.com/wp-json/wp/v2/posts',
        json={
            'title': article['title'],
            'content': article['content'],
            'status': 'publish'
        },
        auth=('user', 'password')
    )
    return wp_response.status_code

Monitor Article Status

def check_article_status():
    response = requests.get(
        'https://api.chatfeatured.com/v1/articles?status=review&limit=100',
        headers={'Authorization': f'Bearer {API_KEY}'}
    )
    
    articles = response.json()['data']
    print(f"Articles waiting for review: {len(articles)}")
    for article in articles:
        print(f"- {article['title']}")

Best Practices

  • Store API Keys in environment variables
  • Use different keys for different applications
  • Implement exponential backoff for retries
  • Validate webhook signatures
  • Handle errors gracefully
Don’t commit API Keys to version control
Don’t share API Keys across applications
Don’t expose Keys in client-side code
Don’t ignore rate limit headers

Troubleshooting

Cause: Invalid API KeySolution:
  • Generate new API Key in ChatFeatured
  • Verify key is not expired
  • Check header format: Authorization: Bearer KEY or X-API-Key: KEY
  • Verify no extra spaces or truncation in key
Cause: Too many requestsSolution:
  • Check X-RateLimit-Reset header for wait time
  • Implement exponential backoff (1s, 2s, 4s, etc.)
  • Reduce request frequency
  • Upgrade plan if you need higher limits
Cause: URL is unreachable or returns errorSolution:
  • Verify webhook URL is publicly accessible
  • Ensure endpoint returns 200 OK response
  • Check server logs for incoming requests
  • Test with a tool like webhook.cool
  • Verify webhook secret is correct if configured

See Also