> 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-retrieving-artifacts.md).

# Retrieving and using artifacts

Learn how to fetch structured output from completed content jobs — outline, draft, SEO metadata, entities, FAQs, FAQ schema, and content score — and how to use each piece in your publishing workflow.

After a content job reaches the `completed` status (or `brief_ready` in stepped mode), you can retrieve its structured artifacts. Each artifact is a self-contained piece of content you can feed directly into your CMS, page template, or downstream automation.

Use `GET /api/agent/v1/copywriter/queue/status` when you need the organization's bounded research and draft queue position, estimated wait, or service alerts. It is a read-only operational status call and does not start work.

## Endpoint

```
GET /api/agent/v1/copywriter/jobs/:id/artifacts
Authorization: Bearer rk_live_...
```

Replace `:id` with the `job_id` returned when you created the job.

### When to call

* **Auto mode** — Call after the status endpoint returns `"completed"`.
* **Stepped mode at `brief_ready`** — You can call immediately to inspect partial artifacts (outline, SEO metadata, entities, FAQs). The `draft` and `score` fields will be `null` until you approve the brief and the draft finishes generating.
* **Stepped mode after approval** — Poll the status endpoint until `"completed"`, then call artifacts for the full set.

If you call the endpoint before the job is ready, the API returns `409` with the code `not_ready`.

### Scope required

`copywriter:read`

## Full response example

A completed job returns the following JSON structure:

```
{
  "outline": [
    {
      "heading": "What Is Emergency Plumbing?",
      "level": "h2",
      "subheadings": [
        { "heading": "Signs You Need Emergency Service", "level": "h3" }
      ]
    }
  ],
  "draft": {
    "format": "markdown",
    "content": "# Emergency Plumber St. Louis\n\nWhen a pipe bursts...",
    "word_count": 1247
  },
  "seo": {
    "title_tag": "Emergency Plumber St. Louis | 24/7 Licensed Service",
    "meta_description": "Need an emergency plumber in St. Louis? ...",
    "h1": "Emergency Plumber St. Louis"
  },
  "entities": [
    { "name": "St. Louis", "type": "location", "relevance": 0.95 }
  ],
  "faqs": [
    {
      "question": "How much does an emergency plumber cost in St. Louis?",
      "answer": "Emergency plumbing in St. Louis typically costs..."
    }
  ],
  "faq_schema_json_ld": "{\"@context\":\"https://schema.org\",\"@type\":\"FAQPage\",...}",
  "score": {
    "overall": 82,
    "overall_max": 100,
    "calculation_state": "partial_categories",
    "category_model": "partial_current",
    "category_total": 38,
    "overall_category_delta": 44,
    "categories": {
      "copywriting": 17,
      "readability": 8,
      "seo": 13
    },
    "category_details": {
      "copywriting": { "score": 17, "max_score": 20, "percent": 85 },
      "readability": { "score": 8, "max_score": 10, "percent": 80 },
      "seo": { "score": 13, "max_score": 15, "percent": 86.7 }
    }
  }
}
```

## Artifact reference

Each field in the response serves a specific purpose. Below is a detailed breakdown.

### outline

An ordered array of heading objects representing the article structure.

| Field         | Type   | Description                                                |
| ------------- | ------ | ---------------------------------------------------------- |
| `heading`     | string | The heading text                                           |
| `level`       | string | HTML heading level: `h2`, `h3`, or `h4`                    |
| `subheadings` | array  | Nested headings under this section (same shape, recursive) |

**How to use:** Compare the outline against your content strategy before approval (stepped mode). You can also use it to generate a table of contents or validate that the draft covers every planned section.

### draft

The generated article content.

| Field        | Type    | Description                         |
| ------------ | ------- | ----------------------------------- |
| `format`     | string  | Always `"markdown"`                 |
| `content`    | string  | The full article in Markdown format |
| `word_count` | integer | Total word count of the draft       |

**How to use:** Convert the Markdown to HTML for your CMS, or pass it directly to a headless CMS that accepts Markdown. The content is ready to publish but you may want to add your own images, internal links, or brand-specific formatting.

**Stepped mode note:** This field is `null` at `brief_ready`. It populates after the brief is approved and the draft finishes generating.

### seo

Pre-written SEO metadata for the page.

| Field              | Type   | Description                                               |
| ------------------ | ------ | --------------------------------------------------------- |
| `title_tag`        | string | Suggested `<title>` tag (typically 50–60 characters)      |
| `meta_description` | string | Suggested meta description (typically 150–160 characters) |
| `h1`               | string | Suggested H1 heading for the page                         |

**How to use:**

* Set `title_tag` as your page’s `<title>` element.
* Set `meta_description` as the `<meta name="description" content="...">` tag.
* Use `h1` as the visible page heading. This may differ slightly from the title tag for better on-page optimization.

### entities

Named entities extracted during research, ranked by relevance to the topic.

| Field       | Type   | Description                                                        |
| ----------- | ------ | ------------------------------------------------------------------ |
| `name`      | string | The entity name (e.g., "St. Louis", "PVC pipe")                    |
| `type`      | string | Entity category (e.g., `location`, `material`, `brand`, `concept`) |
| `relevance` | number | Relevance score from 0 to 1                                        |

**How to use:** Entities help you understand topical coverage. High-relevance entities that are missing from your draft may represent gaps. You can also use entities for internal linking, tagging, or building topic clusters.

### faqs

Question-and-answer pairs derived from competitor content and People Also Ask data.

| Field      | Type   | Description                                 |
| ---------- | ------ | ------------------------------------------- |
| `question` | string | A frequently asked question about the topic |
| `answer`   | string | A concise answer to the question            |

