> ## Documentation Index
> Fetch the complete documentation index at: https://radarkit.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Create article

> Has the Content agent write an article for one of your prompts. The agent reads the pages AI models cite for that prompt, builds an outline and writes in your brand's voice. The draft lands in your editor. Writing takes a few minutes, so keep the run `id` and poll Get article run.

If an article for the same prompt, type and keyword is already being written or is done, you get that run back with `meta.reused: true` and no content credit is spent. Send `force: true` to write another.

Articles started here appear in the project's Agents section on a sheet named API.

Cost: 1 API credit plus 1 AI content credit from the project owner. Nothing is charged when the request is refused.

Limits: 10 calls per minute per key.

Needs: Agents. Your seat must be allowed to manage content.




## OpenAPI

````yaml /openapi.yaml post /projects/{project}/content/articles
openapi: 3.1.0
info:
  title: Radarkit API
  version: 1.0.0
  summary: Your AI visibility data, outside the dashboard.
  description: >
    Radarkit tracks how AI assistants answer the questions your customers ask,
    and what each answer says about your brand. This API gives you that data as
    JSON.


    Every request needs an API key in the `Authorization` header. Every response
    has the same shape: `data`, `meta`, `credits` and `request_id`. Most calls
    cost 1 API credit. Heavier calls cost 2. Exports spend Export rows instead,
    one per row.
  contact:
    name: Radarkit support
    email: mail@radarkit.ai
    url: https://radarkit.ai
servers:
  - url: https://api.radarkit.ai/v1
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Account
    description: Your key, your plan and both balances. Free.
  - name: Projects
    description: One project is one brand or website. Every other call needs a project id.
  - name: Topics
    description: Topics group prompts. Every prompt belongs to one topic.
  - name: Prompts
    description: The questions Radarkit asks every AI model on a schedule.
  - name: Visibility
    description: The daily visibility score per model, precomputed.
  - name: Responses
    description: One row per AI answer, with everything Radarkit found in it.
  - name: Sources
    description: The web pages AI answers cite or consult.
  - name: Competitors
    description: Who the answers recommend and how often.
  - name: Rankings
    description: Recommended domains with their position in the answer.
  - name: Query fanout
    description: The web searches a model ran before answering, one row per answer.
  - name: Web search
    description: How often the models searched and what they searched for, summarised.
  - name: Sentiment
    description: How the answers talk about your brand.
  - name: Exports
    description: >
      Thousands of rows as one gzip file. Four calls in order: estimate, create,
      poll, download.


      Estimate is free and returns the exact row count. Create charges that many
      Export rows and queues the job. Poll the export until its status is
      `ready`. Download follows a redirect to a signed link that works for 30
      minutes. Files are kept for 7 days.
  - name: Content
    description: Have the Content agent write an article for a prompt, then poll the run.
