API documentation
Identify movies by frame or text description — directly from your app, extension or bot. One HTTP request, JSON response with full movie metadata and confidence score.
Quickstart
- 1
Get a key
Open the developer dashboard and submit a request. A key is issued immediately — but in "pending" status.
- 2
Wait for activation
We'll contact you for activation and payment. Then status becomes "active".
- 3
Make your first call
Pass the key as Authorization: Bearer header and POST to /v1/identify.
curl -X POST https://bdkino.com/api/v1/identify \
-H "Authorization: Bearer bdk_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"description": "robot collects garbage on an abandoned Earth",
"lang": "en"
}'Authentication
Every request must contain an Authorization header with an active key. Without it — 401.
Authorization: Bearer bdk_live_xxxxxxxxxxxx- Keep the key on the server only
- Always use HTTPS
- Rotate keys every 6 months
- Never expose the key in frontend / git / Discord
- No plain HTTP — HTTPS only
- Don't share keys between projects — get a separate one
Endpoint: identify a movie
https://bdkino.com/api/v1/identifyAccepts an image (base64) and/or text description. Returns matches from the bdkino database sorted by confidence.
Request parameters
| Field | Type | Required | Description |
|---|---|---|---|
| image_base64 | string | one of* | JPEG/PNG/WebP in base64, up to 15 MB. |
| description | string | one of* | Scene description, 3–2000 chars. |
| lang | string | — | Response metadata language: "en" or "ru". Default "en". |
* At least one — image_base64 OR description must be provided (both allowed).
Example: search by description
curl -X POST https://bdkino.com/api/v1/identify \
-H "Authorization: Bearer bdk_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"description": "robot collects garbage on an abandoned Earth",
"lang": "en"
}'Example: search by frame
# Encode JPEG/PNG/WebP as base64 and put it in place of <BASE64>
curl -X POST https://bdkino.com/api/v1/identify \
-H "Authorization: Bearer bdk_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"image_base64": "<BASE64>",
"lang": "en"
}'Response format
{
"found": true,
"source": "text",
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"results": [
{
"id": 10681,
"media_type": "movie",
"title": "WALL·E",
"year": 2008,
"overview": "In the distant future, a small waste-collecting robot...",
"poster_url": "https://bdkino.com/api/img/w500/hbhFnRzhIxs...",
"blur_b64": "data:image/webp;base64,UklGRk...",
"vote_average": 8.0,
"vote_count": 19234,
"popularity": 87.5,
"confidence": 0.91,
"genres": ["Animation", "Family", "Sci-Fi"],
"keywords": ["robot", "earth", "garbage", "love"],
"cast": ["Ben Burtt", "Elissa Knight", "Jeff Garlin"],
"directors": ["Andrew Stanton"],
"origin_country": ["US"],
"original_language": "en",
"tagline": "An adventure beyond the ordinary world.",
"runtime": 98,
"age_rating": "G",
"collection_id": null,
"collection_name": null
}
],
"fallback_url": "https://bdkino.com/search"
}Field reference
| Field | Type | Description |
|---|---|---|
| found | boolean | true if at least one result |
| source | string | How matched: "phash", "clip", "text" or "cinemind" |
| results | array | Array of matches (≤ 5), sorted by confidence DESC |
| id | integer | Movie ID in bdkino database |
| media_type | string | "movie" / "tv" |
| confidence | float (0–1) | Confidence: ≥ 0.85 — almost always correct |
| genres | string[] | Genres in lang |
| keywords | string[] | Search tags |
| cast | string[] | Up to 10 cast (top-billed) |
| directors | string[] | Directors |
| tagline | string | null | Tagline in lang |
| runtime | integer | null | Runtime in minutes (movie only) |
| age_rating | string | null | MPAA / TV-rating (US) |
| collection_id | integer | null | Collection ID if part of one |
| fallback_url | string | Search page URL when found=false |
Feedback: help train the AI
Each /v1/identify call returns a request_id in the response. Send it back with a vote (correct / wrong) — this goes into the Cinemind training set. A free feedback loop that improves accuracy for everyone.
https://bdkino.com/api/v1/identify/feedbackRequest parameters
| Field | Type | Description |
|---|---|---|
| request_id | UUID | From /v1/identify response (request_id field). Required. |
| vote | "yes" | "no" | "yes" — correct match, "no" — wrong. Required. |
| id | integer | ID of specific result if response had multiple. Default — top. |
| media_type | "movie" | "tv" | Optional. Default from top. |
| comment | string | Optional. Up to 300 chars. Reaches admin if vote=no. |
Example
curl -X POST https://bdkino.com/api/v1/identify/feedback \
-H "Authorization: Bearer bdk_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-H "Accept-Language: en" \
-d '{
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"vote": "yes",
"id": 603,
"media_type": "movie"
}'Response
{
"ok": true,
"vote": "yes",
"training_pair_added": true,
"message": "Thanks! Your vote helps train the AI."
}💎 Why it matters
Every "correct" vote adds a positive training pair, every "wrong" — a negative one. After a few months these pairs go into Cinemind v2 fine-tune — the model becomes more accurate on your queries. Win-win.
Error codes
All errors return JSON of the form {"detail":"<error_code>"}.
SuccessEven when found=false this is still 200.
provide_image_or_description / query_looks_invalidNo image and no description; invalid base64; or the description is gibberish.
invalid_api_keyKey missing, doesn't exist or revoked.
api_key_not_paid / api_key_expiredKey subscription is not paid or has expired. Activate/renew your plan in /developer.
api_key_pending_activationKey not yet activated / rejected by admin.
image_too_large / description_too_longimage_too_large: image > 15 MB · description_too_long: description > 2000 chars.
rate_limitedHourly limit exceeded. Wait until the next hour and retry (exponential backoff).
server_errorTransient. Retry with exponential backoff.
Limits & behavior
| Default rate limit | 120 req / hour / key |
| Image size | ≤ 15 MB |
| Description size | 3 – 2000 chars |
| Request timeout | ≤ 30 s (text) / ≤ 60 s (image) |
| Results per call | ≤ 5 |
| Server-side response cache | none — cache on your side |
| Availability | 99.5 % monthly SLA |
On 429, wait until the next hour and retry; client-side exponential backoff is recommended.
Best practices
Use exponential backoff
On 429 / 5xx wait 1s → 2s → 4s → 8s up to 60s. Don't retry 4xx (except 408/429).
Deduplicate requests
If your service can receive the same video twice — cache the response by hash(image)+description to save quota.
Compress images
1280×720 JPEG q=80 yields ~120 KB and accuracy on par with the original 4K. Resize before base64.
Check confidence
≥ 0.85 — show as a match. 0.55–0.85 — "could be:", let user confirm. < 0.55 — don't show.
Log on your side
Store the request_id from the response — helps support trace the issue faster.
Graceful degradation
If /v1/identify is unavailable — redirect to fallback_url (bdkino search page) and don't block UX.
Playground
Try it right here
Nothing to download: paste your key, type a scene description or upload a frame — and send the request straight from your browser. It hits the same domain, so it works with zero setup.
The key is stored only in this browser (localStorage) and sent directly to bdkino.
Prefer a desktop app or another tool? Alternatives below:
bdkino API Tester (GUI)
Desktop GUI: JSON highlight, request history, key saving. Requires Python 3.10+ installed.
Download .zip (Python required)Troubleshooting
PowerShell complains «Invoke-WebRequest: cannot find -X»›
curl is an alias for Invoke-WebRequest with different parameters. Use curl.exe (with extension — invokes the real binary) or native Invoke-RestMethod. Line continuation in PowerShell is backtick `, not \. See the PowerShell tab above.Getting 401 even though the key is copied in full›
Returns 413 image_too_large›
found=true but results show the wrong movie›
Requests suddenly slow (>10 sec)›
How to test locally without burning quota?›
Ready to start?
Submit a request in the developer dashboard — we'll get back within 24 hours for activation and payment.