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

# Create Transcription

> Programmatically create [AI Transcriptions](https://easy-peasy.ai/audios) from audio files.

## Complete workflow

Transcription is asynchronous — after submitting an audio file, you need to poll for results. Here's the full workflow:

### Step 1: Submit audio for transcription

Submit a publicly downloadable audio URL with this endpoint. A paid subscription and remaining monthly transcription allowance are required. The response includes a `uuid` you'll need for the next steps.

<Note>
  Transcription typically takes **1–5 minutes** depending on audio length. Save the `uuid` from the response.
</Note>

### Step 2: Poll for results

Use [Get Transcription Result](/docs/api-reference/endpoint/get-transcription) with the same account's API key. **Poll every 15–30 seconds** while `transcription_status` is `processing`.

API-key responses return `content`, `segments`, and `transcription_status` **at the top level**, without an `audio` wrapper. `done` means complete even if no speech was detected and `content` is empty. Stop on `failed`. Older records may contain transcript text without a status.

The following Node.js 20+ example stops after ten minutes. Keep the UUID if it times out so you can check the existing job later.

```javascript theme={null}
async function waitForTranscription(uuid, apiKey) {
  const deadline = Date.now() + 10 * 60 * 1000;

  while (Date.now() < deadline) {
    const response = await fetch('https://easy-peasy.ai/api/audios', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': apiKey,
      },
      body: JSON.stringify({ audio_id: uuid }),
      signal: AbortSignal.timeout(Math.max(1, Math.min(30000, deadline - Date.now()))),
    });
    const data = await response.json().catch(() => null);

    if (!response.ok) {
      throw new Error(`Transcription ${uuid}: HTTP ${response.status}: ${data?.error || 'Could not retrieve transcription'}`);
    }
    if (!data || data.uuid !== uuid) {
      throw new Error(`Unexpected response for transcription ${uuid}`);
    }
    if (data.transcription_status === 'failed') {
      throw new Error(`Transcription ${uuid} failed`);
    }
    if (data.transcription_status === 'done' ||
        (!data.transcription_status && data.content)) {
      return data;
    }
    if (data.transcription_status && data.transcription_status !== 'processing') {
      throw new Error(`Unknown transcription status: ${data.transcription_status}`);
    }

    await new Promise(resolve => setTimeout(resolve, Math.max(0, Math.min(15000, deadline - Date.now()))));
  }

  throw new Error(`Timed out waiting for transcription ${uuid}. Keep this UUID and check it later.`);
}
```

### Step 3: Generate AI content (optional)

Once the transcription is complete, use [Generate Audio Content](/docs/api-reference/endpoint/generate-audio-content) to create summaries, titles, action items, and more.

```bash theme={null}
curl -X POST https://easy-peasy.ai/api/generate-audio-content \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{"audio_id": "YOUR_AUDIO_UUID"}'
```

You can also generate specific fields only:

```bash theme={null}
curl -X POST https://easy-peasy.ai/api/generate-audio-content \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "audio_id": "YOUR_AUDIO_UUID",
    "fields": ["summary", "title", "keywords"]
  }'
```

**Content generated depends on the audio type:**

| Audio Type          | Fields                                                                                                                                                   |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Meeting**         | summary, title, description, action items, keywords, timestamped overview, topics & bullets, LinkedIn post                                               |
| **Podcast**         | summary, title, description, show notes, Twitter thread, article, newsletter, keywords, questions, LinkedIn post, timestamped overview, topics & bullets |
| **Therapy Session** | summary, title, description, progress note, SOAP note, DAP note, keywords, timestamped overview, topics & bullets, LinkedIn post                         |


## OpenAPI

````yaml POST /api/transcriptions
openapi: 3.0.1
info:
  title: Easy-Peasy.AI API
  description: >-
    API for Easy-Peasy.AI text, image, video, audio, and chat features.
    Authenticate with an API key from https://easy-peasy.ai/settings/api.
    Individual endpoints document public access and alternative authentication
    methods.
  version: 1.0.5
servers:
  - url: https://easy-peasy.ai
security:
  - apiKeyAuth: []
paths:
  /api/transcriptions:
    post:
      summary: Create Transcription
      description: >-
        Programmatically create [AI
        Transcriptions](https://easy-peasy.ai/audios) from audio files.
      operationId: createTranscription
      requestBody:
        description: The audio parameters to create transcriptions
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TranscriptionRequest'
      responses:
        '200':
          description: Successful transcription creation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TranscriptionResponse'
        '400':
          description: Bad request - missing required fields or invalid values
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: Invalid input
        '401':
          description: Missing or invalid API key, or blocked account.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Paid subscription required or monthly transcription limit reached.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: Server error
components:
  schemas:
    TranscriptionRequest:
      type: object
      required:
        - url
      properties:
        audio_type:
          type: string
          description: The type of audio (e.g., podcast, meeting)
          example: podcast
        language:
          type: string
          description: The language of the audio (e.g., English, Chinese, French)
          example: English
        name:
          type: string
          description: The name of the transcription
          example: Interview with John Doe
        detect_speakers:
          type: boolean
          description: Whether to detect multiple speakers
          example: true
          default: true
        enhanced_quality:
          type: boolean
          description: Whether to use enhanced quality for transcription
          example: true
        url:
          type: string
          description: The URL of the audio file
          example: https://example.com/audiofile.mp3
    TranscriptionResponse:
      type: object
      properties:
        uuid:
          type: string
          description: Unique identifier for the created transcription
          example: 4bc4e8ee-f29e-4a53-996e-5da955c42927
        dashboard_url:
          type: string
          description: URL of the generated transcription
          example: https://easy-peasy.ai/audios/4bc4e8ee-f29e-4a53-996e-5da955c42927
    Error:
      type: object
      properties:
        error:
          oneOf:
            - type: string
            - type: object
              properties:
                message:
                  type: string
                status:
                  type: integer
          description: >-
            Error text, or an object with message and optional status for some
            provider integrations.
          example: Invalid API key
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        API key for authentication. Get yours at
        https://easy-peasy.ai/settings/api

````