# Citations

Source: https://ceyo.ai/docs/signal/citations

### Citations

Fetch successful model responses and the sources cited across a project or location.

**Scope:** Project

### List prompt citations

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

Aggregates every citation attached to responses for one prompt in the selected project. Repeated citations are combined and counted across the requested date range.

#### Path parameters

| Name | Type | Details | Description |
| --- | --- | --- | --- |
| `project_id` | project UUID \| project external ID | Required | Project identifier. |
| `prompt_id` | uuid | Required | Prompt identifier. |

#### Query parameters

| Name | Type | Details | Description |
| --- | --- | --- | --- |
| `start` | date | Optional; Default: 6 days before end | First run date to include, in YYYY-MM-DD format. |
| `end` | date | Optional; Default: Today | Last run date to include, in YYYY-MM-DD format. |
| `models` | string | Optional; Default: All enabled models | Comma-separated or repeated model keys. For example: chatgpt,claude,perplexity. |
| `page` | integer | Optional; Default: 1 | The 1-based page number. |
| `per_page` | integer | Optional; Default: 15 | Number of records per page. Maximum: 50. |

#### Response envelope

`project_id`:**uuid**`prompt_id`:**uuid**`start`:**date**`end`:**date**`models`:**string\[\]**`rows`:**Citation\[\]**`pagination`:**Pagination**

| Name | Type | Details | Description |
| --- | --- | --- | --- |
| `project_id` | uuid |  | Resolved Ceyo project identifier. |
| `prompt_id` | uuid |  | Prompt represented by the response. |
| `start` | date |  | Resolved start date. |
| `end` | date |  | Resolved end date. |
| `models` | string\[\] |  | Model keys included in the response. |
| `rows` | Citation\[\] |  | Paginated citation pages. |
| `pagination` | Pagination |  | Pagination metadata. |

#### Citation

| Name | Type | Details | Description |
| --- | --- | --- | --- |
| `domain` | string |  | Normalized citation hostname. |
| `page` | string |  | Normalized page value used for grouping and display. |
| `url` | string |  | Canonical citation URL. |
| `title` | string \| null |  | Stored page title when supplied by the response provider. |
| `frequency` | integer |  | Citation occurrences across the selected responses. |
| `model_keys` | string\[\] |  | Models that cited the page at least once. |
| `model_frequencies` | Record<string, integer> |  | Citation frequency keyed by model. |

#### Pagination

| Name | Type | Details | Description |
| --- | --- | --- | --- |
| `page` | integer |  | Current 1-based page number. |
| `per_page` | integer |  | Requested number of records per page. |
| `total` | integer |  | Total records matching the request. |
| `total_pages` | integer |  | Total available pages. |

#### Request and response

```curl
curl --request GET \
  --url 'https://api.signal.ceyo.ai/v1/projects/{project_id}/prompts/{prompt_id}/citations?start=2026-07-24&end=2026-07-30&models=chatgpt,perplexity' \
  --header 'Authorization: Bearer ceyo_platform_...'
```

```json
{
  "project_id": "e6c96c98-d777-40e0-94ec-48931f57782f",
  "prompt_id": "4de5e484-ce6a-4e45-ad7c-bd48db2549af",
  "start": "2026-07-24",
  "end": "2026-07-30",
  "models": ["chatgpt", "perplexity"],
  "rows": [
    {
      "domain": "example.com",
      "page": "example.com/ai-visibility",
      "url": "https://example.com/ai-visibility",
      "title": "A guide to AI visibility",
      "frequency": 6,
      "model_keys": ["chatgpt", "perplexity"],
      "model_frequencies": {
        "chatgpt": 4,
        "perplexity": 2
      }
    }
  ],
  "pagination": {
    "page": 1,
    "per_page": 15,
    "total": 8,
    "total_pages": 1
  }
}
```

#### Errors

#### Error response envelope

| Name | Type | Details | Description |
| --- | --- | --- | --- |
| `error` | Error |  | Structured error payload. |

#### Error

