ChatIQBETA
FeaturesPricingDemoBlogDocsContact
Sign inSign up
ChatIQ

Build reliable AI chatbots powered by your team’s knowledge. Secure multi-tenant architecture, instant document ingestion, and guided analytics out of the box.

Product
FeaturesPricingDemo
Resources
DocsContactCustomer Portal
Legal & Preferences
Terms of ServicePrivacy PolicySecurity
© 2025 ChatIQ. All rights reserved.Made with care in distributed workspaces worldwide.

Documents API

Complete reference for managing documents and tracking embedding status via the ChatIQ API.

Documents API

The Documents API allows you to manage knowledge base documents and track their embedding processing status programmatically.


Base Endpoint

All document endpoints are under:

https://chatiq.io/api/v1/documents

List Documents

GET /api/v1/documents

Retrieve all documents accessible by your API key.

Request

GET /api/v1/documents
Authorization: Bearer sk_live_your_api_key_here

Response

{
  "documents": [
    {
      "id": "uuid",
      "title": "Product Documentation",
      "tags": ["product", "docs"],
      "created_at": "2025-11-20T10:00:00Z",
      "is_global": false,
      "canonical_url": "https://example.com/docs"
    }
  ]
}

Create Document

POST /api/v1/documents

Create a new document. Embedding processing will start automatically.

Request

POST /api/v1/documents
Authorization: Bearer sk_live_your_api_key_here
Content-Type: application/json

{
  "title": "Product Information",
  "content": "Your document content here...",
  "tags": ["product", "info"]
}

Request Body

| Field | Type | Required | Description | | --------- | -------- | -------- | ------------------------------ | | title | string | Yes | Document title | | content | string | Yes | Document content (text) | | tags | string[] | No | Array of tags for organization |

Response

{
  "document": {
    "id": "uuid",
    "title": "Product Information",
    "tags": ["product", "info"],
    "created_at": "2025-11-20T10:00:00Z",
    "is_global": false,
    "canonical_url": null
  }
}

Note: Embedding processing starts automatically. Use the status endpoint to track progress.


Get Document

GET /api/v1/documents/:id

Retrieve a specific document by ID.

Request

GET /api/v1/documents/uuid-here
Authorization: Bearer sk_live_your_api_key_here

Response

{
  "document": {
    "id": "uuid",
    "title": "Product Information",
    "content": "Full document content...",
    "tags": ["product", "info"],
    "created_at": "2025-11-20T10:00:00Z",
    "is_global": false,
    "canonical_url": null
  }
}

Update Document

PUT /api/v1/documents/:id

Update an existing document. If content changes, embeddings will be regenerated.

Request

PUT /api/v1/documents/uuid-here
Authorization: Bearer sk_live_your_api_key_here
Content-Type: application/json

{
  "title": "Updated Title",
  "content": "Updated content...",
  "tags": ["updated", "tags"]
}

Request Body

All fields are optional. Only include fields you want to update.

| Field | Type | Required | Description | | --------- | -------- | -------- | -------------------- | | title | string | No | New document title | | content | string | No | New document content | | tags | string[] | No | New tags array |

Response

{
  "document": {
    "id": "uuid",
    "title": "Updated Title",
    "content": "Updated content...",
    "tags": ["updated", "tags"],
    "created_at": "2025-11-20T10:00:00Z",
    "is_global": false,
    "canonical_url": null
  }
}

Note: If content is updated, embedding processing will restart automatically.


Delete Document

DELETE /api/v1/documents/:id

Delete a document and all associated chunks and embeddings.

Request

DELETE /api/v1/documents/uuid-here
Authorization: Bearer sk_live_your_api_key_here

Response

{
  "success": true
}

Get Embedding Status

GET /api/v1/documents/:id/embeddings/status

Check the embedding processing status for a document.

Request

GET /api/v1/documents/uuid-here/embeddings/status
Authorization: Bearer sk_live_your_api_key_here

Response

{
  "document_id": "uuid",
  "status": "processing",
  "progress": {
    "total": 100,
    "pending": 5,
    "processing": 2,
    "completed": 90,
    "failed": 3
  },
  "percentage": 90,
  "failed_jobs": [
    {
      "error": "OpenAI API error: Rate limit exceeded",
      "created_at": "2025-11-20T10:00:00Z"
    }
  ]
}

Status Values

  • not_started - No chunks created yet
  • pending - Jobs queued, waiting to process
  • processing - Jobs currently being processed
  • completed - All jobs completed successfully
  • failed - All jobs failed (no pending/processing jobs)

