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

# Prompts

> Create, update, delete, and retrieve tracked prompts and their analytics, AI responses, domains, and URLs.

Prompts are the AI search queries Topify.ai tracks daily across all AI providers. Each prompt generates responses that are analyzed for brand visibility, sentiment, citations, and competitor mentions.

The API supports full CRUD operations on prompts. Read endpoints are available to all API keys. Write endpoints (create, update, delete) require an admin-scoped API key.

## List prompts

```
GET /projects/{project_id}/prompts
```

Returns all prompts in a project, ordered by creation date.

### Path parameters

| Param        | Type          | Description    |
| ------------ | ------------- | -------------- |
| `project_id` | string (UUID) | The project ID |

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl "https://topify-customer-api-production.up.railway.app/api/public/v1/projects/{project_id}/prompts" \
      -H "X-API-Key: tk_live_..."
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    resp = client.get(f"/projects/{project_id}/prompts")
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const resp = await fetch(`${BASE}/projects/${projectId}/prompts`, { headers });
    ```
  </Tab>
</Tabs>

### Response

```json theme={null}
{
  "success": true,
  "data": {
    "project_id": "a1b2c3d4-...",
    "total": 25,
    "prompts": [
      {
        "id": "e5f6a7b8-...",
        "project_id": "a1b2c3d4-...",
        "content": "What is the best project management tool?",
        "prompt_type": "active",
        "topic_id": "t1u2v3w4-...",
        "country": "US",
        "visibility": 85.0,
        "sentiment": 72,
        "position": 2.3,
        "volume": 150,
        "cvr": 45.0,
        "intent": "commercial",
        "trend": "up",
        "created_at": "2026-01-15T10:30:00+00:00"
      }
    ]
  }
}
```

### Prompt fields

| Field         | Type              | Nullable | Description                                                                  |
| ------------- | ----------------- | -------- | ---------------------------------------------------------------------------- |
| `id`          | string (UUID)     | No       | Prompt ID                                                                    |
| `project_id`  | string (UUID)     | No       | Parent project ID                                                            |
| `content`     | string            | No       | The AI search query text                                                     |
| `prompt_type` | string            | No       | `active`, `suggested`, `pending`, `inactive`, or `url_recommended`           |
| `topic_id`    | string (UUID)     | Yes      | Topic this prompt belongs to                                                 |
| `country`     | string            | Yes      | Target country for localized responses                                       |
| `visibility`  | float             | Yes      | Brand visibility percentage (0--100)                                         |
| `sentiment`   | integer           | Yes      | Brand sentiment score                                                        |
| `position`    | float             | Yes      | Average brand position in responses                                          |
| `volume`      | integer           | Yes      | Number of responses collected                                                |
| `cvr`         | float             | Yes      | Content visibility rate                                                      |
| `intent`      | string            | Yes      | Query intent: `informational`, `commercial`, `navigational`, `transactional` |
| `trend`       | string            | Yes      | Trend direction: `up`, `down`, or `stable`                                   |
| `created_at`  | string (ISO 8601) | No       | Creation timestamp                                                           |

***

## Get prompt

```
GET /projects/{project_id}/prompts/{prompt_id}
```

Returns a single prompt. Same fields as list.

### Path parameters

| Param        | Type          | Description    |
| ------------ | ------------- | -------------- |
| `project_id` | string (UUID) | The project ID |
| `prompt_id`  | string (UUID) | The prompt ID  |

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl "https://topify-customer-api-production.up.railway.app/api/public/v1/projects/{project_id}/prompts/{prompt_id}" \
      -H "X-API-Key: tk_live_..."
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    resp = client.get(f"/projects/{project_id}/prompts/{prompt_id}")
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const resp = await fetch(`${BASE}/projects/${projectId}/prompts/${promptId}`, { headers });
    ```
  </Tab>
</Tabs>

***

## Create prompts

```
POST /projects/{project_id}/prompts
```

Add one or more prompts to a project. Each prompt begins tracking immediately -- Topify.ai will start collecting AI responses and calculating metrics in the background.

<Warning>
  Requires an admin-scoped API key. Viewer keys receive a `403` response.
</Warning>

### Path parameters

| Param        | Type          | Description                   |
| ------------ | ------------- | ----------------------------- |
| `project_id` | string (UUID) | The project to add prompts to |

### Request body

