requireMerchantAuth reads Authorization and accepts only Bearer plus a token that starts with mk_live_. A missing header, a non-Bearer scheme, any other prefix, an unknown key, a revoked key, or a completed account deletion is 401 with error Unauthorized and code UNAUTHORIZED. An expired key is 401 with error API key expired and the same code.
The key must be allowed to access {storeId}: the key owner can access that shop, and a key limited to selected shops must list it. The key owner must have manageBlacklist on that shop. A restricted key must include the scope named on the method. blacklist:write also satisfies blacklist:read. A full-access key skips the scope list and still needs manageBlacklist. A failed shop, scope, or permission check is 403 with error Forbidden and code FORBIDDEN.
storeId in the JSON body is ignored. The shop is the {storeId} in the path.
Merchant routes share one limit of 120 requests per 60 seconds per client IP. Over the limit the response is 429 with error Too many requests and code RATE_LIMITED.
There is no GET, PUT, or PATCH on a single entry. Delete is DELETE /blacklist/{entryId}.
List
blacklist:read
Query:
Rows are the shop’s blacklist, newest
createdAt first, then sliced for the page. The response has no hasMore or cursor.
createdAt and updatedAt are ISO timestamps. reason is a string or null. A page past the end returns entries: [] with the same total.
Invalid page or limit returns 400.
Create
blacklist:write
Status 201. The body is the entry, not wrapped in entries.
value is trimmed again when saved.
ip, userAgent, asn, and country require Premium or Business. That check runs first and returns 403 with error IP, user agent, ASN, and country blocks require Premium or Business., code plan_blacklist_advanced_type, requiredPlan premium, and upgradePath /billing. regex on a type the plan already allows requires Premium or Business and returns 403 with error Regex blacklist rules require Premium or Business., code plan_blacklist_regex, and the same requiredPlan and upgradePath. email and discordId with exact are allowed on Free.
matchType: "regex" must be a safe pattern. An invalid or unsafe pattern returns 400. error is the validator message and code is blacklist_unsafe_regex. Other body and query failures use code BAD_REQUEST. Invalid JSON means the body did not parse. JSON body must be an object means the body was not an object. Field errors are the Zod issues joined with ; .
The created object uses the same fields as a list entry.
Delete
blacklist:write
{entryId} is the entry id. A missing entry, or an entry that belongs to another shop, returns 404 (Blacklist entry not found).
Success is 200:
Errors
Error JSON is
{ "success": false, "error": "...", "code": "..." }. Plan limits also return requiredPlan and upgradePath. A 500 also returns errorId.

