Articles API (Knowledge Base)

The Articles API manages knowledge base articles including creation, publishing, versioning, search, and reader feedback.

Article Object

{
  id: string;                    // UUID
  organization_id: string;       // UUID of the organization
  title: string;                 // Article title
  slug: string;                  // URL-friendly identifier
  content: object;               // Rich text content (TipTap JSON)
  content_html?: string;         // HTML version
  excerpt?: string;              // Short description
  collection_id?: string;        // UUID of parent collection
  status: string;                // draft, review, published, archived
  current_version: number;       // Version number
  view_count: number;            // Total views
  search_text: string;           // Searchable text content
  created_at: string;            // ISO timestamp
  updated_at: string;            // ISO timestamp
  deleted_at?: string;           // ISO timestamp (soft delete)

  // Joined relations
  collection?: {
    name: string;
    slug: string;
  };
}

Status Values

StatusDescription
draftWork in progress, not visible to public
reviewReady for review before publishing
publishedLive and visible to customers
archivedNo longer active but retained

List Articles

List published articles, optionally filtered by collection or search query.

Procedure: articles.list

Authentication: None (public endpoint)

Input:

{
  collectionId?: string;     // Filter by collection UUID
  search?: string;           // Full-text search query
  organizationId?: string;   // Filter by organization
  limit?: number;            // 1-100, default: 20
}

Example:

curl -X GET "https://your-domain.com/api/trpc/articles.list?input=%7B%22collectionId%22:%22uuid%22,%22limit%22:10%7D"

Response:

{
  "result": {
    "data": {
      "json": [
        {
          "id": "uuid",
          "title": "Getting Started Guide",
          "slug": "getting-started",
          "excerpt": "Learn how to set up and configure your account",
          "status": "published",
          "view_count": 1250,
          "collection": {
            "name": "Onboarding",
            "slug": "onboarding"
          },
          "created_at": "2024-01-01T00:00:00.000Z"
        }
      ]
    }
  }
}

Notes:

  • Only returns published articles
  • Results sorted by position (custom ordering)

Get Article by ID

Retrieve a single article by its UUID. Used for dashboard editing.

Procedure: articles.getById

Authentication: Required

Input:

{
  id: string;  // Article UUID
}

Example:

curl -X GET "https://your-domain.com/api/trpc/articles.getById?input=%7B%22id%22:%22article-uuid%22%7D" \
  -H "Cookie: your-session-cookie"

Response:

{
  "result": {
    "data": {
      "json": {
        "id": "uuid",
        "title": "Getting Started Guide",
        "slug": "getting-started",
        "content": {
          "type": "doc",
          "content": [...]
        },
        "content_html": "<p>...</p>",
        "excerpt": "Learn how to set up...",
        "status": "draft",
        "current_version": 3,
        "collection": {
          "name": "Onboarding",
          "slug": "onboarding"
        },
        "created_at": "2024-01-01T00:00:00.000Z"
      }
    }
  }
}

Notes:

  • Returns articles in any status (draft, review, published, archived)
  • Used for editing in the dashboard

Get Article by Slug

Retrieve a published article by its URL slug. Optimized for public access with caching.

Procedure: articles.getBySlug

Authentication: None (public endpoint)

Input:

{
  slug: string;              // URL-friendly slug
  organizationId?: string;   // Optional organization filter
}

Example:

curl -X GET "https://your-domain.com/api/trpc/articles.getBySlug?input=%7B%22slug%22:%22getting-started%22%7D"

Response:

{
  "result": {
    "data": {
      "json": {
        "id": "uuid",
        "title": "Getting Started Guide",
        "slug": "getting-started",
        "content": {
          "type": "doc",
          "content": [...]
        },
        "content_html": "<p>Welcome to our platform...</p>",
        "excerpt": "Learn how to set up...",
        "status": "published",
        "view_count": 1251,
        "collection": {
          "name": "Onboarding",
          "slug": "onboarding"
        }
      }
    }
  }
}

Side Effects:

  • Increments view count asynchronously

Notes:

  • Only returns published articles
  • Results are cached for 30 minutes
  • View counts are tracked automatically

Create Article

Create a new knowledge base article.

