# Download every QR code of a campaign as one ZIP

Source: https://straitlink.in/docs/api/get-campaign-qr-zip/

`GET /v1/qr.zip`

Auth: secret key as Authorization: Bearer. Server-side only.

A ZIP with one QR code per **live** link whose campaign is `campaign` (case-insensitive, the same match as the dashboard's links filter), named `<slug>-qr.<format>` and sorted by slug. Same style rules as GET /v1/links/{slug}/qr: the workspace default or `preset`, overridden by color / background / logo, refused (400) when it would not scan. SVG by default (vector, for print). At most 500 codes as SVG, or 50 as PNG at up to 1024 px. Rate limit: 3 ZIPs a minute per workspace; one PNG ZIP at a time server-wide.

| Parameter | In | Type | Notes |
|---|---|---|---|
| `campaign` (required) | query | `string` | The links' campaign name, e.g. `diwali_sale` |
| `format` | query | `"svg" | "png"` | Image format of every code |
| `size` | query | `integer` | Width and height in pixels (PNG: at most 1024) |
| `margin` | query | `integer` | Quiet zone around each code, in modules |
| `preset` | query | `string` | A saved QR style id (Settings → QR codes) |
| `color` | query | `string` | Code colour as hex, overrides the style |
| `background` | query | `string` | Background colour as hex, overrides the style |
| `logo` | query | `boolean` | Put the app icon in the middle, overrides the style |
| `track` | query | `boolean` | Add utm_source=qr so scans count as the qr channel |
| `tenantId` | query | `string` | Dashboard sessions only: the workspace id |

```bash
curl -X GET "https://strait.link/v1/qr.zip?campaign=value" \
  -H "Authorization: Bearer $SECRET_KEY"
```

- `200`: The ZIP (stored, not compressed)
- `400`: No campaign, unknown preset, colours that would not scan, PNG over 1024 px, or more links than the ZIP holds
- `401`: Missing or invalid secret key / session
- `404`: No live links in this campaign
- `429`: More than 3 ZIPs a minute for this workspace, or another PNG ZIP is being made
- `503`: PNG rendering stayed busy for 30 s; retry or use SVG
