Assign documents
POST
https://app.sulus.ai/api/v1/kb/article-assign
Assign one or more published documents to one or more assistants
Authentication
Send a bearer token created on your dashboard's Developer page:
Authorization: Bearer <YOUR_API_KEY>
Request body
knowledge_article_id
string
Optional
Single-document form. One of knowledge_article_id / knowledge_article_ids is required.
Validation:
sometimes|uuid|exists:knowledge_articles,idStored in
knowledge_article_assignments.knowledge_article_idknowledge_article_ids
array
Optional
Multi-document form.
Validation:
sometimes|array|min:1knowledge_article_ids.*
string
Optional
Validation:
uuid|exists:knowledge_articles,idassistant_id
integer
Optional
Single-assistant form. One of assistant_id / assistant_ids is required.
Validation:
sometimes|integer|exists:assistants,idStored in
knowledge_article_assignments.assistant_idassistant_ids
array
Optional
Multi-assistant form.
Validation:
sometimes|array|min:1assistant_ids.*
integer
Optional
Validation:
integer|exists:assistants,idErrors
| Status | Meaning | Body |
|---|---|---|
422 |
Neither document field supplied | {"message":"knowledge_article_id or knowledge_article_ids is required."} |
422 |
Neither assistant field supplied | {"message":"assistant_id or assistant_ids is required."} |
422 |
Document's library is not an assistant-audience library | {"message":"Only documents from voice libraries can be assigned to assistants."} |
422 |
Document is not published | {"message":"Only published documents can be assigned to assistants."} |
403 |
Assistant belongs to a different organization | {"message":"Assistant does not belong to your organization."} |
403 |
Assistant not owned by the caller (non-admin) | {"message":"You can only assign documents to assistants you own."} |
422 |
Assistant and document belong to different organizations | {"message":"Assistant and document must belong to the same organization."} |
404 |
Document not found, or it does not belong to that library | {"message":"No query results for model [App\\Models\\KnowledgeArticle] <id>."} |
422 |
Validation failed | {"message":"…","errors":{"field":["…"]}} |
403 |
Policy denied — outside your organization, or you cannot write to this resource | {"message":"This action is unauthorized."} |
401 |
Missing or invalid bearer token | |
403 |
Feature knowledge_docs not enabled for the account |
Notes
- When both a document list and an assistant list are supplied, EVERY document is linked to EVERY assistant (a cartesian product), not paired index-by-index.
- Idempotent per pair — an already-existing (assistant_id, knowledge_article_id) assignment is returned unchanged rather than duplicated (unique constraint on the pair).
- The response de-duplicates by assignment id, so re-assigning an existing pair alongside a new one only returns each row once.
- Each successful assignment immediately re-syncs the target assistant's document-search capability so it can find the newly attached document on its next call.
curl --request POST \
--url https://app.sulus.ai/api/v1/kb/article-assign \
--header 'Authorization: Bearer <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--data '{
"knowledge_article_ids": ["b2c3d4e5-f6a7-8901-bcde-f23456789012"],
"assistant_ids": [12]
}'
import requests
url = "https://app.sulus.ai/api/v1/kb/article-assign"
headers = {"Authorization": "Bearer <YOUR_API_KEY>"}
payload = {
"knowledge_article_ids": ["b2c3d4e5-f6a7-8901-bcde-f23456789012"],
"assistant_ids": [12]
}
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/article-assign"
payload := strings.NewReader(`{
"knowledge_article_ids": ["b2c3d4e5-f6a7-8901-bcde-f23456789012"],
"assistant_ids": [12]
}`)
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
200
{
"data": [
{
"id": "d4e5f6a7-b8c9-0123-defa-456789012345",
"reseller_id": "f1e2d3c4-b5a6-4978-8901-234567890abc",
"assistant_id": 12,
"knowledge_article_id": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
"created_at": "2026-07-30T14:50:00.000000Z",
"updated_at": "2026-07-30T14:50:00.000000Z"
}
]
}
Response — POST
/article-assign
200
{
"data": [
{
"id": "d4e5f6a7-b8c9-0123-defa-456789012345",
"reseller_id": "f1e2d3c4-b5a6-4978-8901-234567890abc",
"assistant_id": 12,
"knowledge_article_id": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
"created_at": "2026-07-30T14:50:00.000000Z",
"updated_at": "2026-07-30T14:50:00.000000Z"
}
]
}