Procedure: articles.create

Authentication: Required

Input:

{
  title: string;                                           // 1-500 characters
  slug: string;                                            // 1-200 characters, URL-safe
  content: object;                                         // TipTap JSON document
  excerpt?: string;                                        // Short description
  collectionId?: string;                                   // Parent collection UUID
  status?: 'draft' | 'review' | 'published' | 'archived';  // default: 'draft'
}

Example:

curl -X POST "https://your-domain.com/api/trpc/articles.create" \
  -H "Content-Type: application/json" \
  -H "Cookie: your-session-cookie" \
  -d '{
    "json": {
      "title": "How to Reset Your Password",
      "slug": "reset-password",
      "content": {
        "type": "doc",
        "content": [
          {
            "type": "paragraph",
            "content": [
              {"type": "text", "text": "Follow these steps to reset your password..."}
            ]
          }
        ]
      },
      "excerpt": "Step-by-step guide for resetting your account password",
      "collectionId": "collection-uuid",
      "status": "draft"
    }
  }'

Response:

{
  "result": {
    "data": {
      "json": {
        "id": "uuid",
        "title": "How to Reset Your Password",
        "slug": "reset-password",
        "status": "draft",
        "current_version": 1,
        "created_at": "2024-01-15T10:30:00.000Z"
      }
    }
  }
}

Side Effects:

  • Creates initial version record in article_versions
  • Content is sanitized to prevent XSS

Notes:

  • Rate limited to prevent abuse
  • Slug must be unique within the organization
  • HTML is automatically generated from TipTap content

Update Article

Update an existing article. Creates a new version when content changes.

Procedure: articles.update

Authentication: Required

Input:

{
  id: string;                                              // Required, article UUID
  title?: string;                                          // 1-500 characters
  slug?: string;                                           // 1-200 characters
  content?: object;                                        // TipTap JSON document
  excerpt?: string;                                        // Short description
  status?: 'draft' | 'review' | 'published' | 'archived';
  changeSummary?: string;                                  // Description of changes
}

Example:

curl -X POST "https://your-domain.com/api/trpc/articles.update" \
  -H "Content-Type: application/json" \
  -H "Cookie: your-session-cookie" \
  -d '{
    "json": {
      "id": "article-uuid",
      "content": {...},
      "status": "published",
      "changeSummary": "Added section on two-factor authentication"
    }
  }'

Response:

{
  "result": {
    "data": {
      "json": {
        "id": "uuid",
        "title": "How to Reset Your Password",
        "current_version": 2,
        "status": "published",
        "updated_at": "2024-01-15T11:00:00.000Z"
      }
    }
  }
}

Side Effects:

  • Increments version number
  • Creates version record if content changed
  • Invalidates article cache

Notes:

  • Content changes create a new version for history tracking
  • Cache is automatically invalidated on update

Delete Article

Soft delete an article.

Procedure: articles.delete

Authentication: Required

Input:

{
  id: string;  // Article UUID
}

Example:

curl -X POST "https://your-domain.com/api/trpc/articles.delete" \
  -H "Content-Type: application/json" \
  -H "Cookie: your-session-cookie" \
  -d '{"json":{"id":"article-uuid"}}'

Response:

{
  "result": {
    "data": {
      "json": {
        "success": true
      }
    }
  }
}

Search Articles

Search articles with typo tolerance using trigram similarity matching.

Procedure: articles.search

Authentication: None (public endpoint)

Input:

{
  query: string;                 // Search query
  organizationId?: string;       // Filter by organization
  limit?: number;                // 1-50, default: 10
  similarityThreshold?: number;  // 0-1, default: 0.3
}

Example:

curl -X GET "https://your-domain.com/api/trpc/articles.search?input=%7B%22query%22:%22passowrd%20reset%22,%22limit%22:5%7D"

Response:

{
  "result": {
    "data": {
      "json": [
        {
          "id": "uuid",
          "title": "How to Reset Your Password",
          "slug": "reset-password",
          "excerpt": "Step-by-step guide for resetting your account password",
          "similarity": 0.85,
          "collection": {
            "name": "Account Management",
            "slug": "account"
          }
        },
        {
          "id": "uuid-2",
          "title": "Password Security Best Practices",
          "slug": "password-security",
          "excerpt": "Keep your account safe with strong passwords",
          "similarity": 0.65,
          "collection": {
            "name": "Security",
            "slug": "security"
          }
        }
      ]
    }
  }
}

