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

# Bulkaanmaak van QR-codes

> Maak tot 100 QR-codes tegelijk en download ze als ZIP-archief.

> [!NOTE]
>
> De GetQR API is in bèta en beschikbaar voor geselecteerde workspaces. Details kunnen nog veranderen vóór de algemene release.

Een bulkaanmaak zet een lijst met namen en URL's om in website-QR-codes met één gedeeld ontwerp. Hij loopt op de achtergrond: start hem, vraag de voortgang op en download daarna het ZIP-archief.

| Methode | Pad | Beschrijving |
| - | - | - |
| `GET` | `/api/v1/bulk-qr-creations` | [De huidige bulkaanmaak ophalen](#de-huidige-bulkaanmaak-ophalen) |
| `POST` | `/api/v1/bulk-qr-creations` | [Aanmaken vanuit JSON](#aanmaken-vanuit-json) |
| `POST` | `/api/v1/bulk-qr-creations/csv` | [Aanmaken vanuit een CSV-bestand](#aanmaken-vanuit-een-csv-bestand) |
| `GET` | `/api/v1/bulk-qr-creations/{id}` | [Een bulkaanmaak ophalen](#een-bulkaanmaak-ophalen) |
| `DELETE` | `/api/v1/bulk-qr-creations/{id}` | [Een bulkaanmaak afbreken](#een-bulkaanmaak-afbreken) |
| `GET` | `/api/v1/bulk-qr-creations/{id}/download` | [Het archief downloaden](#het-archief-downloaden) |

## Zo werkt het

**1. Start de bulkaanmaak**

Stuur je rijen met [Aanmaken vanuit JSON](#aanmaken-vanuit-json) of [Aanmaken vanuit een CSV-bestand](#aanmaken-vanuit-een-csv-bestand). De API antwoordt met `202` en de bulkaanmaak met zijn `id`.

**2. Vraag de voortgang op**

Roep [Een bulkaanmaak ophalen](#een-bulkaanmaak-ophalen) om de paar seconden aan, tot `status` `completed` of `failed` is.

**3. Download het archief**

Is `status` `completed`, roep dan [Het archief downloaden](#het-archief-downloaden) aan voor een ZIP met de QR-codeafbeeldingen.

* **Limiet.** Maximaal 100 rijen per bulkaanmaak.
* **Eén tegelijk.** Per workspace loopt maar één bulkaanmaak. Start je er een terwijl er al een loopt, dan krijg je de lopende terug.
* **Idempotentie.** Elk verzoek heeft een `idempotencyKey` nodig. Herhaal je een verzoek met dezelfde sleutel en dezelfde body, dan krijg je de bulkaanmaak terug die al is gestart. Dezelfde sleutel met een andere body geeft `422`.
* **Rijen.** Elke rij heeft een `name` en een `url` nodig. Zie [Rijen](#rijen).
* **Abonnement.** Bulkaanmaak is niet beschikbaar bij het Single QR-abonnement: het verzoek geeft `403 exceeded_limit`.

## Rijen

* **Naam.** Wordt de titel van de QR-code. Bijgesneden en ingekort tot 40 tekens. Herhaalde namen (ongeacht hoofdletters) krijgen een nummer: `Menu`, `Menu 2`, `Menu 3`.
* **URL.** Wordt de bestemming. Het moet een `http`- of `https`-adres met een echt domein zijn, zoals `example.com/menu`, zonder spaties. Een URL zonder schema krijgt `https://`.
* **Lege rijen.** Rijen zonder naam en zonder URL worden overgeslagen. Een rij met maar één van beide wordt geweigerd.

Elke QR-code is een `website`-QR-code op een korte link. Zie [QR-types](https://docs.getqr.com/nl/api/guides/qr-types.md).

## Headers

**Authorization** `string` *required*

`Bearer` gevolgd door je API-sleutel. Zie [Authenticatie](https://docs.getqr.com/nl/api/authentication.md).

**Content-Type** `string`

`application/json` voor [Aanmaken vanuit JSON](#aanmaken-vanuit-json), `multipart/form-data` voor [Aanmaken vanuit een CSV-bestand](#aanmaken-vanuit-een-csv-bestand).

## Het bulkaanmaakobject

**id** `string`

ID van de bulkaanmaak, bijvoorbeeld `cm2k7x9qb0003ax8eb4f6gh2t`.

**status** `string`

`queued`, `processing`, `packaging` of `completed`. Een mislukte of afgebroken bulkaanmaak gaat via `rollingBack` naar `failed`.

**sourceFilename** `string`

Naam van het bronbestand.

**totalCount** `integer`

Aantal rijen.

**createdCount** `integer`

Tot nu toe aangemaakte QR-codes.

**renderedCount** `integer`

Tot nu toe gerenderde QR-codeafbeeldingen.

**percent** `integer`

Totale voortgang, 0 tot 100. Aanmaken loopt tot 40, renderen tot 90, inpakken is 95, en `completed` is 100.

**stalled** `boolean`

`true` als een lopende bulkaanmaak 2 minuten geen voortgang heeft gemaakt. Blijf de status opvragen: [Een bulkaanmaak ophalen](#een-bulkaanmaak-ophalen) start een vastgelopen bulkaanmaak opnieuw.

**error** `object | null`

Als `status` `failed` is: `code` en `message`. Een afgebroken bulkaanmaak heeft de code `cancelled_by_user`. Een mislukte bulkaanmaak wordt teruggedraaid, dus geen van de QR-codes blijft bestaan.

**downloadUrl** `string | null`

Pad van [Het archief downloaden](#het-archief-downloaden), zodra `status` `completed` is.

**createdAt** `string`

Startdatum, ISO 8601.

**updatedAt** `string`

Datum van de laatste update, ISO 8601.

**completedAt** `string | null`

Datum van voltooiing, ISO 8601.

**failedAt** `string | null`

Datum waarop de bulkaanmaak is mislukt, ISO 8601.

## De huidige bulkaanmaak ophalen

`GET /api/v1/bulk-qr-creations`

Geeft de bulkaanmaak terug die nog loopt in je workspace. Loopt er geen, dan krijg je de laatste afgeronde (`completed` of `failed`) terug tot die is afgesloten: dat gebeurt door het archief te downloaden of hem in het dashboard te sluiten. Anders krijg je `null`. Gebruik dit om na een herstart de voortgang weer te volgen.

```bash cURL theme={null}
curl "https://getqr.com/api/v1/bulk-qr-creations" \
  -H "Authorization: Bearer $GETQR_API_KEY"
```

```json 200 theme={null}
{
  "id": "cm2k7x9qb0003ax8eb4f6gh2t",
  "status": "processing",
  "sourceFilename": "campaign-links.csv",
  "totalCount": 50,
  "createdCount": 18,
  "renderedCount": 12,
  "percent": 26,
  "stalled": false,
  "error": null,
  "downloadUrl": null,
  "createdAt": "2026-08-14T08:00:00.000Z",
  "updatedAt": "2026-08-14T08:00:20.000Z",
  "completedAt": null,
  "failedAt": null
}
```

```json 200 (nothing to resume) theme={null}
null
```

## Aanmaken vanuit JSON

`POST /api/v1/bulk-qr-creations`

Start een bulkaanmaak vanuit een lijst met rijen. Antwoordt met `202 Accepted`. De bulkaanmaak loopt op de achtergrond.

**rows** `object[]` *required*

QR-codes om aan te maken, maximaal 100. Elke rij is `{ "name": "...", "url": "..." }` en accepteert geen andere velden. Zie [Rijen](#rijen).

**design** `object` *required*

Ontwerp dat op elke QR-code wordt toegepast: `styles`, `frameOptions` en `logoOptions`, allemaal optioneel. Stuur `{}` voor het standaardontwerp. Andere velden worden geweigerd. Zie [Aanpassing](https://docs.getqr.com/nl/api/guides/customization.md).

**sourceFilename** `string` *required*

Naam die in het dashboard wordt getoond en voor het archief wordt gebruikt, 1 tot 255 tekens.

**idempotencyKey** `string` *required*

Je eigen sleutel voor deze bulkaanmaak, 8 tot 100 tekens.

```bash cURL theme={null}
curl -X POST "https://getqr.com/api/v1/bulk-qr-creations" \
  -H "Authorization: Bearer $GETQR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "rows": [
      { "name": "Menu", "url": "https://example.com/menu" },
      { "name": "Wine list", "url": "example.com/wine" }
    ],
    "design": { "styles": { "dotsOptions": { "type": "rounded" } } },
    "sourceFilename": "campaign-links.csv",
    "idempotencyKey": "campaign-2026-08-14"
  }'
```

```json 202 theme={null}
{
  "id": "cm2k7x9qb0003ax8eb4f6gh2t",
  "status": "queued",
  "sourceFilename": "campaign-links.csv",
  "totalCount": 2,
  "createdCount": 0,
  "renderedCount": 0,
  "percent": 0,
  "stalled": false,
  "error": null,
  "downloadUrl": null,
  "createdAt": "2026-08-14T08:00:00.000Z",
  "updatedAt": "2026-08-14T08:00:00.000Z",
  "completedAt": null,
  "failedAt": null
}
```

## Aanmaken vanuit een CSV-bestand

`POST /api/v1/bulk-qr-creations/csv`

Hetzelfde als [Aanmaken vanuit JSON](#aanmaken-vanuit-json), maar de rijen komen uit een CSV-bestand dat als `multipart/form-data` wordt verstuurd. Antwoordt met `202 Accepted`.

Het bestand moet een `.csv` van maximaal 1.000.000 bytes zijn. De kopregel moet precies `name,url` zijn, gevolgd door maximaal 100 gegevensrijen. Zie [CSV-formaat](https://docs.getqr.com/nl/bulk/csv-format.md).

**file** `file` *required*

Het CSV-bestand.

**design** `string` *required*

Het ontwerpobject, geserialiseerd als JSON, bijvoorbeeld `{"styles":{"dotsOptions":{"type":"rounded"}}}`. Stuur `{}` voor het standaardontwerp.

**idempotencyKey** `string` *required*

Je eigen sleutel voor deze bulkaanmaak, 8 tot 100 tekens.

**sourceFilename** `string`

Naam die in het dashboard wordt getoond en voor het archief wordt gebruikt, maximaal 255 tekens. Standaard de naam van het geüploade bestand.

```bash cURL theme={null}
curl -X POST "https://getqr.com/api/v1/bulk-qr-creations/csv" \
  -H "Authorization: Bearer $GETQR_API_KEY" \
  -F "file=@campaign-links.csv" \
  -F 'design={"styles":{"dotsOptions":{"type":"rounded"}}}' \
  -F "idempotencyKey=campaign-2026-08-14"
```

```csv campaign-links.csv theme={null}
name,url
Menu,https://example.com/menu
Wine list,example.com/wine
```

```json 202 theme={null}
{
  "id": "cm2k7x9qb0003ax8eb4f6gh2t",
  "status": "queued",
  "sourceFilename": "campaign-links.csv",
  "totalCount": 2,
  "createdCount": 0,
  "renderedCount": 0,
  "percent": 0,
  "stalled": false,
  "error": null,
  "downloadUrl": null,
  "createdAt": "2026-08-14T08:00:00.000Z",
  "updatedAt": "2026-08-14T08:00:00.000Z",
  "completedAt": null,
  "failedAt": null
}
```

## Een bulkaanmaak ophalen

`GET /api/v1/bulk-qr-creations/{id}`

Geeft de status en voortgang van een bulkaanmaak terug. Vraag dit op zolang `status` `queued`, `processing` of `packaging` is. `downloadUrl` verschijnt zodra het archief klaar is.

**id** `string` *required*

ID van de bulkaanmaak. Neem die over uit het antwoord van het aanmaken of van de huidige bulkaanmaak.

```bash cURL theme={null}
curl "https://getqr.com/api/v1/bulk-qr-creations/cm2k7x9qb0003ax8eb4f6gh2t" \
  -H "Authorization: Bearer $GETQR_API_KEY"
```

```json 200 theme={null}
{
  "id": "cm2k7x9qb0003ax8eb4f6gh2t",
  "status": "completed",
  "sourceFilename": "campaign-links.csv",
  "totalCount": 50,
  "createdCount": 50,
  "renderedCount": 50,
  "percent": 100,
  "stalled": false,
  "error": null,
  "downloadUrl": "/api/v1/bulk-qr-creations/cm2k7x9qb0003ax8eb4f6gh2t/download",
  "createdAt": "2026-08-14T08:00:00.000Z",
  "updatedAt": "2026-08-14T08:02:10.000Z",
  "completedAt": "2026-08-14T08:02:10.000Z",
  "failedAt": null
}
```

## Een bulkaanmaak afbreken

`DELETE /api/v1/bulk-qr-creations/{id}`

Stopt een lopende bulkaanmaak en verwijdert de QR-codes die al zijn aangemaakt. Het terugdraaien gebeurt tijdens het verzoek, dus het antwoord heeft normaal `status` `failed` en `error.code` `cancelled_by_user`. Breek je een bulkaanmaak af die al is mislukt, dan krijg je hem ongewijzigd terug.

> [!WARNING]
>
> Een voltooide bulkaanmaak kun je niet afbreken: het verzoek geeft `400`. Verwijder de QR-codes in plaats daarvan één voor één via [QR-codes](https://docs.getqr.com/nl/api/endpoints/qr-codes.md).

**id** `string` *required*

ID van de bulkaanmaak.

```bash cURL theme={null}
curl -X DELETE "https://getqr.com/api/v1/bulk-qr-creations/cm2k7x9qb0003ax8eb4f6gh2t" \
  -H "Authorization: Bearer $GETQR_API_KEY"
```

```json 200 theme={null}
{
  "id": "cm2k7x9qb0003ax8eb4f6gh2t",
  "status": "failed",
  "sourceFilename": "campaign-links.csv",
  "totalCount": 50,
  "createdCount": 18,
  "renderedCount": 12,
  "percent": 26,
  "stalled": false,
  "error": {
    "code": "cancelled_by_user",
    "message": "Bulk QR creation was cancelled."
  },
  "downloadUrl": null,
  "createdAt": "2026-08-14T08:00:00.000Z",
  "updatedAt": "2026-08-14T08:00:40.000Z",
  "completedAt": null,
  "failedAt": "2026-08-14T08:00:40.000Z"
}
```

## Het archief downloaden

`GET /api/v1/bulk-qr-creations/{id}/download`

Geeft een ZIP-archief terug met één JPEG van 1024 px per QR-code, genoemd naar de rij: `001-Menu.jpg`, `002-Wine list.jpg` enzovoort. Het archief krijgt de naam van `sourceFilename`. Beschikbaar zodra `status` `completed` is. Door te downloaden wordt de bulkaanmaak afgesloten, zodat [De huidige bulkaanmaak ophalen](#de-huidige-bulkaanmaak-ophalen) hem niet meer teruggeeft.

**id** `string` *required*

ID van de bulkaanmaak.

```bash cURL theme={null}
curl "https://getqr.com/api/v1/bulk-qr-creations/cm2k7x9qb0003ax8eb4f6gh2t/download" \
  -H "Authorization: Bearer $GETQR_API_KEY" \
  --output qr-codes.zip
```

```http 200 theme={null}
HTTP/1.1 200 OK
Content-Type: application/zip
Content-Disposition: attachment; filename="campaign-links-qr-codes.zip"

<binary archive data>
```

## Veelvoorkomende problemen

> [accordion] 422 met "contains an invalid HTTP(S) URL"
>
> Het bericht noemt de rij. Elke URL moet een `http`- of `https`-adres met een echt domein zijn, zoals `example.com/menu`. Corrigeer de rij en verstuur het verzoek opnieuw.

> [accordion] 422 "CSV headers must be exactly: name,url."
>
> De eerste rij van de CSV moet `name,url` zijn, in die volgorde en in kleine letters, zonder andere kolommen.

> [accordion] 422 "This idempotencyKey was already used with a different request body."
>
> Sleutels kun je niet hergebruiken voor een andere batch. Stuur een nieuwe `idempotencyKey`.

> [accordion] 409 "The bulk QR archive is not ready for download."
>
> De bulkaanmaak is nog niet voltooid. Blijf de status opvragen tot `status` `completed` is.

> [accordion] 400 "Cannot cancel a finished bulk QR creation."
>
> De bulkaanmaak is al voltooid, dus hij kan niet meer worden teruggedraaid.

> [accordion] 403 exceeded\_limit
>
> Je workspace heeft het Single QR-abonnement, waarin bulkaanmaak niet zit. Upgrade je abonnement.

> [accordion] Ik kreeg een oudere bulkaanmaak terug in plaats van een nieuwe
>
> Er loopt nog een andere bulkaanmaak in je workspace, of je hebt een `idempotencyKey` hergebruikt. Wacht tot die klaar is, of gebruik een nieuwe sleutel.

## Volgende stappen

> [card] [Aanpassing](https://docs.getqr.com/nl/api/guides/customization.md)

> [card] [QR-codes](https://docs.getqr.com/nl/api/endpoints/qr-codes.md)

> [card] [Bulk aanmaken in de app](https://docs.getqr.com/nl/bulk/overview.md)

> [card] [CSV-formaat](https://docs.getqr.com/nl/bulk/csv-format.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.