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

# Create Recording

> Create a new recording

Create a recording to represent a captured conversation. After creation, use the upload endpoints to upload the audio file.

## Authentication

This endpoint behaves differently depending on your authentication method:

**Using [API Keys](/authentication):**

* Required: `device_id` and `end_user_id` in request body
* Use case: Mobile apps uploading on behalf of users via Bluetooth sync

**Using [Device Tokens](/authentication):**

* Required: Neither `device_id` nor `end_user_id` (automatically extracted from token)
* Use case: 4G/WiFi devices uploading directly to the cloud

See the examples below for both scenarios.

<RequestExample>
  ```bash cURL (API Key) theme={null}
  # Using API Key - include device_id and end_user_id
  curl -X POST https://api.bota.dev/v1/recordings \
    -H "Authorization: Bearer sk_live_..." \
    -H "Content-Type: application/json" \
    -d '{
      "device_id": "dev_abc123",
      "end_user_id": "eu_xyz789",
      "name": "Product interview - Jane Doe",
      "started_at": "2025-01-15T09:00:00Z",
      "ended_at": "2025-01-15T09:30:00Z",
      "metadata": {
        "meeting_type": "interview",
        "location": "office"
      }
    }'
  ```

  ```bash cURL (Device Token) theme={null}
  # Using Device Token - do NOT include device_id or end_user_id
  curl -X POST https://api.bota.dev/v1/recordings \
    -H "Authorization: Bearer dtok_..." \
    -H "Content-Type: application/json" \
    -d '{
      "started_at": "2025-01-15T09:00:00Z",
      "codec": "opus_16k"
    }'
  ```

  ```javascript Node.js theme={null}
  const response = await fetch('https://api.bota.dev/v1/recordings', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer sk_live_...',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      device_id: 'dev_abc123',
      name: 'Product interview - Jane Doe',
      started_at: '2025-01-15T09:00:00Z',
      ended_at: '2025-01-15T09:30:00Z',
      metadata: {
        meeting_type: 'interview',
        location: 'office',
      },
    }),
  });

  const recording = await response.json();
  ```

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

  response = requests.post(
      'https://api.bota.dev/v1/recordings',
      headers={
          'Authorization': 'Bearer sk_live_...',
          'Content-Type': 'application/json',
      },
      json={
          'device_id': 'dev_abc123',
          'name': 'Product interview - Jane Doe',
          'started_at': '2025-01-15T09:00:00Z',
          'ended_at': '2025-01-15T09:30:00Z',
          'metadata': {
              'meeting_type': 'interview',
              'location': 'office',
          },
      },
  )

  recording = response.json()
  ```
</RequestExample>

## Request Body

<ParamField body="device_id" type="string">
  ID of the device that captured (or will capture) the recording. Optional for API-uploaded audio files.

  **Note:** When using device tokens (`dtok_*`), this field is automatically populated from the token and should NOT be included in the request.
</ParamField>

<ParamField body="end_user_id" type="string">
  ID of the end user. Required when using API keys.

  **Note:** When using device tokens (`dtok_*`), this field is automatically populated from the token and should NOT be included in the request.
</ParamField>

<ParamField body="name" type="string">
  Optional human-readable name for the recording (e.g., "Weekly standup", "Client call with Acme").
</ParamField>

<ParamField body="started_at" type="string">
  ISO 8601 timestamp of when the recording started (device time).
</ParamField>

<ParamField body="ended_at" type="string">
  ISO 8601 timestamp of when the recording ended (device time).
</ParamField>

<ParamField body="metadata" type="object">
  Arbitrary key-value metadata (e.g., meeting type, location).
</ParamField>

## Response

Returns the created recording object.

<ResponseExample>
  ```json 201 theme={null}
  {
    "id": "rec_abc123",
    "device_id": "dev_abc123",
    "end_user_id": "eu_xyz789",
    "name": "Product interview - Jane Doe",
    "status": "pending",
    "duration_ms": null,
    "started_at": "2025-01-15T09:00:00Z",
    "ended_at": "2025-01-15T09:30:00Z",
    "transcription_id": null,
    "media": [],
    "metadata": {
      "meeting_type": "interview",
      "location": "office"
    },
    "created_at": "2025-01-15T10:00:00Z"
  }
  ```
</ResponseExample>

## Response Fields

| Field                     | Type            | Description                                                                        |
| ------------------------- | --------------- | ---------------------------------------------------------------------------------- |
| `id`                      | string          | Unique identifier for the recording (`rec_*`).                                     |
| `device_id`               | string          | ID of the device that captured the recording.                                      |
| `end_user_id`             | string          | ID of the associated end user.                                                     |
| `name`                    | string          | Human-readable name for the recording.                                             |
| `status`                  | string          | Current recording status (see below).                                              |
| `duration_ms`             | integer \| null | Recording duration in milliseconds. `null` until audio is uploaded.                |
| `started_at`              | string          | ISO 8601 timestamp of when the recording started.                                  |
| `ended_at`                | string          | ISO 8601 timestamp of when the recording ended.                                    |
| `transcription_id`        | string \| null  | ID of the associated transcription. `null` until transcription is created.         |
| `media`                   | array           | Files associated with this recording (audio, images, video). Empty until uploaded. |
| `media[].id`              | string          | Media identifier (`med_*`).                                                        |
| `media[].type`            | string          | Media type: `audio`, `image`, or `video`.                                          |
| `media[].mime_type`       | string          | MIME type (e.g., `audio/opus`, `image/jpeg`, `video/mp4`).                         |
| `media[].file_size_bytes` | integer         | File size in bytes.                                                                |
| `media[].status`          | string          | Upload status: `pending`, `uploaded`.                                              |
| `media[].captured_at`     | string \| null  | ISO 8601 timestamp of when the media was captured.                                 |
| `media[].created_at`      | string          | ISO 8601 timestamp of when the media record was created.                           |
| `metadata`                | object          | Arbitrary key-value metadata.                                                      |
| `created_at`              | string          | ISO 8601 timestamp of when the recording was created.                              |

## Recording Status

| Status       | Description                              |
| ------------ | ---------------------------------------- |
| `pending`    | Recording created, awaiting audio upload |
| `uploaded`   | Audio uploaded, ready for transcription  |
| `processing` | Transcription in progress                |
| `completed`  | Transcription complete                   |
| `failed`     | Processing failed                        |

## Next Steps

After creating a recording:

1. [Get an upload URL](/api-reference/uploads/create-url)
2. Upload audio to the pre-signed S3 URL
3. [Mark upload complete](/api-reference/uploads/complete)
4. [Trigger transcription](/api-reference/transcriptions/create)
