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/:idsegments:write, POST /api/v5/segments, PATCH /api/v5/segments/:id, DELETE /api/v5/segments/:idsegments:preview, POST /api/v5/segments/previewsegments: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 IDtrigger(string, required), Segment trigger expression (DSL)ad_type(string, required), Entity type to queryaction(string, required), Action to previewaction_params(object, required), Parameters for the actionpage(integer, default: 1), Page numberper_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 namesource(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" }
}
}
totalsaggregates across all matching rows, not just the current page. Custom variables defined in the trigger appear as___variable_namein 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 IDname(string, required), Segment name, max 255 characterstrigger(string, required), Segment trigger expression (DSL)ad_type(string, required), Entity typeaction(string, required), Action to performaction_params(object, default:{}), Parameters for the actionfrequency(string, default:"daily"), How often to run:daily,weekly,monthlyenabled(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 keyforbidden(403), Key does not own the profile, or is missing the required scoperate_limited(429), Too many requests; check theRetry-Afterheaderinvalid_trigger(400), Trigger expression failed to compileinvalid_ad_type(400), Unrecognized ad_type valueinvalid_action(400), Unrecognized action valueinvalid_frequency(400), Unrecognized frequency valuenot_found(404), Segment not found or does not belong to the authenticated profilemissing_profile_id(400), Profile ID header is missinginvalid_id(400), Segment ID is not a valid numeric stringparse_error(422), Trigger expression has a syntax error (validate endpoint)internal_error(500), Unexpected server error