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

# Collections

> Build a private brand knowledge graph by ingesting URLs, then query it with grounded answers and Q&A verification.

Collections let you build a **per-brand private corpus** by ingesting multiple URLs into one unified knowledge graph (TKG). Once built, you can ask questions grounded only in that corpus, or verify existing Q\&A pairs against it.

**Requires a personal access token.** Master keys are rejected.

## Endpoints

| Method   | Path                                     | Description                               |
| -------- | ---------------------------------------- | ----------------------------------------- |
| `POST`   | `/api/v1/collections`                    | Create a collection                       |
| `GET`    | `/api/v1/collections`                    | List your collections                     |
| `GET`    | `/api/v1/collections/{id}`               | Get collection details + ingested URLs    |
| `DELETE` | `/api/v1/collections/{id}`               | Delete a collection and all its data      |
| `POST`   | `/api/v1/collections/{id}/ingest`        | Queue URLs for async ingestion            |
| `GET`    | `/api/v1/collections/{id}/ingest-status` | Poll ingestion progress                   |
| `GET`    | `/api/v1/collections/{id}/graph`         | Get the unified knowledge graph           |
| `POST`   | `/api/v1/collections/{id}/answer`        | Ask a question grounded in the collection |
| `POST`   | `/api/v1/collections/{id}/qa-verify`     | Verify existing Q\&A pairs                |

***

## POST /api/v1/collections

Create a new collection (brand corpus).

### Request Body

<ParamField body="name" type="string" required>
  Collection name, e.g. `"Hyundai UK"`.
</ParamField>

<ParamField body="slug" type="string">
  Optional URL-friendly identifier, e.g. `"hyundai-uk"`.
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://api.factagora.com/api/v1/collections" \
    -H "Authorization: Bearer fag_your_personal_token" \
    -H "Content-Type: application/json" \
    -d '{"name": "Hyundai UK"}'
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "id": "5966a861-6952-482a-a9d0-041ad5d2a667",
    "name": "Hyundai UK",
    "slug": null,
    "status": "active",
    "created_at": "2026-06-29T01:34:47.817583+00:00"
  }
  ```
</ResponseExample>

***

## GET /api/v1/collections

List all collections owned by the authenticated user.

<RequestExample>
  ```bash cURL theme={null}
  curl "https://api.factagora.com/api/v1/collections" \
    -H "Authorization: Bearer fag_your_personal_token"
  ```
</RequestExample>

***

## GET /api/v1/collections/{id}

Get a collection including its ingested URL list and their processing status.

<RequestExample>
  ```bash cURL theme={null}
  curl "https://api.factagora.com/api/v1/collections/5966a861-6952-482a-a9d0-041ad5d2a667" \
    -H "Authorization: Bearer fag_your_personal_token"
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "id": "5966a861-6952-482a-a9d0-041ad5d2a667",
    "name": "Hyundai UK",
    "slug": null,
    "status": "active",
    "created_at": "2026-06-29T01:34:47.817583+00:00",
    "sources": [
      {
        "ingest_source_id": "a5e00acc-aa4a-4ba6-bc44-1409fe64ef81",
        "url": "https://www.hyundai.com/uk/en/models/ioniq6.html",
        "status": "completed",
        "created_at": "2026-06-29T02:00:30.000000+00:00"
      }
    ]
  }
  ```
</ResponseExample>

***

## DELETE /api/v1/collections/{id}

Delete a collection and all its associated data (sources, chunks, claims, predictions, TKG).

<RequestExample>
  ```bash cURL theme={null}
  curl -X DELETE "https://api.factagora.com/api/v1/collections/5966a861-6952-482a-a9d0-041ad5d2a667" \
    -H "Authorization: Bearer fag_your_personal_token"
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "deleted": true
  }
  ```
</ResponseExample>

***

## POST /api/v1/collections/{id}/ingest

Queue one or more URLs for ingestion into the collection's unified knowledge graph. Returns immediately with `202 Accepted` — ingestion runs in the background. Poll `/ingest-status` to track progress.

### Request Body

<ParamField body="urls" type="string[]" required>
  URLs to ingest (1–50). Each URL is fetched, parsed, and its claims/predictions/edges are extracted into the collection TKG.
</ParamField>

<ParamField body="visibility" type="string" default="private">
  Access control for the ingested content. `private` or `public`.
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://api.factagora.com/api/v1/collections/5966a861-6952-482a-a9d0-041ad5d2a667/ingest" \
    -H "Authorization: Bearer fag_your_personal_token" \
    -H "Content-Type: application/json" \
    -d '{
      "urls": [
        "https://www.hyundai.com/uk/en/models/ioniq6.html",
        "https://www.hyundai.com/uk/en/models/ioniq6/trims-prices.html"
      ]
    }'
  ```
</RequestExample>

<ResponseExample>
  ```json 202 theme={null}
  {
    "collection_id": "5966a861-6952-482a-a9d0-041ad5d2a667",
    "queued": 2,
    "ingest_source_ids": [
      "a5e00acc-aa4a-4ba6-bc44-1409fe64ef81",
      "b1343b92-defb-4818-aec2-5ed4299f704b"
    ]
  }
  ```
</ResponseExample>

***

## GET /api/v1/collections/{id}/ingest-status

Poll the ingestion status for all URLs in the collection.

### Status values

| Status       | Meaning                                                             |
| ------------ | ------------------------------------------------------------------- |
| `processing` | Ingestion in progress                                               |
| `completed`  | Successfully ingested                                               |
| `failed`     | Ingestion failed (e.g. URL unreachable or content extraction error) |

