Hydra is now in beta|Get started free|Follow our journey on X.com

Promotions API
On this page

Promotions

Promotions apply automatic discounts to products. A promotion can target all products, or be scoped to specific products, collections, or variants via targets. When a promotion has no targets, it applies to all products in the store.

Promotions support two discount types: percentage (e.g. 20% off) and fixed_amount (e.g. $5 off, in cents). The price_targets field controls which price levels or customer groups are affected (e.g. base price only, a specific tier price key, or a customer group ID).

Base URL: https://api.hydrajs.dev

Endpoints

Method Path Auth Description
GET /v1/promotions Secret List promotions
POST /v1/promotions Secret Create a promotion
GET /v1/promotions/{id} Secret Get a promotion
PATCH /v1/promotions/{id} Secret Update a promotion
DELETE /v1/promotions/{id} Secret Delete a promotion

List promotions

GET /v1/promotions

Returns a paginated list of promotions with their targets.

Query parameters

Parameter Type Default Description
limit integer 25 Results per page (1–250)
cursor string - Pagination cursor from a previous response
sort string created_at Sort field: created_at, updated_at, name
order string desc Sort direction: asc, desc
status string - Filter by status: active, disabled, archived
search string - Filter by name (case-insensitive substring match)
fields string - Comma-separated fields to return

Request

curl https://api.hydrajs.dev/v1/promotions?status=active&limit=10 \
  -H "Authorization: Bearer sk_live_YOUR_KEY"

Response 200

{
	"data": [
		{
			"id": "promo_abc123def456ghij",
			"name": "Summer Sale",
			"type": "percentage",
			"value": 20,
			"status": "active",
			"price_targets": ["base"],
			"starts_at": "2026-08-01T00:00:00Z",
			"ends_at": "2026-09-01T00:00:00Z",
			"targets": [
				{
					"id": "ptgt_abc123def456ghij",
					"target_type": "collection",
					"target_id": "col_abc123",
					"target_name": "Summer Collection"
				}
			],
			"created_at": "2026-07-15T09:30:00Z",
			"updated_at": "2026-07-15T09:30:00Z"
		}
	],
	"pagination": {
		"cursor": "eyJ0IjoiMjAyNi...",
		"has_more": false,
		"total": 1
	}
}

Pagination

All list endpoints use cursor-based pagination. Pass the cursor value from the response to fetch the next page.


Create a promotion

POST /v1/promotions

Creates a new promotion. Returns the created promotion with resolved target names.

Request body

Field Type Required Description
name string Yes Promotion name (1–255 chars)
type string Yes Discount type: percentage, fixed_amount
value integer Yes Discount value (1–100 for percentage, cents for fixed)
status string No active (default) or disabled
price_targets string[] No Price level or customer group to target. Accepts ["base"] (default), ["*"] (all levels), a price tier key (e.g. ["wholesale"]), or a customer group ID (e.g. ["cg_abc123"]). Single value.
starts_at string Yes ISO 8601 start datetime
ends_at string No ISO 8601 end datetime (null = no end, must be after starts_at)
targets object[] No Product/collection/variant scoping (default: [] = all products)
targets[].target_type string Yes product, collection, or variant
targets[].target_id string Yes ID of the target resource

Request

curl -X POST https://api.hydrajs.dev/v1/promotions \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Summer Sale",
    "type": "percentage",
    "value": 20,
    "starts_at": "2026-08-01T00:00:00Z",
    "ends_at": "2026-09-01T00:00:00Z",
    "targets": [
      { "target_type": "collection", "target_id": "col_abc123" }
    ]
  }'

Response 201

{
	"data": {
		"id": "promo_abc123def456ghij",
		"name": "Summer Sale",
		"type": "percentage",
		"value": 20,
		"status": "active",
		"price_targets": ["base"],
		"starts_at": "2026-08-01T00:00:00Z",
		"ends_at": "2026-09-01T00:00:00Z",
		"targets": [
			{
				"id": "ptgt_abc123def456ghij",
				"target_type": "collection",
				"target_id": "col_abc123",
				"target_name": "Summer Collection"
			}
		],
		"created_at": "2026-08-17T12:00:00Z",
		"updated_at": "2026-08-17T12:00:00Z"
	}
}

