Skip to content

Creating content jobs

A complete reference for the POST /copywriter/jobs endpoint — every input field, valid values, execution modes, idempotency, and practical examples.

A complete reference for the POST /copywriter/jobs endpoint — every input field, valid values, execution modes, idempotency, and practical examples.

The POST /api/agent/v1/copywriter/jobs endpoint creates a new content job. This page covers every input field, execution modes, and how to handle retries safely.

POST /api/agent/v1/copywriter/jobs
Authorization: Bearer rk_live_...
Content-Type: application/json

Scope required: copywriter:run

Field Type Required Default Description
topic string Yes — The primary keyword or topic for the content piece. Example: "emergency plumber st louis"
research_only boolean No false Request entity-only research without an outline or draft. It cannot be combined with a draft upload, optimization project, or source URL. See the entity-only endpoint below for topic lists.
entity_content_intent enum No Inferred Available only with research_only: true. Values: business_page, educational, comparison, research. Explicit intent takes precedence over inference.
client_id UUID Yes — The client workspace to scope the job to. The job inherits the client’s brand voice, tone settings, and knowledge base context. The client must belong to your organization — list your clients with GET /api/agent/v1/clients to find a valid ID. Requests without a client_id are rejected with a 400 error.
intent enum No "educate" Search intent that shapes research and content structure. Values: educate, discover, compete, convert.
mode enum No "auto" Execution mode. auto runs the full pipeline end-to-end. stepped pauses after the brief for review. See Execution modes below.
location string No — Target location for SERP geo-targeting. Example: "St. Louis, MO", "London, UK". When set, competitor analysis uses location-specific search results.
language string No "en" Language code for the content. Controls SERP results language, brief language, draft language, and entity extraction language. See Supported languages for all codes.
tone enum No — Writing tone for the draft. Values: clear_practical, expert_detailed, friendly_simple, technical_precise, persuasive_direct. If omitted, the client’s default tone is used.
custom_instructions string No — Free-text guidance for the AI. Applied to both outline generation and draft writing. Example: "Mention 24/7 availability and licensed technicians".
word_count_target integer No — Target word count for the draft. Must be between 100 and 10,000. The AI uses this as a goal — actual word count may vary slightly.
project_mode enum No "new" new creates content from scratch. optimize creates a persistent optimization project for an existing page (requires source_url).
page_contract enum Conditional — Required for generated content. Choose article or commercial_service. It may be omitted when supplying a pre-written draft_body or requesting research_only: true.
source_url URL Conditional — Required when project_mode is "optimize". Rankability imports the existing page and researches optimization guidance; it does not change the live URL.
research_platforms string array No Google Organic Research sources to analyze. AI sources run only when explicitly selected. Broader research changes the evidence gathered, not the fixed completed-deliverable price.

Entity-only research is available to all Rankability organizations. Use POST /api/agent/v1/entities/jobs with copywriter:run and a stable Idempotency-Key. Supply one topic or a topics list of up to five distinct topics, plus an owned client_id. Optional location, language, research_platforms, and content_intent guide research. On this dedicated endpoint the field is named content_intent, without the entity_ prefix; its four values are the same as above.

Each topic receives a separate saved research job. The response returns jobs and indicates partial acceptance. Retry the same request with the same key to reuse accepted IDs and start only unaccepted topics. Poll GET /api/agent/v1/entities/jobs/:job_id with copywriter:read; complete results default to compact ordered core/supporting entities, relevance, aliases, writing eligibility, source counts, and topic/source coverage. Use view=full for source evidence. Reads return up to 50 entities by default, with limit (1–100) and offset for pagination. Follow entity_pagination.has_more until false to retrieve the entire list. Citation discovery does not guarantee successful page capture.

Consult GET /usage first. Entity-only work follows the existing Quick/Optimize usage contract. No brief, draft, publishing, or recurring work is generated. Account terms, API scopes, and client ownership still apply. Historical reports can be readable while requiring revalidation before new writing.

Entity reads from GET /api/agent/v1/copywriter/jobs/:id/artifacts use the same compact default. Set entity_view=full for evidence excerpts, and entity_limit (1–100) and entity_offset to page through saved brief entities. These read options do not regenerate research or modify the saved report.

Set "mode": "auto". The API runs the entire pipeline — research, brief generation, brief approval, and draft writing — without stopping. Your agent only needs to poll until the status reaches completed, then fetch artifacts.

POST /jobs (mode: "auto")
→ queued → researching → generating_draft → completed

Auto mode is included in full-platform pooled usage. Copywriter Core uses one completed-content allowance after a usable new asset is produced.

Set "mode": "stepped". The API runs research and generates the brief, then pauses at brief_ready. Your agent can fetch partial artifacts (outline, SEO metadata, entities, FAQs) to review the brief before approving it.

POST /jobs (mode: "stepped")
→ queued → researching → brief_ready
→ POST /jobs/:id/approve
→ generating_draft → completed

Research and the brief do not complete an outcome. Full-platform work uses pooled usage; Copywriter Core consumes its content-asset allowance only when draft generation produces a usable asset.

To approve the brief and start draft generation:

POST /api/agent/v1/copywriter/jobs/:id/approve
Authorization: Bearer rk_live_...

For the most hands-off option, use the dedicated Autopilot endpoint instead of a content job. Autopilot runs research, brief, draft, extra optimization passes, and fact checking with citations. It is included in full-platform pooled usage; Copywriter Core uses its completed-content allowance. Images remain user-selected in the editor. See Running Autopilot content jobs.

