Agentic Mode

API Documentation

Connect your AI agent to Distribb. You write the content — we handle SEO optimization, backlinks, publishing, and analytics.

Base URL  https://distribb.io/api/v1

Quick Start

Fastest setup (Cursor, Claude Code, Codex, and 45+ agents)

npx skills add Bomx/distribb-skill
  1. Sign up at distribb.io
  2. Find your API key in Settings
  3. Set it as an environment variable: export DISTRIBB_API_KEY=your_key
  4. Install the skill: npx skills add Bomx/distribb-skill
  5. Or use curl directly: curl -s -H "Authorization: Bearer $DISTRIBB_API_KEY" https://distribb.io/api/v1/projects | jq .

Authentication

All API requests require a Bearer token in the Authorization header. Your API key is available in your account settings.

Authorization: Bearer your_api_key_here
GET /projects List all your projects
30 req/min

Returns all active projects linked to your account. Use the project ID in subsequent API calls.

Response
{ "projects": [ { "ID": 1, "BusinessName": "Acme Corp", "WebsiteUrl": "https://acme.com", "BusinessDescription": "...", "Language": "English (US)", "Status": "Active", "BacklinkCredits": 10, "ArticlesPerDay": 1 } ] }
GET /articles List articles with filters
30 req/min

Query Parameters

NameTypeRequiredDescription
project_idintNoFilter by project
statusstringNoDraft, Planned, Published, Generating
limitintNoMax results (default 50, max 200)
offsetintNoPagination offset
Response
{ "articles": [ { "ID": 42, "Title": "Best CRM for Startups", "MainKeyword": "best crm for startups", "Status": "Draft", "ScheduledDate": "2026-03-25T09:00:00", "ProjectID": 1, "Slug": "best-crm-for-startups", "ArticleStyle": "Informative" } ], "count": 1 }
POST /articles Submit a new article
10 req/min

Submit AI-generated content. Distribb handles backlink credit processing, stores the article, and prepares it for publishing.

JSON Body

FieldTypeRequiredDescription
project_idintYesTarget project ID
keywordstringYesMain keyword / topic
titlestringNoArticle title (defaults to keyword)
contentstringNoFull HTML content
meta_descriptionstringNoSEO meta description
scheduled_datestringNoISO 8601 date (e.g. 2026-03-25T09:00:00Z)
article_stylestringNoInformative, Listicle, How-To, etc.
statusstringNoDraft (default) or Planned
Response (201)
{ "article_id": 123, "status": "Draft", "keyword": "best crm for startups", "slug": "best-crm-for-startups", "message": "Article created as Draft.", "backlinks_processed": 2 }
PUT /articles/:id Update an existing article
10 req/min

Update an article's content, title, meta description, status, or scheduled date. Useful for revising articles to add backlink targets after receiving a backlinks_warning. Cannot update published articles.

Body Parameters
contentstringUpdated HTML content
titlestringUpdated title
meta_descriptionstringUpdated meta description
statusstring"Draft" or "Planned"
scheduled_datestringISO 8601 date (e.g. 2026-04-01T09:00:00Z)

Send only the fields you want to update. If content is updated and the project participates in the backlink network, backlinks are re-scanned.

Response
{ "article_id": 123, "updated_fields": ["Content", "IsPreGenerated"], "message": "Article updated successfully.", "backlinks_processed": 2 }
GET /articles/:id Get a single article
30 req/min

Retrieve full article details including content. The article must belong to your account.

Response
{ "ID": 123, "Title": "Best CRM for Startups", "MainKeyword": "best crm for startups", "Content": "<h1>Best CRM for...</h1>...", "MetaDescription": "Compare the top CRM...", "Status": "Draft", "Slug": "best-crm-for-startups", "ScheduledDate": "2026-03-25T09:00:00", "ProjectID": 1, "ArticleStyle": "Informative" }
POST /keywords/search Search keywords with volume data
5 req/min

Search for keyword ideas with search volume and difficulty data. Paid Agentic Mode uses Distribb's keyword data; the Free Agentic plan uses your own DataForSEO or Ahrefs keys (see BYO Keys below).

JSON Body

FieldTypeRequiredDescription
keywordstringYesSeed keyword to research
project_idintNoProject for context and ownership
Response
{ "keywords": [ { "keyword": "crm software for small business", "search_volume": 2400, "keyword_difficulty": 38 } ] }
Bring-Your-Own-Keys (Free Agentic plan)

If the calling user is on the Free Agentic plan and has not yet saved a DataForSEO or Ahrefs API key, this endpoint returns HTTP 402 Payment Required with a machine-readable body so your agent knows what to do. Paid plans never see this response.

