This API serves agent knowledge bases only. Classic knowledge bases use the Classic Knowledge Base API.
Get the Knowledge Base’s Endpoint
For the API key and its scope, see Knowledge Base API. Open the knowledge base in Dify, click API Access in the lower-left corner, and copy the endpoint. It ends with/knowledge-fs/spaces/<knowledge base ID>, and that ID is the knowledge_base_id every operation takes.
Query the Knowledge Base
Decide the retrieval depth (mode) first:
The script below needs Bash, curl, jq, and Python 3. Copy its two code blocks, in order, into
query.sh, run bash query.sh, and when prompted, enter the endpoint you copied and an API key.
1
Create a query token
Call Create Query Token with the question in
query and the depth in mode.2
Run the query
Post Keep the query record ID from the
request to Run Query unchanged, with the query token in place of the API key and trace_id as the X-Trace-ID header.x-query-run-id response header to investigate the answer. It isn’t step 1’s trace_id.3
Read the events
Treat only
answer.done as success. An answer.error can arrive after answer.delta frames, under HTTP 200: discard the partial text. A dropped connection can’t be resumed. After any failure, before or after the stream opens, start again from step 1.Set your client’s read timeout to allow for your slowest depth. Run Query sends no keep-alive events, and a default timeout can cut off a deep or research stream.The returned text stops at 2,000 characters at every depth, with no sign when it was cut off. The chunk text in metadata.evidenceBundle of answer.done is never shortened, so read the retrieved text there when you need all of it.x-session-id as sessionId, so put everything a follow-up needs into its query.
Investigate an Answer
When an answer looks wrong, pass its query record ID to Get Query Record to read the run’s recorded steps. Use the same ID to inspect the evidence:- Call List Query Chunks to read the retrieved chunks, scores, and citations.
- If the retrieved text contradicts itself, call List Query Conflicts to find the conflicting chunks.
- Call List Missing Chunks to see chunks the run needed but couldn’t use, and why.
Prevent Duplicate and Stale Writes
Send anIdempotency-Key header with every write that takes one. If the response is lost, send the same request with the same key: you get the original task, run, or job back instead of a second one. Use a new key for each new operation, since a repeated key returns the earlier result, even one that has finished.
Read an object’s current version right before you update or delete it, and send it in the operation’s version field. A 409 then means it changed after you read it: read it again, check that your change still applies, and resend. A 409 can also mean the Idempotency-Key was already used for a different request: use a new key.
Run a Research Task
Unlike a query atresearch depth, which answers within the stream, a research task runs in the background and keeps its results. Use a query when a user is waiting for the answer, and a research task when the work can wait or you’ll need the results later.
1
Plan
Send your question as
query to Plan Research Task, with the mode and topK you want to use. It returns the estimated cost, latency, and steps without starting anything.2
Create
Call Create Research Task with the same question and settings. To reject the task up front when its estimates go beyond what you’ll accept, add
limits: a task whose estimates exceed them fails with 422.To cap spending while the task runs, add budgetUsd. When you need an answer, set it well above the plan’s estimates.costUsd.max, because each model call has to fit in the budget at the most it could cost. A task that reaches its budget ends as canceled.3
Poll
Call Get Research Task with the returned task ID until the task ends.
4
Read the results
Call List Research Task Results and check the last result for
answer.Browse Documents and Chunks
A document is the item the Document tab shows. It has a document ID, and the file stored behind it has a separate document file ID. A content update, including one from a source sync, stores a new file with a new ID, but the document keeps its ID. Store the document ID, and follow its revisions for the content history.
To show which document a citation came from, pass its
documentAssetId to Get Document by File with 1 as document_asset_version.
To read a document’s chunks, pass the document ID and a revision number to List Chunks. For the content in use for retrieval, take active.revision from Get Document. For older content, find the revision in List Document Revisions.
To set a document’s metadata from another system, such as a CMS or a ticketing tool, call Update Document Metadata.
Add a Source
A source reads through a connection: the provider account or API key set up under Integrations > Data Source and linked to this knowledge base. Add the first source from each provider in Dify, on the knowledge base’s Source tab. To add more over the API:-
Call List Source Connections and pick an
activeconnection whoseconfigurationnames the provider you want. -
Call Create Source with the connection’s
idasconnectionIdand itsconfiguration.providerKindasmetadata.providerKind. Settypeanduriby what the source reads:- A website:
type: web, with the site’s root URL asuri. - An online document platform or drive:
type: connector, withconnector://<connectionId>asuri.
Idempotency-Key, and sending it twice creates two sources. Include a uniquemetadata.client_request_id: if the response is lost, look for it in List Sources before you create the source again. - A website:
Import Website Pages
Fill a website source in one of three ways:- Pick pages from a crawl preview.
- Import URLs you already know.
- Sync a source that has no page list yet: Dify crawls the whole site and imports every page it finds.
1
Preview the crawl
Call Preview Website Crawl, then poll Get Source Run with the returned
id until state is preview_ready or the run ends.A run that ends zero_results found no pages. Check the source’s URL and crawl settings, then preview again.2
Pick pages
Page through List Crawl Preview Pages with the run ID, and collect the
page_id of each page to import.3
Import
Call Import Selected Pages on the same run with those
pageIds. The run continues under the same ID: follow it until it ends.sourceUrls. Pages you leave out lose their documents at the next sync. To delete them in the same run instead, also set replaceExistingSelection: true.
Import Online Documents and Drive Files
Over the API, you can fill a newconnector source once. After a source has imported items, in Dify or over the API, an import can only drop items: one that names a new item fails, even though its failure suggests a retry. Add new items in Dify.
The items you send become the source’s whole content: documents for items you leave out are removed in the same run.
- Browse with List Source Pages for an online document source, or List Source Files for an online drive, as the source’s
metadata.providerKindsays. - Call Import Source Items with the
kindthat matches the provider anditemsbuilt from what you browsed, following the operation’sproviderItemIdformat exactly. - Follow the run with the returned
id.
Follow Source Runs
Follow a run with Get Source Run, using theid from the response that started it, until it ends. A run that reaches completed has already indexed and activated every item it imported or refreshed, so there’s no indexing to track separately.
A source handles one run at a time: starting another sync or import while one is active fails with 502. Wait for the active run to end, or cancel it with Cancel Source Run. A crawl preview counts as active until you import from it or cancel it, so cancel a preview you won’t import from.
To find a run you didn’t start, such as a scheduled sync or one started in Dify, call List Source Runs.
When a run fails, read its failure to see why. To rule out bad credentials, call Test Source Credentials: if valid is false, correct the connection’s credentials in Dify.
To run a failed or canceled run again from the start, under the same ID, call Retry Source Run. To repeat a canceled crawl preview or a failed Import Website Pages run, start a new preview or import with a new Idempotency-Key instead.
Sync and Schedule Sources
To fetch a source’s latest content now, call Sync Source, then follow the run it returns. To sync on a schedule, save one for each source:1
Read both versions
Read the source’s
version from Get Source, then the schedule’s revision from Get Sync Policy. For a source with no schedule yet, Get Sync Policy returns 404: use 0 as the revision.2
Save the schedule
Call Update Sync Policy with
revision as expectedRevision and version as expectedSourceVersion.version, and a schedule still bound to the old one turns itself off at its next due time.
To stop scheduled syncs, save mode: manual with enabled: false. Setting the source’s status to disabled with Update Source only pauses them, and a sync that came due in the meantime runs as soon as the source is active again.
Re-index and Track Indexing
When indexing fails or is canceled, restart the task with Retry Indexing Task. When a document indexed but came out wrong, re-index it. A model change needs no re-index: it rebuilds what it affects on its own. Call Re-index Documents withdocumentIds or with all: true. Only queued items started a task: keep compilation_job.id from each of them.
To know when new content is in use, poll the indexing task until it ends:
- For a re-index, poll Get Indexing Task with
compilation_job.id. - For indexing you didn’t start over the API, such as an upload in Dify, read
latest_task.idfrom Get Document or List Documents. Poll Get Document Indexing Task with the document ID and that task ID.
Change Models or Retrieval Settings
Choose models from Get Available Models. It needs a key with access to all knowledge bases: a key scoped to specific ones gets 403forbidden.
If you set models before the first document is indexed, they aren’t validated until that document is indexed. Then check issues in Get Knowledge Base Settings: it lists whatever keeps the knowledge base from being ready.
While a document is being indexed, a model change is rejected with 409: wait for indexing to finish, or cancel its tasks, first.
Once the knowledge base has indexed content, most settings changes run as a migration in the background:
1
Update
Call Update Knowledge Base Settings. A 202 means the change started a migration: keep
migration.id.2
Poll
Call Get Settings Migration with
migration.id until the migration ends.Delete Documents and Sources
To remove a whole document, delete it in Dify. Over the API, you can delete document files (Delete Document File, Delete Document Files in Batch) and sources (Delete Source). Deleting a document file deletes only the revision built on it, not the document. Avoid deleting the active revision’s file. No older revision takes its place, and the document drops out of List Documents and Dify’s document list. It isn’t deleted, though, and still counts toward your document quota. Deleting a source also deletes the documents it imported. To keep them, first save the IDs of files with thatsource_id from List Document Files, because their source_id becomes null once the deletion completes. Then delete the source with documents=keep. The kept documents are hidden until the deletion completes, and after that no source updates them.
To confirm a deletion finished, poll Get Deletion Job with job.id until the job ends.
For a batch, poll Get Deletion Batch with batch_id until every entry in results is rejected or its job has ended. A rejected file wasn’t deleted, and error says why. A pending entry means the batch stopped partway, and polling won’t move it: send the same request again with the same Idempotency-Key to retry only the pending files.
A deletion that ends failed can’t be retried or cleared, over the API or in Dify. What it was deleting stays hidden, including the documents of a source deleted with documents=keep.
Handle Errors
Errors carry the samecode, message, and status described in Errors, and many add a failure object: its retryPolicy says whether a retry can help. Run Query errors have their own shape, listed on its page.
On a 502, retry a read after a pause. A write may have taken effect before its response was lost. Resend it with the same Idempotency-Key, or, for a write that takes no key, check its outcome before sending it again. A 502 when starting a sync or import can also mean the source already has an active run: see Follow Source Runs.
Except on Get Available Models, 403 forbidden means the workspace has reached its knowledge base request rate limit. The whole workspace shares the limit, and every call counts, reads included. A call the limit rejects counts too, so back off before retrying, and space out your polling. To poll many indexing or bulk tasks in one call, pass their IDs to List Background Tasks as task_ids.