Percentage limits

When type is percentage, value must be between 1 and 100. Values outside this range return a 400 validation error.

Customer group targeting

When price_targets contains a customer group ID (e.g. ["cg_abc123"]), the promotion only applies when the customer is known and is a member of that group. This is resolved during cart pricing when a customer_id is provided. Product listing endpoints show prices without customer-group promotions applied.


Get a promotion

GET /v1/promotions/{id}

Returns a single promotion with its targets and resolved target names.

Request

curl https://api.hydrajs.dev/v1/promotions/promo_abc123def456ghij \
  -H "Authorization: Bearer sk_live_YOUR_KEY"

Response 200

{
	"data": {
		"id": "promo_abc123def456ghij",
		"name": "Summer Sale",
		"type": "percentage",
		"value": 20,
		"status": "active",
		"price_targets": ["base"],
		"starts_at": "2026-08-01T00:00:00Z",
		"ends_at": "2026-09-01T00:00:00Z",
		"targets": [
			{
				"id": "ptgt_abc123def456ghij",
				"target_type": "collection",
				"target_id": "col_abc123",
				"target_name": "Summer Collection"
			}
		],
		"created_at": "2026-07-15T09:30:00Z",
		"updated_at": "2026-07-15T09:30:00Z"
	}
}

Update a promotion

PATCH /v1/promotions/{id}

Updates a promotion. All fields are optional — send only what changed. When targets is provided, it replaces the entire targets list.

Request body

Field Type Required Description
name string No Promotion name (1–255 chars)
type string No percentage or fixed_amount
value integer No Discount value
status string No active or disabled
price_targets string[] No Price level or customer group to target (single value)
starts_at string No ISO 8601 start datetime
ends_at string No ISO 8601 end datetime (null to clear)
targets object[] No Replaces all targets (empty array = all products)

Request

curl -X PATCH https://api.hydrajs.dev/v1/promotions/promo_abc123def456ghij \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"value": 25, "targets": []}'

Response 200

{
	"data": {
		"id": "promo_abc123def456ghij",
		"name": "Summer Sale",
		"type": "percentage",
		"value": 25,
		"status": "active",
		"price_targets": ["base"],
		"starts_at": "2026-08-01T00:00:00Z",
		"ends_at": "2026-09-01T00:00:00Z",
		"targets": [],
		"created_at": "2026-07-15T09:30:00Z",
		"updated_at": "2026-08-17T14:00:00Z"
	}
}

Replace semantics

When targets is included in the update, the entire targets list is replaced. To add a target, send the full list including existing targets. Omit targets entirely to leave them unchanged.


Delete a promotion

DELETE /v1/promotions/{id}

Soft-deletes a promotion by setting its status to archived and marking it as deleted. This action cannot be undone.

Request

curl -X DELETE https://api.hydrajs.dev/v1/promotions/promo_abc123def456ghij \
  -H "Authorization: Bearer sk_live_YOUR_KEY"

Response 204

Empty body.


The promotion object

Field Type Description
id string Unique ID (prefix: promo_)
name string Promotion name
type string Discount type: percentage or fixed_amount
value integer Discount value (percentage 1–100, or cents for fixed)
status string active, disabled, or archived
price_targets string[] Which price level or customer group this promotion targets. Contains a single value: a price tier key (base, *, or custom key) or a customer group ID (cg_...)
starts_at string ISO 8601 start datetime
ends_at string | null ISO 8601 end datetime, or null for no end
targets object[] Scoping targets (empty = applies to all products)
targets[].id string Target ID (prefix: ptgt_)
targets[].target_type string product, collection, or variant
targets[].target_id string ID of the target resource
targets[].target_name string | null Resolved name of the target (may be null if deleted)
created_at string ISO 8601 timestamp
updated_at string ISO 8601 timestamp