HTTP/1.1 402 Payment Required { "error": "byo_keys_required", "message": "Keyword research requires your own DataForSEO or Ahrefs API key.", "plan": "Agentic Free", "required": { "any_of": ["dataforseo", "ahrefs"] }, "setup_url": "https://distribb.io/settings#seo-keys", "docs_url": "https://distribb.io/api-docs#byo-keys", "instructions_for_agent": "Tell the user to add their DataForSEO Login + API Key (or Ahrefs API Key) at distribb.io/settings, then re-run keyword research." }

Agent contract: on receiving 402 with error = "byo_keys_required", halt the keyword-research step and surface instructions_for_agent verbatim to the human user. Do not retry until setup_url has been visited and credentials saved.

Provider precedence when both keys are saved: DataForSEO is used first (full keyword expansion); if only Ahrefs is saved, the response is sourced from Ahrefs Keywords Explorer ("source": "byo_ahrefs"). All other Distribb endpoints (articles, integrations, backlinks) work normally without BYO keys.

GET /integrations List connected CMS platforms
30 req/min

Query Parameters

NameTypeRequiredDescription
project_idintNoFilter to a specific project
Response
{ "integrations": [ { "ID": 1, "Platform": "wordpress", "Status": "Active", "ProjectID": 1, "BusinessName": "Acme Corp" } ] }
POST /articles/generate Expand your content into a full article (Pro only)
5 req/min

Submit your own content (notes, drafts, talking points) and Distribb's AI will expand it into a full SEO-optimized article with YouTube videos, images, quotes, backlinks, and internal links. Requires the Pro plan and costs 1 article credit. Not available on the Agentic plan (use POST /articles instead to submit your own AI-generated content).

JSON Body

FieldTypeRequiredDescription
project_idintYesTarget project ID
keywordstringYesTarget keyword / topic for SEO
source_contentstringYesYour content to expand (notes, draft, talking points, etc.)
instructionsstringNoAdditional guidance (e.g. "add YouTube videos", "focus on beginners")
titlestringNoArticle title (defaults to keyword)
article_stylestringNoInformative, Listicle, How-To, etc. (default: Informative)
Response (202)
{ "article_id": 456, "status": "generating", "keyword": "link building strategies", "slug": "link-building-strategies", "message": "Article generation started. Distribb will expand your content...", "article_credits_remaining": 29 }
POST /articles/:id/publish Publish to connected CMS
5 req/min

Triggers CMS publishing for an article. Distribb handles the integration (WordPress, Webflow, Shopify, Ghost, Wix, Notion, Framer, or Webhook) based on the project's connected platform.

Response (200)
{ "status": "published", "article_id": 123 }
Response (202 - Queued for Retry)
{ "error": "Publishing failed. The article has been queued and will be retried.", "article_id": 123 }
GET /business-context Get project business details
30 req/min

Returns project-specific context needed for high-quality content: business name, description, competitors, custom AI instructions, and language. Use this to ground your AI writer in the user's brand voice.

Query Parameters

NameTypeRequiredDescription
project_idintYesYour project ID
Response
{ "business_name": "Acme Corp", "website_url": "https://acme.com", "description": "CRM platform for startups...", "competitors": ["https://competitor1.com", "https://competitor2.com"], "ai_instructions": "Use a friendly tone, focus on SaaS...", "language": "English (US)", "target_audience": "SaaS founders, startup CTOs", "internal_links_per_article": 5 }
POST your_webhook_url Payload Distribb sends to your endpoint

If you connect a custom Webhook integration (instead of WordPress / Webflow / Shopify / Ghost / Wix / Notion / Framer), Distribb posts each finished article to your URL. The payload is wire-compatible with Outrank’s webhook spec, so any receiver written for Outrank works against Distribb with zero changes. Your endpoint must accept this JSON shape, validate the bearer token, and respond with 200 within 30 seconds.

Headers

NameValue
Content-Typeapplication/json
AuthorizationBearer <your access token> — the token you set in Settings → Integrations → Webhook
X-API-Key<your access token> — same value, sent for receivers that read this header (AWS API Gateway, generic SaaS)
x-make-apikey<your access token> — same value, sent for Make.com Custom Webhook "API Key restriction"
User-AgentDistribb-Publisher/1.0

Distribb sends your access token under three header names so the request authenticates against any common webhook receiver without extra configuration. Your endpoint only needs to validate one of them.

Body

