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

# Create Job

> Create a new batch transcription job with uploaded files, a ZIP, or public URLs.

## Overview

Create a new batch transcription job. The job is created in `CREATED` status with your audio accepted — it does **not** start transcription yet.

Call [Start Job](/api/STTBatch/Start_Job) next.

| Method              | Best for                                 | Content-Type          |
| ------------------- | ---------------------------------------- | --------------------- |
| Direct upload / ZIP | Files on your machine or CI              | `multipart/form-data` |
| Public URL          | HTTPS links, including S3 presigned URLs | `application/json`    |

Authenticated private bucket access is **not** supported.

The **Try it** playground uses the **public URL** (`application/json`) body below. For file upload, use the multipart cURL examples.

## Authentication

| Header         | Required | Description                    |
| -------------- | -------- | ------------------------------ |
| `X-API-Key-ID` | Yes      | Your Gnani Prisma v2.5 API key |

## Request Body

### Public URL (`application/json`) — Try it

| Field                     | Type      | Required | Description                                   |
| ------------------------- | --------- | -------- | --------------------------------------------- |
| `config.model`            | string    | Yes      | `"gnani-prisma-v2.5"`                         |
| `config.language_code`    | string    | Yes      | e.g. `en-IN`                                  |
| `config.mode`             | string    | No       | `"transcribe"`                                |
| `config.with_diarization` | boolean   | No       | Default `false`                               |
| `config.num_speakers`     | integer   | No       | Required when diarization is on (max `2`)     |
| `config.is_multi_channel` | boolean   | No       | Default `false`                               |
| `source.type`             | string    | Yes      | `"cloud_storage"`                             |
| `source.auth.mode`        | string    | Yes      | `"public"`                                    |
| `source.paths`            | string\[] | Yes      | Public HTTPS URLs                             |
| `callback_url`            | string    | No       | Webhook URL — leave empty in Try it if unused |

URLs are validated at **Start Job**, not at create.

### Multipart upload (`multipart/form-data`)

Use cURL / your client — not the Try it panel.