| Name | Type | Details | Description |
| --- | --- | --- | --- |
| `code` | string |  | Stable snake\_case code suitable for programmatic handling. |
| `message` | string |  | Human-readable explanation of the failure. |
| `details` | object \| array \| null |  | Structured validation or request context when available. |
| `request_id` | string |  | Identifier to provide when requesting support. |

```json
{
  "error": {
    "code": "invalid_date_range",
    "message": "The requested date range is invalid.",
    "details": null,
    "request_id": "req_01K1GP6J8QQFZ4D2B6C5A9V3TS"
  }
}
```

#### Status codes

| Name | Type | Details | Description |
| --- | --- | --- | --- |
| `400` | invalid\_date\_range \| range\_too\_large \| invalid\_filter |  | The requested filters or date range are invalid. |
| `401` | invalid\_api\_key |  | Authorization is absent or invalid. |
| `403` | forbidden |  | The API key cannot access this resource. |
| `404` | not\_found |  | The project, location, or prompt was not found. |
| `422` | visibility\_unavailable |  | Visibility is unavailable for the selected scope. |
| `429` | rate\_limit\_exceeded |  | Too many requests were made. |

### List project citations

`GET /projects/{project_id}/citations`

Returns citation frequency across every matching prompt response in the selected project. Results can be grouped by individual page or by domain.

#### Path parameters

| Name | Type | Details | Description |
| --- | --- | --- | --- |
| `project_id` | project UUID \| project external ID | Required | Project identifier. |

#### Query parameters

| Name | Type | Details | Description |
| --- | --- | --- | --- |
| `start` | date | Optional; Default: 6 days before end | First run date to include, in YYYY-MM-DD format. |
| `end` | date | Optional; Default: Today | Last run date to include, in YYYY-MM-DD format. |
| `models` | string | Optional; Default: All enabled models | Comma-separated or repeated model keys. For example: chatgpt,claude,perplexity. |
| `topic_ids` | string | Optional | Comma-separated topic UUIDs. |
| `group` | page \| domain | Optional; Default: page | Return page rows or domain groups containing their top pages. |
| `q` | string | Optional | Search citation domains, URLs, and titles. |
| `domain` | string | Optional | Restrict results to one normalized domain. |
| `exclude_competitors` | boolean | Optional; Default: true | Exclude tracked competitor domains and subdomains. |
| `page` | integer | Optional; Default: 1 | The 1-based page number. |
| `per_page` | integer | Optional; Default: 25 | Number of records per page. Maximum: 100. |

#### Response envelope

`project_id`:**uuid**`start`:**date**`end`:**date**`models`:**string\[\]**`group`:**page | domain**`rows`:**Citation\[\]**`groups`:**CitationDomainGroup\[\]**`pagination`:**Pagination**

| Name | Type | Details | Description |
| --- | --- | --- | --- |
| `project_id` | uuid |  | Resolved Ceyo project identifier. |
| `start` | date |  | Resolved start date. |
| `end` | date |  | Resolved end date. |
| `models` | string\[\] |  | Model keys included in the response. |
| `group` | page \| domain |  | Resolved grouping mode. |
| `rows` | Citation\[\] |  | Page citations when group is page; otherwise empty. |
| `groups` | CitationDomainGroup\[\] |  | Domain groups when group is domain; otherwise empty. |
| `pagination` | Pagination |  | Pagination metadata for the selected grouping. |

#### Citation

| Name | Type | Details | Description |
| --- | --- | --- | --- |
| `domain` | string |  | Normalized citation hostname. |
| `page` | string |  | Normalized page value used for grouping and display. |
| `url` | string |  | Canonical citation URL. |
| `title` | string \| null |  | Stored page title when supplied by the response provider. |
| `frequency` | integer |  | Citation occurrences across the selected responses. |
| `model_keys` | string\[\] |  | Models that cited the page at least once. |
| `model_frequencies` | Record<string, integer> |  | Citation frequency keyed by model. |

#### CitationDomainGroup

