# Fix DeepL API 456 quota exceeded

## TL;DR

You have burned through your character quota, so check usage, then either wait for the reset or move up a tier. The 456 response is DeepL telling you the meter ran out, not a bug. Batch and cache aggressively so the next cycle lasts longer.

## The error

```text
456 Quota exceeded: {"message": "Quota for this billing period has been exceeded"}
POST /v2/translate after a large batch run
```

## Fix it

### Step 1: Check current usage against the limit

```bash
curl -s -H "DeepL-Auth-Key: $DEEPL_AUTH_KEY" https://api-free.deepl.com/v2/usage | head -c 300
```

Expected: You see character_count vs character_limit and how far over you are.

### Step 2: Find what ate the quota

```bash
grep -rn "translate(" scripts/batch-translate.js | head -5
```

Expected: You see whether retries, duplicates, or huge batches caused it.

### Step 3: Add caching so repeats never re-translate

```bash
node -e "console.log('pattern: hash the source text, store results in a local cache file, skip API calls on hit')"
```

Expected: Repeat runs cost zero characters.

### Step 4: Decide: wait for reset or upgrade

```bash
node -e "console.log('usage endpoint shows the reset timing; upgrade in the DeepL console if the workload is recurring')"
```

Expected: You have a plan instead of a surprise next month.

## When to use this

- DeepL returns 456 on translate calls
- A batch job died partway through with quota errors

## When NOT to use this

- The error is 403, that is auth or glossary access
- The error is 429, that is rate limiting not quota

## Tool and version compatibility

- DeepL API free and pro, usage endpoint v2
- Quota is characters per billing period

## Variant phrasings

### quota gone in days on the free tier

The free tier is small by design. Cache everything and batch monthly, or move to pro.

### one bad loop burned the quota

A retry loop without backoff re-sent the same batch. Fix the loop, then ask support about a one-time reset.

## Why it happens

DeepL meters characters per billing period. Large catalogs, uncached re-runs, and retry storms each multiply consumption. The 456 is the meter, it fires exactly when character_count passes character_limit.

## Edge cases

- The usage endpoint itself does not cost quota, poll it freely
- Glossary-only requests still cost characters, the glossary does not make them free
- Split test traffic to a mock in CI so tests never touch quota

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_lKnRypyoj6xmQKuEd_fsVA
