Skip to main content
Qdrant is a bring-your-own (BYOK) external knowledge provider in ModuleX. You connect your own Qdrant instance — Qdrant Cloud or self-hosted — as a credential, then point a workflow Knowledge node at one of your collections to run vector similarity search at run time. Because retrieval runs against your own Qdrant, it is uncosted in ModuleX: it consumes no credits and never hits the billing gate. This page covers connecting a Qdrant credential, the connection fields and Knowledge-node configuration, how BYOK retrieval works under the hood, the catalog actions Qdrant exposes, and the errors you can hit. For the cross-provider picture see Knowledge providers; for the managed (credit-metered) alternative see modulexdb; for the retrieval concept see Knowledge & RAG.
Qdrant is the integration named qdrant on the wire, with integration_type knowledge_provider. It ships one auth schema of type custom (“Qdrant Connection”). Unlike managed knowledge (the modulexdb provider), ModuleX does not ingest, chunk, embed, or store documents for you in Qdrant — you own the collections, the points, and the embeddings. ModuleX only queries what is already in your Qdrant.

How Qdrant fits in ModuleX

ModuleX treats a vector store one of two ways:

Managed (modulexdb)

ModuleX hosts the vectors, ingests and embeds your documents, and bills retrieval and ingest in credits. See Managed knowledge.

BYOK (Qdrant, external)

You host the vectors in your own Qdrant. ModuleX queries them through an adapter using a credential you create. Retrieval is uncosted — no credits, no billing gate.
Qdrant requires a query vector — it does not embed text for you. So a Knowledge node pointed at Qdrant first embeds your query with the embedding model you configure (for example an OpenAI embedding model), then sends that vector to Qdrant’s search API. This means a Qdrant Knowledge node needs an embedding_config; ModuleX raises a configuration error without one.
The embedding model used at query time must match the model that produced the vectors already stored in your Qdrant collection — same provider, same model, same dimension. If they differ, Qdrant returns either a dimension-mismatch error or low-quality results. ModuleX does not validate this for you because it never wrote those vectors.
🎬 MEDIA PLACEHOLDER · MX-MEDIA-4130 · [IMAGE] [IMAGE_DESCRIPTION]: Diagram of the BYOK Qdrant retrieval path inside a workflow run. [IMAGE_DETAILS]: Show: workflow Knowledge node receives a query string, then “embed query” using the configured embedding model (e.g. OpenAI), producing a vector; the vector plus collection name go to the user’s Qdrant instance over its REST API (POST /collections/{name}/points/search); matched points return to the node, which formats them as chunks or a context string into run state. Annotate “BYOK — runs on your Qdrant, no ModuleX credits”. Light theme, 16:9, left-to-right flow.

Before you start

A reachable Qdrant instance

A Qdrant Cloud cluster or a self-hosted Qdrant that ModuleX can reach over HTTP(S), with at least one collection that already contains embedded points.

Owner or admin role

Creating and managing credentials, and browsing the integration catalog, require the owner or admin role in your organization. The retired member role cannot do this. See Roles & permissions.

Your auth headers

Every API call sends Authorization: Bearer mx_live_… and X-Organization-ID. See Authentication.

A matching embedding model

Know which embedding model and dimension produced the vectors in your collection, so you can configure the same model for query embedding.

Connect Qdrant

You connect Qdrant by creating a custom credential for the qdrant integration. The credential stores your Qdrant URL and (optionally) an API key. ModuleX encrypts the credential at rest and never returns the secret material in clear text.
1

Gather your Qdrant connection details

Note your Qdrant URL (including the port — Qdrant’s REST API listens on 6333 by default) and, for Qdrant Cloud, your API key. A local instance typically needs no API key.
2

(Optional) validate the connection before saving

Call POST /credentials/test-temporary to check the connection before persisting it. ModuleX runs Qdrant’s configured test — a GET {url}/collections with your api-key header — and reports is_valid. See Validate a connection before saving.
3

Create the credential

Call POST /credentials with integration_name: "qdrant", auth_type: "custom", and an auth_data object holding url and optional api_key. Set make_default: true to make it the default Qdrant credential for the organization.
4

Reference it from a Knowledge node

