| name | qdrant |
| category | data |
| description | Manage Qdrant vector database via REST API. Use when the user asks to create or delete collections, upsert or search vectors, inspect points, filter by payload fields, manage snapshots, check cluster status, or debug semantic search issues. Covers collection CRUD, point upsert/search/scroll/count, payload indexes, filtering (must/should/must_not), recommend, discover, snapshots, aliases, and cluster operations.
|
| compatibility | Requires curl and a running Qdrant instance (default http://localhost:6333) |
| metadata | {"author":"zeph","version":"1.0"} |
Qdrant Vector Database
Base URL: http://localhost:6333 (default). Override with QDRANT_URL env var.
All examples use curl. Replace localhost:6333 with the actual Qdrant endpoint.
Quick Reference
| Task | Endpoint |
|---|
| List collections | GET /collections |
| Create collection | PUT /collections/{name} |
| Delete collection | DELETE /collections/{name} |
| Collection info | GET /collections/{name} |
| Upsert points | PUT /collections/{name}/points |
| Search | POST /collections/{name}/points/search |
| Scroll (paginate) | POST /collections/{name}/points/scroll |
| Get point | GET /collections/{name}/points/{id} |
| Delete points | POST /collections/{name}/points/delete |
| Count points | POST /collections/{name}/points/count |
| Health check | GET /healthz |
Collections
List all collections
curl -s http://localhost:6333/collections | jq
Create collection
curl -s -X PUT http://localhost:6333/collections/my_collection \
-H "Content-Type: application/json" \
-d '{
"vectors": {
"size": 384,
"distance": "Cosine"
}
}' | jq
Distance metrics: Cosine, Euclid, Dot, Manhattan.
Create collection with named vectors
curl -s -X PUT http://localhost:6333/collections/my_collection \
-H "Content-Type: application/json" \
-d '{
"vectors": {
"content": {"size": 384, "distance": "Cosine"},
"title": {"size": 128, "distance": "Cosine"}
}
}' | jq
Collection info
curl -s http://localhost:6333/collections/my_collection | jq
Key fields: vectors_count, points_count, segments_count, status (green/yellow/red).
Delete collection
curl -s -X DELETE http://localhost:6333/collections/my_collection | jq
Check collection exists
curl -sI http://localhost:6333/collections/my_collection -o /dev/null -w "%{http_code}"
Points
Upsert points (insert or update)
curl -s -X PUT http://localhost:6333/collections/my_collection/points \
-H "Content-Type: application/json" \
-d '{
"points": [
{
"id": 1,
"vector": [0.1, 0.2, 0.3, ...],
"payload": {"title": "Example", "category": "test", "score": 0.95}
},
{
"id": 2,
"vector": [0.4, 0.5, 0.6, ...],
"payload": {"title": "Another", "category": "prod", "score": 0.87}
}
]
}' | jq
Point IDs can be integers or UUIDs.
Upsert with named vectors
curl -s -X PUT http://localhost:6333/collections/my_collection/points \
-H "Content-Type: application/json" \
-d '{
"points": [
{
"id": 1,
"vector": {
"content": [0.1, 0.2, ...],
"title": [0.3, 0.4, ...]
},
"payload": {"title": "Example"}
}
]
}' | jq
Get point by ID
curl -s http://localhost:6333/collections/my_collection/points/1 | jq
Get multiple points
curl -s -X POST http://localhost:6333/collections/my_collection/points \
-H "Content-Type: application/json" \
-d '{"ids": [1, 2, 3]}' | jq
Delete points by ID
curl -s -X POST http://localhost:6333/collections/my_collection/points/delete \
-H "Content-Type: application/json" \
-d '{"points": [1, 2, 3]}' | jq
Delete points by filter
curl -s -X POST http://localhost:6333/collections/my_collection/points/delete \
-H "Content-Type: application/json" \
-d '{
"filter": {
"must": [
{"key": "category", "match": {"value": "obsolete"}}
]
}
}' | jq
Count points
curl -s -X POST http://localhost:6333/collections/my_collection/points/count \
-H "Content-Type: application/json" \
-d '{}' | jq '.result.count'
curl -s -X POST http://localhost:6333/collections/my_collection/points/count \
-H "Content-Type: application/json" \
-d '{
"filter": {
"must": [{"key": "category", "match": {"value": "test"}}]
},
"exact": true
}' | jq '.result.count'
Search
Basic vector search
curl -s -X POST http://localhost:6333/collections/my_collection/points/search \
-H "Content-Type: application/json" \
-d '{
"vector": [0.1, 0.2, 0.3, ...],
"limit": 10,
"with_payload": true,
"with_vector": false
}' | jq
Search with filter
curl -s -X POST http://localhost:6333/collections/my_collection/points/search \
-H "Content-Type: application/json" \
-d '{
"vector": [0.1, 0.2, 0.3, ...],
"limit": 5,
"with_payload": true,
"filter": {
"must": [
{"key": "category", "match": {"value": "prod"}}
],
"must_not": [
{"key": "archived", "match": {"value": true}}
]
}
}' | jq
Search with score threshold
curl -s -X POST http://localhost:6333/collections/my_collection/points/search \
-H "Content-Type: application/json" \
-d '{
"vector": [0.1, 0.2, 0.3, ...],
"limit": 10,
"score_threshold": 0.7,
"with_payload": true
}' | jq
Search with named vector
curl -s -X POST http://localhost:6333/collections/my_collection/points/search \
-H "Content-Type: application/json" \
-d '{
"vector": {
"name": "content",
"vector": [0.1, 0.2, 0.3, ...]
},
"limit": 10,
"with_payload": true
}' | jq
Scroll (paginate through all points)
curl -s -X POST http://localhost:6333/collections/my_collection/points/scroll \
-H "Content-Type: application/json" \
-d '{
"limit": 100,
"with_payload": true,
"with_vector": false
}' | jq
curl -s -X POST http://localhost:6333/collections/my_collection/points/scroll \
-H "Content-Type: application/json" \
-d '{
"limit": 100,
"offset": NEXT_PAGE_OFFSET,
"with_payload": true
}' | jq
Recommend (find similar to existing points)
curl -s -X POST http://localhost:6333/collections/my_collection/points/recommend \
-H "Content-Type: application/json" \
-d '{
"positive": [1, 2],
"negative": [3],
"limit": 10,
"with_payload": true
}' | jq
Filtering
Filters use must (AND), should (OR), must_not (NOT) clauses.
Condition types
{"key": "city", "match": {"value": "Berlin"}}
{"key": "color", "match": {"any": ["red", "blue", "green"]}}
{"key": "status", "match": {"except": ["deleted", "archived"]}}
{"key": "price", "range": {"gte": 10.0, "lte": 100.0}}
{"key": "created_at", "range": {"gte": "2025-01-01T00:00:00Z"}}
{"key": "location", "geo_bounding_box": {
"top_left": {"lat": 52.52, "lon": 13.38},
"bottom_right": {"lat": 52.50, "lon": 13.42}
}}
{"key": "location", "geo_radius": {
"center": {"lat": 52.52, "lon": 13.405},
"radius": 1000.0
}}
{"has_id": [1, 2, 3]}
{"is_empty": {"key": "optional_field"}}
{"is_null": {"key": "nullable_field"}}
{"nested": {"key": "tags", "filter": {
"must": [{"key": "tags[].name", "match": {"value": "important"}}]
}}}
{"values_count": {"key": "tags", "gte": 2}}
Combined filter example
curl -s -X POST http://localhost:6333/collections/my_collection/points/search \
-H "Content-Type: application/json" \
-d '{
"vector": [0.1, 0.2, ...],
"limit": 10,
"filter": {
"must": [
{"key": "status", "match": {"value": "active"}},
{"key": "score", "range": {"gte": 0.5}}
],
"should": [
{"key": "category", "match": {"value": "A"}},
{"key": "category", "match": {"value": "B"}}
],
"must_not": [
{"is_empty": {"key": "embedding"}}
]
}
}' | jq
Payload Indexes
Create indexes on payload fields for faster filtering.
curl -s -X PUT http://localhost:6333/collections/my_collection/index \
-H "Content-Type: application/json" \
-d '{"field_name": "category", "field_schema": "keyword"}' | jq
curl -s -X PUT http://localhost:6333/collections/my_collection/index \
-H "Content-Type: application/json" \
-d '{"field_name": "score", "field_schema": "integer"}' | jq
curl -s -X PUT http://localhost:6333/collections/my_collection/index \
-H "Content-Type: application/json" \
-d '{"field_name": "price", "field_schema": "float"}' | jq
curl -s -X DELETE http://localhost:6333/collections/my_collection/index/category | jq
Index types: keyword, integer, float, bool, geo, datetime, text, uuid.
Payload Operations
Set payload on existing points
curl -s -X POST http://localhost:6333/collections/my_collection/points/payload \
-H "Content-Type: application/json" \
-d '{
"payload": {"new_field": "value", "score": 0.99},
"points": [1, 2, 3]
}' | jq
Delete payload keys
curl -s -X POST http://localhost:6333/collections/my_collection/points/payload/delete \
-H "Content-Type: application/json" \
-d '{
"keys": ["old_field", "deprecated"],
"points": [1, 2, 3]
}' | jq
Snapshots
curl -s http://localhost:6333/collections/my_collection/snapshots | jq
curl -s -X POST http://localhost:6333/collections/my_collection/snapshots | jq
curl -s -o snap.tar http://localhost:6333/collections/my_collection/snapshots/NAME
curl -s -X DELETE http://localhost:6333/collections/my_collection/snapshots/NAME | jq
Aliases
curl -s -X POST http://localhost:6333/aliases \
-H "Content-Type: application/json" \
-d '{"actions": [{"create_alias": {"alias_name": "prod", "collection_name": "v2"}}]}' | jq
curl -s http://localhost:6333/aliases | jq
Service & Health
curl -s http://localhost:6333/healthz
curl -s http://localhost:6333/ | jq
curl -s http://localhost:6333/cluster | jq
curl -s http://localhost:6333/telemetry | jq
curl -s http://localhost:6333/metrics
Common Workflows
Inspect collection health
curl -s http://localhost:6333/collections/my_collection | jq '.result.status, .result.points_count, .result.vectors_count'
curl -s http://localhost:6333/collections/my_collection | jq '.result.optimizer_status'
curl -s http://localhost:6333/collections/my_collection | jq '.result.segments_count'
Debug search quality
curl -s -X POST http://localhost:6333/collections/my_collection/points/search \
-H "Content-Type: application/json" \
-d '{
"vector": [0.1, 0.2, ...],
"limit": 5,
"with_payload": true,
"with_vector": true
}' | jq '.result[] | {id, score, payload}'
Important Notes
- Qdrant default ports: 6333 (HTTP), 6334 (gRPC)
- Point IDs are either unsigned integers or UUIDs (string format)
- Vectors must match the collection's configured dimension exactly
with_payload: true returns all payload; use with_payload: ["field1", "field2"] for specific fields
- Filters on non-indexed fields cause full scan — create payload indexes for fields used in filters
- Collection status:
green = fully optimized, yellow = optimizing, red = error
- Upsert is idempotent — re-upserting a point with the same ID overwrites it
- Scroll with
offset: null starts from the beginning
- Batch operations are more efficient than individual requests