Promotions
Download the complete public OpenAPI schema
Promotions
Run limited-time discounts for agent buyers. A promotion sets when it runs, how much it may give away per order and in total, who may redeem it and how often, and what it applies to. Its arms each pair one discount with how long an offer drawn from it stays valid. A promotion never rewrites a catalog price.
GET /v1/promotions
List promotions
List limited-time promotions by status, market, or search.
Parameters, request, responses, and security
{
"tags": [
"promotions"
],
"summary": "List promotions",
"description": "List limited-time promotions by status, market, or search.",
"operationId": "v1_list_promotions",
"parameters": [
{
"required": false,
"schema": {
"anyOf": [
{
"$ref": "#/components/schemas/PromotionStatus"
},
{
"type": "null"
}
],
"title": "Status"
},
"name": "status",
"in": "query"
},
{
"required": false,
"schema": {
"anyOf": [
{
"type": "string",
"maxLength": 64
},
{
"type": "null"
}
],
"title": "Market Id"
},
"name": "market_id",
"in": "query"
},
{
"required": false,
"schema": {
"anyOf": [
{
"type": "string",
"maxLength": 255,
"minLength": 1
},
{
"type": "null"
}
],
"title": "Q"
},
"name": "q",
"in": "query"
},
{
"required": false,
"schema": {
"type": "integer",
"maximum": 200.0,
"minimum": 1.0,
"title": "Limit",
"default": 50
},
"name": "limit",
"in": "query"
},
{
"required": false,
"schema": {
"type": "integer",
"minimum": 0.0,
"title": "Offset",
"default": 0
},
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PublicV1PromotionListResponse"
}
}
}
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
}
}
},
"security": [
{
"ApiKeyBearer": []
}
],
"x-api-audience": "public_v1",
"x-api-authentication": "required",
"x-operation-id": "v1_list_promotions",
"x-mcp-exposed": true,
"x-public-path": "/v1/promotions",
"x-docs-kind": "list",
"x-docs-order": 40,
"x-docs-depth": 0,
"x-docs-action-order": 1000,
"x-codeSamples": [
{
"lang": "shell",
"label": "curl",
"source": "curl -X GET https://api.openmerchant.dev/v1/promotions \\\n -H 'Authorization: Bearer pr_sk_test_...'"
},
{
"lang": "shell",
"label": "MCP (Streamable HTTP)",
"source": "curl -X POST https://api.openmerchant.dev/mcp/v1 \\\n -H 'Authorization: Bearer pr_sk_test_...' \\\n -H 'Content-Type: application/json' \\\n -d '{\n \"jsonrpc\": \"2.0\",\n \"id\": 1,\n \"method\": \"tools/call\",\n \"params\": {\n \"name\": \"v1_list_promotions\",\n \"arguments\": {}\n }\n}'"
},
{
"lang": "typescript",
"label": "MCP SDK (TS)",
"source": "// Reusing a Client connected to /mcp/v1 — see the \"MCP server\" tag for setup.\nconst result = await client.callTool({\n name: \"v1_list_promotions\",\n arguments: {},\n});"
}
]
}
POST /v1/promotions
Create a promotion
Create one limited-time promotion with its window, caps, identity rules, discount arms, and targets. New promotions start as drafts.
Parameters, request, responses, and security
{
"tags": [
"promotions"
],
"summary": "Create a promotion",
"description": "Create one limited-time promotion with its window, caps, identity rules, discount arms, and targets. New promotions start as drafts.",
"operationId": "v1_create_promotion",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PromotionCreate"
}
}
},
"required": true
},
"responses": {
"201": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PublicV1PromotionRead"
}
}
}
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
}
}
},
"security": [
{
"ApiKeyBearer": []
}
],
"x-api-audience": "public_v1",
"x-api-authentication": "required",
"x-operation-id": "v1_create_promotion",
"x-mcp-exposed": true,
"x-public-path": "/v1/promotions",
"x-docs-kind": "create",
"x-docs-order": 10,
"x-docs-depth": 0,
"x-docs-action-order": 1000,
"x-codeSamples": [
{
"lang": "shell",
"label": "curl",
"source": "curl -X POST https://api.openmerchant.dev/v1/promotions \\\n -H 'Authorization: Bearer pr_sk_test_...' \\\n -H 'Content-Type: application/json' \\\n -d '{\n \"name\": \"...\",\n \"market_id\": \"...\",\n \"currency\": \"AED\",\n \"starts_at\": \"2026-06-30T12:00:00Z\",\n \"ends_at\": \"2026-06-30T12:00:00Z\",\n \"arms\": [\n {\n \"kind\": \"percent\",\n \"ttl_minutes\": 1\n }\n ]\n}'"
},
{
"lang": "shell",
"label": "MCP (Streamable HTTP)",
"source": "curl -X POST https://api.openmerchant.dev/mcp/v1 \\\n -H 'Authorization: Bearer pr_sk_test_...' \\\n -H 'Content-Type: application/json' \\\n -d '{\n \"jsonrpc\": \"2.0\",\n \"id\": 1,\n \"method\": \"tools/call\",\n \"params\": {\n \"name\": \"v1_create_promotion\",\n \"arguments\": {\n \"name\": \"...\",\n \"market_id\": \"...\",\n \"currency\": \"AED\",\n \"starts_at\": \"2026-06-30T12:00:00Z\",\n \"ends_at\": \"2026-06-30T12:00:00Z\",\n \"arms\": [\n {\n \"kind\": \"percent\",\n \"ttl_minutes\": 1\n }\n ]\n }\n }\n}'"
},
{
"lang": "typescript",
"label": "MCP SDK (TS)",
"source": "// Reusing a Client connected to /mcp/v1 — see the \"MCP server\" tag for setup.\nconst result = await client.callTool({\n name: \"v1_create_promotion\",\n arguments: {\n \"name\": \"...\",\n \"market_id\": \"...\",\n \"currency\": \"AED\",\n \"starts_at\": \"2026-06-30T12:00:00Z\",\n \"ends_at\": \"2026-06-30T12:00:00Z\",\n \"arms\": [\n {\n \"kind\": \"percent\",\n \"ttl_minutes\": 1\n }\n ]\n},\n});"
}
]
}
GET /v1/promotions/{promotion_id}
Retrieve a promotion
Retrieve one promotion owned by the credential’s merchant.
Parameters, request, responses, and security
{
"tags": [
"promotions"
],
"summary": "Retrieve a promotion",
"description": "Retrieve one promotion owned by the credential’s merchant.",
"operationId": "v1_get_promotion",
"parameters": [
{
"required": true,
"schema": {
"type": "string",
"title": "Promotion Id"
},
"name": "promotion_id",
"in": "path"
}
],
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PublicV1PromotionRead"
}
}
}
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
}
}
},
"security": [
{
"ApiKeyBearer": []
}
],
"x-api-audience": "public_v1",
"x-api-authentication": "required",
"x-operation-id": "v1_get_promotion",
"x-mcp-exposed": true,
"x-public-path": "/v1/promotions/{promotion_id}",
"x-docs-kind": "retrieve",
"x-docs-order": 30,
"x-docs-depth": 0,
"x-docs-action-order": 1000,
"x-codeSamples": [
{
"lang": "shell",
"label": "curl",
"source": "curl -X GET https://api.openmerchant.dev/v1/promotions/... \\\n -H 'Authorization: Bearer pr_sk_test_...'"
},
{
"lang": "shell",
"label": "MCP (Streamable HTTP)",
"source": "curl -X POST https://api.openmerchant.dev/mcp/v1 \\\n -H 'Authorization: Bearer pr_sk_test_...' \\\n -H 'Content-Type: application/json' \\\n -d '{\n \"jsonrpc\": \"2.0\",\n \"id\": 1,\n \"method\": \"tools/call\",\n \"params\": {\n \"name\": \"v1_get_promotion\",\n \"arguments\": {\n \"promotion_id\": \"...\"\n }\n }\n}'"
},
{
"lang": "typescript",
"label": "MCP SDK (TS)",
"source": "// Reusing a Client connected to /mcp/v1 — see the \"MCP server\" tag for setup.\nconst result = await client.callTool({\n name: \"v1_get_promotion\",\n arguments: {\n \"promotion_id\": \"...\"\n},\n});"
}
]
}
PATCH /v1/promotions/{promotion_id}
Update a promotion
Update a promotion; a supplied arms or targets list fully replaces the persisted one. The four caps cannot be cleared: an explicit null leaves one unchanged.
Parameters, request, responses, and security
{
"tags": [
"promotions"
],
"summary": "Update a promotion",
"description": "Update a promotion; a supplied arms or targets list fully replaces the persisted one. The four caps cannot be cleared: an explicit null leaves one unchanged.",
"operationId": "v1_update_promotion",
"parameters": [
{
"required": true,
"schema": {
"type": "string",
"title": "Promotion Id"
},
"name": "promotion_id",
"in": "path"
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PromotionPatch"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PublicV1PromotionRead"
}
}
}
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
}
}
},
"security": [
{
"ApiKeyBearer": []
}
],
"x-api-audience": "public_v1",
"x-api-authentication": "required",
"x-operation-id": "v1_update_promotion",
"x-mcp-exposed": true,
"x-public-path": "/v1/promotions/{promotion_id}",
"x-docs-kind": "other",
"x-docs-order": 100,
"x-docs-depth": 2,
"x-docs-action-order": 1000,
"x-codeSamples": [
{
"lang": "shell",
"label": "curl",
"source": "curl -X PATCH https://api.openmerchant.dev/v1/promotions/... \\\n -H 'Authorization: Bearer pr_sk_test_...'"
},
{
"lang": "shell",
"label": "MCP (Streamable HTTP)",
"source": "curl -X POST https://api.openmerchant.dev/mcp/v1 \\\n -H 'Authorization: Bearer pr_sk_test_...' \\\n -H 'Content-Type: application/json' \\\n -d '{\n \"jsonrpc\": \"2.0\",\n \"id\": 1,\n \"method\": \"tools/call\",\n \"params\": {\n \"name\": \"v1_update_promotion\",\n \"arguments\": {\n \"promotion_id\": \"...\"\n }\n }\n}'"
},
{
"lang": "typescript",
"label": "MCP SDK (TS)",
"source": "// Reusing a Client connected to /mcp/v1 — see the \"MCP server\" tag for setup.\nconst result = await client.callTool({\n name: \"v1_update_promotion\",\n arguments: {\n \"promotion_id\": \"...\"\n},\n});"
}
]
}
DELETE /v1/promotions/{promotion_id}
Delete a promotion
Delete one promotion with its arms and targets.
Parameters, request, responses, and security
{
"tags": [
"promotions"
],
"summary": "Delete a promotion",
"description": "Delete one promotion with its arms and targets.",
"operationId": "v1_delete_promotion",
"parameters": [
{
"required": true,
"schema": {
"type": "string",
"title": "Promotion Id"
},
"name": "promotion_id",
"in": "path"
}
],
"responses": {
"204": {
"description": "Successful Response"
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
}
}
},
"security": [
{
"ApiKeyBearer": []
}
],
"x-api-audience": "public_v1",
"x-api-authentication": "required",
"x-operation-id": "v1_delete_promotion",
"x-mcp-exposed": true,
"x-public-path": "/v1/promotions/{promotion_id}",
"x-docs-kind": "other",
"x-docs-order": 100,
"x-docs-depth": 2,
"x-docs-action-order": 1000,
"x-codeSamples": [
{
"lang": "shell",
"label": "curl",
"source": "curl -X DELETE https://api.openmerchant.dev/v1/promotions/... \\\n -H 'Authorization: Bearer pr_sk_test_...'"
},
{
"lang": "shell",
"label": "MCP (Streamable HTTP)",
"source": "curl -X POST https://api.openmerchant.dev/mcp/v1 \\\n -H 'Authorization: Bearer pr_sk_test_...' \\\n -H 'Content-Type: application/json' \\\n -d '{\n \"jsonrpc\": \"2.0\",\n \"id\": 1,\n \"method\": \"tools/call\",\n \"params\": {\n \"name\": \"v1_delete_promotion\",\n \"arguments\": {\n \"promotion_id\": \"...\"\n }\n }\n}'"
},
{
"lang": "typescript",
"label": "MCP SDK (TS)",
"source": "// Reusing a Client connected to /mcp/v1 — see the \"MCP server\" tag for setup.\nconst result = await client.callTool({\n name: \"v1_delete_promotion\",\n arguments: {\n \"promotion_id\": \"...\"\n},\n});"
}
]
}