Locations API
A location is a place the store sells in person, such as a shop, a market
stall, or a pop-up. Locations belong to the store, and each is offered at
the checkouts of the sites you pick. A location holds no stock of its own;
each variant still has one stock quantity.
Locations matter for tax: goods handed over in person are taxed where the
sale happens, not where the buyer lives, so a sale at a location that ships
nothing is taxed at the location. The store still collects tax only where it
has a tax registration.
Endpoints
- List Locations -
GET /api/v1/locations/ - Create Location -
POST /api/v1/locations/ - Get Location -
GET /api/v1/locations/{location_id}/ - Update Location -
PUT /api/v1/locations/{location_id}/ - Delete Location -
DELETE /api/v1/locations/{location_id}/
List Locations
Retrieve where the store sells in person, ordered by name. A store has at
most 100 locations.
Endpoint: GET /api/v1/locations/
Scope Required: taxes:read
Query Parameters
| Parameter | Type | Description |
|---|---|---|
after |
string | Cursor for pagination. Location ID to return locations after (e.g., loc_d0b6fmv28q6vn14peun0) |
before |
string | Cursor for pagination. Location ID to return locations before, for paging back |
limit |
integer | Number of locations to return (default 10, max 100) |
The response reports has_more, which is true when another page follows.
A malformed after or before, both at once, or an invalid limit returns
INVALID_REQUEST_ERROR.
Request
curl -X GET "https://studio.easel.engineering/api/v1/locations/?limit=20" \
-H "Authorization: Bearer your_api_key_here"
Response
Status: 200 OK
{
"data": [
{
"id": "loc_d0b6fmv28q6vn14peun0",
"name": "Chicago shop",
"country": "US",
"region": "IL",
"sites": ["sit_d0b6fmv28q6vn14peun1"],
"created_at": "2026-10-25T10:00:00Z",
"updated_at": "2026-10-25T10:00:00Z"
}
],
"has_more": false
}
Create Location
Add a place the store sells in person.
Endpoint: POST /api/v1/locations/
Scope Required: taxes:write
Request Body
{
"name": "Chicago shop",
"country": "US",
"region": "IL",
"sites": ["sit_d0b6fmv28q6vn14peun1"]
}
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | 1 to 64 characters, unique within the store |
country |
string | Yes | ISO 3166-1 alpha-2 country code, such as US. See Country Codes |
region |
string | No | Subdivision code, such as IL for Illinois or BC for British Columbia. Required in the US and Canada, where tax depends on the state or province. Leave it out where Easel lists no regions for the country |
sites |
array | No | IDs of the sites whose checkouts offer the location, at least one. Leave it out to offer it at every site |
Request
curl -X POST "https://studio.easel.engineering/api/v1/locations/" \
-H "Authorization: Bearer your_api_key_here" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: unique-request-id-12345" \
-d '{"name": "Chicago shop", "country": "US", "region": "IL"}'
Response
Status: 201 Created
Returns the Location Object.
Error Responses
Invalid field
Status: 400 Bad Request
{
"error": "Another location has this name",
"code": "INVALID_FIELD"
}
The country must be the code of a country Easel knows, the region must
be one Easel lists for the country, every ID in sites must be one of the
store's sites, and a store can have at most 100 locations.
Get Location
Endpoint: GET /api/v1/locations/{location_id}/
Scope Required: taxes:read
Response
Status: 200 OK
Returns the Location Object.
Update Location
Replace a location with the one in the request, which takes the same fields
as Create Location. Leaving out sites offers the
location at every site again. Orders already sold there keep the tax they
were charged.
Endpoint: PUT /api/v1/locations/{location_id}/
Scope Required: taxes:write
Request Body
{
"name": "Chicago shop",
"country": "US",
"region": "IL",
"sites": ["sit_d0b6fmv28q6vn14peun1", "sit_d0b6fmv28q6vn14peun2"]
}
Response
Status: 200 OK
Returns the Location Object.
Delete Location
Stop selling at a location. Orders already sold there keep the tax they
were charged.
Endpoint: DELETE /api/v1/locations/{location_id}/
Scope Required: taxes:write
Response
Status: 204 No Content
Location Object
| Field | Type | Description |
|---|---|---|
id |
string | Location public ID |
name |
string | The location's name |
country |
string | ISO 3166-1 alpha-2 country code |
region |
string|null | Subdivision code, or null where the country has none |
sites |
array | IDs of the sites whose checkouts offer the location |
created_at |
string | ISO 8601 timestamp |
updated_at |
string | ISO 8601 timestamp |