| Name | Type | Details | Description |
| --- | --- | --- | --- |
| `domain` | string |  | Normalized citation hostname. |
| `frequency` | integer |  | Citation occurrences across every page in the domain. |
| `model_keys` | string\[\] |  | Models that cited the domain. |
| `model_frequencies` | Record<string, integer> |  | Domain citation frequency keyed by model. |
| `pages` | Citation\[\] |  | Highest-frequency pages within the domain. |

#### Pagination

| Name | Type | Details | Description |
| --- | --- | --- | --- |
| `page` | integer |  | Current 1-based page number. |
| `per_page` | integer |  | Requested number of records per page. |
| `total` | integer |  | Total records matching the request. |
| `total_pages` | integer |  | Total available pages. |

> **Grouping**
>
> When `group=page`, results are returned in `rows`. When `group=domain`, `rows` is empty and domain results are returned in `groups`.

#### Request and response

```curl
curl --request GET \
  --url 'https://api.signal.ceyo.ai/v1/projects/{project_id}/citations?start=2026-07-01&end=2026-07-30&group=domain' \
  --header 'Authorization: Bearer ceyo_platform_...'
```

```json
{
  "project_id": "e6c96c98-d777-40e0-94ec-48931f57782f",
  "start": "2026-07-01",
  "end": "2026-07-30",
  "models": ["chatgpt", "perplexity"],
  "group": "domain",
  "rows": [],
  "groups": [
    {
      "domain": "example.com",
      "frequency": 19,
      "model_keys": ["chatgpt", "perplexity"],
      "model_frequencies": {
        "chatgpt": 12,
        "perplexity": 7
      },
      "pages": [
        {
          "domain": "example.com",
          "page": "example.com/ai-visibility",
          "url": "https://example.com/ai-visibility",
          "title": "A guide to AI visibility",
          "frequency": 11,
          "model_keys": ["chatgpt", "perplexity"],
          "model_frequencies": {
            "chatgpt": 7,
            "perplexity": 4
          }
        }
      ]
    }
  ],
  "pagination": {
    "page": 1,
    "per_page": 25,
    "total": 12,
    "total_pages": 1
  }
}
```

#### Errors

#### Error response envelope

| Name | Type | Details | Description |
| --- | --- | --- | --- |
| `error` | Error |  | Structured error payload. |

#### Error

| Name | Type | Details | Description |
| --- | --- | --- | --- |
| `code` | string |  | Stable snake\_case code suitable for programmatic handling. |
| `message` | string |  | Human-readable explanation of the failure. |
| `details` | object \| array \| null |  | Structured validation or request context when available. |
| `request_id` | string |  | Identifier to provide when requesting support. |

```json
{
  "error": {
    "code": "invalid_date_range",
    "message": "The requested date range is invalid.",
    "details": null,
    "request_id": "req_01K1GP6J8QQFZ4D2B6C5A9V3TS"
  }
}
```

#### Status codes

| Name | Type | Details | Description |
| --- | --- | --- | --- |
| `400` | invalid\_date\_range \| range\_too\_large \| invalid\_filter |  | The requested filters or date range are invalid. |
| `401` | invalid\_api\_key |  | Authorization is absent or invalid. |
| `403` | forbidden |  | The API key cannot access this resource. |
| `404` | not\_found |  | The project, location, or prompt was not found. |
| `422` | visibility\_unavailable |  | Visibility is unavailable for the selected scope. |
| `429` | rate\_limit\_exceeded |  | Too many requests were made. |

### Get citation trends

`GET /projects/{project_id}/citations/timeseries`

Returns daily citation totals for the selected project, including a count for each requested model. Dates with no citations are returned with zero values.

#### Path parameters

| Name | Type | Details | Description |
| --- | --- | --- | --- |
| `project_id` | project UUID \| project external ID | Required | Project identifier. |

#### Query parameters

