Demodesk
Query Demodesk recordings, transcripts, summaries, and scorecards via the public REST API for custom integrations and automations.
Demodesk API
Setup — Get Your API Key
Check .env for DEMODESK_API_KEY. If missing, follow one of the options below.
Option A: Auto-extract (if logged into Demodesk in browser)
Extract the API key from a logged-in Demodesk browser session. Falls back to Option B if cookie extraction fails.
# 1. Get session cookie from Chrome cookie store (macOS)
SESSION_COOKIE=$(sqlite3 "$HOME/Library/Application Support/Google/Chrome/Default/Cookies" \
"SELECT encrypted_value FROM cookies WHERE host_key='.demodesk.com' AND name='_demodesk_session'" 2>/dev/null)
# 2. Exchange session cookie for Bearer token
BEARER=$(curl -s -X POST "https://demodesk.com/api/v1/users/login" \
-H "Cookie: _demodesk_session=$SESSION_COOKIE" \
| python3 -c "import sys,json,base64; print(base64.b64decode(json.load(sys.stdin)['meta']['access_token']).decode())")
# 3. Extract auth headers from decoded Bearer bundle
ACCESS_TOKEN=$(echo "$BEARER" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['access_token'])")
CLIENT=$(echo "$BEARER" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['client'])")
UID_VAL=$(echo "$BEARER" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['uid'])")
# 4. Fetch existing API key (or generate new one)
API_KEY=$(curl -s "https://demodesk.com/api/v1/users/show_api_key" \
-H "access-token: $ACCESS_TOKEN" -H "client: $CLIENT" -H "uid: $UID_VAL" -H "token-type: Bearer" \
| python3 -c "import sys,json; print(json.load(sys.stdin)['api_key'])")
# 5. Save to .env
echo "export DEMODESK_API_KEY=$API_KEY" >> .env
grep -qxF '.env' .gitignore 2>/dev/null || echo '.env' >> .gitignore
Note: Chrome cookie decryption is OS-dependent (macOS uses Keychain, Linux uses DPAPI/kwallet). Attempt this best-effort and fall back to Option B on failure.
Option B: Copy from settings
- Open https://demodesk.com/manage/settings/internet-accounts#:~:text=API%20Key
- Click the eye icon to reveal the key (or "Generate API Key" if you're an admin)
- Save it:
echo 'export DEMODESK_API_KEY=paste-your-key-here' >> .env
grep -qxF '.env' .gitignore 2>/dev/null || echo '.env' >> .gitignore
Option C: Manual navigation
Settings > Integrations > Connections > scroll to the API Key section.
Important
- The
exportkeyword is required in.env— without it,source .envsets the variable but subprocesses (likecurl) won't see it. - Always add
.envto.gitignoreif not already there. - The API key inherits permissions from the user who created it. Admin keys have company-wide access.
Loading the Key
source .env && curl -s -H "api-key: $DEMODESK_API_KEY" "https://demodesk.com/api/v2/recordings?limit=5"
Always verify the key is non-empty after sourcing: [ -z "$DEMODESK_API_KEY" ] && echo "Key missing" && exit 1
Known Gotchas
- Rate limit errors return
{"error":{"code":"invalid_api_key"}}not 429. If the key worked before, wait 60 seconds and retry. Don't assume the key is wrong. - Filter brackets need URL-encoding: use
%5B/%5Dinstead of[/]. - Always capture response to
$RESPbefore piping to jq — error responses crash jq. - No
/usersendpoint — get the meeting owner via the recording detail endpoint and filter forpermission:"host"in the participants array.
Live API Reference
For endpoint schemas, filters, and response fields, fetch the live OpenAPI spec:
curl -s https://demodesk.com/api/docs/v2/generated.yaml | head -500
Never rely on memorized schemas — always check the live spec for current field names, filter parameters, enum values, and rate limits.
Quick Reference (paths only)
| Endpoint | Method | Path |
|---|---|---|
| List recordings | GET | /api/v2/recordings |
| Get recording | GET | /api/v2/recordings/{token} |
| Get transcript | GET | /api/v2/recordings/{token}/transcript |
| Batch transcripts | POST | /api/v2/transcripts/batch |
| List summaries | GET | /api/v2/recordings/{token}/summaries |
| List scorecards | GET | /api/v2/recordings/{token}/scorecards |
| Upload recording | POST | /api/v1/externally_recorded_demos |
Base URLs
- V2:
https://demodesk.com/api/v2 - V1:
https://demodesk.com/api/v1
Pagination
Cursor-based. limit accepts 1–100 (default 25).
Check meta.hasNext in the response — if true, pass meta.nextCursor as the cursor= query parameter.
Recipes
1. List recent ready recordings (last 7 days)
source .env
RESP=$(curl -s -H "api-key: $DEMODESK_API_KEY" \
"https://demodesk.com/api/v2/recordings?limit=100&filter%5Bstatus%5D=ready&filter%5BcreatedAfter%5D=$(date -v-7d +%Y-%m-%d)")
echo "$RESP" | jq '.data[] | {token, title, createdAt, duration}'
2. Bulk download all recordings
source .env
CURSOR=""
while true; do
RESP=$(curl -s -H "api-key: $DEMODESK_API_KEY" \
"https://demodesk.com/api/v2/recordings?limit=100&filter%5Bstatus%5D=ready${CURSOR:+&cursor=$CURSOR}")
echo "$RESP" | jq -r '.data[] | .token' | while read -r TOKEN; do
DETAIL=$(curl -s -H "api-key: $DEMODESK_API_KEY" \
"https://demodesk.com/api/v2/recordings/$TOKEN")
URL=$(echo "$DETAIL" | jq -r '.temporaryDirectUrl // empty')
[ -n "$URL" ] && wget -q -O "${TOKEN}.mp4" "$URL"
sleep 1 # rate-limit aware
done
HAS_NEXT=$(echo "$RESP" | jq -r '.meta.hasNext')
[ "$HAS_NEXT" != "true" ] && break
CURSOR=$(echo "$RESP" | jq -r '.meta.nextCursor')
done
3. Get transcript (plaintext + translated)
source .env
# English plaintext
RESP=$(curl -s -H "api-key: $DEMODESK_API_KEY" \
"https://demodesk.com/api/v2/recordings/TOKEN/transcript?format=plaintext")
echo "$RESP" | jq -r '.text'
# German translation
RESP=$(curl -s -H "api-key: $DEMODESK_API_KEY" \
"https://demodesk.com/api/v2/recordings/TOKEN/transcript?format=plaintext&lang=de")
echo "$RESP" | jq -r '.text'
Note: If the transcript is still processing, the API returns 202 — wait and retry.
4. Batch fetch transcripts (up to 100 tokens)
source .env
RESP=$(curl -s -X POST -H "api-key: $DEMODESK_API_KEY" \
-H "Content-Type: application/json" \
-d '{"recordingTokens": ["token1", "token2", "token3"]}' \
"https://demodesk.com/api/v2/transcripts/batch")
echo "$RESP" | jq '.data'
5. Get meeting owner name
source .env
RESP=$(curl -s -H "api-key: $DEMODESK_API_KEY" \
"https://demodesk.com/api/v2/recordings/TOKEN")
echo "$RESP" | jq '.participants[] | select(.permission == "host") | .name'
V1: Upload External Recordings
source .env
curl -s -X POST -H "api-key: $DEMODESK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "External Call",
"recording_url": "https://example.com/recording.mp4",
"scheduled_at": "2025-01-15T10:00:00Z"
}' \
"https://demodesk.com/api/v1/externally_recorded_demos"
Webhooks
Not self-serve. Email support@demodesk.com with your endpoint URL.
Available events: demo.scheduled, demo.rescheduled, demo.canceled, demo.started, demo.ended, recording.uploaded, recording.transcription_postprocessed, and more.
Workflow for AI Assistants
- Check
.envforDEMODESK_API_KEY— if missing, run the setup flow above. source .envand verify the key is non-empty.- Fetch the live OpenAPI spec if you need schema details for fields, filters, or enums.
- Use
curl -sand capture the response to a$RESPvariable first. - Check for errors before piping through
jq. - Use
limit=100and filter client-side when possible (rate-limit aware). - URL-encode filter brackets (
%5B/%5D). - Handle rate limits:
invalid_api_keyerror but key worked before → wait 60 seconds. - Handle 202 responses (transcript still processing) → wait and retry.
- Handle pagination: check
meta.hasNext, usemeta.nextCursor.
Skills y Connections relacionados
¿Quieres integración CRM sin interrupciones con contexto de reuniones en tiempo real? Prueba Demodesk gratis