Authentication
The Easel API uses Bearer token authentication with API keys. All requests must include a valid API key in the Authorization header.
Authentication Flow
- Obtain an API key from your store's admin panel
- Include the API key in the Authorization header of every request
- The API validates the key and checks that its scopes allow the request
API Key Format
API keys are Bearer tokens that must be included in the Authorization header:
Authorization: Bearer your_api_key_here
Keys generated by Easel start with eas_. Keys are created and revoked from
the store's admin panel, not through the API.
Owners and Managers
A store's dashboard users are owners or managers. Managers do the
day-to-day selling and fulfilling; only owners manage the team, billing,
payments, tax, the activity log, and API keys. Only an owner can create or
delete an API key, so a key acts with an owner's rights, limited to its
scopes. A key's requests work the same whichever owner made it, and keep
working if that owner later becomes a manager or leaves the store; delete
the key to stop them.
Scopes
Each API key has a scope for every resource of the API: none, read,
or write. Write includes read. A GET or HEAD request needs read on
the resource its path belongs to, and a POST, PUT, or DELETE request
needs write. Scopes are written resource:access, such as orders:write,
and each endpoint's page names the scope it needs.
When you create a key in the admin panel, choose Read everything,
Write everything, or Custom to set each resource's access yourself.
Give a key only the scopes its integration needs: a key that syncs stock
needs products:write, not access to customers or refunds. A key's scopes
are fixed when it's made; to change them, create a new key and delete the
old one. Keys can't be managed through the API, so a key can never widen
its own scopes.
| Resource | Endpoints |
|---|---|
products |
/api/v1/products/ and everything under it: options, variants, digital files, images, a product's tags and sites, waitlists, and wishlists |
tags |
/api/v1/tags/ |
collections |
/api/v1/sites/{site_id}/collections/, with their tags |
store_filters |
/api/v1/sites/{site_id}/store-filters/ |
reviews |
/api/v1/reviews/ |
orders |
/api/v1/orders/, with an order's events and downloads |
shipments |
/api/v1/orders/{order_id}/shipments/ and /api/v1/carriers/ |
refunds |
/api/v1/orders/{order_id}/refunds/ |
customers |
/api/v1/customers/, with their addresses |
gift_cards |
/api/v1/gift-cards/ |
discount_codes |
/api/v1/sites/{site_id}/discount-codes/ |
shipping_rates |
/api/v1/sites/{site_id}/shipping-rates/ |
sites |
/api/v1/sites/, with a site's pages and gift options |
translations |
/api/v1/sites/{site_id}/translations/ and /api/v1/sites/{site_id}/languages/ |
taxes |
/api/v1/tax-registrations/ and /api/v1/locations/ |
audit_events |
/api/v1/audit-events/ |
Keys made before scopes existed kept what they could do: a read key reads
every resource, and a write key writes every resource.
Request Headers
All authenticated requests must include:
Authorization: Bearer your_api_key_here
Content-Type: application/json
Authentication Errors
Missing Authorization Header
Status: 401 Unauthorized
{
"error": "Authorization header is required",
"code": "MISSING_AUTHORIZATION"
}
Invalid Authorization Format
Status: 401 Unauthorized
{
"error": "Authorization header must be 'Bearer <token>'",
"code": "INVALID_AUTHORIZATION"
}
Empty API Key
Status: 401 Unauthorized
{
"error": "API key cannot be empty",
"code": "EMPTY_TOKEN"
}
Invalid API Key
Status: 401 Unauthorized
{
"error": "Invalid API key",
"code": "INVALID_API_KEY"
}
Authentication Service Error
Status: 500 Internal Server Error
{
"error": "Internal server error",
"code": "INTERNAL_ERROR"
}
Permission Errors
Insufficient Permissions
The key's scopes don't allow the request. The message names the scope it
needs.
Status: 403 Forbidden
{
"error": "This API key requires orders:write",
"code": "INSUFFICIENT_PERMISSIONS"
}
Method Not Allowed
Status: 405 Method Not Allowed
{
"error": "HTTP method not allowed",
"code": "METHOD_NOT_ALLOWED"
}
Store-Related Errors
Store Not Found
Status: 401 Unauthorized
{
"error": "Store not found",
"code": "STORE_NOT_FOUND"
}
Store Lookup Error
Status: 500 Internal Server Error
{
"error": "Internal server error",
"code": "INTERNAL_ERROR"
}
Store Locked
A store locked for billing, or suspended by Easel for its content (see
Moderation), answers every request so.
Status: 403 Forbidden
{
"error": "Store is locked",
"code": "STORE_LOCKED"
}
Rate Limiting
API requests are rate limited per store. When rate limits are exceeded:
Status: 429 Too Many Requests
{
"error": "API rate limit exceeded",
"code": "RATE_LIMITED"
}
Rate Limit Headers
All authenticated requests include rate limit information in the response headers:
X-Ratelimit-Limit: 60
X-Ratelimit-Remaining: 59
X-Ratelimit-Reset: 1672531200
X-Ratelimit-Limit: Maximum requests allowed per time window (60 per minute)X-Ratelimit-Remaining: Requests remaining in current windowX-Ratelimit-Reset: Unix timestamp when the rate limit resets (the next minute boundary)
Rate Limit Service Error
Status: 500 Internal Server Error
{
"error": "Internal server error",
"code": "INTERNAL_ERROR"
}
Example Authenticated Request
curl -X GET "https://studio.easel.engineering/api/v1/products/" \
-H "Authorization: Bearer your_api_key_here" \
-H "Content-Type: application/json"
Security Best Practices
- Keep API keys secure - Never expose API keys in client-side code or public repositories
- Use HTTPS - All API requests should be made over HTTPS
- Rotate keys regularly - Generate new API keys periodically
- Use the narrowest scopes - Grant only the scopes your integration needs
- Monitor usage - Keep track of API key usage and watch for unusual activity