API Documentation
PRE-RELEASE WARNING: This API is currently in pre-release and undergoing rapid development. Breaking changes are occurring frequently as we work toward a stable v1 release. Please use caution when building production systems against this API during the pre-release period.
The Easel API is a RESTful HTTP API for your ecommerce store. Use it to keep inventory in sync, or to pull orders and customer data into your own tools.
What can you do with the API?
- Manage your catalog: Create and update products, variants, options, images, and tags
- Process orders: Update order status, record shipments and refunds, and manage digital downloads
- Manage customers: Store customer information and their addresses
- Configure storefronts: Manage sites, pages, collections, discount codes, and more
Base URL
/api/v1/
Authentication
All API endpoints require authentication using Bearer tokens. See the Authentication documentation for details.
Response Format
All API responses use JSON format. Single resources are returned as a JSON object:
{
"id": "pro_d0b6fmv28q6vn14peun0",
"name": "Example Product",
"status": "active",
"created_at": "2023-01-01T00:00:00Z"
}
List endpoints wrap results in a data array:
{
"data": [
{
"id": "pro_d0b6fmv28q6vn14peun0",
"name": "Example Product"
}
],
"has_more": true
}
Some list endpoints are not paginated and return only data.
Error responses include a descriptive message and an error code:
{
"error": "Resource not found",
"code": "NOT_FOUND"
}
Common error codes include INVALID_JSON, MISSING_FIELD, INVALID_FIELD, INVALID_REQUEST_ERROR, REQUEST_TOO_LARGE, NOT_FOUND, DUPLICATE, CONFLICT, ORDER_CANCELED, TOO_MANY_VARIANTS, and INTERNAL_ERROR.
Request bodies are limited to 1 MiB, except on the file upload endpoints,
which document their own limits. A larger body returns
413 Request Entity Too Large:
{
"error": "Request body is too large",
"code": "REQUEST_TOO_LARGE"
}
Query parameter validation failures use the INVALID_REQUEST_ERROR code. The
error message names the offending parameter, for example:
{
"error": "Invalid 'limit' parameter: cannot exceed 100",
"code": "INVALID_REQUEST_ERROR"
}
Pagination
Lists support cursor-based pagination using the after and before query
parameters, plus limit:
after: Return results after this public IDbefore: Return results before this public IDlimit: Number of results to return (default 10, max 100)afterandbeforecannot be used together
A list keeps one order whichever way you page: a page from before comes in
the same order as a page from after, and holds the results nearest the
cursor. Products, orders, and customers come oldest first; each list's docs
give its order. Searches and filters page with after and before like the
plain list.
Gift card lists also accept a status filter. Order lists also accept
status and refund_status filters, and customer lists accept email and
search filters. The product and customer lists also accept external_source
and external_id to find an imported
record. The waitlisted products
list accepts search and ranks by waiting count, as
does the wishlisted products list. The review
list accepts product, customer, and status filters,
newest first. The translation
list pages by each translation's
cursor, and accepts status, language, and product filters.
The activity log accepts entity_type, entity_id,
and actor filters, newest first.
Paginated responses include a has_more boolean.
Example:
GET /api/v1/products/?after=pro_d0b6fmv28q6vn14peun0&limit=20
Idempotency
To ensure safe retries of write operations (POST and PUT requests), you can provide an Idempotency-Key header. This prevents duplicate operations if a request is retried due to network issues or timeouts.
How it Works
- Include an
Idempotency-Keyheader with a unique string (1 to 256 characters) in your POST or PUT request - If the request succeeds, the response is cached for 24 hours
- Subsequent requests with the same key return the cached response without executing the operation again
- The
X-Idempotency-Replayedheader indicates whether the response was replayed from cache
File uploads (product images, digital files, and gift option images) ignore the Idempotency-Key header: a file is too large to buffer and hash, so uploading it twice stores it twice.
Example
curl -X POST "https://studio.easel.engineering/api/v1/products/" \
-H "Authorization: Bearer your_api_key_here" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: unique-request-id-12345" \
-d '{
"name": "Premium T-Shirt",
"description": "High-quality cotton t-shirt"
}'
Response Headers
When a request includes an Idempotency-Key, the response includes:
X-Idempotency-Replayed: false- Request was processed normallyX-Idempotency-Replayed: true- Response was returned from cache
Important Notes
- Idempotency keys are scoped to your store: a key is shared by every API key in the store, so each key must be unique for the whole store
- Only successful responses (2xx status codes) are cached. Failed requests release the key so it can be retried
- The request body must match exactly for the cached response to be returned. Reusing a key with a different method, path, or body returns
400 Bad Request - Different request methods or paths require different idempotency keys
- Retrying a key while the original request is still in flight returns
409 Conflict; retry after a short delay - Keys are optional. Without a key, requests are processed normally
Imports and External References
Products, product variants, product images, collections, and customers can
record the ID they had in the system they were imported from, such as Shopify
or Etsy. An importer uses this to find what an earlier run created, so it can
run again after a partial failure without making duplicates.
Set both fields when creating the record:
external_source: the system's name, up to 32 lowercase letters, digits,
-, or_(for exampleshopify)external_id: the record's ID in that system, up to 256 characters
Both must be set together, and they can only be set on create; updates ignore
them. Every resource returns both fields, which are null for records made in
Easel.
A reference is unique per store and resource type. Creating a record with a
reference that's already taken returns 409 Conflict with the existing
record's ID, so the importer can update it instead:
{
"error": "A record with this external reference already exists",
"code": "DUPLICATE",
"id": "pro_d0b6fmv28q6vn14peun0"
}
To look a record up before creating it, filter the product or customer list by
both fields. The response's data holds the one matching record, or nothing,
and the other filters and cursor are ignored:
GET /api/v1/products/?external_source=shopify&external_id=632910392
Variants, images, and collections are listed by their product or site, and
each item includes its reference, so match on those fields. When a merchant
deletes a customer, its reference is cleared, so a later import creates the
customer again.
An external reference makes a create safe to repeat across runs, while an
Idempotency-Key makes a single request safe to retry. An importer can use
both.
HTTP Status Codes
200 OK- Request successful201 Created- Resource created204 No Content- Request successful, no response body400 Bad Request- Invalid request data401 Unauthorized- Authentication required or invalid403 Forbidden- The API key's scopes don't allow the request404 Not Found- Resource not found405 Method Not Allowed- Unsupported HTTP method409 Conflict- Resource already exists (aDUPLICATEerror for an
external reference includes the existing record'sid), or the
resource's state doesn't allow the change:CONFLICT, such as canceling
a shipment whose label hasn't been voided,ORDER_CANCELED, which
refuses to ship an order the customer canceled,SYSTEM_COLLECTION,
which refuses to change New Arrivals or Best Sellers, or
TOO_MANY_VARIANTS, which refuses a variant, options or an option value
that would take a product past 100 variants413 Request Entity Too Large- Request body or uploaded file exceeds the size limit429 Too Many Requests- Rate limit exceeded500 Internal Server Error- Server error
Rate Limiting
API requests are rate limited per store at 60 requests per minute. Rate limit information is returned in response headers:
X-Ratelimit-Limit: Total requests allowed per windowX-Ratelimit-Remaining: Requests remaining in the current windowX-Ratelimit-Reset: Unix timestamp when the rate limit resets
When the limit is exceeded, the API returns 429 Too Many Requests.
Data Types
Timestamps
All timestamps are returned in RFC3339 format (ISO 8601):
2023-01-01T00:00:00Z
IDs
Public IDs are used for all external-facing identifiers:
- Products:
pro_d0b6fmv28q6vn14peun0 - Orders:
ord_d0b6fmv28q6vn14peun0 - Customers:
cus_d0b6fmv28q6vn14peun0 - Variants:
prv_d0b6fmv28q6vn14peun0 - Sites:
sit_d0b6fmv28q6vn14peun0
Paginated list cursors use these public IDs.
Monetary Values
All monetary values are integers in the smallest currency unit for your store's currency (for example, cents for USD and yen for JPY):
{
"price": 1999,
"total": 2599
}
API Reference
| Resource | Description |
|---|---|
| Activity Log | Read who changed which product or setting, and when |
| Authentication | API key authentication and scopes |
| Carriers | Look up carrier IDs |
| Collections | Group products on a site |
| Customer Addresses | Manage customer addresses |
| Customers | Store and manage customer information |
| Digital Files | Manage downloadable variant files |
| Discount Codes | Manage site discount codes |
| Gift Options | Manage gift wrapping and other gift options |
| Gift Cards | Issue gift cards and manage their balances |
| Shipments | Record shipments and tracking |
| Order Downloads | Manage digital download links |
| Locations | Choose where the store sells in person |
| Orders | Process and manage customer orders |
| Pages | Manage home and info page content |
| Product Images | Upload and manage product photos |
| Product Options | Manage option choices such as size and color |
| Product Variants | Handle prices, inventory, and sales |
| Products | Manage your product catalog |
| Refunds | List and create refunds |
| Restock Waitlist | Track shoppers waiting for a restock |
| Reviews | Read and moderate product reviews |
| Shipping Rates | Set what each site charges to ship |
| Sites | Manage storefront sites |
| Store Filters | Promote product options to storefront filters |
| Tax Registrations | Choose where the store collects tax |
| Tags | Organize products with tags |
| Translations | Offer a site in other languages and translate its content |
| Wishlists | Track products shoppers have saved |