Public API Reference

Download the Public API Reference (.md)

Version 1.0 — Last Updated: April 2026

Base URL: https://app.merchjar.com/api/v5

Authentication

All requests require a valid API key passed as a Bearer token in the Authorization header. Keys use the prefix mj_live_ followed by a random string.

Authorization: Bearer mj_live_abc123def456...

API keys are created and managed in Merch Jar under Settings > API Keys. From there you can create new keys with specific scopes, view active keys (the full key is only shown once at creation), and revoke keys immediately.

Scopes

Each API key is granted one or more scopes that control which endpoints it can access.

  • segments:read — GET /api/v5/segments, GET /api/v5/segments/:id
  • segments:write — POST /api/v5/segments, PATCH /api/v5/segments/:id, DELETE /api/v5/segments/:id
  • segments:preview — POST /api/v5/segments/preview
  • segments:validate — POST /api/v5/segments/validate

A request to an endpoint whose scope is not present on the key returns 403 Forbidden.

Profile Ownership

The API key must belong to a user who owns the profile referenced in the request. If the profile does not exist or is not owned by the key's user, the response is 403 Forbidden.

Rate Limiting

Requests are rate-limited per API key using a sliding window of 120 requests per minute. Every response includes X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers. When the limit is exceeded the response is 429 Too Many Requests with a Retry-After header.

Endpoints

GET /api/v5/profiles

List all Amazon Advertising profiles connected to the authenticated account.

Required scope: segments:read

Returns an array of profile objects. Each profile includes the profile ID, name, country code, currency, marketplace ID, timezone, type (seller or vendor), and managed status. Use managed=true profiles for segment work — these are actively managed in Merch Jar.

{
"data": [
{
"profile_id": "3456789012345678",
"name": "My Store",
"country_code": "US",
"currency_code": "USD",
"type": "seller",
"managed": true
}
]
}

POST /api/v5/segments/validate

Validate a segment trigger expression without executing it. Useful for checking syntax before saving.

Required scope: segments:validate

Request body fields:

  • trigger (string, required) — Segment trigger expression (DSL)
  • ad_type (string, required) — Entity type context for validation

Valid ad_type values: campaigns, ad_groups, keywords, targets, search_terms

Response — Valid (200):

{
"valid": true,
"variables": {
"my_var": "numeric"
}
}

Response — Invalid (422):

{
"valid": false,
"error": {
"code": "parse_error",
"message": "Unexpected token 'xyz' at position 12",
"position": 12
}
}

POST /api/v5/segments/preview

Preview the entities that match a segment trigger expression. Returns paginated rows with metrics and totals. Custom variables defined in the trigger appear in the response as ___variable_name.

Required scope: segments:preview

Request body fields:

  • profile_id (string, required) — Amazon Advertising profile ID
  • trigger (string, required) — Segment trigger expression (DSL)
  • ad_type (string, required) — Entity type to query
  • action (string, required) — Action to preview
  • action_params (object, required) — Parameters for the action
  • page (integer, default: 1) — Page number
  • per_page (integer, default: 25, max: 100) — Results per page

Valid action values: set_state, set_budget, set_default_bid, set_bid, create_negatives

action_params for set_state:

  • value (integer, default: 2) — 1 = enabled, 2 = paused

action_params for set_budget, set_default_bid, set_bid:

  • direction (string, default: "set-to-$") — How to apply the value. Options: set-to-$, increase-%, decrease-%, increase-$, decrease-$
  • value (number or string, default: 0) — Dollar amount, percentage, or variable name
  • source (string, default: "value") — "value" for literal numbers, "variable" for a DSL variable name

action_params for create_negatives: Pass an empty object {}.

Response (200):

{
"data": [
{
"campaign_name": "My Campaign",
"keyword_text": "running shoes",
"clicks": 45,
"spend": 22.50,
"acos": 25.0,
"___my_variable": 3.5
}
],
"pagination": {
"page": 1,
"per_page": 25,
"total": 142,
"last_page": 6
},
"totals": {
"clicks": 1800,
"spend": 900.00,
"sales": 3200.00,
"acos": 28.1
},
"meta": {
"time_periods": ["7d", "30d"],
"variables": { "my_variable": "numeric" }
}
}
totals aggregates across all matching rows, not just the current page. Custom variables defined in the trigger appear as ___variable_name in each row.

GET /api/v5/segments

List all segments for a profile.

Required scope: segments:read
Required header: profileid: <profile_id>

Returns an array of segment objects. Each object includes: id, profile_id, name, enabled, ad_type, trigger, action, action_params, frequency, last_run, created_at, updated_at.

GET /api/v5/segments/:id

Get a single segment by ID.

Required scope: segments:read
Required header: profileid: <profile_id>

Returns a single segment object with the same shape as items in the list endpoint. Returns 404 if not found.

POST /api/v5/segments

Create a new segment.

Required scope: segments:write