client_id is required — every API-created content job is scoped to a client workspace. The job inherits context from that client:

  • Brand voice — tone, style, and terminology defined in the client’s Brand & voice settings.
  • Knowledge base — uploaded documents, URLs, and pasted text that inform the AI about the client’s products, services, and unique selling points.
  • Domain context — the client’s website domain used for competitor analysis.

If the client_id you send does not exist or belongs to another organization, the request is rejected with a 404 error. For one-off or test content, create a dedicated test client first.

The location field tells the research engine where to simulate the search from. For example, setting "location": "Austin, TX" returns SERP results as if searching from Austin. This affects:

  • Which competitors appear in the analysis
  • Local pack results and map data (if applicable)
  • Location-specific content recommendations in the brief

If omitted, the search uses a generic US location.

The custom_instructions field is free-text guidance that the AI applies during both outline creation and draft writing. Use it to:

  • Emphasize specific selling points: "Highlight our 30-day money-back guarantee"
  • Set structural preferences: "Include a comparison table in the middle of the article"
  • Add constraints: "Do not mention competitor brand names"
  • Guide the angle: "Write from the perspective of an experienced practitioner"

To optimize an existing page instead of creating new content, set project_mode to "optimize" and provide the source_url:

{
"client_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"topic": "best crm for small business",
"project_mode": "optimize",
"page_contract": "article",
"source_url": "https://example.com/blog/best-crm-guide",
"mode": "auto"
}

Rankability creates a persistent Copywriter optimization project, imports the source into the editor, and researches current competitors and guidance. The job does not modify or publish the live page automatically. A successful full-platform outcome is included in pooled usage; Copywriter Core uses its optimization allowance.

To safely retry a request without creating duplicate jobs, include an Idempotency-Key header:

POST /api/agent/v1/copywriter/jobs
Authorization: Bearer rk_live_...
Idempotency-Key: my-unique-request-id-123
Content-Type: application/json

If a job already exists for that idempotency key within your organization, the API returns the existing job instead of creating a new one. This is essential for:

  • Network retry logic — safely retry after a timeout without double-creating
  • Batch scripts — re-run a script without worrying about duplicates
  • Webhook handlers — handle duplicate webhook deliveries gracefully

A successful request returns 201 Created:

{
"job_id": "uuid",
"status": "queued",
"content_type": "article",
"research_platforms": ["organic", "google_video_pack", "youtube_search"],
"usage_impact": { "level": "high", "included": true },
"created_at": "2026-02-25T15:30:00.000Z"
}

usage_impact describes the operation’s relative impact on pooled usage. Call GET /api/agent/v1/usage before starting work to check the current 24-hour and 7-day remaining percentages.

If the idempotency key matches an existing job, the response is 200 OK with the existing job details.

The list and detail endpoints return creation_source so consumers can distinguish Agent API jobs from projects saved in the web application. Agent-created jobs return creation_source: "agent_api" and an auto or stepped mode. Web-app projects return creation_source: "web_app" and mode: null.

queued is reserved for an Agent API job that has been handed off for background processing. A web-app project saved before generation is not queue work: it returns status: "draft" and progress.stage: "not_started". This distinction prevents an intentionally saved project from appearing to be a stalled queue job.

Marking an externally published article as done

Section titled “Marking an externally published article as done”

The API’s status: "completed" means draft generation finished. It does not automatically move the project into the Projects Complete tab.

If you publish through your own CMS or automation, send this request after publication succeeds:

PATCH /api/agent/v1/copywriter/jobs/:id
Authorization: Bearer rk_live_YOUR_KEY_HERE
Content-Type: application/json
{"marked_complete": true}

Your key needs copywriter:run. This performs the same Mark as done action as the editor; it does not publish, verify a live page, or start generation. Send {"marked_complete": false} to undo it.

The response, individual job read, and jobs list include marked_complete and marked_complete_at. The date is null for unfinished projects and older Done projects whose completion date was not recorded. Repeating the same request preserves the date; undoing Done clears it. Wait for current generation to finish before marking Done. The editor’s content checks also apply.

curl -X POST https://app.rankability.com/api/agent/v1/copywriter/jobs \
-H "Authorization: Bearer rk_live_YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{
"client_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"topic": "best crm for small business",
"page_contract": "article"
}'
curl -X POST https://app.rankability.com/api/agent/v1/copywriter/jobs \
-H "Authorization: Bearer rk_live_YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: batch-2026-02-25-crm-guide" \
-d '{
"client_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"topic": "best crm for small business",
"intent": "discover",
"mode": "stepped",
"location": "New York, NY",
"language": "en",
"tone": "expert_detailed",
"custom_instructions": "Include a comparison table. Mention integrations with popular tools.",
"word_count_target": 2000,
"project_mode": "new",
"page_contract": "article",
"research_platforms": ["organic", "chatgpt", "claude"]
}'
curl -X POST https://app.rankability.com/api/agent/v1/copywriter/jobs \
-H "Authorization: Bearer rk_live_YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{
"client_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"topic": "best crm for small business",
"project_mode": "optimize",
"page_contract": "article",
"source_url": "https://example.com/blog/best-crm",
"mode": "auto"
}'
HTTP Code Cause
400 invalid_input Missing client_id, topic, or required page_contract; invalid field values; or source_url missing when project_mode is "optimize".
401 unauthorized Missing, invalid, expired, or revoked API key.
403 plan_required Active subscription required. Subscribe to any plan to access the API.
404 not_found client_id does not exist or does not belong to your organization.
429 rate_limit_exceeded Too many requests. Wait and retry.
429 usage_limit_reached A pooled on-demand window has reached its current limit; retry at the returned recovery time.
503 service_unavailable Queue service is temporarily unavailable. Retry with exponential backoff.