Skip to main content
Connect your internal knowledge base or CMS to Cevro by exposing a REST API endpoint. Cevro will periodically fetch your articles and make them available to your AI agents.

Overview

The Custom KB Connector allows you to:
  • Sync articles from any REST API you control
  • Keep your knowledge base automatically updated (daily, weekly, or manual)
  • Receive instant updates via webhooks when content changes
  • Map your API’s response format to Cevro’s article schema

Quick Start

1

Create your API endpoint

Build a REST endpoint that returns your articles in JSON format.
2

Test the connection

Use the “Test Connection” feature in Cevro to verify your endpoint works.
3

Configure the connector

Set up authentication, field mapping, and sync frequency.
4

Start syncing

Trigger the initial sync and watch your articles appear in Cevro.

API Requirements

Your endpoint must return articles in JSON format. Cevro supports flexible field mapping, so you can adapt to most response structures.

Basic Response Format

{
  "articles": [
    {
      "id": "article-123",
      "title": "How to reset your password",
      "content": "<p>To reset your password, click the 'Forgot Password' link...</p>",
      "url": "https://help.example.com/password-reset",
      "category": "Account",
      "lastModified": "2025-01-15T10:30:00Z"
    }
  ],
  "pagination": {
    "hasMore": true,
    "nextCursor": "eyJwYWdlIjogMn0="
  }
}

Required Fields

FieldDescription
idUnique identifier for the article. Used to track updates and removals.
titleArticle title displayed to users and used for search.
contentArticle body. Can be HTML or plain text.

Optional Fields

FieldDescription
urlSource URL for the article (displayed to users)
categoryCategory or folder for organization
lastModifiedISO 8601 timestamp for incremental sync
Field names are fully customizable. If your API uses body instead of content, or modified_at instead of lastModified, you can configure this in the field mapping.

Authentication

Cevro supports five authentication methods:
No authentication header is sent. Use this for publicly accessible endpoints that don’t require credentials.Configuration:
{
  "authType": "none",
  "credentials": {}
}
Credentials are encrypted at rest using AES-256 encryption. Never share your API credentials publicly.

Additional Headers

You can add custom HTTP headers alongside any authentication method. These are sent with every request to your endpoint. Common use cases:
  • Cloudflare Access — Service token headers (CF-Access-Client-Id, CF-Access-Client-Secret) to bypass Zero Trust protection
  • API gateways — Gateway-specific keys or routing headers
  • Corporate proxies — Authentication headers required by your network infrastructure
1

Click 'Add' in the Additional Headers section

Below the authentication fields, click the Add button.
2

Enter header name and value

Each row has a Header name (e.g., CF-Access-Client-Id) and a Header value field. Values are masked by default.
3

Add more headers if needed

Click Add again to add additional rows. Remove any header by clicking the X button.
Custom headers are applied after your chosen authentication header. If a custom header has the same name as the auth header, the custom header takes precedence.
Additional headers are encrypted at rest alongside your credentials.

Field Mapping

If your API response doesn’t match the default format, configure field mapping using JSONPath expressions.

Default Mapping

{
  "articlesPath": "$.articles",
  "idField": "$.id",
  "titleField": "$.title",
  "contentField": "$.content",
  "urlField": "$.url",
  "categoryField": "$.category",
  "lastModifiedField": "$.lastModified"
}

Custom Mapping Examples

Nested articles array:
// API Response: { "data": { "items": [...] } }
{
  "articlesPath": "$.data.items"
}
Different field names:
// API uses "body" and "headline" instead of "content" and "title"
{
  "titleField": "$.headline",
  "contentField": "$.body"
}
Deeply nested fields:
// API returns: { "metadata": { "articleId": "123" } }
{
  "idField": "$.metadata.articleId"
}

Pagination

Cevro supports cursor-based, offset, and link-follow pagination to handle large article collections. Your API should accept a cursor parameter and return the next cursor in the response: Request: GET /articles?cursor=abc123&limit=100 Response:
{
  "articles": [...],
  "pagination": {
    "hasMore": true,
    "nextCursor": "def456"
  }
}
Configuration:
{
  "type": "cursor",
  "cursorParam": "cursor",
  "limitParam": "limit",
  "defaultLimit": 100,
  "hasMorePath": "$.pagination.hasMore",
  "nextCursorPath": "$.pagination.nextCursor"
}
For APIs that return the next page as a URL in the response body. This is common with Confluence, GitHub, GitLab, and many modern REST APIs. Response:
{
  "results": [...],
  "_links": {
    "next": "/wiki/rest/api/content?start=25&limit=25"
  }
}
Pagination continues while the next-page URL exists and stops when it’s absent — no separate hasMore flag needed. Configuration:
{
  "type": "link",
  "limitParam": "limit",
  "defaultLimit": 25,
  "nextCursorPath": "$._links.next"
}
Both absolute and relative URLs are supported. Relative URLs (like /wiki/rest/api/content?start=25) are automatically resolved against your endpoint URL.

Full Confluence Example

{
  "endpointUrl": "https://your-domain.atlassian.net/wiki/rest/api/content?expand=body.storage",
  "authType": "basic",
  "credentials": {
    "username": "[email protected]",
    "password": "your-api-token"
  },
  "fieldMapping": {
    "articlesPath": "$.results",
    "idField": "$.id",
    "titleField": "$.title",
    "contentField": "$.body.storage.value"
  },
  "paginationConfig": {
    "type": "link",
    "limitParam": "limit",
    "defaultLimit": 25,
    "nextCursorPath": "$._links.next"
  }
}

