Skip to main content
This page is reference material.If you are troubleshooting a theme workflow, start with the workflow pages first:Then come back here if you need the exact error shape or status-code meaning.

Error Response Format

All errors follow a consistent structure:
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid email address",
    "doc_url": "https://docs.shoppex.io/api/errors#VALIDATION_ERROR",
    "details": [
      { "field": "email", "message": "must be a valid email" }
    ]
  }
}
FieldTypeDescription
codestringMachine-readable error code
messagestringHuman-readable description
doc_urlstringLink to relevant documentation
detailsarrayField-level validation errors (optional)

HTTP Status Codes

CodeNameDescription
200OKRequest succeeded
201CreatedResource created successfully
204No ContentSuccess with no response body (e.g., DELETE)
400Bad RequestDomain-specific or business rule error
401UnauthorizedMissing or invalid API key
403ForbiddenValid key but insufficient permissions
404Not FoundResource doesn’t exist
422Validation ErrorInvalid field values
429Too Many RequestsRate limit exceeded
500Server ErrorSomething went wrong on our end

Error Codes Reference

Authentication Errors

HTTP 401 - API key is missing or invalid.
{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid API key.",
    "doc_url": "https://docs.shoppex.io/api/errors#UNAUTHORIZED"
  }
}
Solution: Check that your API key is correct and included in the Authorization header.
HTTP 403 - Your API key is valid but lacks the required scope for this endpoint.
{
  "error": {
    "code": "FORBIDDEN",
    "message": "Missing required API scope.",
    "doc_url": "https://docs.shoppex.io/api/errors#FORBIDDEN"
  }
}
Solution: Go to Settings β†’ API Keys, check which scopes your key has, and add the missing one. Use GET /me/capabilities to inspect active scopes at runtime.
HTTP 403 - Your shop has been suspended by Shoppex.
{
  "error": {
    "code": "FORBIDDEN",
    "message": "Your shop has been suspended.",
    "doc_url": "https://docs.shoppex.io/api/errors#FORBIDDEN"
  }
}
Solution: Contact support at [email protected] to resolve the suspension. This is an account-level issue, not a key configuration problem.

Validation Errors

HTTP 422 - One or more fields failed validation.
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation failed",
    "details": [
      { "field": "email", "message": "must be a valid email" },
      { "field": "price", "message": "must be a positive number" }
    ]
  }
}
Solution: Check the details array for specific field errors.

Request Error Semantics

Use the status code as the first signal:
  • 422 VALIDATION_ERROR means the request shape or field values are invalid
  • 400 means the request was understood, but a business rule rejected it
  • 404 can be generic NOT_FOUND or resource-specific like PRODUCT_NOT_FOUND
For example: a wrong email format on POST /customers returns 422 VALIDATION_ERROR, an expired license on POST /licenses/validate returns 400 LICENSE_EXPIRED, and a missing product on GET /products/prod_xyz returns 404 PRODUCT_NOT_FOUND.

Theme Workflow Troubleshooting

If you are using the theme automation flow:
  • 401 usually means your API key is missing or invalid
  • 403 usually means your key is missing themes.read or themes.write
  • 422 usually means the request body or params are wrong
  • 500 usually means the server failed while validating, previewing, publishing, or reading the theme
The most common mistake: theme.inspect fails with 403 because your key is missing themes.read, and theme.apply fails with 403 because it needs themes.write. A 422 usually means a bad request body or theme id, while 500 means something broke server-side β€” inspect the error and retry.

Resource Errors

HTTP 404 - The requested resource doesn’t exist.
{
  "error": {
    "code": "NOT_FOUND",
    "message": "Requested resource not found",
    "doc_url": "https://docs.shoppex.io/api/errors#NOT_FOUND"
  }
}
Solution: Verify the resource ID is correct.
HTTP 404 - Specific product not found.
{
  "error": {
    "code": "PRODUCT_NOT_FOUND",
    "message": "Product with ID 'prod_xyz' not found",
    "doc_url": "https://docs.shoppex.io/api/errors#PRODUCT_NOT_FOUND"
  }
}
HTTP 404 - Specific invoice not found.
{
  "error": {
    "code": "INVOICE_NOT_FOUND",
    "message": "Invoice with ID 'inv_abc' not found",
    "doc_url": "https://docs.shoppex.io/api/errors#INVOICE_NOT_FOUND"
  }
}
HTTP 404 - Payment not found.
{
  "error": {
    "code": "PAYMENT_NOT_FOUND",
    "message": "Payment with ID 'pay_xyz' not found",
    "doc_url": "https://docs.shoppex.io/api/errors#PAYMENT_NOT_FOUND"
  }
}
HTTP 404 - Customer not found.
{
  "error": {
    "code": "CUSTOMER_NOT_FOUND",
    "message": "Customer with ID 'cust_abc' not found",
    "doc_url": "https://docs.shoppex.io/api/errors#CUSTOMER_NOT_FOUND"
  }
}
HTTP 404 - Category not found.
{
  "error": {
    "code": "CATEGORY_NOT_FOUND",
    "message": "Category with ID 'cat_xyz' not found",
    "doc_url": "https://docs.shoppex.io/api/errors#CATEGORY_NOT_FOUND"
  }
}
HTTP 404 - Coupon not found.
{
  "error": {
    "code": "COUPON_NOT_FOUND",
    "message": "Coupon with ID 'coup_abc' not found",
    "doc_url": "https://docs.shoppex.io/api/errors#COUPON_NOT_FOUND"
  }
}
HTTP 404 - Subscription not found.
{
  "error": {
    "code": "SUBSCRIPTION_NOT_FOUND",
    "message": "Subscription with ID 'sub_xyz' not found",
    "doc_url": "https://docs.shoppex.io/api/errors#SUBSCRIPTION_NOT_FOUND"
  }
}
HTTP 404 - Support ticket not found.
{
  "error": {
    "code": "TICKET_NOT_FOUND",
    "message": "Ticket with ID 'tkt_abc' not found",
    "doc_url": "https://docs.shoppex.io/api/errors#TICKET_NOT_FOUND"
  }
}
HTTP 404 - Review not found.
{
  "error": {
    "code": "REVIEW_NOT_FOUND",
    "message": "Review with ID 'rev_xyz' not found",
    "doc_url": "https://docs.shoppex.io/api/errors#REVIEW_NOT_FOUND"
  }
}
HTTP 404 - Escrow transaction not found.
{
  "error": {
    "code": "ESCROW_NOT_FOUND",
    "message": "Escrow with ID 'esc_abc' not found",
    "doc_url": "https://docs.shoppex.io/api/errors#ESCROW_NOT_FOUND"
  }
}