Request body fields:

  • profile_id (string, required) — Amazon Advertising profile ID
  • name (string, required) — Segment name, max 255 characters
  • trigger (string, required) — Segment trigger expression (DSL)
  • ad_type (string, required) — Entity type
  • action (string, required) — Action to perform
  • action_params (object, default: {}) — Parameters for the action
  • frequency (string, default: "daily") — How often to run: daily, weekly, monthly
  • enabled (boolean, default: true) — Whether the segment should be active

Returns 201 Created with the new segment object. Returns 422 if the trigger expression is invalid.

PATCH /api/v5/segments/:id

Update an existing segment. Only fields included in the request body are updated — all other fields remain unchanged.

Required scope: segments:write
Required header: profileid: <profile_id>

All fields are optional. Updatable fields: name, trigger, ad_type, action, action_params, frequency, enabled. Returns the updated segment object.

DELETE /api/v5/segments/:id

Delete a segment (soft-delete). The segment is disabled and marked as deleted.

Required scope: segments:write
Required header: profileid: <profile_id>

Returns { "success": true } on success, 404 if not found.

Error Reference

All error responses use a consistent envelope:

{
"error": {
"code": "<error_code>",
"message": "<human-readable message>"
}
}
  • unauthorized (401) — Missing, malformed, or revoked API key
  • forbidden (403) — Key does not own the profile, or is missing the required scope
  • rate_limited (429) — Too many requests; check the Retry-After header
  • invalid_trigger (400) — Trigger expression failed to compile
  • invalid_ad_type (400) — Unrecognized ad_type value
  • invalid_action (400) — Unrecognized action value
  • invalid_frequency (400) — Unrecognized frequency value
  • not_found (404) — Segment not found or does not belong to the authenticated profile
  • missing_profile_id (400) — Profile ID header is missing
  • invalid_id (400) — Segment ID is not a valid numeric string
  • parse_error (422) — Trigger expression has a syntax error (validate endpoint)
  • internal_error (500) — Unexpected server error

Examples

Validate a trigger expression

curl -X POST https://app.merchjar.com/api/v5/segments/validate \
-H "Authorization: Bearer mj_live_abc123def456" \
-H "Content-Type: application/json" \
-d '{
"trigger": "impressions(30d) > 100 AND acos(30d) > 40",
"ad_type": "keywords"
}'

Preview keywords with a bid decrease

curl -X POST https://app.merchjar.com/api/v5/segments/preview \
-H "Authorization: Bearer mj_live_abc123def456" \
-H "Content-Type: application/json" \
-d '{
"profile_id": "3456789012345678",
"trigger": "acos(30d) > 50 AND clicks(30d) > 20",
"ad_type": "keywords",
"action": "set_bid",
"action_params": {
"direction": "decrease-%",
"value": 15,
"source": "value"
}
}'

Preview setting budget from a DSL variable

curl -X POST https://app.merchjar.com/api/v5/segments/preview \
-H "Authorization: Bearer mj_live_abc123def456" \
-H "Content-Type: application/json" \
-d '{
"profile_id": "3456789012345678",
"trigger": "LET $ideal_budget = sales(30d) / 30 * 0.3; spend(7d) > 0",
"ad_type": "campaigns",
"action": "set_budget",
"action_params": {
"direction": "set-to-$",
"value": "ideal_budget",
"source": "variable"
}
}'

Create negative keywords from search terms

curl -X POST https://app.merchjar.com/api/v5/segments/preview \
-H "Authorization: Bearer mj_live_abc123def456" \
-H "Content-Type: application/json" \
-d '{
"profile_id": "3456789012345678",
"trigger": "clicks(30d) > 10 AND sales(30d) = 0",
"ad_type": "search_terms",
"action": "create_negatives",
"action_params": {}
}'

List all segments for a profile

curl https://app.merchjar.com/api/v5/segments \
-H "Authorization: Bearer mj_live_abc123def456" \
-H "profileid: 3456789012345678"

Create a new segment

curl -X POST https://app.merchjar.com/api/v5/segments \
-H "Authorization: Bearer mj_live_abc123def456" \
-H "Content-Type: application/json" \
-d '{
"profile_id": "3456789012345678",
"name": "Pause Zero-Sales Campaigns",
"trigger": "spend(30d) > 100 AND sales(30d) = 0",
"ad_type": "campaigns",
"action": "set_state",
"action_params": { "value": 2 },
"frequency": "daily",
"enabled": true
}'

Update a segment

curl -X PATCH https://app.merchjar.com/api/v5/segments/123 \
-H "Authorization: Bearer mj_live_abc123def456" \
-H "Content-Type: application/json" \
-H "profileid: 3456789012345678" \
-d '{
"name": "Updated Segment Name",
"enabled": false
}'

Delete a segment

curl -X DELETE https://app.merchjar.com/api/v5/segments/123 \
-H "Authorization: Bearer mj_live_abc123def456" \
-H "profileid: 3456789012345678"
PREVIOUS ARTICLE
NEXT ARTICLE