Offset Pagination

If your API uses page numbers or offsets: Request: GET /articles?offset=100&limit=100 Configuration:
{
  "type": "offset",
  "cursorParam": "offset",
  "limitParam": "limit",
  "defaultLimit": 100
}

No Pagination

For small knowledge bases that return all articles in a single response:
{
  "type": "none"
}
Cevro limits syncs to 50,000 articles and 500 pagination pages to prevent runaway syncs. If you have more articles, consider filtering by category or date.

Webhooks

Enable instant syncs when your content changes by sending a webhook to Cevro.

Webhook URL

After creating your connector, you’ll receive a webhook URL:
https://api.cevro.ai/api/v1/webhooks/kb-sync/{integrationId}

Sending a Webhook

When your content changes, POST to the webhook URL:
curl -X POST "https://api.cevro.ai/api/v1/webhooks/kb-sync/{integrationId}" \
  -H "Content-Type: application/json" \
  -H "X-Webhook-Secret: whsec_your_secret_here" \
  -d '{
    "event": "content_updated",
    "timestamp": "2025-01-15T10:30:00Z"
  }'

Webhook Payload

FieldTypeDescription
eventstringMust be "content_updated"
timestampstringISO 8601 timestamp of the change
changedIdsstring[](Optional) Specific article IDs that changed

Security

  • The webhook secret is provided when you create the connector (shown only once)
  • Include the secret in the X-Webhook-Secret header
  • Webhooks are rate-limited to 10 requests per minute

Sync Frequency

Choose how often Cevro fetches your articles:
FrequencyDescription
DailySyncs every day at 1 AM (default)
WeeklySyncs every Monday at 1 AM
ManualOnly syncs when you trigger it
Use webhooks alongside scheduled syncs for the best of both worlds: automatic daily updates plus instant syncs when content changes.

Content Guidelines

HTML Content

Article content can include HTML. Cevro will:
  • Preserve formatting (headings, lists, links, tables)
  • Remove <script> tags for security
  • Remove inline event handlers (onclick, onload, etc.)
  • Truncate content exceeding 10 MB

Best Practices

Use semantic HTML

Structure content with proper headings (h1, h2), lists, and paragraphs for better AI comprehension.

Include context

Articles should be self-contained. The AI may not see other articles when answering a question.

Keep titles descriptive

Use clear, searchable titles. “Password Reset” is better than “Article 47”.

Update lastModified

Including timestamps helps Cevro identify which articles have changed.

Troubleshooting

This means Cevro connected to your API successfully (HTTP 200) but couldn’t find articles at the configured path.The wizard will help: When this happens, the test step shows a path picker with detected arrays from your API response. Click a suggested path or type your own, then re-test.Manual fix: Check your articlesPath field mapping. If your API returns { "results": [...] } instead of { "articles": [...] }, update the mapping to "$.results". Common examples:
  • Confluence: $.results
  • Zendesk: $.articles
  • Nested: $.data.items
Verify your credentials are correct. For Bearer tokens, ensure you’re not including the “Bearer ” prefix in the token value (Cevro adds it automatically).
Large knowledge bases may take time to sync. Check the sync logs for progress. If consistently timing out, consider:
  • Increasing your API’s timeout
  • Reducing the number of articles per page
  • Filtering to essential articles only
Ensure your API returns different content when articles change. Cevro compares article content to detect updates. Also verify the lastModified field is updating correctly.
  • Verify the X-Webhook-Secret header matches the secret shown during connector creation
  • Check that your request body includes "event": "content_updated"
  • Webhooks are rate-limited to 10/minute

API Reference

Test Connection

Test your endpoint configuration without creating a connector.
POST /api/v1/integrations/kb-connectors/test
Request:
{
  "endpointUrl": "https://your-api.com/articles",
  "authType": "bearer",
  "credentials": {
    "token": "your-token"
  },
  "fieldMapping": {
    "articlesPath": "$.data"
  }
}
Response:
{
  "success": true,
  "articlesCount": 150,
  "sampleArticle": {
    "id": "article-1",
    "title": "Getting Started",
    "contentPreview": "Welcome to our platform..."
  },
  "detectedSchema": {
    "fields": ["id", "title", "body", "created_at"],
    "suggestedMapping": {
      "idField": "$.id",
      "titleField": "$.title",
      "contentField": "$.body"
    }
  }
}

Trigger Manual Sync

POST /api/v1/integrations/kb-connectors/{id}/sync
Query Parameters:
  • forceFresh=true - Re-sync all articles, ignoring lastModified timestamps

View Sync Logs

GET /api/v1/integrations/kb-connectors/{id}/sync-logs?limit=50

Security

Cevro implements several security measures:
  • Credential encryption: All credentials and custom headers are encrypted at rest using AES-256
  • SSRF protection: Internal/private IP addresses are blocked (localhost, 10.x.x.x, 192.168.x.x, etc.)
  • Content sanitization: Script tags and event handlers are removed from article content
  • Rate limiting: Webhooks are limited to 10 requests per minute
  • Webhook authentication: Constant-time comparison prevents timing attacks on secrets