License Errors

HTTP 404 - License key not found.
{
  "error": {
    "code": "LICENSE_NOT_FOUND",
    "message": "License key not found",
    "doc_url": "https://docs.shoppex.io/api/errors#LICENSE_NOT_FOUND"
  }
}
HTTP 400 - License key is invalid or malformed.
{
  "error": {
    "code": "LICENSE_INVALID",
    "message": "Invalid license key format",
    "doc_url": "https://docs.shoppex.io/api/errors#LICENSE_INVALID"
  }
}
HTTP 400 - License key has expired.
{
  "error": {
    "code": "LICENSE_EXPIRED",
    "message": "License key has expired",
    "doc_url": "https://docs.shoppex.io/api/errors#LICENSE_EXPIRED"
  }
}
HTTP 400 - Hardware ID does not match the registered device.
{
  "error": {
    "code": "LICENSE_HWID_MISMATCH",
    "message": "Hardware ID mismatch. License is bound to a different device.",
    "doc_url": "https://docs.shoppex.io/api/errors#LICENSE_HWID_MISMATCH"
  }
}

Coupon Errors

HTTP 400 - Coupon has expired.
{
  "error": {
    "code": "COUPON_EXPIRED",
    "message": "This coupon has expired",
    "doc_url": "https://docs.shoppex.io/api/errors#COUPON_EXPIRED"
  }
}
HTTP 400 - Coupon has reached maximum uses.
{
  "error": {
    "code": "COUPON_MAX_USES_REACHED",
    "message": "This coupon has reached its maximum number of uses",
    "doc_url": "https://docs.shoppex.io/api/errors#COUPON_MAX_USES_REACHED"
  }
}

Idempotency Errors

HTTP 422 - The same idempotency key was used with a different request body.
{
  "error": {
    "code": "IDEMPOTENCY_CONFLICT",
    "message": "Idempotency key already used with a different request body",
    "doc_url": "https://docs.shoppex.io/api/errors#IDEMPOTENCY_CONFLICT"
  }
}
Solution: Each unique request body needs its own idempotency key. If you’re retrying a failed request, make sure the body matches the original. See the Idempotency section for details.

Rate Limiting

HTTP 429 - Too many requests.
{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Rate limit exceeded. Retry after the reset window.",
    "doc_url": "https://docs.shoppex.io/api/errors#RATE_LIMITED"
  }
}
Response headers:
  • X-RateLimit-Limit
  • X-RateLimit-Remaining
  • X-RateLimit-Reset
  • Retry-After when blocked
Solution: Wait for Retry-After or X-RateLimit-Reset before retrying.

Handling Errors in Code

Every Dev API error response also returns X-Request-Id in the headers. Log that value together with error.code when you need support or want to trace a failing request.
async function createPayment(title: string, email: string, value: number) {
  const response = await fetch('https://api.shoppex.io/dev/v1/payments', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ title, email, value, currency: 'USD' })
  });

  const result = await response.json();

  if (!response.ok) {
    const error = result.error;

    switch (error.code) {
      case 'VALIDATION_ERROR':
        // Handle field-level errors
        error.details?.forEach(d => console.error(`${d.field}: ${d.message}`));
        break;
      case 'RATE_LIMITED':
        // Wait and retry
        const retryAfter = Number(response.headers.get('retry-after') ?? '2');
        console.log(`Rate limited. Waiting ${retryAfter}s before retry...`);
        await new Promise(r => setTimeout(r, retryAfter * 1000));
        return createPayment(title, email, value);
      case 'UNAUTHORIZED':
        console.error('Invalid API key');
        break;
      default:
        console.error(`Error: ${error.message}`);
    }

    throw new Error(error.message);
  }

  return result.data;
}

Best Practices

Log Error Codes

Always log the error.code for debugging. It’s more reliable than parsing messages.

Handle 429s Gracefully

Implement exponential backoff for rate limits. Check X-RateLimit-Reset header.

Validate Before Sending

Validate inputs client-side to catch errors early and reduce API calls.

Use Idempotency Keys

For payment creation, use idempotency keys to safely retry failed requests.