| Field     | Type          | Required | Description                                        |
| --------- | ------------- | -------- | -------------------------------------------------- |
| `prompts` | string\[]     | Yes      | Array of prompt texts to track (1--50 per request) |
| `topicId` | string (UUID) | Yes      | Topic to assign the prompts to                     |
| `country` | string        | No       | ISO country code for localized responses           |

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl -X POST "https://topify-customer-api-production.up.railway.app/api/public/v1/projects/{project_id}/prompts" \
      -H "X-API-Key: tk_live_..." \
      -H "Content-Type: application/json" \
      -d '{
        "prompts": ["What is the best project management tool?", "Top PM software for teams"],
        "topicId": "t1u2v3w4-...",
        "country": "US"
      }'
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    resp = client.post(f"/projects/{project_id}/prompts", json={
        "prompts": ["What is the best project management tool?"],
        "topicId": topic_id,
        "country": "US",
    })
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const resp = await fetch(`${BASE}/projects/${projectId}/prompts`, {
      method: "POST",
      headers: { ...headers, "Content-Type": "application/json" },
      body: JSON.stringify({
        prompts: ["What is the best project management tool?"],
        topicId: topicId,
        country: "US",
      }),
    });
    ```
  </Tab>
</Tabs>

### Response

```json theme={null}
{
  "code": 200,
  "message": "200 OK",
  "data": {
    "projectId": "a1b2c3d4-...",
    "created": 2,
    "prompts": [
      {
        "id": "e5f6a7b8-...",
        "projectId": "a1b2c3d4-...",
        "content": "What is the best project management tool?",
        "promptType": "Active",
        "topicId": "t1u2v3w4-...",
        "country": "US",
        "createdAt": "2026-03-30T10:30:00+00:00"
      }
    ]
  }
}
```

### Error responses

| Status | Cause                                                              |
| ------ | ------------------------------------------------------------------ |
| `400`  | Empty prompts array, whitespace-only content, or missing `topicId` |
| `403`  | API key has read-only (viewer) access                              |
| `409`  | A prompt with the same content already exists in this project      |
| `429`  | Prompt quota exceeded for your plan tier                           |

***

## Update prompt

```
PATCH /projects/{project_id}/prompts/{prompt_id}
```

Update the content, country, topic, or type of an existing prompt.

<Warning>
  Requires an admin-scoped API key.
</Warning>

### Path parameters

| Param        | Type          | Description          |
| ------------ | ------------- | -------------------- |
| `project_id` | string (UUID) | The project ID       |
| `prompt_id`  | string (UUID) | The prompt to update |

### Request body

All fields are optional. Include only the fields you want to change.

| Field        | Type          | Description                                            |
| ------------ | ------------- | ------------------------------------------------------ |
| `content`    | string        | New prompt text (cannot be empty)                      |
| `country`    | string        | ISO country code                                       |
| `topicId`    | string (UUID) | Reassign to a different topic                          |
| `promptType` | string        | Change prompt type (`Active`, `Inactive`, `Suggested`) |

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl -X PATCH "https://topify-customer-api-production.up.railway.app/api/public/v1/projects/{project_id}/prompts/{prompt_id}" \
      -H "X-API-Key: tk_live_..." \
      -H "Content-Type: application/json" \
      -d '{"content": "Best project management tools for remote teams"}'
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    resp = client.patch(f"/projects/{project_id}/prompts/{prompt_id}", json={
        "content": "Best project management tools for remote teams",
    })
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const resp = await fetch(`${BASE}/projects/${projectId}/prompts/${promptId}`, {
      method: "PATCH",
      headers: { ...headers, "Content-Type": "application/json" },
      body: JSON.stringify({ content: "Best project management tools for remote teams" }),
    });
    ```
  </Tab>
</Tabs>

### Response

