Developer Documentation

Gifting API

Send branded merchandise programmatically. Integrate gifting into your CRM, sales workflows, or any application with a simple REST API.

API Key Auth
Inventory Check
Create Sends
Tracking & Status
Webhooks
HMAC Signing

Quick Start

Three steps to send your first gift programmatically.

1

Get your API key

Go to Dashboard → Integrations and create an API key. Requires a Merch OS subscription.

2

Stock your storefront

Add products to a storefront. The API sends from stocked inventory in your warehouse.

3

Create a send

POST to /api/v1/sends with recipient address and items. We handle fulfillment and shipping.

Authentication

All API requests require a valid API key passed in the X-API-Key header. Keys are scoped to your company and require a Merch OS subscription.

bash
curl https://api.brandmerch.com/api/v1/sends/inventory?storefrontId=sf_abc123 \
  -H "X-API-Key: bm_live_your_key_here"

SHA-256 hashed

Keys are stored as irreversible hashes

Company-scoped

Each key is tied to one company account

Revocable instantly

Revoke any key from the dashboard immediately

Base URL

https://api.brandmerch.com

API Endpoints

Click any endpoint to expand the full documentation.

Error Codes

All errors return a JSON body with an error field describing the issue.

CodeMeaningCommon Cause
400Bad RequestMissing required fields or invalid data
401UnauthorizedMissing, invalid, or revoked API key
403ForbiddenNo Merch OS subscription or account deactivated
404Not FoundStorefront or send ID not found / not owned
409ConflictInsufficient inventory for requested quantities
500Internal ErrorServer error — retry or contact support

Webhooks

Subscribe to real-time event notifications. Webhooks are signed with HMAC-SHA256 for verification and retried up to 3 times with exponential backoff.

Available Events

send.created

A new send has been created and inventory reserved

send.shipped

A send has shipped with tracking information

send.delivered

A send has been confirmed delivered

Payload Format

json
{
  "event": "send.shipped",
  "sendId": "send_1700000000000_a1b2c3d",
  "data": {
    "trackingNumber": "1Z999AA10123456784",
    "carrier": "UPS",
    "shippedAt": "2025-03-25T14:30:00.000Z"
  },
  "timestamp": "2025-03-25T14:30:05.000Z"
}

Headers

HeaderDescription
X-BrandMerch-SignatureHMAC-SHA256 hex digest of the request body
X-BrandMerch-EventThe event type (e.g. send.shipped)
Content-Typeapplication/json

Verifying Signatures (Node.js)

typescript
import crypto from 'crypto';

function verifySignature(body: string, signature: string, secret: string): boolean {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(body)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

// In your webhook handler:
app.post('/webhooks/brandmerch', (req, res) => {
  const signature = req.headers['x-brandmerch-signature'];
  const isValid = verifySignature(
    JSON.stringify(req.body),
    signature,
    process.env.BRANDMERCH_WEBHOOK_SECRET
  );

  if (!isValid) return res.status(401).send('Invalid signature');

  const { event, sendId, data } = req.body;
  // Handle the event...

  res.status(200).send('OK');
});

Idempotency

Pass an idempotencyKey in the request body to prevent duplicate sends. If a send with the same key already exists for your company, the API returns the existing send instead of creating a new one (with idempotent: true in the response).

json
// First request → creates the send
{ "storefrontId": "sf_abc", "idempotencyKey": "onboard-jane-2025", ... }
// → 201 { "sendId": "send_...", "status": "reserved" }

// Retry with same key → returns existing send
{ "storefrontId": "sf_abc", "idempotencyKey": "onboard-jane-2025", ... }
// → 200 { "sendId": "send_...", "status": "reserved", "idempotent": true }

Developer FAQ

Common technical questions about the Gifting API.

How do I verify webhook signatures?

Each webhook delivery includes an X-BrandMerch-Signature header containing an HMAC-SHA256 hex digest of the raw request body, signed with the secret returned when you created the webhook subscription. Recompute the HMAC on your end and compare to verify authenticity.

What are the rate limits?

The Sends API shares the global rate limit of 1,000 requests per 15 minutes per API key. Inventory checks (GET) and send creation (POST) both count toward this limit. If you hit the limit, the API returns 429 with a Retry-After header.

What happens if a send fails due to insufficient stock?

The API returns a 409 Conflict with a stockIssues array showing each item's requested vs. available quantity. No order is created and no inventory is reserved. You can retry after restocking.

Can I send to multiple recipients in one API call?

Each POST /sends creates a single shipment to one recipient. For bulk sends, make one API call per recipient. Use idempotency keys to safely retry without creating duplicates.

How do I handle API errors in my integration?

The API returns structured JSON errors with an error field on every non-2xx response. 400 errors indicate invalid input, 401/403 indicate auth issues, 404 means the resource was not found, and 409 means a stock conflict. Always check the HTTP status code and error message before retrying.

Can I test the API without creating real shipments?

Use a storefront in DRAFT status for testing. Sends created against draft storefronts will create real fulfillment requests in your warehouse dashboard, but you can cancel them before shipping. We recommend using a dedicated test storefront with a small amount of test inventory.

How long do API keys last?

API keys do not expire. They remain active until you explicitly revoke them from the Integrations page in your Team Dashboard. We recommend rotating keys periodically and revoking any that are no longer in use.

Ready to integrate?

Get started with the Gifting API today. Create your first API key and send a test gift in minutes.