Draft2Live API

Generate, manage, and publish AI-powered content programmatically. Integrate Draft2Live into your workflows with our REST API.

REST APIJSON responsesAPI key auth

Overview

The Draft2Live API allows you to generate, manage, and publish AI-powered content programmatically. Build custom integrations, automate content workflows, and manage your articles from any platform.

Base URL

https://draft2live.ai/api/v1/public

Response Format

All successful responses are wrapped in a {"data": {...}} envelope. Lists include pagination metadata.

json
// Standard response envelope
{
  "data": {
    "id": 1234,
    "title": "Your article title",
    "status": "draft"
  }
}

// List response with pagination
{
  "data": [
    { "id": 1, "title": "Article 1" },
    { "id": 2, "title": "Article 2" }
  ],
  "meta": {
    "page": 1,
    "per_page": 20,
    "total": 47,
    "total_pages": 3
  }
}

Authentication

Authenticate your API requests using an API key. You can create and manage API keys from your Account → API Keys page.

Keep your API keys secure

Do not share your API key in publicly accessible areas such as client-side code, GitHub, or public forums. Use environment variables on your server.

API Key (recommended)

Pass your API key via the X-API-Key header.

bash
curl -X GET "https://draft2live.ai/api/v1/public/articles" \
  -H "X-API-Key: d2l_your_key_here" \
  -H "Content-Type: application/json"

Bearer Token

JWT bearer tokens are also supported for session-based authentication.

bash
curl -X GET "https://draft2live.ai/api/v1/public/articles" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -H "Content-Type: application/json"

Articles

Manage your generated articles. Retrieve, list, and filter your content library.

GET/articles

Retrieve a paginated list of your articles. Supports filtering by status and language.

Query Parameters

ParameterTypeDescription
pageintegerPage number (default: 1)
per_pageintegerItems per page, max 100 (default: 20)
statusstringFilter by status: draft, published, archived
languagestringFilter by language code (e.g., uk, en, de)

Response

json
{
  "data": [
    {
      "id": 4821,
      "title": "10 SEO-порад для просування інтернет-магазину",
      "slug": "10-seo-porad-dlia-prosuvannia-internet-mahazyny",
      "status": "published",
      "language": "uk",
      "word_count": 2450,
      "model": "gpt-4o",
      "created_at": "2026-04-15T10:23:00Z",
      "updated_at": "2026-04-15T12:05:30Z"
    },
    {
      "id": 4820,
      "title": "How to Build a Content Strategy in 2026",
      "slug": "how-to-build-content-strategy-2026",
      "status": "draft",
      "language": "en",
      "word_count": 1800,
      "model": "claude-sonnet",
      "created_at": "2026-04-14T08:15:00Z",
      "updated_at": "2026-04-14T08:15:00Z"
    }
  ],
  "meta": {
    "page": 1,
    "per_page": 20,
    "total": 142,
    "total_pages": 8
  }
}
GET/articles/{id}

Retrieve full details of a single article including its HTML content.

Path Parameters

ParameterTypeDescription
idintegerThe article ID

Response

json
{
  "data": {
    "id": 4821,
    "title": "10 SEO-порад для просування інтернет-магазину",
    "slug": "10-seo-porad-dlia-prosuvannia-internet-mahazyny",
    "status": "published",
    "language": "uk",
    "word_count": 2450,
    "model": "gpt-4o",
    "content": "<h2>Вступ</h2><p>Просування інтернет-магазину...</p>",
    "meta_title": "10 SEO-порад для інтернет-магазину | 2026",
    "meta_description": "Дізнайтеся про найефективніші SEO-стратегії...",
    "keywords": ["seo", "інтернет-магазин", "просування"],
    "created_at": "2026-04-15T10:23:00Z",
    "updated_at": "2026-04-15T12:05:30Z",
    "publications": [
      {
        "site_id": 12,
        "site_name": "My WordPress Blog",
        "published_at": "2026-04-15T12:05:30Z",
        "external_url": "https://myblog.com/10-seo-porad"
      }
    ]
  }
}

Generation

Generate new articles using AI. Article generation is asynchronous -- submit a job and poll for completion.

POST/articles/generate

Start a new article generation job. Returns a job ID for tracking progress.

Request Body

ParameterTypeDescription
topicstringThe article topic or title
language_codestringTarget language (e.g., uk, en, de, fr)
word_countintegerTarget word count (default: 1500)
modelstringAI model: gpt-4o, claude-sonnet, gemini-pro (default: gpt-4o)
keywordsstring[]SEO keywords to include in the article
custom_instructionsstringAdditional instructions for the AI writer

Request Example

