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

# Filtrado y conceptos

> Cómo funcionan los endpoints de reportes v2: la estructura de solicitud compartida, el árbol de filtros, la agrupación, el alcance, la paginación y el streaming

Los endpoints de reportes v2 comparten **una misma estructura de solicitud y respuesta**:
[Visibility](/es/rest-api/reports/query-visibility-v2),
[Citations](/es/rest-api/reports/query-citations-v2),
[Sentiment](/es/rest-api/reports/query-sentiment-v2),
[Query Fanouts](/es/rest-api/reports/query-fanouts-v2),
[Answers](/es/rest-api/reports/query-answers-v2) y
[FactCheck](/es/rest-api/reports/query-factcheck-v2) (puntuaciones de precisión +
[afirmaciones](/es/rest-api/reports/query-factcheck-claims-v2)). Apréndela una vez y todos
los reportes funcionan igual. Los reportes sociales de YouTube también son reportes v2, con
campos de agrupación y atribución específicos de canales y videos; consulta
[YouTube Channels](/es/rest-api/reports/query-youtube-channels-v2) y
[YouTube Videos](/es/rest-api/reports/query-youtube-videos-v2) para ver sus
campos de solicitud y respuesta específicos de cada endpoint.

<Note>
  FactCheck usa el mismo envoltorio `{ info, data }`, pero es **por categoría** (sin
  parámetros `scope`/`assets`/`metrics`) y acepta un **`filter` más limitado**: un
  `and` de nivel superior con hojas de un solo campo, y solo `topic` se puede negar. Consulta sus páginas
  para conocer los detalles.
</Note>

<Note>
  Todos los endpoints v2 aceptan **nombres o UUID** en cualquier lugar donde un filtro reciba un valor.
  Obtén los UUID de `GET /v1/org/models`, `/v1/org/regions`, `/v1/org/personas`,
  `/v1/org/assets`, `/v1/org/categories` y los endpoints por categoría
  `…/topics`, `…/tags`, `…/prompts`.
</Note>

## Campos comunes de la solicitud

