# Difference Between Groq and OpenAI Whisper Backends in claude-video

> Discover the subtle differences between Groq and OpenAI Whisper backends in claude-video. Learn how endpoint URLs, model IDs, and API keys vary while core logic remains the same. Optimize your setup now.

- Repository: [bradautomates/claude-video](https://github.com/bradautomates/claude-video)
- Tags: deep-dive
- Published: 2026-08-07

---

**The Groq and OpenAI Whisper backends differ only in endpoint URLs, model identifiers, API key environment variables, and User-Agent headers, while sharing identical audio chunking, retry logic, and response parsing implementations in [`skills/watch/scripts/whisper.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/whisper.py).**

The `claude-video` repository provides a flexible transcription pipeline through its `watch` skill, supporting both Groq's Whisper-compatible API and OpenAI's native Whisper API within a single unified codebase. While the transcription workflow processes audio identically regardless of backend, four specific configuration distinctions determine which service handles your request and how the client authenticates.

## Core Backend Configuration Differences

The transcription logic isolates backend-specific behavior to initialization parameters and headers, allowing the rest of the pipeline to remain service-agnostic.

### Endpoint URLs and Model Selection

According to lines 29-34 in [`skills/watch/scripts/whisper.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/whisper.py), the two backends target different API endpoints and model identifiers:

- **Groq Whisper**: Sends requests to `https://api.groq.com/openai/v1/audio/transcriptions` using the `whisper-large-v3` model
- **OpenAI Whisper**: Targets `https://api.openai.com/v1/audio/transcriptions` with the `whisper-1` model

These values are defined as module-level constants and determine the destination for all multipart upload requests.

### API Key Hierarchy and Environment Variables

The `load_api_key` function (lines 65-71 and 98-108) implements a preference-based fallback strategy for authentication:

1. First checks for the `GROQ_API_KEY` environment variable
2. Falls back to `OPENAI_API_KEY` only if the Groq key is absent

This hierarchy makes Groq the default backend when both keys are present, though users can override this behavior through CLI arguments.

### User-Agent Header Requirements

The `_post_whisper` function (lines 45-51) transmits a custom User-Agent string (`watch-skill/1.0 (+claude-code; python-urllib)`) specifically to bypass Cloudflare's default blocking rules that target generic Python urllib clients. While the same header is sent to both services, it serves a functional purpose only for the Groq backend, which runs behind Cloudflare's edge network.

## Shared Transcription Implementation

Despite configuration differences, the core audio processing pipeline remains identical for both backends, ensuring consistent behavior and maintainability.

### Audio Processing Pipeline

The workflow processes audio through the same function sequence regardless of backend selection:

1. **`extract_audio()`**: Creates a mono 16kHz MP3 file that satisfies both services' 25 MiB upload limit
2. **`plan_chunks()`**: Splits oversized audio into time-aligned segments based on `MAX_UPLOAD_BYTES` when files exceed the size restriction
3. **`_build_multipart()`**: Constructs the request body using standard library tools without requiring external dependencies like `requests`, `groq`, or `openai` SDKs
4. **`_segments_from_response()`**: Normalizes the JSON `segments` field into a unified `{start, end, text}` format consumed by the rest of the pipeline

### Retry Logic and Error Handling

Both backends share identical rate-limit handling in `_post_whisper` (lines 71-78). The code counts HTTP 429 responses and retries requests up to `MAX_429_RETRIES` times, applying the same backoff strategy regardless of whether the error originates from Groq or OpenAI infrastructure.

## Practical Usage Examples

Configure and invoke the transcription pipeline using environment variables or CLI arguments to control backend selection.

### Configuring API Keys

Store your preferred backend's API key in the user configuration file:

```bash

# ~/.config/watch/.env

GROQ_API_KEY="your-groq-key-here"

```

Alternatively, export the variable directly in your shell:

```bash
export GROQ_API_KEY="your-groq-key-here"
export OPENAI_API_KEY="your-openai-key-here"

```

When both variables are set, the system defaults to Groq unless explicitly overridden.

### Selecting Backends via CLI

Run transcription with automatic backend selection (prefers Groq if `GROQ_API_KEY` is present):

```bash
python3 -m skills.watch.scripts.whisper /path/to/video.mp4

```

Force a specific backend using the `watch` CLI interface:

```bash
watch https://youtu.be/xyz --whisper openai

```

This bypasses the default preference hierarchy and routes the request to OpenAI's endpoint regardless of which environment variables are set.

## Summary

- Both backends share identical chunking, retry, and parsing logic centralized in [`skills/watch/scripts/whisper.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/whisper.py)
- Groq uses `whisper-large-v3` at `api.groq.com`, while OpenAI uses `whisper-1` at `api.openai.com` as defined in lines 29-34
- The `load_api_key` function prioritizes `GROQ_API_KEY` over `OPENAI_API_KEY` when both are available
- A custom User-Agent header is required for Groq to bypass Cloudflare blocking rules
- Audio processing relies on `extract_audio()`, `plan_chunks()`, `_build_multipart()`, and `_segments_from_response()` regardless of backend selection

## Frequently Asked Questions

### Which backend provides faster transcription speeds?

Groq typically offers lower latency for the `whisper-large-v3` model compared to OpenAI's `whisper-1`, though the claude-video implementation adds no additional processing overhead beyond the network request itself. Actual performance depends on file size, network conditions, and current API load.

### How do I force the use of OpenAI when Groq is configured?

Explicitly specify the backend using the CLI flag `--whisper openai` when invoking the `watch` command. This overrides the default preference hierarchy defined in `load_api_key` that otherwise prioritizes Groq when both `GROQ_API_KEY` and `OPENAI_API_KEY` environment variables are present.

### Why does the Groq backend require a custom User-Agent header?

Groq's API runs behind Cloudflare, which blocks generic Python urllib user-agents by default. The custom header `watch-skill/1.0 (+claude-code; python-urllib)` defined in `_post_whisper` (lines 45-51) identifies the client as a legitimate transcription tool, allowing the request to reach Groq's inference servers.

### What happens when audio files exceed the 25 MiB upload limit?

The `plan_chunks()` function automatically splits large files into segments under `MAX_UPLOAD_BYTES`, processing each chunk sequentially through the selected backend and concatenating results via `_segments_from_response()`. This chunking behavior is identical for both Groq and OpenAI backends.