Use the returned credential_id (plus a collection_name and an embedding_config) in a workflow Knowledge node. See Configure a Knowledge node for Qdrant.
🎬 MEDIA PLACEHOLDER · MX-MEDIA-4131 · [SCREENSHOT] [SCREENSHOT_DESCRIPTION]: The ModuleX app credential dialog for connecting Qdrant. [SCREENSHOT_DETAILS]: Capture the “Connect Qdrant” / “Qdrant Connection” credential form in the integrations/credentials area of the app. Show the Qdrant logo, the Qdrant URL field (placeholder https://xyz-abc.aws.cloud.qdrant.io:6333), the optional API Key field (masked, marked optional, placeholder qdrant-api-key-...), the “Set as default” toggle, and the Test/Save buttons. Light theme, 16:9, crop to the dialog.

Connection fields

The Qdrant auth schema is a single custom schema named “Qdrant Connection” with two fields. Send them inside auth_data.
url
string
required
The base URL of your Qdrant instance, including the port — for example https://xyz-abc.aws.cloud.qdrant.io:6333. A trailing slash is stripped. When omitted at run time the adapter falls back to http://localhost:6333, but the field is required when you create a credential. Not sensitive.
api_key
string
Your Qdrant Cloud API key. Optional — leave it unset for local or unauthenticated instances. Sent to Qdrant as the api-key request header. Sensitive; stored encrypted and masked in responses.

Create the credential

POST /credentials returns 201. For Qdrant you must send auth_type: "custom" because the connection is not an api_key-only schema (the URL is part of the connection). See the full credential model in Credentials & OAuth2.
integration_name
string
required
Must be qdrant.
auth_type
string
required
custom.
auth_data
object
required
The connection material — {"url": "...", "api_key": "..."}. api_key may be omitted for instances that do not require one.
display_name
string
A human-readable label. Defaults to the integration’s display name (Qdrant) when omitted.
make_default
boolean
default:"false"
Set this credential as the default Qdrant credential for the organization. Only one credential per integration can be the default.
Response201 Created (secret masked):
credential_id
string
The credential’s UUID. Pass this as credential_id in a Knowledge node to use this Qdrant connection.
integration_name
string
qdrant.
integration_type
string | null
knowledge_provider.
auth_type
string
custom.
is_default
boolean
Whether this is the organization’s default Qdrant credential.
last_used_at
string | null
ISO-8601 timestamp of the last resolution, or null if never used.
curl -X POST https://api.modulex.dev/credentials \
  -H "Authorization: Bearer mx_live_xxx" \
  -H "X-Organization-ID: 11111111-1111-1111-1111-111111111111" \
  -H "Content-Type: application/json" \
  -d '{
    "integration_name": "qdrant",
    "auth_type": "custom",
    "display_name": "Production Qdrant",
    "make_default": true,
    "auth_data": {
      "url": "https://xyz-abc.aws.cloud.qdrant.io:6333",
      "api_key": "qdrant-api-key-abc123"
    }
  }'

Validate a connection before saving

POST /credentials/test-temporary validates the connection before you persist it. ModuleX runs Qdrant’s configured test endpoint — GET {url}/collections, sending the api-key header — and treats HTTP 200 with a result field present as success. The test is free (cost_level: "free").
integration_name
string
required
qdrant.
auth_type
string
required
custom.
auth_data
object
required
{"url": "...", "api_key": "..."}.
The response reports is_valid, a human-readable message, tested_at, the test_method, and the status_code returned by Qdrant.
curl -X POST https://api.modulex.dev/credentials/test-temporary \
  -H "Authorization: Bearer mx_live_xxx" \
  -H "X-Organization-ID: 11111111-1111-1111-1111-111111111111" \
  -H "Content-Type: application/json" \
  -d '{
    "integration_name": "qdrant",
    "auth_type": "custom",
    "auth_data": {
      "url": "https://xyz-abc.aws.cloud.qdrant.io:6333",
      "api_key": "qdrant-api-key-abc123"
    }
  }'

Configure a Knowledge node for Qdrant

