Developers

Use this API to queue a video transcript job, check job status, and fetch transcript text when processing is complete.

Before You Start

  • API key is required for all transcript endpoints (x-api-key header).
  • Get your API key from the Dashboard after account verification.
  • A queued job can take up to 15 minutes to complete.

Rate Limits

All endpoints are rate-limited per API key to ensure fair usage:

EndpointLimitWindow
/api/transcripts/enqueue4 requestsper hour
/api/transcripts/status60 requestsper minute
/api/transcripts/result20 requestsper minute
/api/transcripts/jobs20 requestsper minute

When a rate limit is exceeded, the API returns HTTP 429 Too Many Requests. We recommend polling status every 5-10 seconds rather than continuously.

1. Queue a Job

Endpoint: POST /api/transcripts/enqueue

Required headers:

x-api-key: YOUR_API_KEY
Content-Type: application/json

Request body parameters:

{
  "youtubeUrl": "https://youtu.be/VIDEO_ID",
  "userEmail": "verified-user@example.com"
}

Expected success response:

{
  "ok": true,
  "jobId": "UUID",
  "status": "pending",
  "remainingInWindow": 3,
  "developerGuideUrl": "https://transcript.vibecodingacademy.club/developer-guide"
}

Save jobId. You need it to check status and get transcript.

2. Check Job Status

Endpoint: GET /api/transcripts/status?jobId=JOB_ID&userEmail=VERIFIED_EMAIL

Required header:

x-api-key: YOUR_API_KEY

Expected response:

{
  "ok": true,
  "jobId": "UUID",
  "status": "pending | completed | failed",
  "error": null,
  "createdAt": "...",
  "updatedAt": "..."
}

3. Get Transcript (When Complete)

Endpoint: GET /api/transcripts/result?jobId=JOB_ID&userEmail=VERIFIED_EMAIL

Required header:

x-api-key: YOUR_API_KEY

Expected success response:

{
  "ok": true,
  "jobId": "UUID",
  "transcript": "Full transcript text...",
  "updatedAt": "..."
}

If status is not complete yet, the endpoint returns HTTP 409 with a not-ready response.

4. List All Jobs

Endpoint: GET /api/transcripts/jobs?userEmail=VERIFIED_EMAIL

Required header:

x-api-key: YOUR_API_KEY

Expected response:

{
  "jobs": [
    {
      "jobId": "UUID",
      "youtubeUrl": "https://youtu.be/VIDEO_ID",
      "status": "completed",
      "transcript": "Full transcript text...",
      "error": null,
      "createdAt": "...",
      "updatedAt": "..."
    }
  ]
}

5. Webhooks (Optional)

Instead of polling for job status, configure a webhook to receive notifications when jobs complete. Set up your webhook URL in the Dashboard.

Webhook Payload

When a job completes (or fails), we POST to your webhook URL:

{
  "event": "job.completed",  // or "job.failed"
  "jobId": "UUID",
  "youtubeUrl": "https://youtu.be/VIDEO_ID",
  "status": "completed",
  "transcript": "Full transcript text...",  // null if failed
  "error": null,  // error message if failed
  "completedAt": "2024-01-15T10:30:00Z"
}

Signature Verification

Every webhook request includes a signature header for security. Always verify the signature before processing the payload.

Headers sent with each webhook:

X-Webhook-Signature: t=1704567890,v1=5257a869e7...
X-Webhook-Timestamp: 1704567890
Content-Type: application/json

Verifying the Signature

The signature uses HMAC-SHA256. Here's how to verify it:

// Node.js / TypeScript example
import { createHmac } from "crypto";

function verifyWebhookSignature(
  payload: string,        // raw request body
  signatureHeader: string, // X-Webhook-Signature header
  secret: string          // your webhook secret (whsec_...)
): boolean {
  // Parse the signature header
  const parts = signatureHeader.split(",");
  const timestamp = parts.find(p => p.startsWith("t="))?.slice(2);
  const signature = parts.find(p => p.startsWith("v1="))?.slice(3);
  
  if (!timestamp || !signature) return false;
  
  // Check timestamp is within 5 minutes
  const now = Math.floor(Date.now() / 1000);
  if (Math.abs(now - parseInt(timestamp)) > 300) return false;
  
  // Compute expected signature
  const signedPayload = `${timestamp}.${payload}`;
  const expected = createHmac("sha256", secret)
    .update(signedPayload)
    .digest("hex");
  
  // Compare signatures (timing-safe)
  return signature === expected;
}

Webhook Best Practices

  • Always verify the signature before processing
  • Respond with 2xx status within 10 seconds
  • Process asynchronously if your handler takes longer
  • Store the webhook secret securely (environment variable)
  • Regenerate your secret if it's ever exposed

Error Responses

All errors return JSON with an error field:

StatusMeaning
400Invalid request (missing/invalid parameters)
401Unauthorized (invalid or missing API key)
403Forbidden (email not verified or key mismatch)
404Job not found
409Transcript not ready (job still processing)
429Rate limit exceeded
500Server error

Dashboard

On the Dashboard, each job row shows a Job ID. Click the Job ID to copy it, then use it in the status and result endpoints.