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.

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.