Articles
Create, list, and manage AI-generated SEO articles.
The Articles API lets you programmatically generate long-form SEO content, retrieve existing articles, and monitor generation progress. All endpoints require a valid API key. Article generation is asynchronous. Start a job with the generate endpoint, then poll the status endpoint until it reports is_complete.
There is no published status. A finished, published article has status cms. There is also no generating and no scheduled status. Filtering on any of those returns an empty list. This is the single most common mistake when integrating.
| Method | Endpoint | Description |
|---|---|---|
GET | /api/v1/articles | List articles (paginated, filterable) |
GET | /api/v1/articles/:id | Get a single article with full content |
POST | /api/v1/articles/generate | Generate an article (1.5 credits, write permission) |
GET | /api/v1/articles/:id/status | Check article generation status |
/api/v1/articlesReturns a paginated list of your articles. Supports filtering by status, project, and search query. Results are sorted by creation date descending by default.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| page | integer | Optional | Page number (1-indexed)(default: 1) |
| limit | integer | Optional | Results per page (1-100)(default: 20) |
| status | string | Optional | Filter by status: draft, queued, cms, needs_editing, failed, archived. Note there is no "published" value, use cms. |
| project_id | uuid | Optional | Filter by project ID |
| search | string | Optional | Search articles by title (case-insensitive partial match) |
| sort | string | Optional | Sort field: created_at, updated_at, title(default: created_at) |
| order | string | Optional | Sort order: asc, desc(default: desc) |
curl "https://www.brainpercent.app/api/v1/articles?page=1&limit=10&status=cms" \
-H "Authorization: Bearer bp_your_key"{
"success": true,
"data": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"title": "The Complete Guide to SEO in 2026",
"slug": "complete-guide-seo-2026",
"status": "cms",
"meta_description": "Learn the latest SEO strategies and techniques for 2026...",
"created_at": "2026-01-15T10:00:00Z",
"updated_at": "2026-01-20T14:30:00Z",
"project_id": "d290f1ee-6c54-4b01-90e6-d701748f0851"
}
],
"pagination": {
"total": 42,
"page": 1,
"limit": 10,
"total_pages": 5,
"has_more": true
}
}/api/v1/articles/:idReturns the full article row for a single article, including the rendered content. Returns 404 if the article does not exist or is not owned by your account.
curl https://www.brainpercent.app/api/v1/articles/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
-H "Authorization: Bearer bp_your_key"{
"success": true,
"data": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"title": "The Complete Guide to SEO in 2026",
"slug": "complete-guide-seo-2026",
"status": "cms",
"content": "<h2>Introduction</h2><p>Search engine optimization continues to evolve...</p>",
"meta_description": "Learn the latest SEO strategies and techniques for 2026...",
"project_id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
"created_at": "2026-01-15T10:00:00Z",
"updated_at": "2026-01-20T14:30:00Z"
}
}/api/v1/articles/generateStart asynchronous article generation. Returns the new article ID with an initial status of 'queued'. Poll /api/v1/articles/:id/status for progress. Requires write permission and costs 1.5 credits from your single account balance. project_id is required: the project supplies the brand, business context, and output language. In the 202 body, credits_deducted is the number of articles billed and credits_remaining is how many more articles your balance covers, so check GET /api/v1/user/credits for the balance itself.
Request Body
| Name | Type | Required | Description |
|---|---|---|---|
| topic | string | Required | The article topic or title (3-500 characters) |
| project_id | uuid | Required | The project this article belongs to. Supplies the brand, business context, and output language. |
| keywords | string[] | Optional | Target SEO keywords (max 20 items) |
| tone | string | Optional | Writing tone: professional, casual, academic, conversational |
| word_count | integer | Optional | Target word count (300-5000)(default: 800) |
curl -X POST https://www.brainpercent.app/api/v1/articles/generate \
-H "Authorization: Bearer bp_your_key" \
-H "Content-Type: application/json" \
-d '{
"topic": "Content Marketing Strategies That Actually Convert",
"project_id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
"keywords": ["content marketing", "conversion", "automation"],
"tone": "professional",
"word_count": 1200
}'{
"success": true,
"data": {
"article_id": "f8c9d0e1-2345-6789-abcd-ef0123456789",
"status": "queued",
"job_id": "01JQ8Z3M4N5P6Q7R8S9T0U1V2W",
"slug": "content-marketing-strategies-that-actually-convert",
"language": "en",
"credits_deducted": 1,
"credits_remaining": 32,
"estimated_time": "10-15 minutes",
"poll_url": "/api/v1/articles/f8c9d0e1-2345-6789-abcd-ef0123456789/status"
}
}/api/v1/articles/:id/statusCheck the generation progress of an article. Poll this endpoint after calling the generate endpoint until is_complete is true, or until the status is 'failed'. is_complete is true when the status is cms or needs_editing.
curl https://www.brainpercent.app/api/v1/articles/f8c9d0e1-2345-6789-abcd-ef0123456789/status \
-H "Authorization: Bearer bp_your_key"{
"success": true,
"data": {
"article_id": "f8c9d0e1-2345-6789-abcd-ef0123456789",
"status": "queued",
"title": "Content Marketing Strategies That Actually Convert",
"slug": "content-marketing-strategies-that-actually-convert",
"progress": 65,
"is_complete": false,
"created_at": "2026-02-01T12:00:00Z",
"updated_at": "2026-02-01T12:04:32Z"
}
}Article Statuses
The status field is one of exactly six values:
| Status | Description |
|---|---|
draft | Article exists but has not been published. |
queued | Generation job has been accepted and is running. Poll the status endpoint. |
cms | Finished and published. This is the terminal success state, there is no "published" status. |
needs_editing | Generation finished but the article is flagged for review before it goes live. Counts as complete. |
failed | Generation failed. |
archived | Article has been archived and is no longer part of the active set. |
published, generating, and scheduled are not article statuses. Use cms for published articles and queued for in-flight generations.
Permissions & Scopes
Each endpoint requires specific API key permissions and the articles scope.
| Endpoint | Permission | Scope |
|---|---|---|
| GET /api/v1/articles | read | articles |
| GET /api/v1/articles/:id | read | articles |
| POST /api/v1/articles/generate | write | articles |
| GET /api/v1/articles/:id/status | read | articles |
New keys are created with ["read"] by default. A key without the write permission receives a 403 from the generate endpoint.
Error Responses
Common error responses for article endpoints:
| Status | Code | When |
|---|---|---|
| 400 | VALIDATION_ERROR | Missing topic or project_id, invalid tone, word_count outside 300-5000, more than 20 keywords |
| 402 | INSUFFICIENT_CREDITS | Not enough credits to cover the generation |
| 403 | FORBIDDEN | API key lacks write permission or the articles scope |
| 404 | NOT_FOUND | Article or project does not exist, or is not owned by your account |
Generation Flow
Article generation is asynchronous and typically takes 10 to 15 minutes. The flow is:
POST /articles/generate → returns 202 with article_id, status queued, and a poll_urlGET /articles/:id/status → poll until is_complete is true (30-second intervals are plenty)cms or needs_editing (success), or failedGET /articles/:id → retrieve the complete article with contentResponse Field Reference
Fields returned in article responses:
| Field | Type | Description |
|---|---|---|
| id | uuid | Unique article identifier |
| title | string | Generated article title |
| slug | string | URL-friendly version of the title |
| status | string | One of draft, queued, cms, needs_editing, failed, archived |
| content | string | Article body (only in single-article responses) |
| meta_description | string | SEO meta description |
| project_id | uuid | Project the article belongs to |
| created_at | datetime | ISO 8601 creation timestamp |
| updated_at | datetime | ISO 8601 last update timestamp |
| progress | integer | Generation progress percentage (status endpoint only) |
| is_complete | boolean | True when status is cms or needs_editing (status endpoint only) |