paths:
  /projects/{project}/content/articles:
    post:
      tags:
        - Content
      summary: Create article
      description: >
        Has the Content agent write an article for one of your prompts. The
        agent reads the pages AI models cite for that prompt, builds an outline
        and writes in your brand's voice. The draft lands in your editor.
        Writing takes a few minutes, so keep the run `id` and poll Get article
        run.


        If an article for the same prompt, type and keyword is already being
        written or is done, you get that run back with `meta.reused: true` and
        no content credit is spent. Send `force: true` to write another.


        Articles started here appear in the project's Agents section on a sheet
        named API.


        Cost: 1 API credit plus 1 AI content credit from the project owner.
        Nothing is charged when the request is refused.


        Limits: 10 calls per minute per key.


        Needs: Agents. Your seat must be allowed to manage content.
      operationId: createArticle
      parameters:
        - $ref: '#/components/parameters/project'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - prompt_id
                - keyword
              properties:
                prompt_id:
                  type: integer
                  description: The prompt the article targets.
                article_type:
                  type: string
                  enum:
                    - blog_post
                    - listicle
                    - comparison
                    - alternatives
                    - faq
                    - first_person_review
                  description: >-
                    The article format. Default is the format the cited pages
                    use most.
                keyword:
                  type: string
                  maxLength: 255
                  description: >-
                    The keyword the article should rank for, as in the Create
                    Content dialog.
                country:
                  type: string
                  minLength: 2
                  maxLength: 2
                  description: >-
                    Two-letter country the article should rank in; drives the
                    SERP research. Default is the project region.
                language:
                  type: string
                  enum:
                    - en
                    - da
                    - de
                    - es
                    - fr
                    - it
                    - pt
                    - nl
                    - pl
                    - ru
                  description: >-
                    Language of the SERP research and of the article. Default is
                    English.
                additional_details:
                  type: string
                  maxLength: 1500
                  description: Instructions for the writer.
                force:
                  type: boolean
                  description: >-
                    Write a new article even if one for the same prompt, type
                    and keyword exists.
                sheet:
                  type: string
                  maxLength: 80
                  description: >-
                    Name of the content sheet the article row goes on, under
                    Agents → Sheets. Default is the project's "API" sheet. A
                    sheet holds 50 rows; a full one rolls over to "Name 2" and
                    `meta.sheet` tells you where the row landed.
            example:
              prompt_id: 2048
              article_type: comparison
              keyword: best crm for startups
              country: US
              language: en
              additional_details: Lead with pricing. Mention the free tier for teams under 3.
      responses:
        '202':
          description: The run has started.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/ContentRun'
                  meta:
                    type: object
                    properties:
                      project:
                        type: string
                      reused:
                        type: boolean
                        description: >-
                          True when an existing run was returned instead of
                          starting a new one.
                      ai_content_credits_remaining:
                        type: integer
                      next_step:
                        type: string
                  credits:
                    $ref: '#/components/schemas/Credits'
                  request_id:
                    $ref: '#/components/schemas/RequestId'
              example:
                data:
                  id: 551
                  project: 64f1a2b3c4d5e6f708192a3b
                  status: processing
                  current_step: creating
                  error: null
                  retryable: false
                  prompt:
                    id: 2048
                  article:
                    id: 812
                    title: null
                    keyword: best crm for startups
                    article_type: comparison
                    write_mode: ai
                    status: draft
                    crawl_status: pending
                    outline_status: pending
                    word_count: null
                    scores:
                      radarkit: null
                      seo: null
                      geo: null
                      readability: null
                    editor_url: >-
                      https://radarkit.ai/dashboard/64f1a2b3c4d5e6f708192a3b/content/812
                    created_at: '2026-09-03T10:30:00+00:00'
                    updated_at: '2026-09-03T10:30:00+00:00'
                  started_at: '2026-09-03T10:30:00+00:00'
                  completed_at: null
                meta:
                  project: 64f1a2b3c4d5e6f708192a3b
                  reused: false
                  ai_content_credits_remaining: 19
                  next_step: >-
                    Poll GET /v1/content/runs/{id} until status is completed,
                    then open editor_url or fetch the body with include=body.
                credits:
                  charged: 1
                  remaining: 2941
                request_id: req_01j9x519n0o1p2q3r4s5t6u7v8
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '402':
          description: >-
            `INSUFFICIENT_CONTENT_CREDITS`: the owner has no AI content credits.
            `INSUFFICIENT_CREDITS`: no API credits left. `PLAN_INACTIVE` or
            `OWNER_PLAN_INACTIVE`: a plan is not active.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: >-
            `SCOPE_MISSING`: the key has no Agents permission.
            `PROJECT_FORBIDDEN`: the key cannot reach this project.
            `PERMISSION_DENIED`: your seat cannot manage content.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: >-
            `PROJECT_NOT_FOUND`: no project with that id. `PROMPT_NOT_FOUND`: no
            active prompt with that id in this project.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '422':
          description: >-
            `VALIDATION_FAILED`: a field is wrong, `details` says which.
            `CONTENT_REJECTED`: the Content agent refused the request, the
            message says why.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          $ref: '#/components/responses/RateLimited'
