SeoboxSeobox

Seobox REST API

S
By Seobox Eng Team
Published on: 2026-07-1512 min readLast reviewed: 2026-07-15
TL;DR

List sites, read generated articles, and trigger new content generation programmatically — the reference for the Seobox public API.

Reference doc
APIReference

Overview

The Seobox API lets you list connected sites, read generated articles, and trigger new content generation from your own systems — useful for agencies syncing multiple client accounts, or for triggering generation from an internal tool instead of the dashboard.

All endpoints are served from:

https://api.seobox.tech/v1

Every request must include your API key and, for workspace-scoped endpoints, the target workspace:

x-api-key: sk_live_your_key_here
x-workspace-id: wsp_abc123
Key takeaway: Generate your API key from Account Settings → API Access. Keys carry explicit read and/or write scopes — request only what you need.

Authentication

Pass your API key on every request via the x-api-key header. Keys are scoped to read, write, or both — a read-only key can list sites and blogs but will be rejected on /generate. Missing or invalid keys return 401 Unauthorized; a valid key without the required scope returns 403 Forbidden.

Endpoints scoped to a specific workspace (most of them) additionally require an x-workspace-id header identifying which workspace within your account to operate on. Omitting it on a workspace-scoped endpoint returns a 400 Bad Request with a message telling you which header is missing.

Endpoints

GET /v1/api/sites

Lists every active site connected to your account.

Scope required: read

curl https://api.seobox.tech/v1/api/sites \
  -H "x-api-key: sk_live_your_key_here"
{
  "success": true,
  "data": [
    {
      "uid": "site_9f2a...",
      "domain": "example.com",
      "name": "Example Co Blog",
      "cms_type": "wordpress",
      "gsc_connected": true,
      "status": "active"
    }
  ]
}

GET /v1/api/blogs

Lists generated articles for a site, scoped to a workspace. Supports cursor-based pagination.

Scope required: read · Requires: x-workspace-id

curl "https://api.seobox.tech/v1/api/blogs?limit=20" \
  -H "x-api-key: sk_live_your_key_here" \
  -H "x-workspace-id: wsp_abc123"
{
  "success": true,
  "data": [
    {
      "uid": "blog_7c1e...",
      "title": "Keyword Research That Finds Intent, Not Just Volume",
      "slug": "keyword-research-that-finds-intent",
      "status": "published",
      "target_keyword": "keyword research",
      "seo_score": 91,
      "published_url": "https://example.com/blog/keyword-research-that-finds-intent",
      "published_at": "2026-07-05T09:12:00.000Z"
    }
  ],
  "next_cursor": "blog_5a2d..."
}

Pass the returned next_cursor back as a cursor query parameter to fetch the next page.

GET /v1/api/blogs/:uid

Fetches a single generated article by its unique ID.

Scope required: read · Requires: x-workspace-id

curl https://api.seobox.tech/v1/api/blogs/blog_7c1e... \
  -H "x-api-key: sk_live_your_key_here" \
  -H "x-workspace-id: wsp_abc123"

Returns 404 Not Found if the article doesn't exist, or doesn't belong to the account/workspace identified by your key and header.

POST /v1/api/generate

Queues a new article for generation against a target keyword.

Scope required: write · Requires: x-workspace-id

curl -X POST https://api.seobox.tech/v1/api/generate \
  -H "x-api-key: sk_live_your_key_here" \
  -H "x-workspace-id: wsp_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "site_uid": "site_9f2a...",
    "keyword": "b2b saas seo",
    "secondary_keywords": ["saas content marketing"],
    "tone": "expert, direct"
  }'
Field Type Required Notes
site_uid string Yes Must reference an active site in the workspace
keyword string Yes 2–200 characters
secondary_keywords string[] No Up to 10 supporting keywords
tone string No Freeform tone guidance passed to the writer

This returns immediately with 202 Accepted — generation runs asynchronously:

{
  "success": true,
  "run_id": "run_3e9b...",
  "blog_uid": "blog_1a4f..."
}

Poll GET /v1/api/blogs/:uid with the returned blog_uid to check status, or subscribe to the generation.completed webhook event to be notified the moment it's ready instead of polling.

Errors

All errors follow the same shape:

{
  "success": false,
  "error": { "message": "Site not found" }
}
Status Meaning
400 Malformed request or missing required header/field
401 Missing or invalid API key
403 Valid key, insufficient scope
404 Resource not found, or not owned by your account/workspace
429 Rate limit exceeded

Rate limits

API requests are rate-limited per key. If you're bursting past your limit, requests return 429 Too Many Requests with a Retry-After header — back off and retry rather than hammering the endpoint, especially for /generate, which is the most expensive call in the API.

FAQ

Can I revoke an API key without affecting others? Yes, keys are generated individually per account from Account Settings and can be rotated or revoked independently.

Is there a sandbox/test environment? Use a read-scoped key against /sites and /blogs to integrate safely before granting write scope for /generate in production.

How do I know when a generated article is done? Either poll GET /v1/api/blogs/:uid for a published status, or register a webhook for generation.completed — see Webhooks.