Returns the updated prompt with all fields (same shape as [get prompt](#get-prompt)).

### Error responses

| Status | Cause                                                             |
| ------ | ----------------------------------------------------------------- |
| `400`  | Empty request body, whitespace-only content, or no fields changed |
| `403`  | API key has read-only access                                      |
| `404`  | Prompt not found in this project                                  |

***

## Delete prompt

```
DELETE /projects/{project_id}/prompts/{prompt_id}
```

Permanently delete a prompt and stop tracking it. Historical analytics data for this prompt is also removed.

<Warning>
  This action cannot be undone. Requires an admin-scoped API key.
</Warning>

### Path parameters

| Param        | Type          | Description          |
| ------------ | ------------- | -------------------- |
| `project_id` | string (UUID) | The project ID       |
| `prompt_id`  | string (UUID) | The prompt to delete |

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl -X DELETE "https://topify-customer-api-production.up.railway.app/api/public/v1/projects/{project_id}/prompts/{prompt_id}" \
      -H "X-API-Key: tk_live_..."
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    resp = client.delete(f"/projects/{project_id}/prompts/{prompt_id}")
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const resp = await fetch(`${BASE}/projects/${projectId}/prompts/${promptId}`, {
      method: "DELETE",
      headers,
    });
    ```
  </Tab>
</Tabs>

### Response

```json theme={null}
{
  "code": 200,
  "message": "200 OK",
  "data": {
    "promptId": "e5f6a7b8-...",
    "message": "Prompt deleted successfully"
  }
}
```

### Error responses

| Status | Cause                            |
| ------ | -------------------------------- |
| `403`  | API key has read-only access     |
| `404`  | Prompt not found in this project |

***

## Prompt analytics

```
GET /projects/{project_id}/prompts/{prompt_id}/analytics
```

Returns time-series visibility, position, and sentiment data grouped by date and AI provider.

### Query parameters

| Param           | Type    | Default | Description                     |
| --------------- | ------- | ------- | ------------------------------- |
| `duration_days` | integer | `7`     | Days to look back               |
| `date_from`     | string  | --      | Start date (`YYYY-MM-DD`)       |
| `date_to`       | string  | --      | End date (`YYYY-MM-DD`)         |
| `providers`     | string  | --      | Comma-separated provider filter |

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl "https://topify-customer-api-production.up.railway.app/api/public/v1/projects/{project_id}/prompts/{prompt_id}/analytics?duration_days=7" \
      -H "X-API-Key: tk_live_..."
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    resp = client.get(f"/projects/{project_id}/prompts/{prompt_id}/analytics", params={"duration_days": 7})
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const resp = await fetch(`${BASE}/projects/${projectId}/prompts/${promptId}/analytics?duration_days=7`, { headers });
    ```
  </Tab>
</Tabs>

### Response

```json theme={null}
{
  "success": true,
  "data": {
    "prompt_id": "e5f6a7b8-...",
    "prompt_content": "What is the best project management tool?",
    "volume": 42,
    "sentiment": 72,
    "visibility_chart": {
      "2026-03-01": [
        { "provider": "chatgpt", "value": 85.0 },
        { "provider": "perplexity", "value": 90.0 }
      ],
      "2026-03-02": [
        { "provider": "chatgpt", "value": 80.0 }
      ]
    },
    "position_chart": {
      "2026-03-01": [
        { "provider": "chatgpt", "value": 2.0 }
      ]
    },
    "sentiment_chart": {
      "2026-03-01": [
        { "provider": "chatgpt", "value": 75.0 }
      ]
    }
  }
}
```

### Response fields

| Field              | Type          | Nullable | Description                                          |
| ------------------ | ------------- | -------- | ---------------------------------------------------- |
| `prompt_id`        | string (UUID) | No       | Prompt ID                                            |
| `prompt_content`   | string        | No       | The AI search query text                             |
| `volume`           | integer       | Yes      | Total responses collected                            |
| `sentiment`        | integer       | Yes      | Overall brand sentiment across the period            |
| `visibility_chart` | object        | No       | Date-keyed map of `ProviderMetric[]` (visibility %)  |
| `position_chart`   | object        | No       | Date-keyed map of `ProviderMetric[]` (avg position)  |
| `sentiment_chart`  | object        | No       | Date-keyed map of `ProviderMetric[]` (avg sentiment) |

**ProviderMetric:**

| Field      | Type   | Description                                 |
| ---------- | ------ | ------------------------------------------- |
| `provider` | string | AI provider name (e.g., `chatgpt`)          |
| `value`    | float  | Metric value for that provider on that date |

***

## AI responses (chats)

```
GET /projects/{project_id}/prompts/{prompt_id}/chats
```

Returns raw AI responses with brand mentions, sentiment, position, and citation references.

### Query parameters

Same as [analytics](#prompt-analytics).

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl "https://topify-customer-api-production.up.railway.app/api/public/v1/projects/{project_id}/prompts/{prompt_id}/chats?duration_days=7" \
      -H "X-API-Key: tk_live_..."
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    resp = client.get(f"/projects/{project_id}/prompts/{prompt_id}/chats", params={"duration_days": 7})
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const resp = await fetch(`${BASE}/projects/${projectId}/prompts/${promptId}/chats?duration_days=7`, { headers });
    ```
  </Tab>
</Tabs>

### Response

```json theme={null}
{
  "success": true,
  "data": {
    "items": [
      {
        "id": "c1d2e3f4-...",
        "date": "2026-03-01T12:00:00+00:00",
        "mentioned": true,
        "position": 2,
        "all_mentions": [
          {
            "name": "Acme Corp",
            "icon_url": "https://logo.clearbit.com/acme.com",
            "icon_urls": ["https://logo.clearbit.com/acme.com", "https://www.google.com/s2/favicons?domain=acme.com&sz=64"]
          }
        ],
        "chat_preview": "When it comes to project management tools...",
        "platform": "chatgpt",
        "model": "gpt-4o",
        "full_content": "When it comes to project management tools, Acme Corp stands out for...",
        "prompt_content": "What is the best project management tool?",
        "references": [
          {
            "title": "Best PM Tools 2026",
            "link": "https://techcrunch.com/best-pm-tools",
            "snippet": "Acme Corp ranked #1...",
            "reference_index": 1
          }
        ],
        "brands_mentioned": {
          "Acme Corp": { "position": 1, "count": 3 },
          "Competitor A": { "position": 2, "count": 1 }
        },
        "sentiment": 80,
        "sentiment_by_brands": {
          "Acme Corp": 80,
          "Competitor A": 60
        }
      }
    ]
  }
}
```

### ChatItem fields

| Field                 | Type              | Nullable | Description                                                                     |
| --------------------- | ----------------- | -------- | ------------------------------------------------------------------------------- |
| `id`                  | string (UUID)     | No       | LLM output ID                                                                   |
| `date`                | string (ISO 8601) | No       | When the response was generated                                                 |
| `mentioned`           | boolean           | No       | Whether your brand was mentioned                                                |
| `position`            | integer           | Yes      | Your brand's rank position in this response                                     |
| `all_mentions`        | BrandMention\[]   | No       | All brands mentioned in the response                                            |
| `chat_preview`        | string            | No       | First sentence of the response (max 150 chars)                                  |
| `platform`            | string            | No       | AI provider (`chatgpt`, `perplexity`, `google_ai_overview`, `gemini`, `claude`) |
| `model`               | string            | No       | Specific model used (e.g., `gpt-4o`)                                            |
| `full_content`        | string            | No       | Complete AI response text                                                       |
| `prompt_content`      | string            | No       | The prompt that generated this response                                         |
| `references`          | ReferenceItem\[]  | No       | Citations/sources in the response                                               |
| `brands_mentioned`    | object            | Yes      | Raw brand extraction data (brand name to position/count mapping)                |
| `sentiment`           | integer           | Yes      | Your brand's sentiment score in this response                                   |
| `sentiment_by_brands` | object            | Yes      | Sentiment scores keyed by brand name                                            |

**BrandMention:**

| Field       | Type      | Description                               |
| ----------- | --------- | ----------------------------------------- |
| `name`      | string    | Brand name as it appeared in the response |
| `icon_url`  | string    | Primary logo URL                          |
| `icon_urls` | string\[] | Multiple logo URL sources                 |

**ReferenceItem:**

| Field             | Type    | Description                              |
| ----------------- | ------- | ---------------------------------------- |
| `title`           | string  | Citation title                           |
| `link`            | string  | Citation URL                             |
| `snippet`         | string  | Citation snippet text                    |
| `reference_index` | integer | Position of the citation in the response |

***

## Domains

```
GET /projects/{project_id}/prompts/{prompt_id}/domains
```

Returns domain-level citation breakdown, sorted by citation count descending.

### Query parameters

Same as [analytics](#prompt-analytics).

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl "https://topify-customer-api-production.up.railway.app/api/public/v1/projects/{project_id}/prompts/{prompt_id}/domains?duration_days=7" \
      -H "X-API-Key: tk_live_..."
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    resp = client.get(f"/projects/{project_id}/prompts/{prompt_id}/domains", params={"duration_days": 7})
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const resp = await fetch(`${BASE}/projects/${projectId}/prompts/${promptId}/domains?duration_days=7`, { headers });
    ```
  </Tab>
</Tabs>

### Response

```json theme={null}
{
  "success": true,
  "data": {
    "items": [
      {
        "domain": "techcrunch.com",
        "domain_type": 1,
        "citation_count": 15,
        "avg_citations": 2.5,
        "used_percentage": 75.0,
        "mentioned": true,
        "brands_appeared": [
          {
            "name": "Acme Corp",
            "icon_url": "https://logo.clearbit.com/acme.com",
            "icon_urls": ["https://logo.clearbit.com/acme.com"]
          }
        ],
        "favicon_url": "https://www.google.com/s2/favicons?domain=techcrunch.com&sz=64",
        "favicon_urls": [
          "https://logo.clearbit.com/techcrunch.com",
          "https://www.google.com/s2/favicons?domain=techcrunch.com&sz=64"
        ]
      }
    ]
  }
}
```

### DomainItem fields

| Field             | Type         | Nullable | Description                                           |
| ----------------- | ------------ | -------- | ----------------------------------------------------- |
| `domain`          | string       | No       | Domain name                                           |
| `domain_type`     | integer      | No       | Source category ID                                    |
| `citation_count`  | integer      | No       | Total citation count across all responses             |
| `avg_citations`   | float        | No       | Average citations per response that cited this domain |
| `used_percentage` | float        | No       | How frequently this domain appears (percentage)       |
| `mentioned`       | boolean      | No       | Whether your brand appeared alongside this domain     |
| `brands_appeared` | BrandInfo\[] | No       | Brands that appeared in responses citing this domain  |
| `favicon_url`     | string       | Yes      | Primary favicon URL                                   |
| `favicon_urls`    | string\[]    | No       | Multiple favicon URL sources                          |

**BrandInfo:**

| Field       | Type      | Description               |
| ----------- | --------- | ------------------------- |
| `name`      | string    | Brand name                |
| `icon_url`  | string    | Primary logo URL          |
| `icon_urls` | string\[] | Multiple logo URL sources |

***

## URLs

```
GET /projects/{project_id}/prompts/{prompt_id}/urls
```

Returns URL-level citation data, sorted by mention count descending.

### Query parameters

Same as [analytics](#prompt-analytics).

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl "https://topify-customer-api-production.up.railway.app/api/public/v1/projects/{project_id}/prompts/{prompt_id}/urls?duration_days=7" \
      -H "X-API-Key: tk_live_..."
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    resp = client.get(f"/projects/{project_id}/prompts/{prompt_id}/urls", params={"duration_days": 7})
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const resp = await fetch(`${BASE}/projects/${projectId}/prompts/${promptId}/urls?duration_days=7`, { headers });
    ```
  </Tab>
</Tabs>

### Response

```json theme={null}
{
  "success": true,
  "data": {
    "items": [
      {
        "url": "https://techcrunch.com/best-pm-tools-2026",
        "title": "Best PM Tools 2026",
        "domain": "techcrunch.com",
        "url_type": null,
        "url_type_name": "unknown",
        "mentioned_count": 8,
        "brands_appear": [
          {
            "name": "Acme Corp",
            "icon_url": "https://logo.clearbit.com/acme.com",
            "icon_urls": ["https://logo.clearbit.com/acme.com"]
          }
        ],
        "first_seen": "2026-02-15T00:00:00+00:00",
        "last_seen": "2026-03-01T00:00:00+00:00"
      }
    ]
  }
}
```

### UrlItem fields

| Field             | Type              | Nullable | Description                                       |
| ----------------- | ----------------- | -------- | ------------------------------------------------- |
| `url`             | string            | No       | Full URL                                          |
| `title`           | string            | No       | Page title                                        |
| `domain`          | string            | No       | Domain extracted from URL                         |
| `url_type`        | integer           | Yes      | URL type ID                                       |
| `url_type_name`   | string            | No       | URL type label (e.g., `unknown`)                  |
| `mentioned_count` | integer           | No       | Number of times this URL was cited                |
| `brands_appear`   | BrandInfo\[]      | No       | Brands appearing in responses that cited this URL |
| `first_seen`      | string (ISO 8601) | No       | Earliest citation date                            |
| `last_seen`       | string (ISO 8601) | No       | Most recent citation date                         |
