Illustration API

Path: /docs/api/illustration

The Illustration API generates illustrated images for Markdown articles. Submit your article content, and GeoWriter creates a cover image and body illustrations that are inserted directly into the output Markdown.

Authentication

  • Header: Authorization: Bearer <API_KEY>
  • API key format: sk-gw-...
  • Access: a valid, active Integration API key can call all Illustration API endpoints.

Response Format

Success:

{
  "success": true,
  "data": {},
  "message": ""
}

Error:

{
  "success": false,
  "message": "Error description",
  "data": null
}

1. Create Illustration Task

POST /api/v1/illustration/create

Submit a Markdown article to generate illustrations. GeoWriter creates an async task and returns immediately. The task is processed in the background by the geo-imager service.

Parameters:

  • markdown: required, article Markdown content (1–50,000 characters).
  • cover: optional, defaults to true. Generate a cover image.
  • cover_style: optional, defaults to "cinematic". Cover image style. Valid values: tech, minimal, editorial, cinematic, flat, abstract, sketch, watercolor, isometric, ink, comic, retro. Invalid values silently fall back to "cinematic".
  • max_images: optional, defaults to 3. Max body images to generate (0–5). Set to 0 to generate a cover image only.
  • image_styles: optional, image style presets array. Each entry must be one of the valid style values listed above. Invalid entries are silently dropped.
  • platform: optional, defaults to "general". Target platform.
  • aspect_ratio: optional, defaults to "16:9". Image aspect ratio. Valid values: 16:9, 1:1, 3:2, 4:3, 3:4, 9:16, 2:1, 1:2, 21:9, 9:21. Invalid values silently fall back to "16:9".
  • resolution: optional, defaults to "1k". Image resolution. Valid values: 1k, 2k. Invalid values silently fall back to "1k".
  • idempotency_key: optional, client submit token for duplicate-submit guard (Redis-backed, not full persistent idempotency).
{
  "markdown": "# Best Hiking Trails\n\nThe best hiking trails offer...",
  "cover": true,
  "max_images": 3,
  "aspect_ratio": "16:9"
}
{
  "success": true,
  "data": {
    "id": "7234567890123456789",
    "status": "PENDING",
    "created_at": "2026-06-04T10:00:00Z"
  },
  "message": "Illustration task created successfully."
}

Error Responses:

  • 401 — Invalid or missing API key.
  • 422 — Validation error or insufficient points balance.
  • 429 — Duplicate submission detected or rate limit exceeded.

2. Get Task Progress

GET /api/v1/illustration/progress/{id}

Poll the processing status of an illustration task. Progress is coarse-grained with three discrete values: 0 (PENDING), 50 (PROCESSING), 100 (COMPLETED). It is not a continuous 0–100 percentage.

{
  "success": true,
  "data": {
    "id": "7234567890123456789",
    "task_type": "illustration",
    "status": "PROCESSING",
    "progress": 50,
    "provider_job_id": "imgjob_01jv8w7m4k8t2example",
    "provider_status": "processing",
    "error_message": null,
    "can_retry": false,
    "created_at": "2026-06-04T10:00:00Z"
  },
  "message": ""
}

Status values:

  • PENDING (progress 0) — Local task created, waiting for worker to submit upstream job.
  • PROCESSING (progress 50) — Upstream job submitted, images being generated.
  • COMPLETED (progress 100) — Upstream job completed, results written back.
  • FAILED (progress 0) — Upstream submission or processing failed.

3. Get Task Detail

GET /api/v1/illustration/detail/{id}

Retrieve the full task including input and illustrated output. The output contains the illustrated Markdown (with images inserted) and an image array with metadata.

{
  "success": true,
  "data": {
    "id": "7234567890123456789",
    "task_type": "illustration",
    "status": "COMPLETED",
    "progress": 100,
    "input": {
      "markdown": "# Best Hiking Trails\n\n...",
      "options": {
        "cover": true,
        "max_images": 3,
        "aspect_ratio": "16:9"
      }
    },
    "output": {
      "success": true,
      "markdown": "# Best Hiking Trails\n\n![Cover image](https://cdn.geowriter.ai/img/xxx.png)\n\nThe best hiking trails offer... ![Trail view](https://cdn.geowriter.ai/img/yyy.png)",
      "images": [
        {
          "role": "cover",
          "url": "https://cdn.geowriter.ai/img/xxx.png",
          "alt": "Cover image for Best Hiking Trails",
          "image_type": "cover",
          "style": "cinematic",
          "position": 0,
          "resolution": "1k",
          "aspect_ratio": "16:9"
        },
        {
          "role": "body",
          "url": "https://cdn.geowriter.ai/img/yyy.png",
          "alt": "Scenic trail view",
          "image_type": "illustration",
          "style": "photorealistic",
          "position": 5,
          "resolution": "1k",
          "aspect_ratio": "16:9"
        }
      ],
      "stats": {
        "images_generated": 3,
        "cost_usd": 0.15,
        "duration_ms": 12500
      }
    },
    "error_message": null,
    "retry_count": 0,
    "can_retry": false,
    "created_at": "2026-06-04T10:00:00Z",
    "updated_at": "2026-06-04T10:02:30Z"
  },
  "message": ""
}

Image fields:

  • role"cover" or "body"
  • url — CDN URL of the generated image
  • alt — Alt text for the image
  • image_type"cover" or "illustration"
  • style — Style used for generation
  • position — Character position in the output Markdown
  • resolution — Image resolution (e.g. "1k")
  • aspect_ratio — Image aspect ratio (e.g. "16:9")

4. Retry Failed Task

POST /api/v1/illustration/retry/{id}

Retry a failed illustration task. Only allowed when can_retry is true. Maximum 1 retry per task. Retries are free of charge.

{
  "success": true,
  "data": {
    "id": "7234567890123456789",
    "status": "PENDING",
    "retry_count": 1
  },
  "message": "Task retry initiated."
}

Error Responses:

  • 400 — Task not in failed state, or max retries already used.
  • 401 — Invalid or missing API key.
  • 404 — Task not found or not owned by authenticated user.

Polling Pattern

Client-side polling targets GeoWriter only. Each progress / detail request may trigger GeoWriter to sync the downstream geo-imager status when the local poll interval is due.

  1. Call POST /create with your Markdown content.
  2. Poll GET /progress/{id} every 10 seconds until status is COMPLETED or FAILED.
  3. When COMPLETED, call GET /detail/{id} to retrieve the illustrated Markdown and image array.
  4. If FAILED and can_retry is true, call POST /retry/{id} and resume polling.

Points

  • Create task: −10 points (deducted at creation).
  • Retry: free (no additional charge).

Rate Limits

60 requests/minute per API key (shared with all Integration API endpoints).

Migration from Post API

If you are currently using the Post API for document generation, the Illustration API works alongside it:

  • Post API — generates full articles from keywords. Use for end-to-end content creation.
  • Illustration API — adds illustrations to existing Markdown content. Use when you already have article text and only need images.

A common workflow is to generate an article with the Post API, then enhance it with illustrations using the Illustration API.