Logo
Search
Docs

Create document

POST https://app.sulus.ai/api/v1/kb/knowledge-bases/{knowledge_base}/articles

Create a document in a library

Authentication

Send a bearer token created on your dashboard's Developer page:

Authorization: Bearer <YOUR_API_KEY>

Path parameters

knowledge_base string Required

The library.

Validation: the library's UUID
Stored in knowledge_bases.id

Request body

title string Required
Validation: required|string|max:255
Stored in knowledge_articles.title
content string Required

Rich HTML content. No length limit — stored in a longtext column.

Validation: required|string
Stored in knowledge_articles.content
status string Optional Nullable

Defaults to draft. archived is not settable at creation.

Validation: nullable|in:draft,published
Stored in knowledge_articles.status

Errors

StatusMeaningBody
404 Library not found {"message":"No query results for model [App\\Models\\KnowledgeBase] <id>."}
403 Policy denied — outside your organization, or you cannot write to this resource {"message":"This action is unauthorized."}
422 Validation failed {"message":"…","errors":{"field":["…"]}}
401 Missing or invalid bearer token
403 Feature knowledge_docs not enabled for the account

Notes

  • content_hash is a sha256 of the extracted plain text, computed on every save; embedded_content_hash only updates once a sync of that exact content has completed.
  • When status is published, the search-index sync runs synchronously before the response is returned (see Overview's "Publishing and search sync"). A draft is created with sync_status pending and no sync is attempted.
  • Sync failures during create are swallowed (logged, not raised) — the response still returns 201 with whatever sync_status the attempt left behind (typically error, with sync_error populated).
curl --request POST \
  --url https://app.sulus.ai/api/v1/kb/knowledge-bases/{knowledge_base}/articles \
  --header 'Authorization: Bearer <YOUR_API_KEY>' \
  --header 'Content-Type: application/json' \
  --data '{
  "title": "Return Policy",
  "content": "<h2>Returns</h2><p>Items can be returned within 30 days of purchase with a receipt.</p>",
  "status": "published"
}'
import requests

url = "https://app.sulus.ai/api/v1/kb/knowledge-bases/{knowledge_base}/articles"
headers = {"Authorization": "Bearer <YOUR_API_KEY>"}
payload = {
  "title": "Return Policy",
  "content": "<h2>Returns</h2><p>Items can be returned within 30 days of purchase with a receipt.</p>",
  "status": "published"
}

response = requests.post(url, json=payload, headers=headers)
print(response.json())
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	url := "https://app.sulus.ai/api/v1/kb/knowledge-bases/{knowledge_base}/articles"
	payload := strings.NewReader(`{
  "title": "Return Policy",
  "content": "<h2>Returns</h2><p>Items can be returned within 30 days of purchase with a receipt.</p>",
  "status": "published"
}`)
	req, _ := http.NewRequest("POST", url, payload)
	req.Header.Add("Authorization", "Bearer <YOUR_API_KEY>")
	req.Header.Add("Content-Type", "application/json")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
Response 201
{
    "data": {
        "id": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
        "knowledge_base_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "reseller_id": "f1e2d3c4-b5a6-4978-8901-234567890abc",
        "title": "Return Policy",
        "content": "<h2>Returns</h2><p>Items can be returned within 30 days of purchase with a receipt.</p>",
        "plain_text": "Returns Items can be returned within 30 days of purchase with a receipt.",
        "structured_text": "\n\n## Returns\n\nItems can be returned within 30 days of purchase with a receipt.",
        "content_hash": "3f9c2a106b4e4a2d9f0a1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f708192a3b4c5",
        "embedded_content_hash": "3f9c2a106b4e4a2d9f0a1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f708192a3b4c5",
        "status": "published",
        "char_count": 73,
        "chunk_count": 1,
        "sync_status": "synced",
        "sync_error": null,
        "last_synced_at": "2026-07-30T14:22:04.000000Z",
        "created_at": "2026-07-30T14:22:03.000000Z",
        "updated_at": "2026-07-30T14:22:04.000000Z"
    }
}