Get Bulk Task
Returns the progress of the indexing tasks in a bulk task. In this API a bulk task comes from Re-index Documents, and only the API key that started it can read it.
Items that Re-index Documents reported as not_found count as completed, so completed_items can equal total_items even when no document was re-indexed. Compare total_items with the number of queued items in that response to catch it. For the re-index flow, see Re-index and Track Indexing.
curl --request GET \
--url https://{api_base_url}/knowledge-fs/spaces/{knowledge_base_id}/bulk-jobs/{bulk_task_id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://{api_base_url}/knowledge-fs/spaces/{knowledge_base_id}/bulk-jobs/{bulk_task_id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://{api_base_url}/knowledge-fs/spaces/{knowledge_base_id}/bulk-jobs/{bulk_task_id}', 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_base_url}/knowledge-fs/spaces/{knowledge_base_id}/bulk-jobs/{bulk_task_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://{api_base_url}/knowledge-fs/spaces/{knowledge_base_id}/bulk-jobs/{bulk_task_id}"
req, _ := http.NewRequest("GET", url, nil)
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.get("https://{api_base_url}/knowledge-fs/spaces/{knowledge_base_id}/bulk-jobs/{bulk_task_id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://{api_base_url}/knowledge-fs/spaces/{knowledge_base_id}/bulk-jobs/{bulk_task_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"canceled_items": 0,
"completed_items": 1,
"created_at": "2026-09-06T02:30:00Z",
"failed_item_ids": [],
"failed_items": 0,
"failures": [],
"id": "c7d9e1f3-5a7b-4c9d-8e0f-1a2b3c4d5e6f",
"knowledge_space_id": "9b2e5b7a-3c1d-4e2f-8a9b-1c2d3e4f5a6b",
"status": "running",
"total_items": 2,
"type": "document_reindex",
"updated_at": "2026-09-06T02:31:12Z"
}Authorizations
Every request authenticates with an API key: Authorization: Bearer {API_KEY}. App endpoints take an app API key; knowledge endpoints take a knowledge base API key (Get Started).
Keep keys server-side; never embed them in client code. Requests with a missing or invalid key fail with HTTP 401 (unauthorized).
Path Parameters
Knowledge base ID: the last segment of the Service API endpoint shown in the knowledge base's API Access dialog (…/knowledge-fs/spaces/<knowledge base ID>), and the segment after /datasets/new/ in the address bar.
Bulk task ID: bulk_job_id of the Re-index Documents response. List Background Tasks also returns it, as the id of a document_bulk task. The id of a document_delete task from Delete Document is a deletion job ID: follow it with Get Deletion Job.
Response
The bulk task.
Items whose task was canceled, including documents that were disabled when the re-index was requested.
Items that completed or were reported as not_found.
When the bulk task was created, ISO 8601.
IDs of the failed items, as submitted to Re-index Documents. They are not indexing task IDs. Map them to tasks with the items entries you kept from that response.
Items whose task failed.
One entry per failed item. Empty when none failed.
Show child attributes
Show child attributes
Bulk task ID.
Internal ID of the knowledge base. Not the knowledge base ID in the path.
Aggregate state:
running: at least one item is still in progress.completed: every item completed (reached at leastprojection_built, which comes beforepublished) or was reported asnot_found.failed: every item is terminal and at least one failed.canceled: every item is terminal, none failed, and at least one was canceled.
completed does not guarantee that the new revisions are active yet. When that matters, check each task with Get Indexing Task for stage: published, using the task IDs you kept from Re-index Documents.
Number of items submitted.
document_reindex for bulk tasks from this API. document_upload and document_delete arise only from Dify operations. A deletion over this API answers with a deletion job, which is not a bulk task: follow it with Get Deletion Job or Get Deletion Batch.
Latest change across the bulk task and its indexing tasks, ISO 8601.
Was this page helpful?
curl --request GET \
--url https://{api_base_url}/knowledge-fs/spaces/{knowledge_base_id}/bulk-jobs/{bulk_task_id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://{api_base_url}/knowledge-fs/spaces/{knowledge_base_id}/bulk-jobs/{bulk_task_id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://{api_base_url}/knowledge-fs/spaces/{knowledge_base_id}/bulk-jobs/{bulk_task_id}', 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_base_url}/knowledge-fs/spaces/{knowledge_base_id}/bulk-jobs/{bulk_task_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://{api_base_url}/knowledge-fs/spaces/{knowledge_base_id}/bulk-jobs/{bulk_task_id}"
req, _ := http.NewRequest("GET", url, nil)
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.get("https://{api_base_url}/knowledge-fs/spaces/{knowledge_base_id}/bulk-jobs/{bulk_task_id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://{api_base_url}/knowledge-fs/spaces/{knowledge_base_id}/bulk-jobs/{bulk_task_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"canceled_items": 0,
"completed_items": 1,
"created_at": "2026-09-06T02:30:00Z",
"failed_item_ids": [],
"failed_items": 0,
"failures": [],
"id": "c7d9e1f3-5a7b-4c9d-8e0f-1a2b3c4d5e6f",
"knowledge_space_id": "9b2e5b7a-3c1d-4e2f-8a9b-1c2d3e4f5a6b",
"status": "running",
"total_items": 2,
"type": "document_reindex",
"updated_at": "2026-09-06T02:31:12Z"
}