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

# Create voucher

> Create a new completed voucher with the next sequential code.

**Required scope:** `vouchers:write`
**Rate limit:** 60 requests/minute
**Status code on success:** `201 Created`
**Idempotency:** supported – pass `Idempotency-Key` to safely retry. See [Idempotency](/developer-api/idempotency).

The new voucher is created in the `completed` status – i.e. ready to redeem
immediately. The voucher code is generated server-side; you cannot supply it.
The expiry date is calculated from your tenant's configured voucher expiry
window (default: 3 years).

## Request body

| Field              | Type             | Required | Notes                                                                          |
| ------------------ | ---------------- | -------- | ------------------------------------------------------------------------------ |
| `amount`           | decimal (string) | yes      | Greater than 0, less than or equal to 10000                                    |
| `purchaser_name`   | string           | yes      | 1–255 characters                                                               |
| `purchaser_email`  | string (email)   | no       | If supplied, a `Customer` is found-or-created and linked                       |
| `recipient_name`   | string           | no       | Up to 255 characters                                                           |
| `recipient_email`  | string (email)   | no       | Stored encrypted; used for delivery if you wire it up                          |
| `personal_message` | string           | no       | Up to 1000 characters                                                          |
| `notes`            | string           | no       | Internal notes – accepted but not returned in the response                     |
| `location_id`      | UUID             | no       | Required only when creating a location-specific voucher with a tenant-wide key |

If your API key is **location-scoped**, the new voucher is forced to that
location. Supplying a different `location_id` returns `403 Forbidden`.

## Response

```json theme={null}
{
  "id": "8d82f0d2-7f94-4a3b-8b55-1e2e3a4f5b6c",
  "code": "00000124",
  "amount": "100.00",
  "balance": "100.00",
  "status": "completed",
  "recipient_name": "Sam Recipient",
  "recipient_email": "sam@example.com",
  "expiry_date": "2029-04-26T01:23:45Z",
  "created_at": "2026-04-26T01:23:45Z",
  "updated_at": "2026-04-26T01:23:45Z",
  "location_id": null
}
```

## Errors

* `403` – API key is scoped to a different location than `location_id`.
* `404` – `location_id` does not match an active location in your tenant.
* `409` – `Idempotency-Key` reused with a different request body within the
  24h replay window (see [Idempotency](/developer-api/idempotency)).
* `422` – Validation error on any field (e.g. `amount <= 0`, `amount > 10000`,
  invalid email format).

## Examples

```bash theme={null}
curl -X POST \
  -H "X-API-Key: vg_live_EXAMPLEdoNotUseThis123456" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "100.00",
    "purchaser_name": "Alex Buyer",
    "purchaser_email": "buyer@example.com",
    "recipient_name": "Sam Recipient",
    "recipient_email": "sam@example.com",
    "personal_message": "Happy birthday!"
  }' \
  https://api.vouchergrid.com/api/v1/developer/vouchers
```

```ts theme={null}
const res = await fetch(
  "https://api.vouchergrid.com/api/v1/developer/vouchers",
  {
    method: "POST",
    headers: {
      "X-API-Key": process.env.VOUCHERGRID_API_KEY!,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      amount: "100.00",
      purchaser_name: "Alex Buyer",
      purchaser_email: "buyer@example.com",
      recipient_name: "Sam Recipient",
      recipient_email: "sam@example.com",
      personal_message: "Happy birthday!",
    }),
  },
);
const voucher = await res.json();
```