bash
curl -X POST "https://draft2live.ai/api/v1/public/articles/generate" \
  -H "X-API-Key: d2l_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "topic": "Як обрати CMS для інтернет-магазину у 2026 році",
    "language_code": "uk",
    "word_count": 2000,
    "model": "gpt-4o",
    "keywords": ["CMS", "інтернет-магазин", "WordPress", "Drupal"],
    "custom_instructions": "Focus on e-commerce features and SEO capabilities"
  }'

Response

json
{
  "data": {
    "job_id": "gen_a1b2c3d4e5f6",
    "status": "pending",
    "estimated_seconds": 45,
    "created_at": "2026-04-15T14:30:00Z"
  }
}
GET/articles/jobs/{job_id}

Check the status of a generation job. Poll this endpoint until status is 'completed' or 'failed'.

Path Parameters

ParameterTypeDescription
job_idstringThe generation job ID returned from the generate endpoint

Response (in progress)

json
{
  "data": {
    "job_id": "gen_a1b2c3d4e5f6",
    "status": "in_progress",
    "progress": 65,
    "article_id": null
  }
}

Response (completed)

json
{
  "data": {
    "job_id": "gen_a1b2c3d4e5f6",
    "status": "completed",
    "progress": 100,
    "article_id": 4822,
    "completed_at": "2026-04-15T14:30:48Z"
  }
}

Response (failed)

json
{
  "data": {
    "job_id": "gen_a1b2c3d4e5f6",
    "status": "failed",
    "progress": 0,
    "article_id": null,
    "error": "Insufficient credits to complete generation"
  }
}

Images

Generate AI images using multiple models (Flux, GPT Image, Gemini) with style presets and auto-prompt enhancement. Requires the ai_image_generation feature on your plan.

POST/images/generate

Generate an AI image and save it to your media library.

Request body
ParameterTypeDescription
promptstringImage description (3-1000 chars)
aspect_ratiostring1:1, 16:9, 9:16, 4:3, 3:4 (default: 1:1)
modelstringauto, flux-flex, flux-pro, flux-max, gpt-image, gemini (default: auto)
stylestringrealistic, cartoon, watercolor, oil-painting, 3d-render, anime, sketch, pop-art, pixel-art, cyberpunk
auto_promptbooleanAuto-enhance prompt with AI (default: true)
folder_idintegerFolder ID to save image to
Example request
bash
curl -X POST https://draft2live.ai/api/v1/public/images/generate \
  -H "X-API-Key: d2l_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Modern office building at sunset, glass facade reflecting orange sky",
    "aspect_ratio": "16:9",
    "model": "flux-pro",
    "style": "realistic"
  }'
Response
json
{
  "data": {
    "id": 142,
    "url": "/uploads/users/4/media/2026/04/modern-office-building.png",
    "filename": "modern-office-building.png",
    "width": 1344,
    "height": 768,
    "cost_usd": 0.04,
    "model_used": null
  }
}
GET/images/models

List available image generation models with cost estimates.

Response
json
{
  "data": {
    "models": [
      {
        "key": "flux-klein",
        "name": "Flux Klein",
        "cost_estimate": 0.014
      },
      {
        "key": "flux-flex",
        "name": "Flux Flex",
        "cost_estimate": 0.025
      },
      {
        "key": "flux-pro",
        "name": "Flux Pro",
        "cost_estimate": 0.04
      },
      {
        "key": "flux-max",
        "name": "Flux Max",
        "cost_estimate": 0.08
      },
      {
        "key": "gpt-image",
        "name": "GPT Image",
        "cost_estimate": 0.04
      },
      {
        "key": "gemini",
        "name": "Gemini Image",
        "cost_estimate": 0.04
      }
    ]
  }
}

Sites

Manage your connected CMS sites (WordPress, Drupal). Sites are configured in the dashboard and referenced by ID when publishing.

GET/sites

List all CMS sites connected to your account.

Response

json
{
  "data": [
    {
      "id": 12,
      "name": "My WordPress Blog",
      "type": "wordpress",
      "url": "https://myblog.com",
      "status": "connected",
      "last_sync_at": "2026-04-15T09:00:00Z"
    },
    {
      "id": 15,
      "name": "Corporate Drupal Site",
      "type": "drupal",
      "url": "https://corporate.example.com",
      "status": "connected",
      "last_sync_at": "2026-04-14T18:30:00Z"
    }
  ]
}

Publishing

Publish generated articles to your connected CMS sites. Supports WordPress and Drupal with category assignment and publish status control.

POST/articles/{id}/publish

Publish an article to a connected CMS site.

Path Parameters

ParameterTypeDescription
idintegerThe article ID to publish

Request Body

ParameterTypeDescription
site_idintegerTarget CMS site ID
publish_statusstringCMS post status: publish, draft, pending (default: draft)
categoriesinteger[]Array of CMS category IDs