| Name | Type | Details | Description |
| --- | --- | --- | --- |
| `start` | date | Optional; Default: 6 days before end | First run date to include, in YYYY-MM-DD format. |
| `end` | date | Optional; Default: Today | Last run date to include, in YYYY-MM-DD format. |
| `models` | string | Optional; Default: All enabled models | Comma-separated or repeated model keys. For example: chatgpt,claude,perplexity. |
| `topic_ids` | string | Optional | Comma-separated topic UUIDs. |
| `exclude_competitors` | boolean | Optional; Default: true | Exclude tracked competitor domains and subdomains. |
| `group` | domain \| page | Optional; Default: domain | Control whether top citations represent domains or pages. |

#### Response envelope

`project_id`:**uuid**`start`:**date**`end`:**date**`models`:**string\[\]**`points`:**CitationTimeseriesPoint\[\]**

| Name | Type | Details | Description |
| --- | --- | --- | --- |
| `project_id` | uuid |  | Resolved Ceyo project identifier. |
| `start` | date |  | Resolved start date. |
| `end` | date |  | Resolved end date. |
| `models` | string\[\] |  | Model keys included in the response. |
| `points` | CitationTimeseriesPoint\[\] |  | One zero-filled point for each date in the range. |

#### CitationTimeseriesPoint

| Name | Type | Details | Description |
| --- | --- | --- | --- |
| `date` | date |  | Calendar date represented by the point. |
| `totals` | Record<string, integer> |  | Citation count keyed by model. |
| `total` | integer |  | Total citations across the selected models. |
| `top_citations` | TopCitation\[\] |  | Up to five highest-frequency domains or pages. |

#### TopCitation

| Name | Type | Details | Description |
| --- | --- | --- | --- |
| `domain` | string |  | Normalized citation hostname. |
| `url` | string \| null |  | Citation URL when grouping by page. |
| `title` | string \| null |  | Stored page title when grouping by page. |
| `frequency` | integer |  | Citation occurrences for this date. |

#### Request and response

```curl
curl --request GET \
  --url 'https://api.signal.ceyo.ai/v1/projects/{project_id}/citations/timeseries?start=2026-07-24&end=2026-07-30&models=chatgpt,perplexity' \
  --header 'Authorization: Bearer ceyo_platform_...'
```

```json
{
  "project_id": "e6c96c98-d777-40e0-94ec-48931f57782f",
  "start": "2026-07-24",
  "end": "2026-07-30",
  "models": ["chatgpt", "perplexity"],
  "points": [
    {
      "date": "2026-07-30",
      "totals": {
        "chatgpt": 12,
        "perplexity": 8
      },
      "total": 20,
      "top_citations": [
        {
          "domain": "example.com",
          "url": "https://example.com/ai-visibility",
          "title": "A guide to AI visibility",
          "frequency": 7
        }
      ]
    }
  ]
}
```

#### Errors

#### Error response envelope

| Name | Type | Details | Description |
| --- | --- | --- | --- |
| `error` | Error |  | Structured error payload. |

#### Error

| Name | Type | Details | Description |
| --- | --- | --- | --- |
| `code` | string |  | Stable snake\_case code suitable for programmatic handling. |
| `message` | string |  | Human-readable explanation of the failure. |
| `details` | object \| array \| null |  | Structured validation or request context when available. |
| `request_id` | string |  | Identifier to provide when requesting support. |

```json
{
  "error": {
    "code": "invalid_date_range",
    "message": "The requested date range is invalid.",
    "details": null,
    "request_id": "req_01K1GP6J8QQFZ4D2B6C5A9V3TS"
  }
}
```

#### Status codes

| Name | Type | Details | Description |
| --- | --- | --- | --- |
| `400` | invalid\_date\_range \| range\_too\_large \| invalid\_filter |  | The requested filters or date range are invalid. |
| `401` | invalid\_api\_key |  | Authorization is absent or invalid. |
| `403` | forbidden |  | The API key cannot access this resource. |
| `404` | not\_found |  | The project, location, or prompt was not found. |
| `422` | visibility\_unavailable |  | Visibility is unavailable for the selected scope. |
| `429` | rate\_limit\_exceeded |  | Too many requests were made. |
