GeoCopyGeoCopy
REST API v2

Programmatic SEO articles from $0.50 each

Prepaid credits from $0.60 per article on smaller packs down to $0.50 on Scale. No subscription.

-H "Authorization: Bearer $KEY" \
-d '{"primary_keyword":"crm startups"}'
✔ 201 — job queued
→ id: a1b2c3d4
researching → drafting → published
✔ published — markdown + schema ready

One POST to start, then GET polls on a separate per-minute limit.

Dashboard vs API

Same article engine, different buying motion. Use the dashboard when editors need campaigns, review queues, and CMS publishing. Use the API when you want prepaid credits, no monthly plan, and programmatic control from your own stack.

From $0.98/article

Dashboard

Monthly plans for teams that publish through WordPress, Webflow, or the built-in review workflow — with seats, sites, and campaign tooling.

  • Editor UI, approvals, and CMS connectors
  • Subscription quota with optional overage
  • Best when humans are in the loop
Compare plans
Developer path

Developer API

Prepaid credit packs from $0.60 down to $0.50 per article. No subscription required. Integrate with cron, workers, or your product backend.

  • REST v2 — start jobs, poll status, pull markdown
  • Credits never expire; scale concurrency by pack
  • Best for programmatic SEO at volume
Get API credits

Best for

Teams using CMS workflows, campaigns, and review queues

Developers, cron jobs, and multi-app content pipelines

Billing

Monthly subscription with article quota

One-time prepaid packs ($0.60–$0.50/article)

Lock-in

Plan renews monthly

No subscription required

Credits

Monthly quota + optional overage

Prepaid balance — use anytime

Concurrency

Portal generation limits

5 / 10 / 20 parallel jobs by pack tier

Credit packs

Buy once, use anytime — credits never expire. Higher packs unlock more parallel generations and lower per-article cost.

Side Project Pack

$30one-time

50 articles · $0.60 each

Ship one app or test the API locally.

  • 5 concurrent generations
  • 10 article starts/min (POST)
  • 150 status polls/min (GET)
Most popular

Indie SaaS Pack

$55one-time

100 articles · $0.55 each

Cron-driven content for one product or a couple of client sites.

  • 10 concurrent generations
  • 20 article starts/min (POST)
  • 300 status polls/min (GET)

Scale Pack

$100one-time

200 articles · $0.50 each

Programmatic SEO across several sites or a content-heavy launch.

  • 20 concurrent generations
  • 30 article starts/min (POST)
  • 600 status polls/min (GET)

How it works

  1. Create an account and buy a credit pack in the Developer hub.
  2. POST /api/v2/articles with your keyword, intent category, and optional brand voice overrides.
  3. GET /api/v2/articles/:id until status is published.
  4. Optional: webhooks for article.generated events.

API reference

Start a generation job, poll until the article is ready, and optionally override brand voice, reader perspective, and article category per request. Authenticate with a Bearer API key from the Developer hub.

Create article

POST/api/v2/articles

Starts an async SEO article generation job. Returns 202 with an article id and poll_url. Consumes one API credit per successful start (by pack tier).

Body Parameters

JSON
  • primary_keywordrequired

    string

    Main SEO keyword or phrase the article should rank for. Drives research, outline, and on-page optimization.

  • secondary_keywords

    array of string

    Optional supporting keywords. When omitted, GeoCopy derives related terms from the primary keyword and intent category.

  • intent_category

    string "informational" | "how_to" | "comparison" | "commercial" | "transactional" | "listicle" | "local"

    Article format / search intent category. Controls outline structure, word-count targets, and module selection. Default: informational.

  • search_intent

    string

    Free-text search intent label stored on the article (e.g. informational, commercial). Defaults to informational when omitted. Default: informational.

  • topic

    string

    Optional title or topic override. When omitted, the primary keyword is used as the working title.

  • target_word_count

    integer

    Target article length in words. When omitted, GeoCopy uses the default for the intent category (typically ~1,200–1,800).

  • length_preference

    "shorter" | "standard" | "comprehensive" "shorter" | "standard" | "comprehensive"

    Pipeline length bias applied on top of the category default.

  • reader_voice

    string "practitioner" | "expert_authority" | "editorial"

    Narrative perspective preset. Practitioner allows first person where appropriate; expert_authority is third-person peer voice; editorial is reportage-style. Default: expert_authority (or your Developer hub default).

  • brand_voice

    string or object

    Brand voice override as plain text or a JSON brand-voice document (tone, vocabulary, example phrases). When omitted, your account brand brief from the Developer hub is used.

  • first_person_stance

    string "I" | "we" | "our team" | "the team" | "none"

    First-person pronoun policy merged into brand voice when using a JSON brand_voice object. Use none to forbid first person.

Create article
curl -X POST https://app.geocopy.io/api/v2/articles \
  -H "Authorization: Bearer sk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "primary_keyword": "best project management tools for remote teams",
  "secondary_keywords": [
    "remote team collaboration",
    "async project management"
  ],
  "intent_category": "comparison",
  "search_intent": "commercial",
  "topic": "Best Project Management Tools for Remote Teams (2026)",
  "target_word_count": 1800,
  "length_preference": "standard",
  "reader_voice": "practitioner",
  "first_person_stance": "we",
  "brand_voice": {
    "tone": "Direct, practical B2B SaaS — no hype.",
    "first_person_stance": "we",
    "vocabulary_to_avoid": [
      "synergy",
      "leverage",
      "game-changer"
    ]
  }
}'
Response202
{
  "id": "5c79a135-46a7-4374-990a-eb110c97fa33",
  "status": "queued",
  "poll_url": "/api/v2/articles/5c79a135-46a7-4374-990a-eb110c97fa33",
  "billing": {
    "creation_channel": "api",
    "charged_via": "api_credit",
    "charged_at": "2026-05-30T12:00:00.000Z",
    "export_is_billed": false,
    "charge_timing": "on_create",
    "credits_remaining": 47
  }
}

