---
title: "Create a gift-link CSV export"
method: POST
path: "/campaigns/{id}/distribution/exports"
tags: ["Gift links"]
---

# Create a gift-link CSV export

`POST /campaigns/{id}/distribution/exports`

## Request

- Base URL: `https://gtmswag.com/api/v1`
- URL: `https://gtmswag.com/api/v1/campaigns/{id}/distribution/exports`
- Auth: one of:
  - HTTP bearer
  - OAuth 2 (authorization code, authorization URL `https://gtmswag.com/oauth/authorize`, token URL `https://gtmswag.com/oauth/token`, scopes: `gifts:links:read`)

The website's bulk export: `scope` `all`, `selection` (`recipientIds` or `giftIds`) or `filtered`. By default it holds ready links plus the original source columns; `includeUnavailable:true` lists everyone for a status report. Returns the export ID, an authenticated `downloadUrl` (valid 24 hours), counts and exclusions. Creates an export record only. Accepts an MCP OAuth token with `gifts:links:read`.

## Path parameters

- `id` string, required

## Request body

- object
  - `recipientIds` string[]: Explicit stable recipient IDs to select.
  - `giftIds` string[]: Explicit gift/send IDs to select.
  - `search` string: Filter supplied recipient name, email, source ID, company or profile.
  - `availability` 'ready' | 'awaiting_approval' | 'preparing_links' | 'unavailable': Filter current link availability; ready means usable now.
  - `scope` 'all' | 'selection' | 'filtered', required: Explicit all, selection or filtered recipient scope.
  - `preset` 'original' | 'compact': original preserves selected source columns; compact exports gift-link identity columns.
  - `includeUnavailable` boolean: True creates a full status report with blank unavailable links; false exports ready links only.
  - `columnPrefix` string: Optional prefix for appended gift columns; collisions receive gtm_swag_ automatically.
  - `optionalColumns` string[]: Additional technical columns; default export has only gift_link, gift_status and gift_expires_at.

## Response `201`

Success: `{"data": GiftLinkExport}`.

- GiftLinkExportResponse: The success body: `{"data": GiftLinkExport}`.
  - `data` GiftLinkExport, required: A gift-link CSV export to download within 24 hours.
    - `id` string, required
    - `downloadUrl` string, required
    - `filename` string, required
    - `columns` string[], required
    - `mode` 'test' | 'live' | 'mixed', required
    - `counts` DistributionCounts, required
      - `total` integer, required
      - `ready` integer, required
      - `unavailable` integer, required
    - `excluded` object[], required
      - `recipient_id` string, required
      - `name` string, required
      - `availability_reason` string, required
    - `earliestExpiry` string, nullable, required

## Other responses

- `400`: Bad request: `VALIDATION_ERROR`, `INVALID_JSON`. Each example says when.
- `401`: Not authenticated: `AUTH_REQUIRED`. no credentials, or an OAuth token on a route that only takes workspace keys; the key is malformed, unknown or revoked.
- `403`: Forbidden: `INSUFFICIENT_SCOPE`. Each example says when.
- `404`: Not found: `NOT_FOUND`. Each example says when.
- `409`: Conflict: `IMPORT_INCOMPLETE`. Each example says when.
- `413`: Request too large: `INVALID_REQUEST`. the body exceeds 1 MiB.
- `415`: Unsupported media type: `INVALID_REQUEST`. a write with a body that is not `Content-Type: application/json` (a key request with no body needs no Content-Type).
- `429`: Too many requests: `RATE_LIMIT`. more than 240 requests in the current minute for this workspace (REST and MCP share the limit); wait `retryAfterMs`.
- `default`: Any other refusal or failure, such as 403 CSRF (a cross-origin `Origin` header), 403 HTTPS_REQUIRED or 500 INTERNAL_ERROR, with what to do next.

---

[API](https://skmtc.dev/gtmswag/apis/gtm-swag-api.md) · [All operations](https://skmtc.dev/gtmswag/apis/gtm-swag-api/llms.txt) · [OpenAPI document](https://skmtc.dev/gtmswag/apis/gtm-swag-api/revisions/9ff86fa99afe?raw)