**How to use:** Add these as an FAQ section at the bottom of your article, or weave individual Q\&A pairs into relevant sections of the content. FAQs improve the chance of appearing in Google’s featured snippets and People Also Ask boxes.

### faq\_schema\_json\_ld

A ready-to-use JSON-LD string for the [FAQPage](https://schema.org/FAQPage) structured data type.

**How to use:** Inject this string into your page’s `<head>` inside a `<script type="application/ld+json">` tag:

```
<script type="application/ld+json">
  {{ faq_schema_json_ld }}
</script>
```

This tells search engines that your page contains FAQ content, which can trigger rich results in the SERP. The schema is pre-built from the `faqs` array — you do not need to construct it yourself.

### score

The content optimization score, calculated by comparing your draft against top-ranking competitors.

| Field                    | Type            | Description                                                                            |
| ------------------------ | --------------- | -------------------------------------------------------------------------------------- |
| `overall`                | integer         | Composite score from 0 to 100                                                          |
| `overall_max`            | integer         | Maximum overall score; currently `100`                                                 |
| `calculation_state`      | string          | Whether the stored overall and available category model are internally comparable      |
| `category_model`         | string          | Current seven-category, partial-current, legacy/unknown, or unavailable category model |
| `category_total`         | integer or null | Sum of the returned category values                                                    |
| `overall_category_delta` | integer or null | Stored overall minus `category_total`                                                  |
| `categories`             | object          | Backward-compatible numeric category scores                                            |
| `category_details`       | object          | Each category's `score`, `max_score`, and percentage of its maximum                    |

The standard category maxima are Copywriting 20, Readability 10, SEO 15, Structure 10, Coverage 15, Uniqueness 20, and Credibility 10. A legacy category without a defined modern maximum returns `max_score: null` and `percent: null` rather than an invented denominator. `legacy_mismatch` identifies a complete modern category set that does not sum to the stored overall, normally because the persisted record predates the current score calculation. Do not describe that difference as weighting unless the response explicitly supplies a weighted model.

**How to use:** Use the overall score as a quality gate in your automation. For example, only publish drafts that score 70 or above, and flag lower-scoring drafts for manual review. The category breakdown tells you exactly where the draft is strong or weak.

**Stepped mode note:** This field is `null` at `brief_ready`. The score is only available after the draft is generated.

## Edit or remove a saved project

These lifecycle routes use the normal organization scope. Send a stable `Idempotency-Key` header on every mutation so reconnect retries do not repeat the operation.

| Method   | Path                                      | Purpose                                                       |
| -------- | ----------------------------------------- | ------------------------------------------------------------- |
| `PATCH`  | `/api/agent/v1/copywriter/jobs/:id/brief` | Patch selected fields of a stepped-mode brief before approval |
| `PUT`    | `/api/agent/v1/copywriter/jobs/:id/draft` | Replace the complete draft body with Markdown or HTML         |
| `DELETE` | `/api/agent/v1/copywriter/jobs/:id`       | Permanently delete the project and its saved artifacts        |

Brief patching preserves omitted sections and refuses jobs that are not in the editable brief-ready state. Draft replacement refuses an active generation job and resets scores and review artifacts tied to the previous body. Deletion is permanent. Read the current project first and require a human confirmation of the exact topic before replacing or deleting content; the MCP tools enforce that preflight automatically.

## Stepped mode: partial artifacts

In stepped mode, calling the artifacts endpoint at `brief_ready` returns a partial response. This lets you inspect the research output before committing to draft generation.

| Field                | At brief\_ready | At completed |
| -------------------- | --------------- | ------------ |
| `outline`            | Available       | Available    |
| `draft`              | `null`          | Available    |
| `seo`                | Available       | Available    |
| `entities`           | Available       | Available    |
| `faqs`               | Available       | Available    |
| `faq_schema_json_ld` | Available       | Available    |
| `score`              | `null`          | Available    |

To move from `brief_ready` to `completed`, approve the brief:

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

Then poll the status endpoint until `"completed"` and fetch artifacts again for the full set.

## Practical examples

### Publishing to a CMS

After retrieving artifacts, map each field to your CMS:

* `seo.title_tag` → Page title / `<title>`
* `seo.meta_description` → Meta description field
* `seo.h1` → Page heading
* `draft.content` → Post body (convert Markdown to HTML if needed)
* `faq_schema_json_ld` → Custom code / head injection field

### Quality gate automation

```
artifacts = fetch_artifacts(job_id)

if artifacts["score"]["overall"] >= 70:
    publish_to_cms(artifacts)
else:
    flag_for_review(job_id, artifacts["score"])
```

### Building a table of contents

```
for section in artifacts["outline"]:
    print(f"{section['level']}: {section['heading']}")
    for sub in section.get("subheadings", []):
        print(f"  {sub['level']}: {sub['heading']}")
```

## Error responses

| HTTP | Code        | When                                                          |
| ---- | ----------- | ------------------------------------------------------------- |
| 404  | `not_found` | Job ID does not exist or does not belong to your organization |
| 409  | `not_ready` | Job has not completed yet — keep polling the status endpoint  |

## Related articles

* [Creating content jobs](/api/api-creating-content-jobs.md) — How to create jobs and understand auto vs stepped mode.
* [Getting started with the API](/api/api-getting-started.md) — End-to-end walkthrough from API key to finished content.
* [Understanding your content score](/copywriter/understanding-your-content-score.md) — How the 0–100 content score is calculated and what each category measures.
