Upload a file to a knowledge folder
curl --request POST \
--url https://api.langdock.com/knowledge/{folderId} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form file='@example-file' \
--form 'url=<string>'import requests
url = "https://api.langdock.com/knowledge/{folderId}"
files = { "file": ("example-file", open("example-file", "rb")) }
payload = { "url": "<string>" }
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('file', '<string>');
form.append('url', '<string>');
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
options.body = form;
fetch('https://api.langdock.com/knowledge/{folderId}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.langdock.com/knowledge/{folderId}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"url\"\r\n\r\n<string>\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: multipart/form-data"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.langdock.com/knowledge/{folderId}"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"url\"\r\n\r\n<string>\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.langdock.com/knowledge/{folderId}")
.header("Authorization", "Bearer <token>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"url\"\r\n\r\n<string>\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.langdock.com/knowledge/{folderId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"url\"\r\n\r\n<string>\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"message": "The file \"quarterly-report.pdf\" is declared as a PDF but its content does not start with the expected PDF header.",
"code": "BAD_REQUEST"
}{
"message": "The provided API key is invalid."
}{
"message": "Knowledge folder not shared with this API key. Please share the folder with the API key in the Langdock App to upload or update files.",
"code": "FORBIDDEN"
}{
"message": "Knowledge folder not found",
"code": "NOT_FOUND"
}{
"message": "Upload request timed out. Please try again with a smaller file or check your connection.",
"code": "REQUEST_TIMEOUT"
}{
"message": "File size exceeds the maximum allowed size of 256MB. Please upload a smaller file.",
"code": "PAYLOAD_TOO_LARGE"
}{
"message": "You have exceeded the maximum number of requests per minute (50)",
"code": "TOO_MANY_REQUESTS"
}{
"message": "Internal server error"
}{
"message": "Storage capacity exceeded. Please contact your administrator.",
"code": "SERVICE_UNAVAILABLE"
}Knowledge Folder API
Upload File to Knowledge Folder
Upload a new file to a Knowledge base
POST
/
knowledge
/
{folderId}
Upload a file to a knowledge folder
curl --request POST \
--url https://api.langdock.com/knowledge/{folderId} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form file='@example-file' \
--form 'url=<string>'import requests
url = "https://api.langdock.com/knowledge/{folderId}"
files = { "file": ("example-file", open("example-file", "rb")) }
payload = { "url": "<string>" }
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('file', '<string>');
form.append('url', '<string>');
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
options.body = form;
fetch('https://api.langdock.com/knowledge/{folderId}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.langdock.com/knowledge/{folderId}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"url\"\r\n\r\n<string>\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: multipart/form-data"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.langdock.com/knowledge/{folderId}"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"url\"\r\n\r\n<string>\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.langdock.com/knowledge/{folderId}")
.header("Authorization", "Bearer <token>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"url\"\r\n\r\n<string>\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.langdock.com/knowledge/{folderId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"url\"\r\n\r\n<string>\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"message": "The file \"quarterly-report.pdf\" is declared as a PDF but its content does not start with the expected PDF header.",
"code": "BAD_REQUEST"
}{
"message": "The provided API key is invalid."
}{
"message": "Knowledge folder not shared with this API key. Please share the folder with the API key in the Langdock App to upload or update files.",
"code": "FORBIDDEN"
}{
"message": "Knowledge folder not found",
"code": "NOT_FOUND"
}{
"message": "Upload request timed out. Please try again with a smaller file or check your connection.",
"code": "REQUEST_TIMEOUT"
}{
"message": "File size exceeds the maximum allowed size of 256MB. Please upload a smaller file.",
"code": "PAYLOAD_TOO_LARGE"
}{
"message": "You have exceeded the maximum number of requests per minute (50)",
"code": "TOO_MANY_REQUESTS"
}{
"message": "Internal server error"
}{
"message": "Storage capacity exceeded. Please contact your administrator.",
"code": "SERVICE_UNAVAILABLE"
}Uploads a new file to a specified Knowledge base. The file will be processed, embedded, and made available for semantic search.
File size limits depend on the file type: 10 MB for plain text, Markdown, JSON, and VTT files; 30 MB for XML files; and 256 MB for other supported document types. See the supported file types reference for supported formats.
This endpoint accepts the same
File validation happens before the API accepts the upload. If validation fails, the async endpoint returns the same
Before You Start
- API key scope: Requires an API key with the
KNOWLEDGE_FOLDER_APIscope. The API key itself needs the Editor role on the Knowledge base. See Share Knowledge bases with the API for setup instructions. - Knowledge bases: The Knowledge Folder API manages resources that appear as Knowledge bases in the Library.
Base URL
https://api.langdock.com
Dedicated deploymentsReplace
api.langdock.com with <your-deployment-url>/api/public in all requests.Request Format
This endpoint acceptsmultipart/form-data requests with the file attached.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
folderId | string | Yes | The ID of the Knowledge base |
Form Fields
| Field | Type | Required | Description |
|---|---|---|---|
file | file | Yes | The file to upload. See size limits below. |
url | string | No | Optional source URL to associate with the file |
Supported File Types
Knowledge bases support document and text formats such as:- PDF (
.pdf) - Word documents (
.doc,.docx) - Text files (
.txt) - Markdown (
.md) - HTML (
.html) - PowerPoint (
.pptx,.ppt)
Executable files and other potentially dangerous file types are blocked for security reasons.
Examples
Upload a File with cURL
curl -X POST "https://api.langdock.com/knowledge/{folderId}" \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@/path/to/document.pdf"
Upload a File with JavaScript
const FormData = require("form-data");
const fs = require("fs");
const axios = require("axios");
async function uploadFile(folderId, filePath) {
const form = new FormData();
form.append("file", fs.createReadStream(filePath));
const response = await axios.post(
`https://api.langdock.com/knowledge/${folderId}`,
form,
{
headers: {
Authorization: "Bearer YOUR_API_KEY",
...form.getHeaders(),
},
}
);
return response.data;
}
Upload with Source URL
const FormData = require("form-data");
const fs = require("fs");
const axios = require("axios");
async function uploadFileWithUrl(folderId, filePath, sourceUrl) {
const form = new FormData();
form.append("file", fs.createReadStream(filePath));
form.append("url", sourceUrl);
const response = await axios.post(
`https://api.langdock.com/knowledge/${folderId}`,
form,
{
headers: {
Authorization: "Bearer YOUR_API_KEY",
...form.getHeaders(),
},
}
);
return response.data;
}
Response Format
Success Response (200 OK)
{
status: "success";
result: {
id: string; // Unique attachment ID
name: string; // Original filename
mimeType: string; // MIME type of the file
createdAt: string; // ISO 8601 timestamp
updatedAt: string; // ISO 8601 timestamp
url: string | null; // Source URL if provided
};
}
Example Response
{
"status": "success",
"result": {
"id": "att_abc123def456",
"name": "quarterly-report.pdf",
"mimeType": "application/pdf",
"createdAt": "2025-01-15T10:30:00.000Z",
"updatedAt": "2025-01-15T10:30:00.000Z",
"url": null
}
}
File Validation Response (400 Bad Request)
If the file fails validation, the API returns the reason inmessage:
{
"message": "The file \"quarterly-report.pdf\" is declared as a PDF but its content does not start with the expected PDF header.",
"code": "BAD_REQUEST"
}
Error Handling
try {
const response = await uploadFile(folderId, filePath);
} catch (error) {
if (error.response) {
console.error(error.response.data.message ?? "Upload failed");
}
}
| Status | Meaning |
|---|---|
400 | Invalid request or file validation failure |
401 | Invalid or missing API key |
403 | API key does not have access to the Knowledge base |
404 | Knowledge base not found |
408 | Upload timed out |
413 | File exceeds the size limit |
429 | Rate limit exceeded |
500 | Unexpected server error |
503 | Storage capacity exceeded |
Processing Status
After upload, the file is processed asynchronously. Use the Retrieve Files endpoint to check processing status. ThesyncStatus field indicates the current state:
UPLOADING- File is being uploadedUPLOADED- File is uploaded and queued for processingEXTRACTING- Text is being extracted from the fileEMBEDDING- Embeddings are being generatedSYNCED- File is ready for searchACTION_FAILED,EXTRACTION_FAILED,EMBEDDING_FAILED,TIMEOUT- Processing failed
Async Upload Variant
For large files or when you don’t need to wait for the upload response, you can use the async upload endpoint:POST /knowledge/{folderId}/upload-async
multipart/form-data fields and returns 202 Accepted after the file is received. Processing continues in the background.
{
"status": "processing",
"result": {
"id": "att_abc123def456",
"name": "quarterly-report.pdf",
"mimeType": "application/pdf",
"createdAt": "2025-01-15T10:30:00.000Z",
"updatedAt": "2025-01-15T10:30:00.000Z",
"url": null,
"processingStatus": "UPLOADED",
"statusUrl": "/api/public/knowledge/{folderId}/{attachmentId}"
},
"message": "File uploaded successfully and is being processed in the background. Poll the statusUrl to check when processing completes (syncStatus: SYNCED)."
}
400 Bad Request response shown above instead of 202 Accepted.
Use GET {statusUrl} to poll processing status. The response returns the current status in result.syncStatus.
Langdock intentionally blocks browser-origin requests to protect your API key and ensure your applications remain secure. For more information, please see our guide on API Key Best Practices.
Was this page helpful?