Retrieve article

GET/api/v2/articles/:id

Poll job status until the article reaches a terminal state (published, failed, or rejected). Returns the full nested document including markdown body, metadata, and billing when complete.

Path Parameters

JSON
  • idrequired

    string (uuid)

    Article ID returned from POST /api/v2/articles.

From production pipelineRetrieve example based on: How to Transfer a Domain Name: Avoid Hidden Costs & Traps
Retrieve article
curl -s "https://app.geocopy.io/api/v2/articles/YOUR_ARTICLE_ID" \
  -H "Authorization: Bearer sk_live_your_key_here"
Response200
{
  "id": "5c79a135-46a7-4374-990a-eb110c97fa33",
  "status": "approved",
  "created_at": "2026-05-28T17:05:53.623Z",
  "updated_at": "2026-05-30T19:07:23.613Z",
  "published_at": null,
  "meta": {
    "title": "How to Transfer a Domain Name: Avoid Hidden Costs & Traps",
    "slug": "how-to-transfer-domain-name",
    "summary": "Transferring a domain name takes 5–7 days and often comes with hidden costs and 60-day locks. This guide reveals what registrars don't tell you and how to avoid common traps.",
    "primary_keyword": "how to transfer a domain name",
    "keywords_targeted": [
      "how to transfer a domain name"
    ],
    "search_intent": "informational",
    "meta_title": "How to Transfer a Domain Name: Avoid Hidden Costs & Traps",
    "meta_description": "Learn how to transfer a domain name without hidden fees or timing traps. Step-by-step guide with ICANN rules, renewal costs, and security tips to save money.",
    "word_count": 2195,
    "reading_time_minutes": 11
  },
  "images": {
    "featured": "https://images.pexels.com/photos/4160092/pexels-photo-4160092.jpeg?auto=compress&cs=tinysrgb&h=650&w=940",
    "alt_text": "How to Transfer a Domain Name: Avoid Hidden Costs & Traps - featured image"
  },
  "content": {
    "format": "markdown",
    "body": "# How to Transfer a Domain Name: Avoid Hidden Costs and Timing Traps\n\nHow to transfer a domain name involves moving its registration from one registrar to another—a process that takes 5-7 days and locks you into the new registrar for another 60 days once complete. Most registrars advertise \"free transfers\" but charge renewal fees upfront, add privacy protection as a paid extra, or require you to disable two-factor authentication in ways that can make how to transfer a domain\n\n…",
    "html": null
  },
  "schema_jsonld": {
    "@context": "https://schema.org",
    "@type": "Article",
    "headline": "How to Transfer a Domain Name: Avoid Hidden Costs & Traps",
    "_note": "Full JSON-LD included in production responses"
  },
  "links": {
    "external_url": null,
    "external_post_id": null
  },
  "billing": {
    "creation_channel": "portal",
    "charged_via": null,
    "charged_at": null,
    "export_is_billed": false
  }
}

Rate limits

GeoCopy rate-limits the API on three independent axes so you can run production pipelines without one client starving another, and without status polling competing with new generations.

Concurrent jobs cap how many articles can be in-flight at once (queued through drafting, until published, failed, rejected, or archived). Article starts measure POST /api/v2/articles calls per minute — each successful start consumes one API credit and queues a new job. Status polls measure GET traffic to /api/v2/articles, /api/v2/articles/:id, and /api/v2/account per minute; that bucket is separate, so a tight poll loop will not reduce how many articles you can start.

Limits are set by your highest active credit pack. If you buy a larger pack later, concurrency and per-minute ceilings increase immediately. When you exceed a limit, the API returns HTTP 429 with a Retry-After hint. Check your live caps anytime with GET /api/v2/account.

Side Project Pack

50 articles · $0.60 each

5
parallel
10
POST / min
150
GET / min

Indie SaaS Pack

Popular

100 articles · $0.55 each

10
parallel
20
POST / min
300
GET / min

Scale Pack

200 articles · $0.50 each

20
parallel
30
POST / min
600
GET / min
Credit packParallel jobsIn-flight generations at the same timeArticle startsPOST /api/v2/articles per minuteStatus pollsGET polls & account checks per minute

Side Project Pack

50 articles · $30 pack

510150

Indie SaaS Pack

100 articles · $55 pack

1020300

Scale Pack

200 articles · $100 pack

2030600

Per-minute counters reset on a rolling 60-second window. Concurrent slots free up when a job reaches a terminal status. Exceeding a limit returns 429 Too Many Requests with Retry-After when applicable.

REST API on every plan

Every paid plan can enable REST API access. Starter includes Tier 1 throughput, Growth Tier 2, Pro Tier 3. Each API article uses your plan quota unless you have prepaid credits.

Need API-only, prepaid credits? See Developer API pricing.

Developer API

Need CMS workflows and team seats? Compare dashboard plans