Notes:

  • Uses trigram similarity for typo-tolerant matching (e.g., "passowrd" matches "password")
  • Falls back to full-text search if trigram search fails
  • Only searches published articles
  • Results sorted by similarity score

Generate Article Draft

Generate an AI-assisted article draft based on a prompt or ticket context.

Procedure: articles.generateDraft

Authentication: Required

Input:

{
  prompt: string;       // Minimum 10 characters, describes desired article
  ticketId?: string;    // Optional ticket UUID for context
}

Example:

curl -X POST "https://your-domain.com/api/trpc/articles.generateDraft" \
  -H "Content-Type: application/json" \
  -H "Cookie: your-session-cookie" \
  -d '{
    "json": {
      "prompt": "Write a help article explaining how to integrate our API with Zapier",
      "ticketId": "ticket-uuid"
    }
  }'

Response:

{
  "result": {
    "data": {
      "json": {
        "title": "Integrating with Zapier",
        "content": {
          "type": "doc",
          "content": [
            {
              "type": "heading",
              "attrs": {"level": 1},
              "content": [{"type": "text", "text": "Integrating with Zapier"}]
            },
            {
              "type": "paragraph",
              "content": [{"type": "text", "text": "This guide walks you through..."}]
            }
          ]
        },
        "excerpt": "Learn how to connect your account to Zapier for automated workflows"
      }
    }
  }
}

Notes:

  • If ticketId is provided, uses ticket subject, description, and AI summary for context
  • Generated content is a draft - review and edit before publishing
  • Subject to AI usage limits

Submit Feedback

Submit reader feedback on an article (helpful/not helpful).

Procedure: articles.submitFeedback

Authentication: None (public endpoint, but records user if authenticated)

Input:

{
  articleId: string;      // Article UUID
  helpful: boolean;       // Was the article helpful?
  comment?: string;       // Optional feedback comment
}

Example:

curl -X POST "https://your-domain.com/api/trpc/articles.submitFeedback" \
  -H "Content-Type: application/json" \
  -d '{
    "json": {
      "articleId": "article-uuid",
      "helpful": true,
      "comment": "This solved my issue, thanks!"
    }
  }'

Response:

{
  "result": {
    "data": {
      "json": {
        "id": "feedback-uuid",
        "article_id": "article-uuid",
        "helpful": true,
        "comment": "This solved my issue, thanks!",
        "created_at": "2024-01-15T10:30:00.000Z"
      }
    }
  }
}

Notes:

  • Can be submitted anonymously or by authenticated users
  • Feedback is linked to user ID if authenticated

Article Versioning

Articles support versioning to track changes over time:

  • Each article has a current_version number
  • When content is updated, a new version is created in article_versions
  • Version history includes:
    • Version number
    • Title and content at that version
    • Change summary
    • Author who made the change
    • Timestamp

Rate Limits

OperationLimit
Create articleRate limited per user
Search100 per minute
Submit feedback10 per minute per IP

Caching

The getBySlug endpoint implements caching for performance:

  • Cache duration: 30 minutes
  • Cache is automatically invalidated when article is updated
  • View counts are tracked separately from cached content

Content Format

Articles use TipTap JSON format for rich text content. Example structure:

{
  "type": "doc",
  "content": [
    {
      "type": "heading",
      "attrs": {"level": 1},
      "content": [{"type": "text", "text": "Article Title"}]
    },
    {
      "type": "paragraph",
      "content": [
        {"type": "text", "text": "Regular text "},
        {"type": "text", "marks": [{"type": "bold"}], "text": "bold text"},
        {"type": "text", "text": " and more."}
      ]
    },
    {
      "type": "bulletList",
      "content": [
        {
          "type": "listItem",
          "content": [
            {"type": "paragraph", "content": [{"type": "text", "text": "List item 1"}]}
          ]
        }
      ]
    }
  ]
}

All content is automatically sanitized to prevent XSS attacks.