Merly Merchant Public API

Last updated: 2026-06-16

Getting started

The Merchant Public API lets you build headless storefronts, ERP integrations, and custom loyalty experiences on top of Merly.

Create API keys from your Integrations screen. Each key is scoped to your store and can be revoked at any time.

Authentication

Send your API key on every request using either an Authorization Bearer header or x-merchant-api-key.

Do not publish or embed API keys in client-side JavaScript. Keys grant access to customer wallet data for your store.

curl -X GET "https://{your-gateway}/api/v1/merchant/customers/{customer_user_id}/balance" \
  -H "Authorization: Bearer pk_live_…" \
  -H "x-correlation-id: $(uuidgen)"

Security: Keep API keys on your server only. Never expose them in client-side JavaScript, mobile apps, or public repositories.

Base URL & versioning

All merchant public routes are exposed through your Merly API gateway under /api/v1/merchant.

Use your production gateway hostname in all environments except local sandboxes provided by your Merly contact.

https://{your-gateway}/api/v1/merchant

Rate limits

Each API key has a per-minute rate limit (default 120 requests/minute, configurable at key creation between 10 and 600).

When exceeded, the gateway returns HTTP 429 with error rate_limit_exceeded and a correlation_id for support.

Default: 120 req/min · Configurable 10600 at key creation.

Scopes

ScopeLabelDescription
read:balanceRead balanceWallet balance and plan tier
read:tierRead tierSubscription tier and status
read:activityRead activityPaginated wallet transaction history
read:couponsValidate couponsCheckout validation for Merly credit coupon codes (headless)
write:webhooksTest webhooksSend signed test lifecycle events to your configured outbound webhook URL
write:catalogPublish catalogPublish store policy and product directory (headless merchants)
write:customersLink customersLink external customer IDs to Merly wallets (headless merchants)
write:ordersIngest ordersReport paid orders for purchase earn (headless merchants)

Endpoints

GETCustomer wallet balance

/api/v1/merchant/customers/{customer_id}/balance

Scope: read:balance

Returns the Merly wallet balance and plan tier for a customer. customer_id is the Merly Identity user_id (UUID).

Example response

{
  "customer_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
  "platform": "shopify",
  "store_key": "your-store.myshopify.com",
  "balance": "1500.0000",
  "plan_tier": "SILVER",
  "correlation_id": "…"
}

GETSubscription tier

/api/v1/merchant/customers/{customer_id}/tier

Scope: read:tier

Returns the customer's Merly subscription tier and status.

Example response

{
  "customer_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
  "platform": "shopify",
  "store_key": "your-store.myshopify.com",
  "plan_tier": "SILVER",
  "subscription_status": "active",
  "correlation_id": "…"
}

GETWallet activity

/api/v1/merchant/customers/{customer_id}/activity

Scope: read:activity

Paginated wallet transaction history for the customer.

Query parameters

{
  "page": "Page number (default 1)",
  "page_size": "Items per page (default 20, max 100)",
  "type": "Optional transaction type filter"
}

Example response

{
  "customer_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
  "current_balance": "1500.0000",
  "total_count": 42,
  "page": 1,
  "page_size": 20,
  "transactions": []
}

POSTTest outbound webhook

/api/v1/merchant/webhooks/test

Scope: write:webhooks

Sends a signed test lifecycle event to the outbound webhook URL configured in Integrations.

Request body

{
  "event_type": "merly.points.earned"
}

Example response

{
  "ok": true,
  "event_type": "merly.points.earned",
  "correlation_id": "…"
}

POSTPublish catalog policy and products

/api/v1/merchant/catalog/publish

Scope: write:catalog

Headless merchants only. Requires x-idempotency-key.

Request body

{
  "policy_store_only": true,
  "cap": {
    "max_coupon_value_usd": 50
  }
}

Example response

{
  "ok": true,
  "product_count": 0,
  "catalog_store_id": "hl_boutique-example-com",
  "correlation_id": "…"
}

POSTIngest paid order

/api/v1/merchant/orders

Scope: write:orders

Request body

{
  "order_id": "ord_1",
  "external_customer_id": "cust_1",
  "customer_email": "buyer@example.com",
  "currency": "USD",
  "total": "120.00",
  "subtotal": "110.00"
}

Example response

{
  "order_id": "ord_1",
  "earn_granted": 110,
  "correlation_id": "…"
}

POSTValidate Merly credit coupon at merchant checkout

/api/v1/merchant/coupons/validate

Scope: read:coupons

Request body

{
  "coupon_code": "MERLY-ABC123"
}

Example response

{
  "valid": true,
  "coupon_code": "MERLY-ABC123",
  "credits_amount": "300.0000",
  "expires_at": null,
  "correlation_id": "…"
}

Outbound webhooks

Configure your outbound webhook URL under Integrations. Merly signs payloads with X-Merly-Signature: sha256={hex} when a signing secret is set.

Use POST /api/v1/merchant/webhooks/test (scope write:webhooks) to verify delivery.

CanonicalPublic alias
merly.points.earnedpoints.earned
merly.points.redeemedpoints.redeemed
merly.tier.changedtier.changed
merly.order.ingestedorder.ingested

Key management

Create and revoke API keys from the Integrations section of your merchant admin: Shopify app, WooCommerce plugin, or the Merly Merchant Portal for headless stores. Each key is shown in full only once at creation — store it securely.

Errors

HTTPerrorDescription
401missing_api_keyNo Bearer or x-merchant-api-key header
401invalid_api_keyKey revoked, wrong hash, or unknown prefix
403insufficient_scopeKey lacks required scope for route
429rate_limit_exceededPer-key RPM exceeded
404customer_wallet_not_foundNo wallet for customer_id