Request Example

bash
curl -X POST "https://draft2live.ai/api/v1/public/articles/4821/publish" \
  -H "X-API-Key: d2l_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "site_id": 12,
    "publish_status": "draft",
    "categories": [5, 12]
  }'

Response

json
{
  "data": {
    "publication_id": 891,
    "article_id": 4821,
    "site_id": 12,
    "site_name": "My WordPress Blog",
    "external_id": 3456,
    "external_url": "https://myblog.com/?p=3456",
    "status": "draft",
    "published_at": "2026-04-15T14:45:00Z"
  }
}
GET/articles/{id}/publications

List all publications (CMS posts) created from a specific article.

Path Parameters

ParameterTypeDescription
idintegerThe article ID

Response

json
{
  "data": [
    {
      "publication_id": 891,
      "site_id": 12,
      "site_name": "My WordPress Blog",
      "site_type": "wordpress",
      "external_id": 3456,
      "external_url": "https://myblog.com/10-seo-porad",
      "status": "published",
      "published_at": "2026-04-15T14:45:00Z"
    }
  ]
}

Hosted Sites

Programmatically build and manage hosted websites (served at {slug}.draft2blog.com) — sites, pages, blog posts, custom domains, outbound webhooks and images. These endpoints run the same validated code as the dashboard (ownership, quotas, moderation, sanitization), so nothing behaves less safely than the UI.

Interactive reference & MCP

Full request/response schemas live in the always-current Swagger UI at /api/v1/public/docs. The same endpoints back a remote MCP server so a model (e.g. Claude) can build sites in conversation — connect https://draft2live.ai/mcp with your API key.

Base path & auth

https://draft2live.ai/api/v1/public/hosted

Same X-API-Key: d2l_… as above; requires a plan with API access. A read-only key may call GET only; mutations need a read+write key.

Discovery

GET/hosted/account

The account behind the API key: email, plan tier, and key scopes (read vs read,write).

GET/hosted/templates

Curated site templates to start from. Each item's `key` feeds POST /hosted/sites/from-template. Optional ?category= and ?locale=.

Sites

GET/hosted/sites

List your hosted sites (id, name, slug, status, public URL, quota).

bash
curl "https://draft2live.ai/api/v1/public/hosted/sites" -H "X-API-Key: d2l_your_key"
POST/hosted/sites

Create a BLANK site. Prefer from-template for a ready design.

ParameterTypeDescription
namestringSite display name.
slugstringBecomes {slug}.draft2blog.com; unique + moderated.
template_keystringLayout key, e.g. "minimal".
default_localestringe.g. "uk".
theme_configobjectTheme/settings object.
POST/hosted/sites/from-template

Create a site by cloning a curated template (no AI).

ParameterTypeDescription
namestringSite display name.
slugstringBecomes {slug}.draft2blog.com; unique + moderated.
template_keystringFrom GET /hosted/templates, e.g. "cafe-warm".
default_localestringDefault "uk".
bash
curl -X POST "https://draft2live.ai/api/v1/public/hosted/sites/from-template" \
  -H "X-API-Key: d2l_your_key" -H "Content-Type: application/json" \
  -d '{"name":"My Cafe","slug":"my-cafe","template_key":"cafe-warm"}'
GET/hosted/sites/{site_id}

Get one site (theme, settings, status).

PATCH/hosted/sites/{site_id}

Update a site. Only the fields you pass change.

ParameterTypeDescription
namestringRename the site.
default_localestringChange default language.
template_keystringChange layout.
theme_configobjectTheme/settings.
analytics_tokenstringAnalytics token.
DELETE/hosted/sites/{site_id}

Permanently delete a site and all its pages/posts. Irreversible.

Pages

GET/hosted/sites/{site_id}/pages

List a site's pages (id, title, slug, page_type, status).

POST/hosted/sites/{site_id}/pages

Add a page. Sections (the page content) are validated + sanitized server-side.

ParameterTypeDescription
titlestringPage title.
slugstringURL slug.
localestringPage locale.
sectionsarrayList of section objects (page content).
page_typestring"standard" or "blog_listing".
meta_descriptionstringSEO description.
PATCH/hosted/sites/{site_id}/pages/{page_id}

Update a page (title, slug, sections, SEO, status, nav_order, background). Only passed fields change.

DELETE/hosted/sites/{site_id}/pages/{page_id}

Delete a page from a site.

Blog posts

GET/hosted/sites/{site_id}/posts

List blog posts published to a site (id, title, slug, status).

POST/hosted/sites/{site_id}/posts

Publish one of your articles to a site as a blog post.

ParameterTypeDescription
article_idintegerThe article to publish.
slugstringCustom post slug.
publishbooleanfalse = draft. Default true.
PATCH/hosted/sites/{site_id}/posts/{post_id}