<RequestExample>
  ```bash cURL theme={null}
  curl "https://api.factagora.com/api/v1/collections/5966a861-6952-482a-a9d0-041ad5d2a667/ingest-status" \
    -H "Authorization: Bearer fag_your_personal_token"
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "collection_id": "5966a861-6952-482a-a9d0-041ad5d2a667",
    "sources": [
      {
        "ingest_source_id": "a5e00acc-aa4a-4ba6-bc44-1409fe64ef81",
        "url": "https://www.hyundai.com/uk/en/models/ioniq6.html",
        "status": "completed",
        "created_at": "2026-06-29T02:00:30.000000+00:00"
      },
      {
        "ingest_source_id": "b1343b92-defb-4818-aec2-5ed4299f704b",
        "url": "https://www.hyundai.com/uk/en/models/ioniq6/trims-prices.html",
        "status": "processing",
        "created_at": "2026-06-29T02:00:30.000000+00:00"
      }
    ],
    "summary": {
      "total": 2,
      "processing": 1,
      "completed": 1,
      "failed": 0
    }
  }
  ```
</ResponseExample>

***

## GET /api/v1/collections/{id}/graph

Get the collection's unified knowledge graph as nodes and edges, shaped for graph visualization.

<RequestExample>
  ```bash cURL theme={null}
  curl "https://api.factagora.com/api/v1/collections/5966a861-6952-482a-a9d0-041ad5d2a667/graph" \
    -H "Authorization: Bearer fag_your_personal_token"
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "nodes": [
      {
        "id": "13c7afac-ea6f-44b4-807e-01c7935a8bfc",
        "label": "IONIQ 6 electric range up to 338 miles",
        "type": "CLAIM"
      },
      {
        "id": "7872d682-7c9c-43ba-a3e6-6a729b57ce06",
        "label": "Hyundai Electric Vehicle Range Will Expand and Improve",
        "type": "PREDICTION"
      }
    ],
    "edges": [
      {
        "from": "13c7afac-ea6f-44b4-807e-01c7935a8bfc",
        "to": "7872d682-7c9c-43ba-a3e6-6a729b57ce06",
        "label": "SUPPORTS"
      }
    ]
  }
  ```
</ResponseExample>

***

## POST /api/v1/collections/{id}/answer

Ask a question and get an answer grounded **only** in this collection's knowledge graph. Uses semantic search (pgvector) to retrieve the most relevant content before generating an answer.

If the knowledge graph does not contain enough information to answer, `grounded` is set to `false` to prevent hallucination.

### Request Body

<ParamField body="question" type="string" required>
  The question to answer.
</ParamField>

<ParamField body="language" type="string" default="English">
  Language for the answer (e.g. `"Korean"`, `"Japanese"`).
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://api.factagora.com/api/v1/collections/5966a861-6952-482a-a9d0-041ad5d2a667/answer" \
    -H "Authorization: Bearer fag_your_personal_token" \
    -H "Content-Type: application/json" \
    -d '{"question": "What is the IONIQ 6 electric range?"}'
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "question": "What is the IONIQ 6 electric range?",
    "answer": "The IONIQ 6 has a driving range of up to 338 miles.",
    "grounded": true,
    "sources": [
      {
        "url": "https://www.hyundai.com/uk/en/models/ioniq6.html",
        "title": "IONIQ 6 | Hyundai UK"
      }
    ],
    "meta": {
      "executionTimeMs": 1285
    }
  }
  ```
</ResponseExample>

***

## POST /api/v1/collections/{id}/qa-verify

Verify existing Q\&A pairs against the collection knowledge graph. Each pair receives one of three verdicts:

| Verdict       | Meaning                                                           |
| ------------- | ----------------------------------------------------------------- |
| `correct`     | The answer is supported by the collection's knowledge             |
| `incorrect`   | The answer contradicts the knowledge — a `correction` is provided |
| `unsupported` | The collection does not have enough information to verify         |

### Request Body

<ParamField body="qa_pairs" type="array" required>
  Array of question/answer pairs to verify (1–50).

  <Expandable title="qa_pairs fields">
    <ParamField body="question" type="string" required>The question</ParamField>
    <ParamField body="answer" type="string" required>The answer to verify</ParamField>
  </Expandable>
</ParamField>

<ParamField body="language" type="string" default="English">
  Language for verdict summaries and corrections.
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://api.factagora.com/api/v1/collections/5966a861-6952-482a-a9d0-041ad5d2a667/qa-verify" \
    -H "Authorization: Bearer fag_your_personal_token" \
    -H "Content-Type: application/json" \
    -d '{
      "qa_pairs": [
        {
          "question": "What is the IONIQ 6 charging time?",
          "answer": "The IONIQ 6 charges from 10% to 80% in 18 to 36 minutes."
        },
        {
          "question": "Is the IONIQ 6 available as a petrol car?",
          "answer": "Yes, the IONIQ 6 is available as a petrol car."
        }
      ]
    }'
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "results": [
      {
        "question": "What is the IONIQ 6 charging time?",
        "answer": "The IONIQ 6 charges from 10% to 80% in 18 to 36 minutes.",
        "verdict": "correct",
        "confidence": 0.92,
        "correction": null,
        "summary": "The collection confirms IONIQ 6 charges from 10% to 80% in 18–36 minutes on a 350 kW ultra-fast charger."
      },
      {
        "question": "Is the IONIQ 6 available as a petrol car?",
        "answer": "Yes, the IONIQ 6 is available as a petrol car.",
        "verdict": "incorrect",
        "confidence": 0.95,
        "correction": "The IONIQ 6 is a fully electric vehicle. No petrol variant is available.",
        "summary": "The collection describes the IONIQ 6 exclusively as an electric car."
      }
    ],
    "meta": {
      "executionTimeMs": 2100
    }
  }
  ```
</ResponseExample>
