> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lyrcs.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Submit your first transcription job and download an LRC file in under 5 minutes

## Prerequisites

You'll need an API key. See [Authentication](/getting-started/authentication) for how to request one.

Set your key as an environment variable:

```bash theme={null}
export LYRCS_API_KEY="lyrcs_sk_live_..."
```

***

## Step 1: Submit a transcription job

Send an audio URL and the source language. The API returns a `job_id` immediately — processing happens asynchronously.

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://lyrcs.ai/api/v1/transcribe \
    -H "Authorization: Bearer $LYRCS_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "audio_url": "https://example.com/song.mp3",
      "language": "Tamil"
    }'
  ```

  ```javascript Node.js theme={null}
  const response = await fetch("https://lyrcs.ai/api/v1/transcribe", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.LYRCS_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      audio_url: "https://example.com/song.mp3",
      language: "Tamil",
    }),
  });

  const { job_id } = await response.json();
  console.log("Job queued:", job_id);
  ```

  ```python Python theme={null}
  import os, requests

  response = requests.post(
      "https://lyrcs.ai/api/v1/transcribe",
      headers={"Authorization": f"Bearer {os.environ['LYRCS_API_KEY']}"},
      json={
          "audio_url": "https://example.com/song.mp3",
          "language": "Tamil",
      },
  )

  job_id = response.json()["job_id"]
  print("Job queued:", job_id)
  ```
</CodeGroup>

**Response:**

```json theme={null}
{
  "job_id": "a1b2c3d4-...",
  "status": "queued",
  "language": "Tamil",
  "created_at": "2024-01-01T00:00:00.000Z",
  "review_required": false,
  "align_requested": true,
  "word_align_requested": true
}
```

<Tip>
  Use `GET /api/v1/languages` to see the exact accepted language name strings. Values are case-sensitive — `"Tamil"` works, `"tamil"` does not.
</Tip>

***

## Step 2: Poll for completion

Poll `GET /api/v1/jobs/{job_id}` until `status` is `"complete"` or `"failed"`. Jobs typically complete within 60–90 seconds.

<CodeGroup>
  ```bash curl theme={null}
  curl https://lyrcs.ai/api/v1/jobs/a1b2c3d4-... \
    -H "Authorization: Bearer $LYRCS_API_KEY"
  ```

  ```javascript Node.js theme={null}
  async function waitForJob(jobId, apiKey, { intervalMs = 10000, timeoutMs = 180000 } = {}) {
    const deadline = Date.now() + timeoutMs;

    while (Date.now() < deadline) {
      const res = await fetch(`https://lyrcs.ai/api/v1/jobs/${jobId}`, {
        headers: { Authorization: `Bearer ${apiKey}` },
      });
      const job = await res.json();

      if (job.status === "complete") return job;
      if (job.status === "failed") throw new Error("Job failed: " + jobId);

      await new Promise((r) => setTimeout(r, intervalMs));
    }

    throw new Error("Job timed out after 3 minutes");
  }

  const job = await waitForJob("a1b2c3d4-...", process.env.LYRCS_API_KEY);
  console.log("Transcript:", job.results.transcript);
  ```

  ```python Python theme={null}
  import os, time, requests

  def wait_for_job(job_id, api_key, interval=10, timeout=180):
      headers = {"Authorization": f"Bearer {api_key}"}
      deadline = time.time() + timeout

      while time.time() < deadline:
          r = requests.get(
              f"https://lyrcs.ai/api/v1/jobs/{job_id}",
              headers=headers,
          )
          job = r.json()

          if job["status"] == "complete":
              return job
          if job["status"] == "failed":
              raise RuntimeError(f"Job failed: {job_id}")

          time.sleep(interval)

      raise TimeoutError("Job timed out after 3 minutes")

  job = wait_for_job("a1b2c3d4-...", os.environ["LYRCS_API_KEY"])
  print("Transcript:", job["results"]["transcript"])
  ```
</CodeGroup>

**Response when complete:**

```json theme={null}
{
  "job_id": "a1b2c3d4-...",
  "status": "complete",
  "language": "Tamil",
  "align_requested": true,
  "word_align_requested": true,
  "created_at": "2024-01-01T00:00:00.000Z",
  "completed_at": "2024-01-01T00:01:32.000Z",
  "duration_seconds": 214,
  "studio_url": "https://lyrcs.ai/studio/a1b2c3d4-...",
  "results": {
    "transcript": "...",
    "transliteration": "...",
    "translation": "...",
    "cultural_notes": null,
    "downloads": {
      "lrc_original": "https://lyrcs.ai/api/v1/jobs/a1b2c3d4-.../download/lrc/original",
      "lrc_transliterated": "https://lyrcs.ai/api/v1/jobs/a1b2c3d4-.../download/lrc/transliterated",
      "srt_original": "https://lyrcs.ai/api/v1/jobs/a1b2c3d4-.../download/srt/original",
      "srt_transliterated": "https://lyrcs.ai/api/v1/jobs/a1b2c3d4-.../download/srt/transliterated",
      "words_original": "https://lyrcs.ai/api/v1/jobs/a1b2c3d4-.../download/words/original",
      "words_transliterated": "https://lyrcs.ai/api/v1/jobs/a1b2c3d4-.../download/words/transliterated"
    }
  }
}
```

***

## Step 3: Download lyric files

Use any of the download URLs from `results.downloads`. Authentication is required. In addition to LRC and SRT, `words_original` and `words_transliterated` contain per-word timestamps as a JSON array — useful for word-by-word karaoke highlight.

<CodeGroup>
  ```bash curl theme={null}
  curl https://lyrcs.ai/api/v1/jobs/a1b2c3d4-.../download/lrc/original \
    -H "Authorization: Bearer $LYRCS_API_KEY" \
    -o song.lrc
  ```

  ```javascript Node.js theme={null}
  const lrcUrl = job.results.downloads.lrc_original;
  const res = await fetch(lrcUrl, {
    headers: { Authorization: `Bearer ${process.env.LYRCS_API_KEY}` },
  });
  const lrcText = await res.text();
  // lrcText is a standard LRC file ready for delivery
  ```

  ```python Python theme={null}
  lrc_url = job["results"]["downloads"]["lrc_original"]
  r = requests.get(
      lrc_url,
      headers={"Authorization": f"Bearer {os.environ['LYRCS_API_KEY']}"},
  )
  with open("song.lrc", "w") as f:
      f.write(r.text)
  ```
</CodeGroup>

The response is a plain-text `.lrc` file with `Content-Disposition: attachment`.

***

## What's next

<CardGroup cols={2}>
  <Card title="Three API Modes" icon="sliders" href="/guides/three-api-modes">
    When to use align=false, review=true, or the default pipeline.
  </Card>

  <Card title="Webhooks" icon="webhook" href="/guides/webhooks">
    Receive events instead of polling. Covers all 5 event types and signature verification.
  </Card>

  <Card title="Batch Processing" icon="layer-group" href="/guides/batch-processing">
    Submit up to 20 jobs at once with a single webhook on completion.
  </Card>

  <Card title="Error Reference" icon="triangle-exclamation" href="/errors">
    All error codes, HTTP statuses, and rate limit headers.
  </Card>
</CardGroup>