FieldTypeDescription
event_typestringAlways "publish_articles"
timestampstringWhen the webhook was sent (ISO 8601, UTC)
data.articles[].idstringDistribb article ID
data.articles[].titlestringArticle title
data.articles[].slugstringURL slug, e.g. lawn-care-toronto
data.articles[].content_htmlstringFull article body as HTML (with <h2>, <p>, <ul>, <figure>, etc.). Render this if your CMS displays HTML directly.
data.articles[].content_markdownstringSame body converted to real Markdown. Render this if your CMS expects Markdown. Pick one of the two — never both.
data.articles[].meta_descriptionstringSEO meta description (~155 chars)
data.articles[].created_atstringWhen the article was created (ISO 8601, UTC)
data.articles[].image_urlstringPublic URL of the feature image (already hosted on our CDN). Use as-is or re-upload to your storage.
data.articles[].alt_textstringAlt text for the feature image
data.articles[].tagsstring[]SEO tags / keywords
data.articles[].authorstringAuthor display name
data.articles[].statusstring"Published" or "Draft" — based on the publishing preference set on your project
Example payload
{ "event_type": "publish_articles", "timestamp": "2026-04-18T15:21:00Z", "data": { "articles": [ { "id": "63452", "title": "Essential Lawn Maintenance Toronto Guide 2026", "slug": "essential-lawn-maintenance-toronto-2026", "content_html": "<h2>Why a Healthy Lawn Matters</h2><p>Toronto lawns face...</p>...", "content_markdown": "## Why a Healthy Lawn Matters\n\nToronto lawns face...", "meta_description": "A practical guide to year-round lawn care in Toronto...", "created_at": "2026-04-15T12:23:16Z", "image_url": "https://rebelgrowth.s3.us-east-1.amazonaws.com/blog-images/lawn-1.jpg", "alt_text": "lawn maintenance Toronto", "tags": ["lawn care", "toronto", "seasonal"], "author": "Trim Gym Lawn Care", "status": "Published" } ] } }
Expected response (200)
{ "status": "ok", "published_url": "https://yourdomain.com/blog/essential-lawn-maintenance-toronto-2026" }

If you return a published_url in the response body, Distribb will store it and link to it from your dashboard. Any non-2xx response triggers up to 3 retries with exponential backoff.

Common pitfalls
  • Wall-of-text output → you're rendering content_html through a Markdown parser (or content_markdown through an HTML renderer). Pick the field that matches your renderer.
  • Missing images → your CMS strips remote <img> tags. Either allow our S3 domain or re-upload image_url to your own storage before saving.
  • 401 from your endpoint → the bearer token in Settings doesn't match what your endpoint expects. Update one of them.

MCP Server Model Context Protocol

Instead of writing curl commands, connect the Distribb MCP server to Claude or Cursor and call every endpoint as a native tool — no CLI flags, no shell scripts. The agent calls list_projects, create_article, publish_article directly — same workflow, zero boilerplate.

1
Download the server

Clone the distribb-skill repo or download distribb_mcp_server.py directly.

git clone https://github.com/Bomx/distribb-skill # or just download distribb_mcp_server.py
2
Install dependencies
pip install mcp requests python-dotenv
3
Add to your MCP config

Cursor: ~/.cursor/mcp.json  ·  Claude Desktop: ~/Library/Application Support/Claude/claude_desktop_config.json

{ "mcpServers": { "distribb": { "command": "python3", "args": ["/path/to/distribb_mcp_server.py"], "env": { "DISTRIBB_API_KEY": "your_api_key_here" } } } }
4
Restart your client

Claude or Cursor will launch the server automatically. The tools appear immediately in the agent's tool list.


Available tools
list_projects Get all projects and their IDs
get_business_context Brand voice, competitors, AI instructions
search_keywords Keyword research with volume + difficulty
get_internal_links Existing pages to cross-link in new articles
get_backlink_targets Partner URLs to earn backlink credits
get_backlinks_status Credit balance and network status
list_articles Content calendar, filterable by status
get_article Full article details including content
create_article Submit a new SEO article
update_article Revise draft or planned articles
publish_article Push to CMS + trigger social repurposing
list_integrations See connected CMS and social platforms

Typical Workflow

Here is how an AI agent typically uses the API to create and publish an SEO article:

1. GET /projects # Get your project ID 2. GET /business-context?project_id=1 # Fetch brand voice + competitors 3. POST /keywords/search # Find target keywords 4. GET /internal-links?project_id=1&keyword=... # Get pages to link to 5. GET /backlink-targets?project_id=1&keyword=... # Get network URLs to cite 6. # Your AI writes the article using context from steps 2-5 7. POST /articles # Submit the article 8. POST /articles/123/publish # Publish to CMS

Errors

All error responses follow the same format:

{ "error": "Description of what went wrong" }
Status CodeMeaning
400Bad request — missing or invalid parameters
401Unauthorized — invalid or missing API key
403Forbidden — resource does not belong to your account
404Not found — resource does not exist
429Rate limited — too many requests, wait and retry
500Server error — something went wrong on our end