| Field          | Type          | Required | Description                                                                                                                                                                                |
| -------------- | ------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `config`       | string (JSON) | Yes      | STT config. Required: `model`, `language_code`. Optional: `mode` (default `transcribe`), `with_diarization`, `num_speakers` (required when diarization is on, max `2`), `is_multi_channel` |
| `files`        | file          | Yes      | Audio or ZIP. Max **100** files/job, **10 MB**/file, ZIP up to **50 MB** compressed                                                                                                        |
| `callback_url` | string        | No       | HTTPS webhook. See [Webhook sample payloads](/api/STTBatch/Introduction#webhooks)                                                                                                          |

Send `config` as a form field with `Content-Type: application/json` (see cURL `-F '...;type=application/json'`).

## Example cURL

### Direct upload (live-verified)

```bash theme={null}
curl --request POST \
  --url https://api.vachana.ai/stt/v3/batch/jobs \
  --header 'X-API-Key-ID: <YOUR_API_KEY>' \
  -F 'config={"model":"gnani-prisma-v2.5","language_code":"en-IN","mode":"transcribe","with_diarization":false,"is_multi_channel":false};type=application/json' \
  -F "files=@./customer_call.wav"
```

### Public URL

```bash theme={null}
curl --request POST \
  --url https://api.vachana.ai/stt/v3/batch/jobs \
  --header 'Content-Type: application/json' \
  --header 'X-API-Key-ID: <YOUR_API_KEY>' \
  --data '{
    "config": {
      "model": "gnani-prisma-v2.5",
      "language_code": "en-IN",
      "mode": "transcribe"
    },
    "source": {
      "type": "cloud_storage",
      "auth": { "mode": "public" },
      "paths": ["https://cdn.example.com/audio/call-001.mp3"]
    }
  }'
```

### Diarization (2 speakers)

```bash theme={null}
curl --request POST \
  --url https://api.vachana.ai/stt/v3/batch/jobs \
  --header 'X-API-Key-ID: <YOUR_API_KEY>' \
  -F 'config={"model":"gnani-prisma-v2.5","language_code":"en-IN","mode":"transcribe","with_diarization":true,"num_speakers":2};type=application/json' \
  -F "files=@./stereo_call.wav"
```

## Response

### Success — multipart upload (`201`)

```json theme={null}
{
  "job_id": "019fa79e-81f9-7a8a-a446-6eff16ddec30",
  "status": "CREATED",
  "total_files_accepted": 1,
  "created_at": "2026-07-28T07:26:50.926489Z",
  "message": "1 file(s) uploaded. Call POST /v1/jobs/{job_id}/start to begin processing."
}
```

Save `job_id`. Always start with:

```text theme={null}
POST /stt/v3/batch/jobs/{job_id}/start
```

(even if the message mentions `/v1/jobs/...`)

### Success — public URL create (`201`)

```json theme={null}
{
  "job_id": "019fa79c-ec88-770c-b498-371fc21fb40e",
  "status": "CREATED",
  "created_at": "2026-07-28T07:25:07.137907Z",
  "message": "Job created. Call POST /stt/v3/batch/jobs/{job_id}/start to begin processing.",
  "total_files_accepted": null
}
```

### Error responses

**401 Missing API key**

```json theme={null}
{
  "detail": {
    "error_code": "MISSING_API_KEY",
    "message": "Missing API key",
    "status_code": 401
  }
}
```

**400 Unsupported language**

```json theme={null}
{
  "error": "UNSUPPORTED_LANGUAGE",
  "message": "Value error, This service does not support language_code 'xx-XX'. Supported languages: bn-BD, bn-IN, en-IN, hi-IN, kn-IN, ml-IN, mr-IN, ta-IN, te-IN"
}
```

<ResponseField name="job_id" type="string">
  Unique job identifier. Required for Start / Status / Files / Cancel.
</ResponseField>

<ResponseField name="status" type="string">
  Always `CREATED` on success.
</ResponseField>

<ResponseField name="total_files_accepted" type="integer">
  Number of files accepted for multipart/ZIP uploads. May be `null` for public-URL creates.
</ResponseField>

## Webhook samples

If you pass `callback_url`, Gnani sends a `POST` to your URL when the job finishes.

Full payload examples (including `transcripts[]` / `full_transcript`):

→ **[Webhook samples on Batch STT Introduction](/api/STTBatch/Introduction#webhooks)**

Events: `job.completed` · `job.partial_failure` · `job.failed` · `job.cancelled`

## Use Cases

* Uploading one or many call recordings for offline transcription
* Sending a ZIP of customer audio for batch processing
* Pointing to public HTTPS / S3 presigned URLs without re-uploading files

Next: [Start Job](/api/STTBatch/Start_Job)


## OpenAPI

````yaml STTBatch.yml POST /stt/v3/batch/jobs
openapi: 3.1.0
info:
  title: Gnani Speech-to-Text Batch API
  version: 3.0.0
  description: >
    Batch STT Jobs API for asynchronous transcription of long or multiple audio
    files.


    Authenticate every request with the `X-API-Key-ID` header.
servers:
  - url: https://api.vachana.ai
    description: Production
security:
  - ApiKeyAuth: []
paths:
  /stt/v3/batch/jobs:
    post:
      tags:
        - Speech-to-Text (Batch)
      summary: Create Job
      description: >
        Create a batch transcription job from public HTTPS URLs (JSON body).

        For multipart file upload, use cURL with `multipart/form-data` (see docs
        page examples).

        Job is created in `CREATED` status — call Start Job next.
      operationId: create_batch_job
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateJobPublicUrlRequest'
            example:
              config:
                model: gnani-prisma-v2.5
                language_code: en-IN
                mode: transcribe
                with_diarization: false
                is_multi_channel: false
              source:
                type: cloud_storage
                auth:
                  mode: public
                paths:
                  - https://cdn.example.com/audio/call-001.mp3
      responses:
        '201':
          description: Job created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateJobResponse'
              example:
                job_id: 019fa854-1db0-7e45-a026-7a6b09ff6d7c
                status: CREATED
                created_at: '2026-07-28T10:45:12.769450Z'
                message: >-
                  Job created. Call POST /stt/v3/batch/jobs/{job_id}/start to
                  begin processing.
                total_files_accepted: null
        '401':
          description: Unauthorized
components:
  schemas:
    CreateJobPublicUrlRequest:
      type: object
      required:
        - config
        - source
      properties:
        config:
          $ref: '#/components/schemas/STTConfig'
        source:
          type: object
          required:
            - type
            - auth
            - paths
          properties:
            type:
              type: string
              example: cloud_storage
            auth:
              type: object
              required:
                - mode
              properties:
                mode:
                  type: string
                  example: public
            paths:
              type: array
              items:
                type: string
                format: uri
              example:
                - https://cdn.example.com/audio/call-001.mp3
        callback_url:
          type: string
          format: uri
          description: Optional HTTPS webhook URL for terminal job results
    CreateJobResponse:
      type: object
      properties:
        job_id:
          type: string
          format: uuid
        status:
          type: string
          example: CREATED
        created_at:
          type: string
          format: date-time
        message:
          type: string
        total_files_accepted:
          type: integer
          nullable: true
    STTConfig:
      type: object
      required:
        - model
        - language_code
      properties:
        model:
          type: string
          example: gnani-prisma-v2.5
        language_code:
          type: string
          example: en-IN
        mode:
          type: string
          example: transcribe
          default: transcribe
        with_diarization:
          type: boolean
          example: false
          default: false
        num_speakers:
          type: integer
          minimum: 1
          maximum: 2
          description: Required when with_diarization is true (max 2)
        is_multi_channel:
          type: boolean
          example: false
          default: false
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key-ID
      description: Your Gnani Prisma v2.5 API key

````