components:
  parameters:
    project:
      name: project
      in: path
      required: true
      description: The project id. 24 characters. From List projects.
      schema:
        type: string
        pattern: ^[0-9a-f]{24}$
      example: 64f1a2b3c4d5e6f708192a3b
  schemas:
    ContentRun:
      type: object
      properties:
        id:
          type: integer
        project:
          type: string
        status:
          type: string
          enum:
            - processing
            - completed
            - failed
            - cancelled
        current_step:
          type:
            - string
            - 'null'
        error:
          type:
            - string
            - 'null'
        retryable:
          type: boolean
          description: True for failed and cancelled runs.
        prompt:
          type: object
          properties:
            id:
              type:
                - integer
                - 'null'
        article:
          type:
            - object
            - 'null'
          properties:
            id:
              type: integer
            title:
              type:
                - string
                - 'null'
            keyword:
              type:
                - string
                - 'null'
            article_type:
              type:
                - string
                - 'null'
            write_mode:
              type:
                - string
                - 'null'
            status:
              type:
                - string
                - 'null'
            crawl_status:
              type:
                - string
                - 'null'
            outline_status:
              type:
                - string
                - 'null'
            word_count:
              type:
                - integer
                - 'null'
            scores:
              type: object
              properties:
                radarkit:
                  type:
                    - number
                    - 'null'
                seo:
                  type:
                    - number
                    - 'null'
                geo:
                  type:
                    - number
                    - 'null'
                readability:
                  type:
                    - number
                    - 'null'
            editor_url:
              type:
                - string
                - 'null'
              description: Open this in the dashboard to edit and publish.
            created_at:
              type:
                - string
                - 'null'
              format: date-time
            updated_at:
              type:
                - string
                - 'null'
              format: date-time
        started_at:
          type:
            - string
            - 'null'
          format: date-time
        completed_at:
          type:
            - string
            - 'null'
          format: date-time
        body_markdown:
          type: string
          description: The article as Markdown. Only with `include=body`.
    Credits:
      type: object
      description: >-
        What this call cost and what is left. Also in the
        `X-RadarKit-Credits-Charged` and `X-RadarKit-Credits-Remaining` headers.
      properties:
        charged:
          type: integer
          description: API credits spent on this call.
        remaining:
          type:
            - integer
            - 'null'
          description: API credits left on the billed account. Null on free calls.
    RequestId:
      type: string
      description: >-
        A unique id for this call. Also in the `X-Request-Id` header. Quote it
        when you contact support.
      example: req_01j9x4m2p7q8r9s0t1u2v3w4x5
    Error:
      type: object
      description: Every failed call has this shape and no `data`.
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              description: Stable. Build on this, not on the message.
            message:
              type: string
              description: For people. May change.
            details:
              description: >-
                More when there is more to say. Which field failed, how long to
                wait, which id already exists.
              oneOf:
                - type: object
                - type: array
                  items:
                    type: object
        request_id:
          $ref: '#/components/schemas/RequestId'
  responses:
    Unauthenticated:
      description: >-
        `UNAUTHENTICATED`: no key, a wrong key, or a revoked or expired key.
        `KEY_IN_QUERY` (400) if the key was in the URL.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: UNAUTHENTICATED
              message: >-
                Missing or invalid API key. Send it as: Authorization: Bearer
                rk_live_YOUR_KEY
            request_id: req_01j9x4q7z8y9x0w1v2u3t4s5r6
    RateLimited:
      description: >-
        `RATE_LIMITED`: too many calls. Wait the seconds in `Retry-After` and
        send the same request again. Nothing was charged.
      headers:
        Retry-After:
          description: Seconds to wait.
          schema:
            type: integer
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: RATE_LIMITED
              message: Too many requests. Slow down and retry.
              details:
                retry_after: 21
            request_id: req_01j9x4r2s3t4u5v6w7x8y9z0a1
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        Your API key. Create one in Settings, API keys. Send it as
        `Authorization: Bearer rk_live_YOUR_KEY`.

````