A workflow Knowledge node is the surface that retrieves from Qdrant during a run. For an external provider you set provider_type to qdrant, point it at a collection_name, and supply an embedding_config so ModuleX can embed the query before searching. The full node configuration is below; fields marked (external) apply to Qdrant and the other external providers, and fields marked (native only) apply only to modulexdb.
credential_id
string
required
The UUID of the Qdrant credential to use.
provider_type
string
default:"modulexdb"
One of modulexdb, qdrant, pinecone, weaviate, mongodb_atlas. Set it to qdrant.
query
string
required
The search query. Supports {{nodeId.path}} references so the query can come from an earlier node’s output. See Variables & references.
query_from_input
boolean
default:"false"
When true, use the workflow input as the query instead of the query field.
collection_name
string
required
(external) The Qdrant collection to search. Required for Qdrant — the node raises a configuration error without it.
namespace
string | null
(external) Namespace, used by Pinecone-style providers. Qdrant does not use namespaces; leave it unset.
embedding_config
object
(external) Required for Qdrant. The model ModuleX uses to embed the query into a vector before searching Qdrant. See The embedding_config object.
top_k
integer
default:"5"
Number of results to retrieve. Range 150. Passed to Qdrant as the search limit.
min_score
number
default:"0.3"
Minimum similarity-score floor, 0.01.0. When greater than 0, sent to Qdrant as score_threshold; Qdrant drops points below it.
max_tokens
integer
default:"2000"
Maximum tokens in the formatted context string (used when output_format is context or both). Range 10010000.
filters
object | null
(external) A provider-specific filter, passed straight to Qdrant as its filter clause. Use Qdrant’s filter syntax (for example must/should/must_not conditions on payload fields).
document_ids
string[] | null
(native only) Restrict retrieval to specific document IDs. Applies to modulexdb knowledge bases, not Qdrant.
output_format
string
default:"context"
How results are written into run state — chunks (individual matches with metadata), context (one RAG-ready context string), or both.
include_metadata
boolean
default:"true"
Include each match’s payload/metadata in the results. Maps to Qdrant’s with_payload.
include_source
boolean
default:"true"
Include source-document info in the formatted context string.

The embedding_config object

Qdrant stores vectors but does not embed text, so the Knowledge node embeds your query first. embedding_config selects the embedding model and is required for Qdrant.
integration_name
string
required
The embedding provider integration, for example openai. See LLM providers.
provider_id
string
required
The provider routing slug, for example openai.
model_id
string
required
The embedding model id, for example text-embedding-3-small. Must match the model that produced the vectors in your collection.
credential_id
string | null
The credential for the embedding provider. When null, ModuleX uses the organization’s default credential for integration_name.
Knowledge node config (Qdrant)
{
  "credential_id": "c0ffee00-1111-2222-3333-444455556666",
  "provider_type": "qdrant",
  "collection_name": "product_docs",
  "query": "{{trigger.question}}",
  "top_k": 5,
  "min_score": 0.3,
  "output_format": "context",
  "embedding_config": {
    "integration_name": "openai",
    "provider_id": "openai",
    "model_id": "text-embedding-3-small",
    "credential_id": null
  }
}
The Knowledge node is configured on the canvas in the workflow builder, or programmatically as part of a workflow’s node graph. There is no standalone REST endpoint that queries an external provider directly — Qdrant retrieval happens inside a workflow run. The native knowledge-bases search API (POST /knowledge-bases/{id}/search) targets modulexdb, not Qdrant.

How BYOK retrieval works

When a Knowledge node with provider_type: "qdrant" executes during a run, ModuleX:
1

Resolves and decrypts the credential

Loads your Qdrant credential for the current organization and decrypts the url and api_key. A missing or wrong-org credential fails the node with a credential error. See Data security & encryption.
2

Embeds the query

Because Qdrant requires a query vector, ModuleX embeds the resolved query using your embedding_config. Without embedding_config, the node raises a configuration error.
3

Searches your Qdrant collection

The Qdrant adapter calls POST {url}/collections/{collection_name}/points/search with the query vector, limit (top_k), with_payload (include_metadata), with_vector, an optional score_threshold (min_score), and any filters. It sends the api-key header when an API key is set.
4

Normalizes and formats results

Each Qdrant point becomes a standard match (id, score, extracted text content, payload metadata). Text content is pulled from common payload fields (content, text, chunk_text, page_content, data, body, summary, document). The node then writes them into run state as chunks, a context string, or both per output_format. See Workflow engine & nodes.
Text-content extraction depends on your payload using one of the recognized field names. If your Qdrant points store their text under a different key, the returned content is empty (the metadata still comes through when include_metadata is on). Store retrievable text under a field such as content or text.

BYOK billing

Qdrant is bring-your-own. Retrieval runs against your Qdrant instance and is not metered in ModuleX credits. Only managed knowledge — modulexdb knowledge bases — is credit-billed for retrieval and ingest.

No ModuleX credit charge

Querying Qdrant draws down no plan allowance and no wallet balance. There is no per-retrieval credit cost.

No billing-gate denials

Because BYOK retrieval is uncosted, a Qdrant Knowledge node never produces the 402/403/429 DenialEnvelope that managed knowledge can. See Usage gating & limits.