Update a post (slug, status live/draft, per-post SEO, noindex).

DELETE/hosted/sites/{site_id}/posts/{post_id}

Unpublish / remove a blog post from a site.

Custom domains

GET/hosted/sites/{site_id}/domains

List custom domains connected to a site + their verification/SSL status.

POST/hosted/sites/{site_id}/domains

Connect a custom domain. Returns the DNS records to set.

ParameterTypeDescription
hostnamestringe.g. "www.example.com".

Webhooks (autopost)

Fire post.published / post.updated / post.unpublished as signed (HMAC-SHA256) JSON to your URL — fan out to Zapier / Make / n8n or your own endpoint. HTTPS only; each delivery carries X-D2L-Signature.

GET/hosted/sites/{site_id}/webhooks

List a site's webhooks (the signing secret is shown only on create).

POST/hosted/sites/{site_id}/webhooks

Create a webhook. Returns the signing secret once.

ParameterTypeDescription
namestringLabel.
urlstringPublic HTTPS target (private/loopback rejected).
eventsarraySubset of post.published, post.updated, post.unpublished.
bash
curl -X POST "https://draft2live.ai/api/v1/public/hosted/sites/24/webhooks" \
  -H "X-API-Key: d2l_your_key" -H "Content-Type: application/json" \
  -d '{"name":"zapier","url":"https://hooks.zapier.com/...","events":["post.published"]}'
DELETE/hosted/sites/{site_id}/webhooks/{webhook_id}

Delete a webhook.

POST/hosted/sites/{site_id}/webhooks/{webhook_id}/test

Send a sample delivery now and return the result (throttled).

GET/hosted/sites/{site_id}/webhooks/{webhook_id}/logs

Recent delivery attempts (event, status, error), newest first.

Images

GET/hosted/images/search

Search real stock photos (Unsplash/Pexels) — returns ready image URLs to drop into sections.

bash
curl "https://draft2live.ai/api/v1/public/hosted/images/search?query=coffee%20shop&count=6" \
  -H "X-API-Key: d2l_your_key"
POST/hosted/images/generate

Generate an original image with AI (needs the ai_image_generation plan feature + credits). Returns the hosted URL.

ParameterTypeDescription
promptstringImage description (min 3 chars).
aspect_ratiostring1:1 | 16:9 | 9:16 | 4:3 | 3:4.
modelstringauto | flux-flex | flux-pro | gpt-image | gemini.

MCP (Claude)

Connect a model (e.g. Claude in Claude Code) to build and manage your hosted sites in conversation — "list my sites", "create a site from the cafe template", "publish this article". The MCP tools wrap the SAME validated endpoints above, forwarding your API key, so the model goes through identical server-side checks and can't bypass anything.

Endpoint & auth

https://draft2live.ai/mcp

Streamable HTTP. Authenticate with your d2l_ key in the connector header. Create a key in Account → API keys (needs a plan with API access). A read-only key exposes only the read tools.

Connect in Claude Code

bash
claude mcp add --transport http draft2live https://draft2live.ai/mcp \
  --header "Authorization: Bearer d2l_your_key"

Or via .mcp.json

json
{
  "mcpServers": {
    "draft2live": {
      "type": "http",
      "url": "https://draft2live.ai/mcp",
      "headers": { "Authorization": "Bearer d2l_your_key" }
    }
  }
}

Tools

whoami, list_templates, list_sites, get_site, create_site, create_site_from_template, update_site, delete_site, list_pages, create_page, update_page, delete_page, list_posts, publish_post, update_post, unpublish_post, list_domains, add_domain, search_image, generate_image. A read-only key can call the list_* / get_* / whoami / search_image tools only.

Usage

Check your account credit balance and usage statistics.

GET/usage/credits

Get your current credit balance and usage for the current billing period.

Response

json
{
  "data": {
    "plan": "pro",
    "credits_remaining": 847,
    "credits_total": 1000,
    "credits_used": 153,
    "billing_period_start": "2026-04-01T00:00:00Z",
    "billing_period_end": "2026-04-30T23:59:59Z",
    "generations_this_period": 42
  }
}

Errors

The API uses standard HTTP status codes. Errors return a consistent JSON body with an error field.

json
{
  "error": {
    "code": "insufficient_credits",
    "message": "You do not have enough credits to complete this request.",
    "status": 402
  }
}
StatusCodeDescription
401unauthorizedInvalid or missing API key
402insufficient_creditsNot enough credits to complete the request
403forbiddenFeature not available on your current plan
404not_foundThe requested resource does not exist
422validation_errorInvalid request body or parameters
500internal_errorAn unexpected error occurred on our end

Need help? Contact us at [email protected] or visit the dashboard.