Polling Strategy

For real-time status updates, poll this endpoint:

async function waitForEmbedding(documentId, apiKey, interval = 2000) {
  while (true) {
    const response = await fetch(
      `https://chatiq.io/api/v1/documents/${documentId}/embeddings/status`,
      {
        headers: {
          Authorization: `Bearer ${apiKey}`,
        },
      }
    );

    const status = await response.json();

    console.log(`Progress: ${status.percentage}%`);

    if (status.status === "completed") {
      return status;
    }

    if (status.status === "failed" && status.progress.pending === 0) {
      throw new Error("Embedding failed");
    }

    // Wait before next poll
    await new Promise((resolve) => setTimeout(resolve, interval));
  }
}

List Embedding Jobs

GET /api/v1/embeddings/jobs

List embedding jobs with optional filtering.

Request

GET /api/v1/embeddings/jobs?document_id=uuid&status=failed&limit=50&offset=0
Authorization: Bearer sk_live_your_api_key_here

Query Parameters

| Parameter | Type | Required | Description | | ------------- | ------ | -------- | ---------------------------------------------------------------- | | document_id | string | No | Filter by document ID | | status | string | No | Filter by status: pending, processing, completed, failed | | limit | number | No | Number of results (default: 50, max: 100) | | offset | number | No | Pagination offset (default: 0) |

Response

{
  "jobs": [
    {
      "id": "uuid",
      "document_id": "uuid",
      "status": "completed",
      "attempts": 1,
      "error": null,
      "created_at": "2025-11-20T10:00:00Z",
      "updated_at": "2025-11-20T10:01:00Z",
      "locked_at": null
    }
  ],
  "pagination": {
    "limit": 50,
    "offset": 0,
    "total": 1
  }
}

Retry Failed Job

POST /api/v1/embeddings/jobs/:id/retry

Retry a failed embedding job by resetting it to pending status.

Request

POST /api/v1/embeddings/jobs/uuid-here/retry
Authorization: Bearer sk_live_your_api_key_here

Response

{
  "success": true,
  "job": {
    "id": "uuid",
    "status": "pending"
  }
}

Note: Only jobs with status failed can be retried.


Complete Example: Upload and Track

async function uploadDocumentWithTracking(title, content, apiKey) {
  // 1. Create document
  const createResponse = await fetch("https://chatiq.io/api/v1/documents", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${apiKey}`,
    },
    body: JSON.stringify({ title, content }),
  });

  const { document } = await createResponse.json();
  console.log(`Document created: ${document.id}`);

  // 2. Poll for embedding status
  while (true) {
    const statusResponse = await fetch(
      `https://chatiq.io/api/v1/documents/${document.id}/embeddings/status`,
      {
        headers: {
          Authorization: `Bearer ${apiKey}`,
        },
      }
    );

    const status = await statusResponse.json();
    console.log(
      `Progress: ${status.percentage}% (${status.progress.completed}/${status.progress.total})`
    );

    if (status.status === "completed") {
      console.log("Document is ready for use!");
      return document;
    }

    if (status.status === "failed" && status.progress.pending === 0) {
      // Retry failed jobs
      const jobsResponse = await fetch(
        `https://chatiq.io/api/v1/embeddings/jobs?document_id=${document.id}&status=failed`,
        {
          headers: {
            Authorization: `Bearer ${apiKey}`,
          },
        }
      );

      const { jobs } = await jobsResponse.json();

      for (const job of jobs) {
        await fetch(
          `https://chatiq.io/api/v1/embeddings/jobs/${job.id}/retry`,
          {
            method: "POST",
            headers: {
              Authorization: `Bearer ${apiKey}`,
            },
          }
        );
      }

      console.log(`Retried ${jobs.length} failed jobs`);
    }

    // Wait 2 seconds before next poll
    await new Promise((resolve) => setTimeout(resolve, 2000));
  }
}

Error Codes

| Code | Status | Description | | ------------------ | ------ | ----------------------------- | | UNAUTHORIZED | 401 | API key missing or invalid | | NOT_FOUND | 404 | Document not found | | VALIDATION_ERROR | 400 | Invalid request body | | DATABASE_ERROR | 500 | Database operation failed | | INVALID_STATUS | 400 | Cannot retry job (not failed) |


Rate Limits

Document operations count toward your plan's rate limits. See Rate Limits for details.


Next Steps

  • See Getting Started for onboarding
  • See Complete API Reference for all endpoints
  • See Streaming Guide for chat streaming