Build with PerceptDB
The live multimodal data cloud. Store objects, embeddings, events, and metadata — query with SQL, API, CLI, or natural language.
Quickstart
A complete pipeline — here, from an RTSP camera — to natural-language search. The same flow works for logs, sensors, audio, and any other stream.
Sign up at perceptdb.com, pick a plan, and grab an API key from Settings → API keys.
export PERCEPT_KEY="pk_live_…" # Settings → API keys
In the console: Streams → New stream → paste an RTSP/HLS URL (cameras) — capture and perception start automatically. For logs, sensors, or events, push JSON with the stream's ingest token:
curl -X POST https://perceptdb.com/api/v1/streams/{streamId}/events \
-H "Authorization: Bearer pk_strm_…" \
-H "Content-Type: application/json" \
-d '{"body": "FATAL: connection pool exhausted", "payload": {"service": "api"}}'curl -X POST https://perceptdb.com/api/v1/objects \
-H "Authorization: Bearer $PERCEPT_KEY" \
-d '{"filename": "dock-cam.mp4", "mimeType": "video/mp4"}'
# → PUT your bytes to the returned uploadUrl, then:
curl -X POST https://perceptdb.com/api/v1/objects/{objectId}/complete \
-H "Authorization: Bearer $PERCEPT_KEY"curl -X POST https://perceptdb.com/api/v1/search \
-H "Authorization: Bearer $PERCEPT_KEY" \
-d '{"query": "person carrying a package near the entrance"}'Console → Alerts → New alert. Pick a ready-made preset (after-hours person, error in logs, sensor over limit…) or describe a custom watch in plain English — matches notify you by bell + Discord.
Core concepts
Five primitives. Everything is built from these.
SDKs
Official Python and TypeScript SDKs are in development. The REST API is a plain JSON interface, so any HTTP client works today:
Python (requests)
import requests
r = requests.post(
"https://perceptdb.com/api/v1/search",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"query": "person carrying a package near the entrance"},
)
hits = r.json()["hits"]TypeScript (fetch)
const r = await fetch("https://perceptdb.com/api/v1/search", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.PERCEPT_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({ query: "person in a red hoodie at the loading dock" }),
});
const { hits } = await r.json();Percept SQL
Postgres-compatible plus multimodal functions.
Semantic + metadata hybrid query
SELECT object, stream, caption, capture_ts,
SEMANTIC_SCORE('person carrying cardboard box') AS score
FROM frame_captions
WHERE stream ILIKE '%dock%'
AND capture_ts > NOW() - INTERVAL '24 hours'
ORDER BY score DESC NULLS LAST
LIMIT 20;Time-window event query
SELECT s.name AS stream, e.event_type, e.count, e.created_at
FROM object_events e
JOIN streams s ON s.id = e.stream_id
WHERE e.event_type = 'person_present'
AND (e.created_at AT TIME ZONE 'America/Los_Angeles')
> (NOW() AT TIME ZONE 'America/Los_Angeles')::date
ORDER BY e.created_at DESC;What you can query
REST API
Base URL: https://perceptdb.com/api/v1 · auth via Authorization: Bearer <api key>
/v1/searchSemantic search across text + video frames/v1/sqlRead-only SQL over your project views (SEMANTIC_SCORE supported)/v1/objectsList objects/v1/objectsStart an upload (returns a presigned PUT URL)/v1/objects/{id}/completeFinish an upload — perception runs automatically/v1/objects/{id}Object metadata + download URL/v1/eventsQuery derived perception events/v1/indexesVector index stats/v1/streams/{id}/eventsPush events to a stream (per-stream ingest token)/v1/streams/{id}/webhookWebhook ingest (Slack, GitHub, custom)CLI
A percept CLI is in development. Until it ships, everything is available through the console and the REST API above — the API examples in the Quickstart cover the same flows (upload, ingest, search, SQL).