API Documentation
Complete reference for the Danaya REST API. All endpoints require authentication unless stated otherwise.
https://api.danaya.tech/api/v1Every response uses the same envelope: success responses carry a data object, errors carry an error code and a human-readable message.
// Success
{ "success": true, "data": { /* ... */ }, "message": "..." }
// Error
{ "success": false, "error": "ERROR_CODE", "message": "Human-readable message" }Authentication
All API requests must include your API key in the X-API-Key header. API keys follow the format rs_live_*.
// Example request header
X-API-Key: rs_live_abc123def456...
// Key format: rs_live_<48 hex> (production) or rs_test_<48 hex> (test)You can generate and manage API keys from your Dashboard. Keep your keys secret and never expose them in client-side code.
API access is available on the API and Enterprise plans only. The API plan includes 100 seals per month, 100 AI analyses per month, video sealing (up to 60s), optional private media storage, and up to 5 API keys.
Authentication and quota failures return one of these codes:
// Authentication errors
401 NO_API_KEY // X-API-Key header missing
401 INVALID_API_KEY_FORMAT // not rs_live_/rs_test_ + 48 hex
401 INVALID_API_KEY // unknown or revoked key
403 API_ACCESS_DENIED // your plan has no API access
403 EMAIL_NOT_VERIFIED // verify your email first
429 RATE_LIMIT_EXCEEDED // too many requestsRate limits: for API-plan keys, the /seals and /verify endpoints are unlimited. A shared IP limiter of 300 requests per 15 minutes applies to /ai-analysis and /check-duplicate. Every authenticated response includes X-RateLimit headers.
// Rate-limit response headers
X-RateLimit-Limit-Minute: unlimited
X-RateLimit-Remaining-Minute: unlimited
X-RateLimit-Limit-Day: unlimited
// API-plan keys are unlimited on /seals and /verify.
// A shared IP limiter (300 req / 15 min) applies to
// /ai-analysis and /check-duplicate. Max 5 API keys per account.Seals
Create, list, retrieve, and delete content authenticity seals.
Each hash object accepts: hash (64 hex, required), index (required), type ("photo" or "video_frame"), and optionally phash (16 hex perceptual hash for similarity), mediaIndex and frameIndex. The markers group a video's frames by source in the report and detail view (Video 1, Frame 1, 2...). Omit them for flat numbering.
/api/v1/seals// JSON body with pre-computed SHA-256 hashes
// Hashes must be computed client-side (no file uploads)
// Max items per seal = your plan's limit (API plan = 5)
{
"name": "My Evidence",
"hashes": [
// Each hash: hash (64 hex, required), index (required),
// type ("photo" | "video_frame"), phash (optional, 16 hex,
// perceptual hash for similarity), mediaIndex / frameIndex (optional).
{ "hash": "a1b2c3d4e5f6...", "index": 0, "type": "photo", "phash": "103030b1f0e8dcd0", "mediaIndex": 0 }
],
"location": { "latitude": 48.8566, "longitude": 2.3522 },
"mediaType": "photo" // "photo" | "video" | "mixed"
}
// Sealing a VIDEO: send one "video_frame" hash per sampled frame.
// Share mediaIndex across frames of the same video, increment frameIndex,
// so the report / detail view groups them ("Video 1 - Frame 1, 2, ...").
// Two videos = mediaIndex 0 and 1. Omit the markers for flat numbering.
{
"name": "Two clips",
"hashes": [
{ "hash": "aaaa...", "index": 0, "type": "video_frame", "mediaIndex": 0, "frameIndex": 0 },
{ "hash": "bbbb...", "index": 1, "type": "video_frame", "mediaIndex": 0, "frameIndex": 1 },
{ "hash": "cccc...", "index": 2, "type": "video_frame", "mediaIndex": 1, "frameIndex": 0 }
],
"mediaType": "video"
}/api/v1/seals// Query parameters
page=1
limit=10
search="inspection" // Optional: search by name/shortId
mediaType="photo" // Optional: photo | video | mixed
sortOrder="newest" // Optional: newest | oldest
isAiGenerated="true" // Optional: filter by AI detection/api/v1/seals/:shortId{
"success": true,
"data": {
"seal": {
"shortId": "pfrr-ggjz",
"hashes": [{ "hash": "a1b2c3d4...", "index": 0, "type": "photo", "phash": "103030b1f0e8dcd0", "mediaIndex": 0 }],
"mediaType": "photo",
"timestamp": "2026-04-05T10:30:00Z",
"hmacValid": true,
"location": { "latitude": 48.8566, "longitude": 2.3522 },
"createdAt": "2026-04-05T10:30:00Z"
},
"verifyUrl": "https://danaya.tech/verify/pfrr-ggjz"
}
}/api/v1/seals/:shortId{
"success": true,
"data": null,
"message": "Seal deleted successfully"
}
// Requires a key with delete permission (API / Enterprise plans).
// Errors: 403 DELETE_NOT_ALLOWED, 404 SEAL_NOT_FOUND.
// Deleting a seal also erases any stored media + report./api/v1/seals/:shortId/certificate?lang=fr// Query parameter
lang="fr" // Optional: en (default), fr, es, zh, ar/api/v1/seals/:shortId/media// multipart/form-data
// Field name: "images" (up to 10 files)
// Header: X-API-Key: rs_live_...
images=@photo1.jpg
images=@photo2.jpg/api/v1/seals/:shortId/expiration// Set expiration (ISO 8601 date)
{
"expiresAt": "2031-04-05T00:00:00Z"
}
// Remove expiration
{
"expiresAt": null
}/api/v1/check-duplicate// Check a single hash
{
"hash": "a1b2c3d4e5f6..."
}
// Or check multiple hashes (max 50)
{
"hashes": [
"a1b2c3d4e5f6...",
"b2c3d4e5f6a1..."
]
}Capture Sessions
Capture sessions allow users to create seals via web browser by scanning a QR code from the dashboard. This enables capturing photos on any device with a browser.
Capture sessions are not available for API-only plans. Sessions expire after 15 minutes and can be reused within that time window.
/api/capture-sessions{
"sessionToken": "abc123def456...",
"expiresAt": "2025-06-15T10:45:00Z",
"expiresIn": 900
}/api/capture-sessions/validate/:token{
"user": {
"email": "user@example.com",
"name": "John Doe",
"plan": "api",
"sealsThisMonth": 12
},
"sessionToken": "abc123def456..."
}/api/capture-sessions/:token{
"isValid": true,
"isUsed": false,
"expiresAt": "2025-06-15T10:45:00Z",
"remainingSeconds": 720
}/api/capture-sessions/:token/seals{
"name": "My Photo Evidence",
"hashes": [
{ "hash": "a1b2c3...", "index": 0, "type": "photo" }
],
"location": { "latitude": 48.8566, "longitude": 2.3522, "accuracy": 10 },
"deviceInfo": { "platform": "web", "deviceId": "...", "appVersion": "web-1.0" },
"mediaType": "photo" // "photo" | "video" | "audio"
}AI Analysis
Submit images, audio, or video for AI-powered deepfake and manipulation detection.
/api/v1/ai-analysis// multipart/form-data: supports images, audio & video
Content-Type: multipart/form-data
// Form field
images: <binary file(s)>
// Supported formats:
// Images: JPEG, PNG
// Audio: MP3, WAV, AAC, OGG, FLAC, M4A
// Video: MP4, WEBMVerification
Verify the authenticity of sealed content. These endpoints are open to everyone and require no account or API key.
/api/v1/verify/:shortId{
"success": true,
"data": {
"verified": true,
"seal": {
"shortId": "pfrr-ggjz",
"timestamp": "2026-04-05T10:30:00Z",
"location": { "latitude": 48.8566, "longitude": 2.3522 },
"hmacValid": true,
"mediaType": "photo",
"hashCount": 3,
"createdAt": "2026-04-05T10:30:00Z"
}
}
}/api/v1/verify/check{
"shortId": "pfrr-ggjz",
"hash": "a1b2c3d4e5f6..." // 64 hex chars (SHA-256)
}