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.
Endpoint
Section titled “Endpoint”POST /api/agent/v1/copywriter/jobsAuthorization: Bearer rk_live_...Content-Type: application/jsonScope required: copywriter:run
Request body fields
Section titled “Request body fields”| 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 topic research
Section titled “Entity-only topic research”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.
Execution modes
Section titled “Execution modes”Auto mode (default)
Section titled “Auto mode (default)”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 → completedAuto mode is included in full-platform pooled usage. Copywriter Core uses one completed-content allowance after a usable new asset is produced.
Stepped mode
Section titled “Stepped mode”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 → completedResearch 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/approveAuthorization: Bearer rk_live_...Autopilot (separate endpoint)
Section titled “Autopilot (separate endpoint)”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.
How client_id works
Section titled “How client_id works”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.
How location affects SERP targeting
Section titled “How location affects SERP targeting”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.
How custom_instructions guides output
Section titled “How custom_instructions guides output”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"
Optimizing existing content
Section titled “Optimizing existing content”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.
Idempotency keys
Section titled “Idempotency keys”To safely retry a request without creating duplicate jobs, include an Idempotency-Key header:
POST /api/agent/v1/copywriter/jobsAuthorization: Bearer rk_live_...Idempotency-Key: my-unique-request-id-123Content-Type: application/jsonIf 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
Response
Section titled “Response”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.
Reading job provenance and status
Section titled “Reading job provenance and status”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/:idAuthorization: Bearer rk_live_YOUR_KEY_HEREContent-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.
Example requests
Section titled “Example requests”Minimal request (auto mode)
Section titled “Minimal request (auto mode)”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" }'Full request with all fields
Section titled “Full request with all fields”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"] }'Optimize an existing page
Section titled “Optimize an existing page”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" }'Common errors
Section titled “Common errors”| 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. |
Related articles
Section titled “Related articles”- Running Autopilot content jobs — The fully hands-off pipeline with optimization and fact checking.
- Supported languages — All 32 language codes and how the language field controls output.
- Retrieving and using artifacts — How to fetch and use the outline, draft, SEO metadata, and more.
- Content types reference — Details on Educate, Discover, Compete, and Convert intents.
