OptStuff

Error Codes

Complete reference of all HTTP error codes returned by the OptStuff API, with causes, solutions, and troubleshooting guides.

This page lists all error codes returned by the OptStuff API and provides troubleshooting guidance for common issues.

HEAD requests use a fast path (no image transformation) but still perform a lightweight upstream probe, so upstream-related failures (404 / 410 / 502, and rare 500 fetch failures) can apply to both GET and HEAD.

Error Code Reference

HTTP StatusErrorCauseSolution
400Invalid path formatMalformed URL structureCheck that the URL follows /api/v1/{projectSlug}/{operations}/{imageUrl}
400Invalid image URLUnable to parse image URL from pathVerify the image URL is valid and does not include the protocol (https://)
401Missing signature parameterskey or sig query parameter not providedInclude both ?key={publicKey}&sig={signature} in the URL
401Invalid API keyAPI key not found in databaseVerify the public key (pk_...) is correct
401API key has been revokedKey was explicitly revokedCreate a new API key from the dashboard
401API key has expiredKey is past its expiresAt dateCreate a new key or rotate the existing one
401API key does not belong to this projectPublic key is valid but bound to a different projectUse the correct key for the project, or check projectSlug in the URL
403Invalid or expired signatureHMAC-SHA256 verification failed, or exp has passedSee Troubleshooting Signature Errors below
403Forbidden: Invalid refererReferer header doesn't match project's allowed domainsAdd your domain in project settings (see Domain Whitelisting)
403Forbidden: Source domain not allowedImage source domain not in project's allowed listAdd the domain in project Settings → Domain Security → Image Sources (see Domain Whitelisting)
404Project not foundprojectSlug doesn't match any projectCheck the project slug is correct
429Rate limit exceededPer-minute or per-day limit reachedWait for Retry-After seconds, or increase limits
502Image processing failedUpstream fetch/transform/probe failureVerify source image availability and retry; check upstream origin stability
500Image processing failedInternal error during optimization or upstream fetch error without a mappable status codeCheck that the source image is accessible and in a supported format

Troubleshooting Signature Errors

If you're getting 403 Invalid or expired signature, check these common mistakes:

1. Wrong Key

Make sure you're signing with the secret key (sk_...), not the public key (pk_...).

2. Wrong Path Order

// ✅ Correct: {operations}/{imageUrl}
const path = "w_800,f_webp/images.example.com/photo.jpg";

// ❌ Wrong: {imageUrl}/{operations}
const path = "images.example.com/photo.jpg/w_800,f_webp";

3. Wrong Timestamp Unit

// ✅ Correct: Unix seconds
const exp = Math.floor(Date.now() / 1000) + 3600;

// ❌ Wrong: Unix milliseconds
const exp = Date.now() + 3600000;

4. Expiration Not Included in Payload

If you pass exp in the URL, you must include it in the signed payload:

// ✅ Correct: include exp in payload
const payload = `w_800,f_webp/images.example.com/photo.jpg?exp=1706500000`;

// ❌ Wrong: exp in URL but not in payload
const payload = `w_800,f_webp/images.example.com/photo.jpg`;

5. Wrong Encoding

// ✅ Correct: base64url, truncated to 32 characters
const signature = hmac.digest("base64url").substring(0, 32);

// ❌ Wrong: standard base64 (contains +, /, =)
const signature = hmac.digest("base64");

6. Lost Secret Key

The secret key is only shown once at creation or rotation. If you've lost it:

  1. Go to Dashboard → Project → API Keys
  2. Click Rotate on the key
  3. Copy and save the new secret key
  4. Update your environment variables and redeploy

The public key can always be viewed and copied from the API key list.

Error Response Format

GET error responses include an error field in a JSON body. HEAD error responses return status and headers only (no response body), while using the same status code mapping.

For GET, additional fields may be present depending on the error:

FieldWhen IncludedDescription
errorAlwaysHuman-readable error message
details400 (invalid image URL)Additional context about the failure
usage400 (invalid path), 401 (missing params)Hints showing the correct URL format
examples400 (invalid path)Example valid URLs
reason429Whether the minute or day limit was hit
retryAfter429Seconds to wait before retrying
limit429The limit that was exceeded

Rate Limit Response Format

When a 429 error is returned:

{
  "error": "Rate limit exceeded",
  "reason": "Too many requests per minute",
  "retryAfter": 12,
  "limit": 60
}

HTTP headers:

HTTP/1.1 429 Too Many Requests
Retry-After: 12
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0

Last updated on

On this page