> For the complete documentation index, see [llms.txt](https://help.rankability.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://help.rankability.com/api/api-creating-content-jobs.md).

# Creating content jobs

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

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

**Scope required:** `copywriter:run`

## 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"`                                                                                                                                                                                                                        |
| `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](/api/api-supported-languages.md) 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 only when supplying a pre-written `draft_body`.                                                                                                                                                                        |
| `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.                                                                                                                                              |

## Execution modes

### 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 → completed
```

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

### 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 → 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_...
```

### 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](/api/api-copywriter-autopilot.md).

## 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

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

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

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

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

## 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

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.

## Example requests

### 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

```
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

```
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

| 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

* [Running Autopilot content jobs](/api/api-copywriter-autopilot.md) — The fully hands-off pipeline with optimization and fact checking.
* [Supported languages](/api/api-supported-languages.md) — All 32 language codes and how the language field controls output.
* [Retrieving and using artifacts](/api/api-retrieving-artifacts.md) — How to fetch and use the outline, draft, SEO metadata, and more.
* [Content types reference](/copywriter/content-types-reference.md) — Details on Educate, Discover, Compete, and Convert intents.