| Campo | Tipo | Notas |
| - | - | - |
| `category_id` | UUID (obligatorio) | La categoría que se consulta. |
| `start_date` / `end_date` | fecha (obligatorio) | `YYYY-MM-DD`, hora del Este, **inclusivo** en ambos extremos. |
| `scope` | `owned` · `all` | Restringe a tus activos/dominios propios o clasifica todo. Los valores predeterminados varían según el reporte. |
| `group_by` | string\[] | Divide los resultados en filas por dimensión (consulta [Agrupación](#agrupación)). |
| `metrics` | string\[] | Qué métricas calcular. Se devuelven como **campos con nombre en cada fila**. |
| `interval` | `day` · `week` · `month` | Tamaño del intervalo al agrupar por `date`. Valor predeterminado: `day`. |
| `filter` | árbol | Árbol de `and`/`or`/`not`/hojas (consulta [Filtros](#filtros)). |
| `sort` | `{ field, dir }` | Ordena las filas (donde se admite). |
| `limit` | `1`–`50` | Filas por página. Valor predeterminado: `10`. |
| `cursor` | string | Token de página de `info.next_cursor`. |

<Warning>
  A diferencia de los reportes v1 (donde `end_date` es exclusivo), **en v2 `end_date` es
  inclusivo**. Para obtener del 9 al 15 de junio, envía `start_date: "2026-06-09"`,
  `end_date: "2026-06-15"`.
</Warning>

## Agrupación

`group_by` convierte una fila agregada en una fila por valor. Cada campo agrupado
se devuelve en la fila:

```json theme={null}
// group_by: ["model"]  →  each row carries the model it's for
{ "asset": { "name": "Profound", "owned": true }, "model": { "id": "…", "name": "ChatGPT" }, "visibility_score": 0.52 }
```

* Agrupa por `date` (con `interval`) para obtener una serie temporal.
* Las filas incluyen un `rank` cuando se agrupan por una dimensión **que no es de fecha**.
* Las dimensiones disponibles varían según el reporte; consulta la referencia de cada endpoint.

## Métricas

Solicita las métricas que quieras; se devuelven como **campos con nombre** en cada fila
(sin arreglos posicionales ni búsquedas en `info.query`):

```json theme={null}
{ "rank": 1, "visibility_score": 0.48, "share_of_voice": 0.077, "average_position": 2.5 }
```

## Alcance y selección de activos

* **`scope`:** `owned` limita a los activos/dominios que te pertenecen; `all` clasifica todo.
* **Solo Visibility:** elige los activos con el parámetro independiente **`assets`**: un
  nombre (`is`), una lista (`in`, que anula `scope`) o `{ op, value }`. Una
  selección devuelve todas las coincidencias e ignora `limit`.
* **Sentiment** requiere un **`asset`** (el sentimiento es por marca).

## Filtros

`filter` es un árbol recursivo, con **profundidad máxima de 3**, para todos los reportes, incluidos
los reportes sociales de YouTube:

```json theme={null}
{
  "and": [
    { "or":  [ { "field": "model", "op": "is", "value": "ChatGPT" },
               { "field": "model", "op": "is", "value": "Perplexity" } ] },
    { "not": { "field": "region", "op": "is", "value": "United States" } }
  ]
}
```

Tipos de nodo: `{ "and": [ … ] }`, `{ "or": [ … ] }`, `{ "not": <node> }` y
hojas `{ "field", "op", "value" }`.

### Operadores

| Operador | Significado |
| - | - |
| `is` / `not_is` | Coincidencia exacta / negada |
| `in` / `not_in` | Coincide con cualquier valor de una lista (no vacía) / negado |
| `contains` / `not_contains` | Subcadena (distingue mayúsculas y minúsculas) |
| `contains_case_insensitive` / `not_contains_case_insensitive` | Subcadena (no distingue mayúsculas y minúsculas) |
| `matches` | Expresión regular (patrón ≥ 3 caracteres) |
| `exists` | Tiene algún valor; solo en `tag` / `persona` (envuélvelo en `not` para "ninguno") |

`value` es un único valor, o una lista para `in` / `not_in`. Nombres **o** UUID;
`contains` / `matches` buscan coincidencias en los nombres.

### Dos capas de filtros

Los campos se dividen en dos capas. Se combinan con `and`; **`or`/`not` no pueden mezclar
capas** (hacerlo devuelve `422`).

**Capa de prompts** (árbol completo, conjunto completo de operadores):
`model`, `topic`, `region`, `persona`, `prompt`, `tag`.

**Capa de entidades / citas** (solo hojas `and` de nivel superior, varía según el reporte):

| Reporte | Campos de la capa de entidades |
| - | - |
| Visibility | La entidad (`asset`) usa el parámetro **`assets`**, *no* `filter`. |
| Citations | `domain` (todos los operadores, considera subdominios), `page` (todos los operadores), `analysis_type` (`visibility`·`sentiment`·`factcheck`·`all`), `citation_category` (`owned`·`competition`·`social`·`earned_media`·`earned_institutions`·`pr_wire`·`other`·personalizada), `citation_tag` (tus etiquetas personalizadas; `is`/`in`) |
| Sentiment | `theme` / `claim`: `is`/`in`, un solo valor, nombre o id. Con `source: "citation"`: `citation_category` (`is`/`in`) y `page` (`contains_case_insensitive`, un valor) |
| Query Fanouts | `analysis_type` (`visibility`·`sentiment`·`factcheck`·`all`), `is`/`in` |
| Answers | `analysis_type` es **a nivel de prompt** (`visibility`·`sentiment`·`factcheck`; `is`/`in`/`not_in`; si se omite = todos). `domain`/`page` son hojas `and` de nivel superior: `is` con un valor o `in` con una lista (coincidencia exacta de la URL citada) |
| YouTube social | `channel` es el filtro de la capa de entidades. `domain` y `page` no aplican porque las filas de YouTube ya están limitadas a fuentes de YouTube. |

<Note>
  En citas, filtra por `domain` en el reporte de dominios y por `page` cuando
  uses `group_by: ["page"]`; cada uno filtra la entidad de su propio reporte.
</Note>

<Note>
  Sentiment con `source: "citation"` siempre devuelve filas de páginas y no
  admite `group_by`. Usa filtros de la capa de prompts para limitar qué citas cuentan,
  y usa `citation_category` o `page` para limitar las páginas devueltas.
</Note>

<Note>
  Los reportes de YouTube usan el filtro de entidad `channel`. Se puede combinar con
  filtros a nivel de prompt mediante `and`, pero no bajo `or` ni `not`.
  Los filtros `domain` y `page` de YouTube se rechazan en lugar de aproximarse.
</Note>

<Note>
  Enumera las etiquetas de citas de una categoría con [Get Citation Tags](/api-reference/organization/get-category-citation-tags).
  Coloca todas las etiquetas que quieras en una sola hoja `in` (los valores se combinan con OR). Combinar con AND dos
  hojas `citation_tag` separadas, o pasar una lista vacía, devuelve `422`.
</Note>

## Ordenamiento

Donde se admite, `sort` es `{ "field": "<metric>", "dir": "asc" | "desc" }`.
El campo debe ser una métrica solicitada y ordenable (o `date` cuando se agrupa por
fecha). **Citations no tiene `sort`:** siempre se clasifica con las más citadas primero.

## Paginación

Las respuestas devuelven `limit` filas más `info.next_cursor`. Envía ese token como
`cursor` para obtener la página siguiente; `next_cursor` es `null` en la última página.

## Streaming

Todos los endpoints de reportes, excepto los reportes sociales de YouTube, tienen una variante **`/stream`**
(Server-Sent Events): un evento `summary` (el bloque `info`) y, luego, un evento `result`
por fila. `limit`/`cursor` se ignoran; devuelve todo de forma predeterminada.
Envía `max_results` para establecer un límite. El streaming de Sentiment acepta tanto `source: "response"`
como `source: "citation"` usando las mismas estructuras de fila específicas de cada fuente que el
endpoint paginado.

## Estructura de la respuesta

Todos los reportes devuelven `{ info, data }`:

```json theme={null}
{
  "info": {
    "total_results": 8427,
    "count": 10,
    "next_cursor": "…",
    "models": ["ChatGPT", "Google Gemini", "..."],
    "start_date": "2026-06-09",
    "end_date": "2026-06-15",
    "filter": null
  },
  "data": [
    { "rank": 1, "visibility_score": 0.48 }
  ]
}
```

`info` devuelve la consulta resuelta (modelos dentro del alcance, el filtro aplicado, las fechas,
la paginación); `data` contiene las filas, con las métricas como campos con nombre y las
dimensiones de `group_by` adjuntas.