Embedding may still cost

The query-embedding step uses your embedding_config. If that points at a BYOK model (for example OpenAI), the embedding is billed by that provider. If it points at a managed model, the embedding is credit-metered.

Hosted by you

Storage, indexing, and query throughput for your Qdrant are governed by your Qdrant Cloud plan or self-hosted capacity, not by ModuleX.

Browse Qdrant in the catalog

The integration catalog is the read-only discovery surface. Use it to fetch Qdrant’s metadata, actions, and auth schema. These catalog endpoints authenticate with a Clerk JWT (the app token) rather than an mx_live_* API key, and still require X-Organization-ID and the owner/admin role.
provider_name
string
required
qdrant.
Response200 OK, an IntegrationDetail:
name
string
qdrant.
display_name
string
Qdrant.
integration_type
string
knowledge_provider.
categories
string[]
["Vector Database", "semantic-search"].
actions
object[]
The catalog actions Qdrant declares — query, list_collections, get_collection_info. See Catalog actions.
auth_schemas
object[]
The single custom “Qdrant Connection” schema, with its fields (url, api_key) and a test_endpoint.
docs_url
string | null
null for Qdrant (the package/JSON manifest carries app_url https://qdrant.tech but no docs_url).
metadata
object | null
The integration’s extra_metadata. Note provider_type (external) is present in the source manifest but is dropped on sync and is not returned by the catalog API.
Knowledge-provider auth schemas use a fields array (not the setup_environment_variables array used by LLM/tool manifests). The catalog returns auth_schemas verbatim, so when you read a knowledge-provider detail, look for fields.
curl https://api.modulex.dev/integrations/knowledge-providers/qdrant \
  -H "Authorization: Bearer <clerk_jwt_token>" \
  -H "X-Organization-ID: 11111111-1111-1111-1111-111111111111"

Catalog actions

Qdrant declares three actions in its manifest. These describe the operations the provider exposes; in practice they are driven by the Knowledge node (query) and used for connection discovery (list_collections, get_collection_info).

Errors and edge cases

Missing collection_name
configuration error
A Qdrant Knowledge node without collection_name fails with a configuration error before any call to Qdrant.
Missing embedding_config
configuration error
Qdrant requires a query vector. Without embedding_config, the node fails with an error asking you to configure integration_name, provider_id, model_id, and optionally credential_id.
Credential not found
run error
If the credential_id does not resolve in the current organization, the node fails with a credential-not-found error. Confirm the credential belongs to the org set in X-Organization-ID.
Invalid API key (401)
authentication error
Qdrant returning 401 surfaces as an authentication error (“Invalid API key”). Re-check the api_key in your credential.
Collection not found (404)
query error
Qdrant returning 404 for the search surfaces as a query error (Collection not found: {name}). Verify the collection exists on that instance.
Connection failure
connection error
If ModuleX cannot reach the Qdrant URL, the node fails with a connection error. Confirm the URL, port (6333 by default), and that the instance is reachable from ModuleX.
Dimension mismatch
upstream error
If the query vector’s dimension does not match the collection’s vector size, Qdrant rejects the search. Use an embedding model whose dimension matches the collection.
These errors arise inside a workflow run, so they appear as node/run errors in the run stream rather than as a top-level HTTP error envelope. For the error-envelope shapes on the REST surface, see Errors & status codes.

Managing the credential

Day-to-day operations use the standard credentials API. For Qdrant specifically:
  • Rotate the URL or key. Secrets are immutable through PUT /credentials/{id} (that route updates only display_name and metadata). To change the URL or API key, create a new Qdrant credential and delete the old one.
  • Set the default. POST /credentials/{id}/set-default makes one Qdrant credential the organization default, used when a node resolves to the default.
  • Test a saved connection. POST /credentials/{id}/test re-runs Qdrant’s test endpoint against the stored URL and key.
  • Delete. DELETE /credentials/{id} removes it and returns 204. Knowledge nodes pointing at it will fail credential resolution until another valid Qdrant credential exists.
See Managing credentials for the app workflow and Credentials & OAuth2 for the complete API.

Where to go next

Knowledge providers

Compare Qdrant with modulexdb and the other external vector stores.

modulexdb (managed)

The credit-metered, ModuleX-hosted alternative that ingests and embeds for you.

Knowledge node

Configure retrieval inside a workflow, including external providers like Qdrant.

Knowledge & RAG

How ModuleX retrieves company knowledge — managed and BYOK.