Eto API
Build on Eto’s infrastructure: Etsy marketplace data, listing creation, orders, finance, product research and AI content, all behind one REST API and one key.
/api/v1/. There is also a v2 preview reference — a fuller document covering the same v1 routes plus the whole Etsy marketplace data model. It is a documentation preview, not a second API.
For AI agents
This page is written to be read by software as well as by people. Everything below is also published in machine-readable form, generated from the same source, so an agent given only this URL can discover the whole API and build a correct request without scraping the HTML.
| Fetch this | To get |
|---|---|
| llms.txt | Index of every endpoint with a one-line description, in the llms.txt format. Start here. |
| llms-full.txt | This entire reference as one Markdown file: auth, limits, errors and every endpoint with runnable examples. |
| openapi.json | OpenAPI 3.1. Every operation has a stable operationId, typed parameters and the full error catalogue. |
| Any page as Markdown | Add .md to a section, or send Accept: text/markdown to this page. Each endpoint has its own file under /dev/docs/<category>/<slug>.md. |
| where-everything-is.md | The app itself: every page, section and feature with the exact path through the interface. Also as JSON at feature-map.json. |
| MCP server | The same API as MCP tools, one per operation, named after the operation ID. |
Any section of this page is available as Markdown: send Accept: text/markdown to this URL, add ?format=md, or fetch https://eto.tools/dev/docs/index.md. Anchors are #ep- followed by the endpoint slug, and each endpoint below carries its slug, operation ID and Markdown URL as data- attributes.
Base URL
Every endpoint hangs off one host. Paths on this page are written relative to it.
https://eto.tools/api/v1/
Authentication
Every request carries an API key in the X-Eto-API-Key header. Generate, rotate and revoke keys in the API console in your Eto dashboard.
curl -H "X-Eto-API-Key: eto_your_key_here" \
"https://eto.tools/api/v1/listings/search?keywords=wallet"
One key opens every endpoint on this page, scoped to your own account and the stores connected to it. Treat it like a password: if it leaks, rotate it in the console and the old key stops working immediately.
OAuth bearer tokens
MCP clients that sign in with Eto send Authorization: Bearer <token> instead of a key. Both forms are accepted on every endpoint and resolve to the same account. See Connect an AI client.
INVALID_API_KEY, and access stops the moment a plan is downgraded.
Rate limits
Two limits apply, both counted per account rather than per key — rotating a key does not reset them.
Retry-After: 1.Retry-After counts the seconds to the reset.Every response, successful or not, carries the current budget:
X-RateLimit-Limit-Second: 2
X-RateLimit-Remaining-Second: 1
X-RateLimit-Limit-Day: 5000
X-RateLimit-Remaining-Day: 4987
A refused request returns the standard error body, so you can tell the two limits apart:
{
"error": {
"code": "RATE_LIMIT_SECOND",
"status": 429,
"message": "Rate limit exceeded (2 requests/second).",
"hint": "Wait 1s before retrying.",
"docs": "https://eto.tools/dev/docs#rate-limits"
}
}
Retry on 429 after the Retry-After header says to, and back off exponentially if it happens repeatedly.
Pagination
List endpoints page with limit and offset query parameters. Both are optional; each endpoint documents its own default and ceiling, and asking for more than the ceiling is clamped rather than rejected.
| Name | Type | Required | Description |
|---|---|---|---|
| limit | integer | optional | Rows to return. Marketplace endpoints default to 25 (max 100); Eto orders default to 20 (max 200). |
| offset | integer | optional | Rows to skip. Default 0. |
Responses carry the total alongside the page, so you can stop when offset + len(results) >= count:
{
"count": 1000,
"results": [ /* … up to `limit` rows … */ ]
}
orders, deliveries — and return total next to it. The per-endpoint response examples below show the exact field names.
Store connection
Endpoints that read or write shop data need that Etsy shop connected to your Eto account. Connect one at eto.tools/dashboard/stores, then list the shop ids with GET /api/v1/stores.
Store connection uses OAuth and must be done through the Eto dashboard — there is no API endpoint for this. Once connected, Eto manages credential refresh automatically.
Listing Builder
Listing Builder guide
How It Works
The ETO Listing Builder lets you create Etsy listings with a single API call. ETO handles all the complexity — variation property ordering, Cartesian product completion, price/quantity/SKU auto-detection, image uploading, category attributes, and personalization.
Three modes:
| state="draft" | Saves to ETO only. Zero Etsy calls. Instant. You can review and edit in the ETO dashboard before publishing. |
| state="publish" | Saves to ETO + publishes to Etsy as a draft listing. Synchronous: the request blocks for roughly 5–15 seconds per shop and returns the final results (including Etsy image URLs) in the response body. |
| state="active" | Same as publish + activates on Etsy. Costs $0.20 USD per listing per shop. |
You can only publish to Etsy shops connected to your ETO account. Use GET /api/v1/stores to see your connected shops.
Step 1: Get Your Store Data
Before creating a listing, you need IDs for shipping profiles, return policies, processing profiles, and shop sections. We give you four dedicated "live" endpoints — one per profile type. Each one is a single GET, makes ONE Etsy API call, returns the absolute latest data right now, never from cache.
Live profile endpoints (always fresh, no cache):
| GET | /api/v1/stores/{shop_id}/shipping-profiles/live | shipping_profile_id |
| GET | /api/v1/stores/{shop_id}/return-policies/live | return_policy_id |
| GET | /api/v1/stores/{shop_id}/processing-profiles/live | processing_profile_id (a.k.a. readiness_state_id) |
| GET | /api/v1/stores/{shop_id}/shop-sections/live | shop_section_id |
Each response is the same shape:
{
"shop_id": "12345678",
"fetched_at": "2026-04-19T14:30:00Z",
"count": 2,
"<profile_type>": [ { "<id_field>": ..., "title": "...", ... } ]
}Example — fetch all four in parallel from your client:
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/stores/12345678/shipping-profiles/live"
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/stores/12345678/return-policies/live"
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/stores/12345678/processing-profiles/live"
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/stores/12345678/shop-sections/live"IDs you will need when building the listing payload:
| shipping_profile_id | Required for physical listings. |
| return_policy_id | Required for physical listings. |
| processing_profile_id | Controls how the processing time is shown. |
| shop_section_id | Optional. Files the listing under a shop section. |
Why use these instead of /details or /sync?
| /details | Serves cached data. It can be stale, and it omits return_policies and processing_profiles. |
| /sync | Refreshes everything in one shot, but it is heavier (about 5 Etsy calls). Use it only when you want the full snapshot refreshed. |
| /live | The simplest path: pick the profile type you need, get the latest data, done. |
Step 2: Get the Category Schema
Each Etsy category has different attributes. Call the schema endpoint to discover them:
GET /api/v1/categories/{category_id}/listing-schemaThis returns:
- required_fields: title, description, price, quantity, taxonomy_id, listing_type
- optional_fields: tags, materials, styles, sku, who_made, when_made, dimensions, weight, etc.
- category_attributes: dynamic attributes for this category (e.g. Primary color, Sleeve length, Neckline)
Each attribute has: property_id, name, required, possible_values (with value_id and name), scales
- variation_properties: which properties can be used for product variations (e.g. Color, Size)Cache this response — categories rarely change.
Example: Category 482 (T-Shirts) has 11 attributes:
Materials, Primary color, Secondary color, Size, Sustainability, Sleeve length,
Neckline, Clothing style, Occasion, Holiday, Graphic
Step 3: Upload Images (Two Options)
Option A — Remote URLs:
Pass publicly accessible URLs directly in images[].url. ETO downloads them server-side.
Example: "url": "https://i.etsystatic.com/12345/image.jpg"Option B — Local files:
1. Upload your file: POST /api/v1/uploads (multipart/form-data with "file" field)
2. Use the returned eto-upload:// URL in images[].urlExample:
curl -X POST -H "X-Eto-API-Key: eto_..." -F "file=@my_photo.jpg" -F "type=image" https://eto.tools/api/v1/uploads
Response: {"url": "eto-upload:///path/to/file.jpg", ...}
Then use: "images": [{"url": "eto-upload:///path/to/file.jpg", "rank": 1}]Images:
- Min 1, max 20 per listing
- Formats: JPG, PNG, GIF (max 100MB each)
- rank: 1-20 (rank 1 = primary photo shown to buyers)
- For variation images: use the index (0-based) in variation_images.mapping
Step 4: Create the Listing
Send a single POST with everything:
POST /api/v1/listings/createThe request body is a JSON object with these top-level keys:
state, shops[], listing{}, images[], personalization{}, category_attributes{}, variations{}
Optional: digital_files[], videos[]For state="draft": Returns instantly with listing_pk and dashboard_url. For state="publish"/"active": Returns job_id. Poll with GET /api/v1/listings/create/{job_id}.
Variations — How They Work
Etsy allows up to 2 variation properties per listing (e.g. Color + Size). You provide the data — ETO automatically detects what varies and sets the correct Etsy toggles:
- Prices vary: if offerings have different prices, ETO detects which property causes it
- Quantities vary: same auto-detection
- SKUs vary: if each offering has a unique sku, ETO sets sku_on_property
- Processing profiles vary: if offerings have different processing_profile_id values
- Photos vary: if you provide variation_images.mapping, ETO links images to property valuesStructure:
"variations": {
"properties": [
{"property_id": 200, "name": "Color", "values": ["Black", "White", "Navy"]},
{"property_id": 62809790533, "name": "Size", "scale_id": 17, "values": ["S", "M", "L", "XL"]}
],
"offerings": [
{"color": "Black", "size": "S", "price": 29.99, "quantity": 20, "sku": "BLK-S", "processing_profile_id": 123},
{"color": "Black", "size": "XL", "price": 34.99, "quantity": 15, "sku": "BLK-XL", "processing_profile_id": 456},
...
],
"variation_images": {
"property": "color",
"mapping": {"Black": 0, "White": 1, "Navy": 2}
}
}Key rules:
- Offering keys use the lowercased property name (e.g. "color", "size")
- Each offering value must match one of the property's values array
- variation_images.mapping values are 0-based indices into the images[] array
- Only ONE property can have variation images (Etsy constraint)
- ETO fills in missing combinations with is_enabled=false automatically
Category Attributes
Each Etsy category has specific attributes (e.g. T-Shirts have Primary color, Sleeve length, Neckline). Use the listing-schema endpoint to discover them, then pass the values you want:
"category_attributes": {
"200": {"value_ids": [1], "values": ["Black"]},
"325502675244": {"value_ids": [2668], "values": ["Short sleeve"]},
"325502675262": {"value_ids": [2678], "values": ["Crew"]}
}The key is the property_id (from listing-schema category_attributes). The value_ids and values come from listing-schema possible_values. Some properties have scales (like Size) — include scale_id when applicable.
Personalization
Etsy's multi-question personalization system lets sellers collect up to 5 custom details from buyers. Pass a "questions" array inside the personalization object. ETO handles the Etsy API translation.
Limits:
- Maximum 5 questions per listing
- Maximum 1 file-upload question (unlabeled_upload or labeled_upload) per listing
- Set "enabled": false (or omit personalization entirely) to disable━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ QUESTION TYPES ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. text_input — Free text field
Buyers type freeform text (names, dates, quotes, etc.).Fields:
question_text string REQUIRED 1-45 chars, must start with letter/number
instructions string optional max 120 chars, must start with letter/number
required boolean optional default false
max_allowed_characters integer optional 1-1024, default 256Example:
{
"question_type": "text_input",
"question_text": "Name for engraving",
"instructions": "Enter first and last name exactly as you want it engraved",
"required": true,
"max_allowed_characters": 30
}2. dropdown — List of options
Buyers select from a predefined list. No instructions field allowed.Fields:
question_text string REQUIRED 1-45 chars, must start with letter/number
required boolean optional default false
options array REQUIRED 1-30 items
options[].label string REQUIRED 1-20 chars, must be unique (case-insensitive)DO NOT include "instructions" — Etsy rejects dropdowns with instructions.Example:
{
"question_type": "dropdown",
"question_text": "Thread color",
"required": true,
"options": [
{"label": "Gold"},
{"label": "Silver"},
{"label": "Rose Gold"},
{"label": "Black"}
]
}3. unlabeled_upload — File upload
Buyers upload files (images, PDFs, etc.) without per-file labels.
Accepted formats: .jpg, .png, .svg, .pdf, .heic (up to 100MB each).Fields:
question_text string REQUIRED 1-45 chars, must start with letter/number
instructions string optional max 120 chars, must start with letter/number
required boolean optional default false
max_allowed_files integer optional 1-10, default 1Example:
{
"question_type": "unlabeled_upload",
"question_text": "Upload your logo",
"instructions": "High-resolution PNG or SVG preferred, minimum 300 DPI",
"required": true,
"max_allowed_files": 3
}4. labeled_upload — File upload with labels
Like unlabeled_upload, but each file slot has a named label shown to the buyer.
The options array MUST have exactly as many items as max_allowed_files.Fields:
question_text string REQUIRED 1-45 chars, must start with letter/number
instructions string optional max 120 chars, must start with letter/number
required boolean optional default false
max_allowed_files integer REQUIRED 2-10 (minimum 2 for labeled uploads)
options array REQUIRED exactly max_allowed_files items
options[].label string REQUIRED 1-45 charsExample:
{
"question_type": "labeled_upload",
"question_text": "Upload design files",
"instructions": "Please upload high-res files only",
"required": true,
"max_allowed_files": 3,
"options": [
{"label": "Front design"},
{"label": "Back design"},
{"label": "Sleeve design"}
]
}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ FULL EXAMPLE — All 4 question types ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
"personalization": {
"enabled": true,
"questions": [
{
"question_type": "text_input",
"question_text": "Name for engraving",
"instructions": "Enter first and last name",
"required": true,
"max_allowed_characters": 30
},
{
"question_type": "text_input",
"question_text": "Special date",
"instructions": "Format: MM/DD/YYYY",
"required": false,
"max_allowed_characters": 10
},
{
"question_type": "dropdown",
"question_text": "Font style",
"required": true,
"options": [
{"label": "Script"},
{"label": "Block"},
{"label": "Serif"},
{"label": "Handwritten"}
]
},
{
"question_type": "dropdown",
"question_text": "Gift wrapping",
"required": false,
"options": [
{"label": "None"},
{"label": "Standard box"},
{"label": "Premium box"}
]
},
{
"question_type": "labeled_upload",
"question_text": "Upload design files",
"instructions": "High-res PNG or SVG, minimum 300 DPI",
"required": true,
"max_allowed_files": 2,
"options": [
{"label": "Front design"},
{"label": "Back design"}
]
}
]
}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ VALIDATION ERRORS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
If validation fails, ETO returns 400 with specific field-level errors:
{"error": "VALIDATION_FAILED", "fields": {
"personalization.questions": "Maximum 5 questions allowed.",
"personalization.questions.upload": "Maximum 1 upload-type question.",
"personalization.questions[0].question_text": "Required.",
"personalization.questions[0].question_text": "Max 45 characters. Provided: 52.",
"personalization.questions[0].question_text": "Must start with a letter or number.",
"personalization.questions[0].instructions": "Dropdown questions cannot have instructions.",
"personalization.questions[0].instructions": "Max 120 characters. Provided: 135.",
"personalization.questions[0].max_allowed_characters": "Must be 1-1024. Provided: 2000.",
"personalization.questions[0].max_allowed_files": "Must be 2-10. Provided: 1.",
"personalization.questions[0].options": "At least 1 option required.",
"personalization.questions[0].options[2].label": "Option label cannot be empty.",
"personalization.questions[0].options[2].label": "Max 20 characters. Provided: 25.",
"personalization.questions[0].options[2].label": "Duplicate option: \"Gold\".",
"personalization.questions[0].options": "Labeled upload requires exactly 3 file labels (matching max_allowed_files). Provided: 2."
}}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ DISABLING PERSONALIZATION ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
To remove all personalization from a listing:
"personalization": {"enabled": false}Or simply omit the personalization object entirely. On existing listings, this calls DELETE on the Etsy personalization endpoint.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ LEGACY SHORTHAND (still supported) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
If you omit "questions" but set "enabled": true, ETO creates a single text_input question from the flat fields. This is for backward compatibility only — use "questions" for new code.
"personalization": {
"enabled": true,
"is_required": false,
"instructions": "Enter name or initials",
"max_chars": 15
}Equivalent to:
"personalization": {
"enabled": true,
"questions": [{
"question_type": "text_input",
"question_text": "Personalization",
"instructions": "Enter name or initials",
"required": false,
"max_allowed_characters": 15
}]
}
Complete Example — Maxed Out Physical Listing
This example creates a physical listing with EVERY feature: 5 images, 12 variations (3 colors x 4 sizes), prices/quantities/SKUs/processing profiles all varying, photos linked to colors, 5 personalization questions (2 text + 2 dropdown + 1 labeled upload), all 11 category attributes, full store settings.
curl -X POST -H "X-Eto-API-Key: eto_your_key" -H "Content-Type: application/json" \
"https://eto.tools/api/v1/listings/create" \
-d '{
"state": "publish",
"shops": [{
"shop_id": 57124360,
"shipping_profile_id": 291257702631,
"return_policy_id": 1435074483195,
"processing_profile_id": 1456101932490,
"shop_section_id": 56909368
}],
"listing": {
"title": "Vintage Band Tee - Custom Graphic Design",
"description": "Premium cotton vintage-style t-shirt...",
"listing_type": "physical",
"taxonomy_id": 482,
"price": 29.99,
"quantity": 100,
"who_made": "i_did",
"when_made": "2020_2026",
"sku": "VBT-MAIN",
"tags": ["vintage tee", "band shirt", "graphic tee", ...],
"materials": ["cotton", "polyester"],
"styles": ["Casual", "Vintage"],
"item_weight": 6.0,
"item_weight_unit": "oz"
},
"images": [
{"url": "https://example.com/black-tee.jpg", "rank": 1},
{"url": "https://example.com/white-tee.jpg", "rank": 2},
{"url": "https://example.com/navy-tee.jpg", "rank": 3},
{"url": "https://example.com/detail-shot.jpg", "rank": 4},
{"url": "https://example.com/size-chart.jpg", "rank": 5}
],
"personalization": {
"enabled": true,
"questions": [
{
"question_type": "text_input",
"question_text": "Name for print",
"instructions": "First and last name as you want it printed",
"required": true,
"max_allowed_characters": 30
},
{
"question_type": "text_input",
"question_text": "Special date",
"instructions": "Format: MM/DD/YYYY",
"required": false,
"max_allowed_characters": 10
},
{
"question_type": "dropdown",
"question_text": "Font style",
"required": true,
"options": [
{"label": "Script"},
{"label": "Block"},
{"label": "Serif"},
{"label": "Handwritten"}
]
},
{
"question_type": "dropdown",
"question_text": "Gift wrapping",
"required": false,
"options": [
{"label": "None"},
{"label": "Standard box"},
{"label": "Premium box"}
]
},
{
"question_type": "labeled_upload",
"question_text": "Upload design files",
"instructions": "High-res PNG or SVG, minimum 300 DPI",
"required": true,
"max_allowed_files": 2,
"options": [
{"label": "Front design"},
{"label": "Back design"}
]
}
]
},
"category_attributes": {
"200": {"value_ids": [1], "values": ["Black"]},
"52047899002": {"value_ids": [10], "values": ["White"]},
"62809790533": {"value_ids": [2139], "values": ["M"], "scale_id": 17},
"325502675244": {"value_ids": [2668], "values": ["Short sleeve"]},
"325502675262": {"value_ids": [2678], "values": ["Crew"]},
"325502673988": {"value_ids": [2556], "values": ["Streetwear"]},
"46803063641": {"value_ids": [19], "values": ["Birthday"]},
"46803063659": {"value_ids": [35], "values": ["Christmas"]},
"332797777099": {"value_ids": [2558], "values": ["Animal"]}
},
"variations": {
"properties": [
{"property_id": 200, "name": "Color", "values": ["Black", "White", "Navy"]},
{"property_id": 62809790533, "name": "Size", "scale_id": 17, "values": ["S", "M", "L", "XL"]}
],
"offerings": [
{"color": "Black", "size": "S", "price": 29.99, "quantity": 20, "sku": "BLK-S", "processing_profile_id": 1456101932490},
{"color": "Black", "size": "XL", "price": 34.99, "quantity": 15, "sku": "BLK-XL", "processing_profile_id": 1458328250863},
{"color": "White", "size": "S", "price": 29.99, "quantity": 20, "sku": "WHT-S", "processing_profile_id": 1456101932490},
...
],
"variation_images": {
"property": "color",
"mapping": {"Black": 0, "White": 1, "Navy": 2}
}
}
}'
Response — Draft (state="draft")
{
"listing_pk": 1135,
"status": "draft",
"message": "Listing saved as draft in ETO. Open it in the ETO dashboard to review and publish.",
"dashboard_url": "/dashboard/single-research/1135/"
}The listing is saved in ETO with all fields pre-filled. Open the dashboard URL to review, edit anything, and publish when ready. Zero Etsy API calls were made.
Response — Publish/Active (state="publish" or "active")
The request runs synchronously: it blocks for ~5–15 seconds per shop while ETO creates the draft on Etsy, uploads images/videos/files, sets inventory and variations, and fetches the final image URLs back. Set your HTTP client timeout to at least 60s (120s for multi-shop calls).
200 OK — successful publish:
{
"job_id": "lcj_aDzKwnFW5sYHewZaPTduRw",
"listing_pk": 1173,
"status": "completed",
"poll_url": "/api/v1/listings/create/lcj_aDzKwnFW5sYHewZaPTduRw",
"dashboard_url": "/dashboard/single-research/1173/",
"shops_count": 1,
"results": [{
"shop_id": "53081804",
"status": "ok",
"listing_id": 4489813117,
"listing_url": "https://www.etsy.com/listing/4489813117",
"currency_code": "GBP",
"price": 24.99,
"images": [
{"listing_image_id": 5523110099001, "url_fullxfull": "https://i.etsystatic.com/...", "rank": 1}
],
"videos": []
}]
}For state="active", successful shops also carry "activated": true and "activation_cost_usd": 0.20.
Per-shop failures are reported inside results[] with status="error" and an Etsy-side error payload. Other shops in the same request can still succeed.
Backwards compatibility: job_id and poll_url are still in the response so existing clients that call GET /api/v1/listings/create/{job_id} continue to work. The job will be in "completed" state on the first poll.
500 Internal Server Error — job-level failure (e.g. the entire publish flow threw):
{
"job_id": "lcj_...",
"listing_pk": 1174,
"status": "failed",
"error": "<human-readable reason>",
"poll_url": "/api/v1/listings/create/lcj_...",
"results": []
}
Validation & Preflight Errors (400)
The listing-create endpoint validates heavily before writing any state. If a preflight check fails, you get a 400 with a fields object pointing at the exact problem:
{
"error": {
"code": "VALIDATION_FAILED",
"status": 400,
"message": "Request validation failed.",
"fields": {
"images[1].url": "Uploaded file is no longer available on the server. Re-upload via POST /api/v1/uploads and use the new url.",
"shops[0].shop_section_id": "Section 999999999 not found in shop 53081804."
}
}
}Common preflight errors:
• images[N].url / digital_files[N].url / videos[N].url — the eto-upload:// URL you referenced no longer resolves to a file on the server. This can happen if the upload was done a long time ago or if the server was redeployed. Re-upload via POST /api/v1/uploads and use the fresh URL.
• shops[N].shop_section_id — the section ID does not belong to that shop. Call GET /api/v1/stores/{shop_id}/shop-sections/live to fetch the current sections.
• Standard field-shape errors (title too long, missing taxonomy_id, etc.) from the schema validator.
All preflight errors are fatal: if a 400 is returned, nothing was persisted on the ETO side and no Etsy draft was created. Retrying with a fixed payload is safe.
For AI Agents
1. Always call GET /api/v1/stores first to get valid shop_ids. 2. Get profile IDs from the four live endpoints (each returns the absolute latest, no cache):
GET /api/v1/stores/{shop_id}/shipping-profiles/live → shipping_profile_id
GET /api/v1/stores/{shop_id}/return-policies/live → return_policy_id
GET /api/v1/stores/{shop_id}/processing-profiles/live → processing_profile_id
GET /api/v1/stores/{shop_id}/shop-sections/live → shop_section_id
Fetch them in parallel for speed.3. Call GET /api/v1/categories/{id}/listing-schema for any new category to discover attributes and variation properties. 4. Use the "required" field on category_attributes to know which are mandatory. 5. Use "possible_values" from the schema to select valid value_ids for each attribute. 6. Default to state="draft" unless the user explicitly asks to publish or activate. 7. state="active" costs $0.20 USD per listing per shop — always warn the user. 8. For variations: just provide the data (prices, quantities, SKUs, processing_profile_id per offering). ETO auto-detects what varies. 9. For variation images: set variation_images.property to the property name (e.g. "color") and mapping to {value: image_index}. 10. Images can be URLs or local files uploaded via POST /api/v1/uploads.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| category_id | integer | REQUIRED | Etsy taxonomy/category ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/categories/2078/listing-schema"
Response
{"category_id": 2078, "required_fields": {...}, "category_attributes": [...], "variation_properties": [...]}
state="draft" → saves to ETO only. No Etsy API calls. Returns immediately.
state="publish" → saves to ETO and creates a draft listing on Etsy. Blocking: the request holds open until Etsy has accepted the listing and all images/videos/files are attached (typically 5–15s per shop). Returns the final results inline.
state="active" → same as publish + activates each listing on Etsy. Costs $0.20 USD per listing per shop.
You can only publish to Etsy shops connected to your ETO account. Use GET /api/v1/stores to list them.
For backwards compatibility, the response still includes job_id and poll_url so existing clients that poll GET /api/v1/listings/create/{job_id} continue to work — the job will be in "completed" state on the first poll.
Validation errors (400 VALIDATION_FAILED):
• images[N].url / digital_files[N].url / videos[N].url — "Uploaded file is no longer available on the server. Re-upload via POST /api/v1/uploads and use the new url."
Fires when the eto-upload:// path no longer resolves on disk. Re-upload and retry.
• shops[N].shop_section_id — "Section X not found in shop Y."
Fires when the section ID does not belong to the shop. Call GET /api/v1/stores/{shop_id}/shop-sections/live to fetch the current sections.
All preflight validation runs before any ETO row or Etsy draft is created — a 400 means nothing was persisted and retrying with a fixed payload is safe.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| state | string | optional |
"draft" saves to ETO only (instant, zero Etsy calls). "publish" saves to ETO and creates a draft listing on Etsy (blocking, 5–15s per shop). "active" same as publish + activates on Etsy (blocking, costs $0.20 USD per listing per shop).
Default:
draftEnum:
draftpublishactive |
| shops[].shop_id | integer | REQUIRED |
The unique positive non-zero numeric ID for an Etsy Shop. Must be connected to your ETO account. Use GET /api/v1/stores to list connected shops.
Constraints:
>= 1 |
| shops[].price | number Nullable | optional |
Per-shop price override in the shop's native currency. If omitted, uses listing.price.
Constraints:
>= 0.20 |
| shops[].shipping_profile_id | integer Nullable | optional |
The numeric ID of the shipping profile associated with the listing. Required when listing_type is physical. Get the latest IDs from GET /api/v1/stores/{shop_id}/shipping-profiles/live.
Constraints:
>= 1 |
| shops[].return_policy_id | integer Nullable | optional |
The numeric ID of the return policy. Required for physical listings. Get the latest IDs from GET /api/v1/stores/{shop_id}/return-policies/live.
Constraints:
>= 1 |
| shops[].processing_profile_id | integer Nullable | optional |
The numeric ID of the processing/readiness state profile. Controls processing time display on the listing. Get the latest IDs from GET /api/v1/stores/{shop_id}/processing-profiles/live.
Constraints:
>= 1 |
| shops[].shop_section_id | integer Nullable | optional |
The numeric ID of the shop section to organize the listing under. Get the latest IDs from GET /api/v1/stores/{shop_id}/shop-sections/live.
Constraints:
>= 1 |
| shops[].production_partner_ids | array Nullable | optional | An array of unique IDs of production partners for this listing. Get IDs from POST /api/v1/stores/{shop_id}/sync. |
| listing.title | string | REQUIRED |
The listing's title string. Valid title strings contain only letters, numbers, punctuation marks, mathematical symbols, whitespace characters, ™, ©, and ®. You can only use the %, :, & and + characters once each.
Constraints:
max 140 charsRegex:
/[^\p{L}\p{Nd}\p{P}\p{Sm}\p{Zs}™©®]/u |
| listing.description | string | REQUIRED | A description string of the product for sale in the listing. Newlines are rendered by Etsy. HTML tags are stripped. |
| listing.listing_type | string | REQUIRED |
An enumerated type string that indicates whether the listing is a physical product or a digital download.
Enum:
physicaldigital |
| listing.taxonomy_id | integer | REQUIRED |
The numerical taxonomy ID of the listing. Use GET /api/v1/categories/{id}/listing-schema to find valid IDs and discover required category attributes and variation properties.
Constraints:
>= 1 |
| listing.price | number | optional |
The positive non-zero price of the product. Required unless variations define per-variant prices. Note: The price is the minimum possible price. Variation offerings can set different prices per combination.
Constraints:
>= 0.20 |
| listing.quantity | integer | optional |
The positive non-zero number of products available for purchase. Required unless variations define per-variant quantities. Note: For variation listings, this is overridden by per-offering quantities.
Constraints:
1-999 |
| listing.who_made | string | optional |
An enumerated string indicating who made the product. Helps buyers locate the listing under the Handmade heading. Requires 'is_supply' and 'when_made'.
Default:
i_didEnum:
i_didsomeone_elsecollective |
| listing.when_made | string | optional |
An enumerated string for the era in which the maker made the product in this listing. Helps buyers locate the listing under the Vintage heading. Requires 'is_supply' and 'who_made'.
Default:
2020_2026Enum:
made_to_order2020_20262010_20192007_2009before_20072000_20061990s1980s1970s1960s1950s1940s1930s1920s1910s1900s |
| listing.tags | array Nullable | optional |
A list of tag strings for the listing. Valid tag strings contain only letters, numbers, whitespace characters, -, ', ™, ©, and ®. Default value is null.
Constraints:
max 13 items, each max 20 charsRegex:
/[^\p{L}\p{Nd}\p{Zs}\-'™©®]/u |
| listing.materials | array Nullable | optional |
A list of material strings for materials used in the product. Valid materials strings contain only letters, numbers, and whitespace characters. Default value is null.
Constraints:
max 13 itemsRegex:
/[^\p{L}\p{Nd}\p{Zs}]/u |
| listing.styles | array Nullable | optional |
An array of style strings for this listing, each of which is free-form text string such as "Formal", or "Steampunk". Valid style strings contain only letters, numbers, and whitespace characters. Default value is null.
Constraints:
max 2 itemsRegex:
/[^\p{L}\p{Nd}\p{Zs}]/u |
| listing.sku | string | optional |
Optional internal identifier. First 32 characters are sent to Etsy (Etsy's limit). The full SKU (up to 512 chars) is stored in ETO for order fulfillment and can be retrieved via the ETO API.
Constraints:
max 512 chars (32 to Etsy) |
| listing.is_supply | boolean | optional |
When true, tags the listing as a supply product, else indicates that it's a finished product. Helps buyers locate the listing under the Supplies heading. Requires 'who_made' and 'when_made'.
Default:
false |
| listing.is_customizable | boolean | optional | When true, a buyer may contact the seller for a customized order. The default value is true when a shop accepts custom orders. Does not apply to shops that do not accept custom orders. |
| listing.is_taxable | boolean | optional | When true, applicable shop tax rates apply to this listing at checkout. |
| listing.should_auto_renew | boolean | optional | When true, renews a listing for four months upon expiration. |
| listing.item_weight | number Nullable | optional |
The numeric weight of the product measured in units set in 'item_weight_unit'. Default value is null. If set, the value must be greater than 0.
Constraints:
> 0 |
| listing.item_weight_unit | string Nullable | optional |
A string defining the units used to measure the weight of the product. Default value is null.
Enum:
ozlbgkg |
| listing.item_length | number Nullable | optional |
The numeric length of the product measured in units set in 'item_dimensions_unit'. Default value is null. If set, the value must be greater than 0.
Constraints:
> 0 |
| listing.item_width | number Nullable | optional |
The numeric width of the product measured in units set in 'item_dimensions_unit'. Default value is null. If set, the value must be greater than 0.
Constraints:
> 0 |
| listing.item_height | number Nullable | optional |
The numeric height of the product measured in units set in 'item_dimensions_unit'. Default value is null. If set, the value must be greater than 0.
Constraints:
> 0 |
| listing.item_dimensions_unit | string Nullable | optional |
A string defining the units used to measure the dimensions of the product. Default value is null.
Enum:
inftmmcmmydinches |
| listing.processing_min | integer Nullable | optional | The minimum number of days required to process this listing. Default value is null. |
| listing.processing_max | integer Nullable | optional | The maximum number of days required to process this listing. Default value is null. |
| images[].url | string | REQUIRED |
A publicly accessible URL to the image file. ETO downloads the image server-side and uploads it to Etsy. Supported formats: JPG, PNG, GIF. Max 100MB per image.
Constraints:
min 1, max 10 images |
| images[].rank | integer | optional |
Position in the listing image gallery. Rank 1 is the primary/leftmost photo shown to buyers. If omitted, images are ordered by their position in the array.
Constraints:
1-10 |
| digital_files[].url | string | optional |
A publicly accessible URL to the digital file. Required for listing_type=digital. ETO downloads the file server-side and uploads it to Etsy. Max 100MB per file. Supported types: .bmp, .doc, .gif, .jpeg, .jpg, .mobi, .mov, .mp3, .mpeg, .pdf, .png, .psp, .rtf, .stl, .txt, .zip, .ePUB, .iBook.
Constraints:
min 1, max 5 files (for digital listings) |
| digital_files[].name | string | optional |
The display name for the digital file shown to buyers after purchase. Letters, numbers, periods, hyphens, and underscores only. No spaces or parentheses.
Constraints:
3-70 charsRegex:
/^[a-zA-Z0-9._-]+$/ |
| videos[].url | string Nullable | optional |
A publicly accessible URL to the video file. ETO downloads the video server-side and uploads it to Etsy. MP4 or MOV format, max 15 seconds, no audio. Max 100MB.
Constraints:
max 1 video per listing |
| personalization.enabled | boolean | optional |
When true, enables personalization for this listing. ETO uses the modern Etsy personalization API to set this up after listing creation.
Default:
false |
| personalization.is_required | boolean | optional |
When true, the buyer must enter personalization text before purchasing. Only applies when personalization.enabled is true.
Default:
false |
| personalization.instructions | string | optional |
Instructions shown to the buyer at checkout describing what personalization to enter (e.g. 'Enter up to 10 characters for monogram'). Only applies when personalization.enabled is true.
Constraints:
max 256 chars |
| personalization.max_chars | integer | optional |
The maximum character count for the buyer's personalization message. Only applies when personalization.enabled is true.
Constraints:
1-1024 |
| category_attributes | object | optional | Category-specific listing attributes. Keys are property_id strings. Values are objects with value_ids, values, and optional scale_id. Use GET /api/v1/categories/{id}/listing-schema to discover which attributes exist, which are required, and their valid values for a given category. |
| category_attributes.{property_id}.value_ids | array | optional | The Etsy value IDs for the selected attribute values. Get valid IDs from the listing-schema endpoint possible_values array. |
| category_attributes.{property_id}.values | array | optional | Human-readable attribute value strings corresponding to each value_id. |
| category_attributes.{property_id}.scale_id | integer Nullable | optional | Scale ID for properties that use scales (e.g. alpha sizing). Get valid scale IDs from the listing-schema endpoint scales array. |
| variations.properties | array | optional |
Array of variation property definitions. Etsy allows at most 2 variation properties per listing. Use GET /api/v1/categories/{id}/listing-schema variation_properties to discover available properties for the chosen category.
Constraints:
max 2 items |
| variations.properties[].property_id | integer | REQUIRED | The Etsy property ID from the listing-schema variation_properties (e.g. 200 for Primary color, 100 for Size, 513 for Style). |
| variations.properties[].name | string | REQUIRED | Human-readable property name (e.g. 'Color', 'Size'). This name (lowercased) is used as the key in each offering to specify the value. |
| variations.properties[].scale_id | integer Nullable | optional | Scale ID for sized properties (e.g. Alpha sizing: XS, S, M, L, XL). Get valid scale IDs from the listing-schema endpoint. |
| variations.properties[].values | array | REQUIRED | All possible values for this property (e.g. ['Black', 'Brown', 'Tan'] for Color). Parentheses characters () are not allowed in values. |
| variations.offerings | array | optional | Array of offerings, one per variation combination. Each offering uses the lowercased property name as a key to specify which value it represents. ETO auto-detects which properties affect price/quantity and builds the Etsy inventory payload accordingly. |
| variations.offerings[].{property_name} | string | REQUIRED | The value for this property in this offering. The key is the lowercased property name (e.g. 'color': 'Black', 'size': 'S'). Must match one of the values listed in variations.properties[].values. |
| variations.offerings[].price | number | optional |
Price for this specific variation combination. If all offerings have the same price, ETO automatically tells Etsy that price does not vary by property. If prices differ, ETO detects which property causes the difference.
Constraints:
>= 0.20 |
| variations.offerings[].quantity | integer | optional |
Stock quantity for this specific variation combination. Set to 0 along with enabled=false to create the combination but hide it from the listing.
Constraints:
0-999 |
| variations.offerings[].sku | string Nullable | optional |
Per-variant SKU identifier. First 32 characters are sent to Etsy, full SKU (up to 512 chars) is stored in ETO. Must be unique across all offerings if provided.
Constraints:
max 512 chars (32 to Etsy) |
| variations.offerings[].enabled | boolean | optional |
When false, the offering is created but hidden from the listing. Etsy receives is_enabled=false and quantity=0. Useful for pre-creating combinations that are temporarily out of stock.
Default:
true |
| variations.offerings[].processing_profile_id | integer Nullable | optional |
Per-variant processing/readiness profile ID. If different values are set across offerings, ETO automatically sets readiness_state_on_property. If omitted, the shop-level processing_profile_id applies.
Constraints:
>= 1 |
| variations.variation_images.property | string | optional | The name of the variation property whose values should be linked to specific listing images (e.g. 'color'). Only one property can have variation images per listing (Etsy constraint). Case-insensitive match against variations.properties[].name. |
| variations.variation_images.mapping | object | optional | Maps property values to image indices. Keys are value names (e.g. 'Black'), values are 0-based indices into the images[] array. Example: {"Black": 0, "Brown": 1, "Tan": 2}. If a value references an out-of-bounds index, validation returns an error. |
Example
curl -X POST -H "X-Eto-API-Key: eto_your_key" -H "Content-Type: application/json" \
"https://eto.tools/api/v1/listings/create" \
-d '{
"state": "draft",
"shops": [{"shop_id": 12345678, "shipping_profile_id": 111222, "return_policy_id": 333444, "price": 24.99}],
"listing": {
"title": "Custom Leather Wallet - Personalized Gift for Him",
"description": "Handmade genuine leather wallet with optional monogram...",
"listing_type": "physical",
"taxonomy_id": 2078,
"price": 24.99,
"quantity": 50,
"who_made": "i_did",
"when_made": "2020_2026",
"tags": ["leather wallet", "personalized gift", "groomsmen gift"],
"materials": ["leather", "thread"],
"sku": "WALLET-CUSTOM-001",
"item_weight": 4.5,
"item_weight_unit": "oz"
},
"images": [
{"url": "https://example.com/wallet-front.jpg", "rank": 1},
{"url": "https://example.com/wallet-back.jpg", "rank": 2}
],
"variations": {
"properties": [
{"property_id": 200, "name": "Color", "values": ["Black", "Brown", "Tan"]}
],
"offerings": [
{"color": "Black", "price": 24.99, "quantity": 50, "sku": "W-BLK"},
{"color": "Brown", "price": 24.99, "quantity": 50, "sku": "W-BRN"},
{"color": "Tan", "price": 27.99, "quantity": 30, "sku": "W-TAN"}
],
"variation_images": {"property": "color", "mapping": {"Black": 0, "Brown": 1}}
}
}'
Response
# state="draft" — 201 Created
{
"listing_pk": 1173,
"status": "draft",
"message": "Listing saved as draft in ETO. Open it in the ETO dashboard to review and publish.",
"dashboard_url": "/dashboard/single-research/1173/"
}
# state="publish" or "active" — 200 OK, synchronous
{
"job_id": "lcj_aDzKwnFW5sYHewZaPTduRw",
"listing_pk": 1173,
"status": "completed",
"poll_url": "/api/v1/listings/create/lcj_aDzKwnFW5sYHewZaPTduRw",
"dashboard_url": "/dashboard/single-research/1173/",
"shops_count": 1,
"results": [
{
"shop_id": "53081804",
"status": "ok",
"listing_id": 4489813117,
"listing_url": "https://www.etsy.com/listing/4489813117",
"currency_code": "GBP",
"price": 24.99,
"images": [
{"listing_image_id": 5523110099001, "url_fullxfull": "https://i.etsystatic.com/...", "rank": 1},
{"listing_image_id": 5523110099002, "url_fullxfull": "https://i.etsystatic.com/...", "rank": 2}
],
"videos": []
}
]
}
# For state="active", each succeeded shop also includes:
# "activated": true, "activation_cost_usd": 0.20
# On per-shop failure (other shops may still succeed):
# {"shop_id": "...", "status": "error", "error": "<reason>", "etsy_status": 400, "details": {...}}
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| job_id | string | REQUIRED | The job_id returned by POST /api/v1/listings/create |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/listings/create/lcj_abc123def456"
Response
{
"job_id": "lcj_aDzKwnFW5sYHewZaPTduRw",
"status": "completed",
"created_at": "2026-04-16T21:07:20.963219+00:00",
"completed_at": "2026-04-16T21:07:28.245564+00:00",
"results": [
{
"shop_id": "53081804",
"status": "ok",
"listing_id": 4489813117,
"listing_url": "https://www.etsy.com/listing/4489813117",
"currency_code": "GBP",
"price": 24.99,
"images": [
{"listing_image_id": 5523110099001, "url_fullxfull": "https://i.etsystatic.com/...", "rank": 1}
],
"videos": [],
"warnings": [
{"code": "recovery_update_failed", "fields": ["shop_section_id"], "reason": "Etsy rejected the section update"}
]
}
]
}
# Terminal statuses: "completed" | "failed"
# On job-level failure: response also includes "error_message": "<reason>"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your connected Etsy shop ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/stores/12345678/details"
Response
{
"shop_id": "12345678",
"shop_name": "MyShop",
"currency_code": "USD",
"shipping_from_country_iso": "US",
"listing_active_count": 142,
"review_average": 4.8,
"review_count": 523,
"is_vacation": false,
"url": "https://www.etsy.com/shop/MyShop",
"last_synced_at": "2026-04-10T14:30:00Z",
"shipping_profiles": [
{"shipping_profile_id": 111222, "title": "Standard Shipping", "min_processing_days": 1, "max_processing_days": 3, "primary_cost": "5.99", "currency_code": "USD"}
],
"shop_sections": [
{"shop_section_id": 44556, "title": "New Arrivals", "rank": 1, "active_listing_count": 15}
],
"return_policies": null,
"processing_profiles": null,
"production_partners": null
}
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your connected Etsy shop ID |
Example
curl -X POST -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/stores/12345678/sync"
Response
{
"shop_id": "12345678",
"shop_name": "MyShop",
"currency_code": "USD",
"last_synced_at": "2026-04-12T16:45:00Z",
"shipping_profiles": [
{"shipping_profile_id": 111222, "title": "Standard Shipping", "min_processing_days": 1, "max_processing_days": 3, "primary_cost": "5.99", "currency_code": "USD"}
],
"shop_sections": [
{"shop_section_id": 44556, "title": "New Arrivals", "rank": 1, "active_listing_count": 15}
],
"return_policies": [
{"return_policy_id": 333444, "accepts_returns": true, "accepts_exchanges": true, "return_deadline": 30}
],
"processing_profiles": [
{"readiness_state_id": 555666, "readiness_state": "ready_to_ship", "min_processing_days": 1, "max_processing_days": 3, "processing_days_display_label": "1-3 business days"}
],
"production_partners": [
{"production_partner_id": 999, "partner_name": "PrintCo", "location": "USA"}
]
}
Send as multipart/form-data with a "file" field and optional "type" field.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| file | file | REQUIRED |
The file to upload. Send as multipart/form-data.
Constraints:
max 100MB |
| type | string | optional |
The type of file being uploaded.
Default:
imageEnum:
imagevideodigital |
Example
curl -X POST -H "X-Eto-API-Key: eto_your_key" \
-F "file=@my_product_photo.jpg" \
-F "type=image" \
"https://eto.tools/api/v1/uploads"
Response
{
"url": "eto-upload:///path/to/uploaded/file.jpg",
"filename": "my_product_photo.jpg",
"size": 102400,
"content_type": "image/jpeg",
"type": "image",
"note": "Use this url value in images[].url when calling POST /api/v1/listings/create."
}
Search
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| keywords | string | REQUIRED | Search keywords |
| limit | integer | optional |
Number of results (max 100)
Default:
25 |
| offset | integer | optional |
Pagination offset
Default:
0 |
| sort_on | string | optional |
Sort field: created, price, score
Default:
created |
| sort_order | string | optional |
Sort order: asc, desc
Default:
desc |
| min_price | number | optional | Minimum price filter |
| max_price | number | optional | Maximum price filter |
| category_id | integer | optional | Filter by product category ID (get IDs from /categories) |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/listings/search?keywords=leather+wallet&limit=10"
Response
{"count": 1000, "results": [{"listing_id": 123, "title": "...", "price": {"amount": 2999, "divisor": 100, "currency_code": "USD"}, ...}]}
Listings
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| listing_id | integer | REQUIRED | The Etsy listing ID |
| includes | string | optional | Comma-separated associations to include: Images, Shop, User, Translations, Inventory, Videos |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/listings/1234567890?includes=Images,Shop"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| listing_id | integer | REQUIRED | The Etsy listing ID to delete |
Example
curl -X DELETE -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/listings/1234567890"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| listing_id | integer | REQUIRED | The Etsy listing ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/listings/1234567890/images"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| listing_id | integer | REQUIRED | The Etsy listing ID |
| limit | integer | optional |
Number of reviews (max 100)
Default:
25 |
| offset | integer | optional |
Pagination offset
Default:
0 |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/listings/1234567890/reviews?limit=5"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| listing_id | integer | REQUIRED | The Etsy listing ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/listings/1234567890/inventory"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| listing_id | integer | REQUIRED | The Etsy listing ID |
Example
curl -X PUT -H "X-Eto-API-Key: eto_your_key" -H "Content-Type: application/json" -d '{"products": [...]}' "https://eto.tools/api/v1/listings/1234567890/inventory"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| listing_id | integer | REQUIRED | The Etsy listing ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/listings/1234567890/videos"
GET returns {personalization_questions: [...]} with up to 5 questions.
POST replaces all questions. DELETE removes personalization entirely.
Question types: text_input, dropdown, unlabeled_upload, labeled_upload.
Max 1 file-upload question per listing. See the Listing Builder guide for full field constraints.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| listing_id | integer | REQUIRED | The Etsy listing ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/listings/1234567890/personalization"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| listing_ids | string | REQUIRED | Comma-separated listing IDs |
| includes | string | optional | Comma-separated associations: Images, Shop, User, Inventory |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/listings/batch?listing_ids=123,456,789"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| listing_id | integer | REQUIRED | The listing ID |
| product_id | integer | REQUIRED | The product variant ID |
| offering_id | integer | REQUIRED | The offering ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/listings/1234567890/products/555666777/offerings/888999000"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| listing_id | integer | REQUIRED | The listing ID |
| product_id | integer | REQUIRED | The product variant ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/listings/1234567890/inventory/products/555666777"
Shops
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | The Etsy shop ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | The Etsy shop ID |
| limit | integer | optional |
Number of reviews (max 100)
Default:
25 |
| offset | integer | optional |
Pagination offset
Default:
0 |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/reviews?limit=5"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | The Etsy shop ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/sections"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| title | string | REQUIRED | Section title |
Example
curl -X POST -H "X-Eto-API-Key: eto_your_key" -H "Content-Type: application/json" -d '{"title": "New Section"}' "https://eto.tools/api/v1/shops/12345678/sections"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
Example
curl -X PUT -H "X-Eto-API-Key: eto_your_key" -H "Content-Type: application/json" -d '{"title": "My Shop Name"}' "https://eto.tools/api/v1/shops/12345678"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_name | string | REQUIRED | Shop name to search for |
| limit | integer | optional |
Number of results (max 100)
Default:
25 |
| offset | integer | optional |
Pagination offset
Default:
0 |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops?shop_name=handmade&limit=5"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| section_id | integer | REQUIRED | The section ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/sections/12345"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/section-listings"
Store Management
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| limit | integer | optional |
Number of listings (max 100)
Default:
25 |
| offset | integer | optional |
Pagination offset
Default:
0 |
| state | string | optional |
Listing state: active, draft, inactive
Default:
active |
| sort_on | string | optional |
Sort field
Default:
created |
| sort_order | string | optional |
Sort direction
Default:
desc |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/listings?limit=10&state=active"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| listing_id | integer | REQUIRED | The listing ID to update |
Example
curl -X PATCH -H "X-Eto-API-Key: eto_your_key" -H "Content-Type: application/json" -d '{"title": "Updated Title"}' "https://eto.tools/api/v1/shops/12345678/listings/1234567890"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| limit | integer | optional |
Number of results (max 100)
Default:
25 |
| offset | integer | optional |
Pagination offset
Default:
0 |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/listings/active?limit=10"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| limit | integer | optional |
Number of results (max 100)
Default:
25 |
| offset | integer | optional |
Pagination offset
Default:
0 |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/listings/featured?limit=5"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| listing_id | integer | REQUIRED | The listing ID |
| language | string | REQUIRED | Language code (e.g. "fr", "de", "es") |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/listings/1234567890/translations/fr"
Finance
━━━ WHAT YOU GET BACK (always returned) ━━━
shop_id — the store
shop_name — store display name
currency — e.g. "GBP", "USD"
start / end — the range you requested
balance_cents — current store balance (latest ledger entry, not range-scoped)
paid_out_cents — total deposited to bank in this range
sales_count — number of sales
gross_sales_cents — raw sale revenue before any deductions
sales_cents — display sales value (gross - refunds - cancelled + remitted tax)
fees_cents — total Etsy fees charged (negative number)
ads_cents — total ad spend (negative number)
refund_cents — total refunded to buyers
cancelled_cents — total cancelled order amounts
recoup_cents — Etsy recovering money from your balance
remitted_tax_cents — sales tax / VAT remitted by Etsy (negative)
gross_profit_cents — profit before COGS (gross + fees + ads + tax)
cogs_cents — cost of goods sold (from your item costs in Eto)
net_profit_cents — gross profit minus COGS
All amounts in cents. Divide by 100 for display. Negative = money out.
━━━ HOW TO PICK THE DATE WINDOW ━━━
EASIEST — pass `period`: today, yesterday, last_7_days, last_30_days, this_month, last_month.
The server resolves it in the shop timezone (override with `timezone`). No timestamps, no math.
Specific days — pass `start_date` / `end_date` as "YYYY-MM-DD" (inclusive).
Advanced — pass raw `start` / `end` unix seconds (range is [start, end), max 366 days).
The response echoes back a `range` object (exact start/end unix, start_local/end_local ISO,
timezone, label) AND the current server time — so you never compute or guess dates, and never
need a separate "what time is it" call. If the user means THEIR calendar day, pass their timezone.
Any store — use any shop_id connected to your Eto account (GET /api/v1/stores to list them).
━━━ BREAKDOWNS (optional) ━━━
Add &breakdown= to get detailed sub-breakdowns. Combine with commas.
breakdown=fees — returns breakdown.fees with:
listing, listing_credits, transaction, transaction_credits,
processing, processing_credits, shipping, shipping_credits,
vat_on_fees, vat_on_fees_credits, regulatory, regulatory_credits,
other, total
breakdown=ads — returns breakdown.ads with:
etsy_ads, offsite_ads, offsite_ads_credits, subscription, total
breakdown=sales — returns breakdown.sales with:
gross_sales_cents, refund_cents, cancelled_cents,
remitted_tax: { sales_tax, sales_tax_credits, vat_ep, vat_ep_credits, total }
breakdown=gross — same as sales (alias)
breakdown=profit — returns both breakdown.gross_profit and breakdown.net_profit:
gross_profit: { gross_sales_cents, fees_cents, ads_cents, remitted_tax_cents, total }
net_profit: { gross_profit_cents, cogs_cents, total }
Combine: &breakdown=fees,ads,profit returns all three at once.
Omit entirely to get just the top-level numbers.
━━━ WHAT HAS BREAKDOWNS vs WHAT DOESN'T ━━━
HAS breakdown: fees, ads, sales/gross, profit
NO breakdown: balance_cents, paid_out_cents, sales_count, refund_cents,
cancelled_cents, recoup_cents, cogs_cents, remitted_tax_cents
(some of these appear inside the sales or profit breakdown instead)
━━━ HOURLY BREAKDOWN (optional, single-day only) ━━━
Add &hourly=true to get a per-hour breakdown alongside the day summary.
Only works when your range is 24 hours or less (single day).
If your range is longer than 24h, hourly returns null with a note.
What you get: an "hourly" array with one object per hour, from hour 0
(midnight) up to the hour containing your end time.
Each hour object contains:
hour — 0-23 (the hour index)
hour_start — unix timestamp of this hour's start
hour_end — unix timestamp of this hour's end
entry_count — number of ledger entries in this hour
sales_count — number of sales
gross_sales_cents — raw revenue for this hour
sales_cents — display sales (gross - refunds - cancelled + tax)
fees_cents — Etsy fees charged this hour
ads_cents — ad spend this hour
remitted_tax_cents — tax remitted this hour
refund_cents — refunds this hour
cancelled_cents — cancellations this hour
recoup_cents — Etsy recoupments this hour
gross_profit_cents — profit before COGS
cogs_cents — cost of goods sold this hour
net_profit_cents — profit after COGS
paid_out_cents — payouts this hour
Combine with breakdowns: &hourly=true&breakdown=fees,ads works fine.
The hourly array gives per-hour summary metrics.
The breakdown object gives sub-category detail for the FULL day.
Turn it off: just omit &hourly (default is off). No penalty for not using it.
Multi-day range: hourly is ignored (returns null + hourly_note explaining why).
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID (from GET /api/v1/stores) |
| period | string | optional | EASIEST — a named window the server resolves for you, no timestamps: today, yesterday, last_7_days, last_30_days, this_month, last_month. |
| start_date | string | optional | Calendar day "YYYY-MM-DD" (inclusive). Use with end_date for a custom range. |
| end_date | string | optional | Calendar day "YYYY-MM-DD" (inclusive). Defaults to start_date (single day). |
| timezone | string | optional | IANA timezone for resolving period/dates (e.g. "Europe/London", "America/New_York"). Defaults to the shop's local timezone. Pass the USER's timezone (e.g. Europe/Helsinki) if they mean their own calendar day. |
| start | integer | optional | Advanced: raw range start as unix seconds (inclusive). Prefer period/start_date. |
| end | integer | optional | Advanced: raw range end as unix seconds (exclusive, max 366 days). Prefer period/start_date. |
| breakdown | string | optional | Comma-separated breakdowns to include: fees, ads, sales, gross, profit. Omit for top-level numbers only. |
| hourly | string | optional | Set to "true" to get per-hour metrics. Only works for single-day queries (range ≤ 24h). Returns array of 24 hour objects. Default: off. |
Example
# ── All metrics for a period (no breakdown) ──
curl -H "X-Eto-API-Key: eto_your_key" \
"https://eto.tools/api/v1/finance/12345678?start=1716508800&end=1717113600"
# ── All metrics for a single day ──
curl -H "X-Eto-API-Key: eto_your_key" \
"https://eto.tools/api/v1/finance/12345678?start=1716508800&end=1716595200"
# ── All metrics + fee breakdown ──
curl -H "X-Eto-API-Key: eto_your_key" \
"https://eto.tools/api/v1/finance/12345678?start=1716508800&end=1717113600&breakdown=fees"
# ── All metrics + ads breakdown ──
curl -H "X-Eto-API-Key: eto_your_key" \
"https://eto.tools/api/v1/finance/12345678?start=1716508800&end=1717113600&breakdown=ads"
# ── All metrics + profit breakdown (shows gross + net) ──
curl -H "X-Eto-API-Key: eto_your_key" \
"https://eto.tools/api/v1/finance/12345678?start=1716508800&end=1717113600&breakdown=profit"
# ── All metrics + sales/tax breakdown ──
curl -H "X-Eto-API-Key: eto_your_key" \
"https://eto.tools/api/v1/finance/12345678?start=1716508800&end=1717113600&breakdown=sales"
# ── All metrics + EVERY breakdown combined ──
curl -H "X-Eto-API-Key: eto_your_key" \
"https://eto.tools/api/v1/finance/12345678?start=1716508800&end=1717113600&breakdown=fees,ads,sales,profit"
# ── Single day + fee and ads breakdown ──
curl -H "X-Eto-API-Key: eto_your_key" \
"https://eto.tools/api/v1/finance/12345678?start=1716508800&end=1716595200&breakdown=fees,ads"
# ── Single day + hourly breakdown (per-hour metrics) ──
curl -H "X-Eto-API-Key: eto_your_key" \
"https://eto.tools/api/v1/finance/12345678?start=1716508800&end=1716595200&hourly=true"
# ── Single day + hourly + fee breakdown (combine both) ──
curl -H "X-Eto-API-Key: eto_your_key" \
"https://eto.tools/api/v1/finance/12345678?start=1716508800&end=1716595200&hourly=true&breakdown=fees"
Response
// ── Response WITHOUT breakdown ──
{
"shop_id": "12345678",
"shop_name": "My Etsy Shop",
"currency": "GBP",
"start": 1716508800,
"end": 1717113600,
"balance_cents": 125430,
"paid_out_cents": 90000,
"sales_count": 15,
"gross_sales_cents": 125000,
"sales_cents": 120000,
"fees_cents": -15000,
"ads_cents": -5000,
"refund_cents": 8000,
"cancelled_cents": 2000,
"recoup_cents": 0,
"remitted_tax_cents": -3000,
"gross_profit_cents": 102000,
"cogs_cents": 30000,
"net_profit_cents": 72000
}
// ── Response WITH breakdown=fees,ads,sales,profit ──
{
"shop_id": "12345678",
"shop_name": "My Etsy Shop",
"currency": "GBP",
"start": 1716508800,
"end": 1717113600,
"balance_cents": 125430,
"paid_out_cents": 90000,
"sales_count": 15,
"gross_sales_cents": 125000,
"sales_cents": 120000,
"fees_cents": -15000,
"ads_cents": -5000,
"refund_cents": 8000,
"cancelled_cents": 2000,
"recoup_cents": 0,
"remitted_tax_cents": -3000,
"gross_profit_cents": 102000,
"cogs_cents": 30000,
"net_profit_cents": 72000,
"breakdown": {
"fees": {
"listing": -400,
"listing_credits": 40,
"transaction": -8125,
"transaction_credits": 325,
"processing": -4800,
"processing_credits": 192,
"shipping": -650,
"shipping_credits": 0,
"vat_on_fees": -1200,
"vat_on_fees_credits": 0,
"regulatory": -500,
"regulatory_credits": 0,
"other": 0,
"total": -15118
},
"ads": {
"etsy_ads": -3000,
"offsite_ads": -1500,
"offsite_ads_credits": 0,
"subscription": -999,
"total": -5499
},
"sales": {
"gross_sales_cents": 125000,
"refund_cents": 8000,
"cancelled_cents": 2000,
"remitted_tax": {
"sales_tax": -2000,
"sales_tax_credits": 200,
"vat_ep": -1200,
"vat_ep_credits": 0,
"total": -3000
}
},
"gross_profit": {
"gross_sales_cents": 125000,
"fees_cents": -15000,
"ads_cents": -5000,
"remitted_tax_cents": -3000,
"total": 102000
},
"net_profit": {
"gross_profit_cents": 102000,
"cogs_cents": 30000,
"total": 72000
}
}
}
// ── Response WITH hourly=true (single day) ──
{
"shop_id": "12345678",
"shop_name": "My Etsy Shop",
"currency": "GBP",
"start": 1716508800,
"end": 1716595200,
"balance_cents": 125430,
"paid_out_cents": 12000,
"sales_count": 5,
"gross_sales_cents": 45000,
"sales_cents": 43500,
"fees_cents": -5400,
"ads_cents": -1200,
"refund_cents": 1500,
"cancelled_cents": 0,
"recoup_cents": 0,
"remitted_tax_cents": 0,
"gross_profit_cents": 38400,
"cogs_cents": 10000,
"net_profit_cents": 28400,
"hourly": [
{
"hour": 0,
"hour_start": 1716508800,
"hour_end": 1716512400,
"entry_count": 0,
"sales_count": 0,
"gross_sales_cents": 0,
"sales_cents": 0,
"fees_cents": 0,
"ads_cents": 0,
"remitted_tax_cents": 0,
"refund_cents": 0,
"cancelled_cents": 0,
"recoup_cents": 0,
"gross_profit_cents": 0,
"cogs_cents": 0,
"net_profit_cents": 0,
"paid_out_cents": 0
},
{ "hour": 1, "..." : "..." },
{ "hour": 2, "..." : "..." },
"... (hours 3-8 omitted for brevity) ...",
{
"hour": 9,
"hour_start": 1716541200,
"hour_end": 1716544800,
"entry_count": 4,
"sales_count": 2,
"gross_sales_cents": 18000,
"sales_cents": 18000,
"fees_cents": -2160,
"ads_cents": -600,
"remitted_tax_cents": 0,
"refund_cents": 0,
"cancelled_cents": 0,
"recoup_cents": 0,
"gross_profit_cents": 15240,
"cogs_cents": 4000,
"net_profit_cents": 11240,
"paid_out_cents": 0
},
"... (hours 10-23) ..."
]
}
━━━ MODES ━━━
EASIEST — send { "period": "today" } (or yesterday/last_7_days/last_30_days/this_month/last_month), or { "date": "2026-06-01" }, or { "start_date": "...", "end_date": "..." }. The server resolves the window (shop timezone, override with "timezone") and re-fetches it — no unix math. Single day → day mode, multi-day → range mode. The response echoes a `range` object with the exact window + server time.
1. Incremental — send empty body or {}.
Fetches only new entries since last sync. Fast, safe to call often.
Use for: keeping data fresh on a schedule (e.g. every 15 min).
Returns: new_entries, total_fetched, affected_days.
2. Single day — send { "day_start": unix_ts }.
Re-fetches ALL entries for that day. Replaces stale data.
Optionally include day_end (defaults to day_start + 86399).
Use for: a day that looks wrong or incomplete.
Returns: day_start, day_end, new_entries, total_fetched.
3. Date range — send { "start": unix_ts, "end": unix_ts }.
Deletes existing entries in the range, re-fetches from Etsy, recomputes summaries.
Use for: full reconciliation of a period. Heaviest mode.
Returns: start, end, deleted_stale, new_entries.
━━━ WHAT YOU GET BACK ━━━
success — true if sync completed
mode — "incremental", "day", or "range"
new_entries — number of new ledger entries saved
total_fetched — total entries fetched from Etsy (incremental + day modes)
affected_days — list of day timestamps that had changes (incremental mode only)
deleted_stale — entries deleted before re-fetch (range mode only)
day_start / day_end — the day that was synced (day mode only)
start / end — the range that was synced (range mode only)
━━━ NOTES ━━━
This is the ONLY finance endpoint that makes Etsy API calls.
Counts toward your Eto rate limit AND Etsy API cost billing.
If the store's OAuth token expired, returns STORE_TOKEN_EXPIRED.
If Etsy's API is down, returns UPSTREAM_ERROR with detail.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| period | string | optional | EASIEST — resolve a window server-side and re-fetch it: today, yesterday, last_7_days, last_30_days, this_month, last_month. No timestamps. |
| date | string | optional | Re-fetch one calendar day "YYYY-MM-DD" (resolved in the shop/timezone). |
| start_date | string | optional | Range mode — first day "YYYY-MM-DD" (inclusive). |
| end_date | string | optional | Range mode — last day "YYYY-MM-DD" (inclusive). |
| timezone | string | optional | IANA timezone for resolving period/date (default: shop timezone). |
| day_start | integer | optional | Advanced single-day mode — unix timestamp of the day start. |
| day_end | integer | optional | Advanced single-day mode — unix timestamp of the day end (default: day_start + 86399). |
| start | integer | optional | Advanced range mode — start of range to re-fetch (unix seconds). |
| end | integer | optional | Advanced range mode — end of range to re-fetch (unix seconds). |
Example
# ── Incremental sync (get latest entries) ──
curl -X POST -H "X-Eto-API-Key: eto_your_key" \
"https://eto.tools/api/v1/finance/12345678/sync"
# ── Re-fetch a single day ──
curl -X POST -H "X-Eto-API-Key: eto_your_key" \
-H "Content-Type: application/json" \
-d '{"day_start": 1716508800}' \
"https://eto.tools/api/v1/finance/12345678/sync"
# ── Re-fetch a single day with explicit end ──
curl -X POST -H "X-Eto-API-Key: eto_your_key" \
-H "Content-Type: application/json" \
-d '{"day_start": 1716508800, "day_end": 1716595199}' \
"https://eto.tools/api/v1/finance/12345678/sync"
# ── Re-fetch an entire date range ──
curl -X POST -H "X-Eto-API-Key: eto_your_key" \
-H "Content-Type: application/json" \
-d '{"start": 1716508800, "end": 1717113600}' \
"https://eto.tools/api/v1/finance/12345678/sync"
Response
// ── Incremental ──
{
"success": true,
"mode": "incremental",
"new_entries": 12,
"total_fetched": 15,
"affected_days": [1716508800, 1716595200]
}
// ── Single day ──
{
"success": true,
"mode": "day",
"day_start": 1716508800,
"day_end": 1716595199,
"new_entries": 22,
"total_fetched": 22
}
// ── Date range ──
{
"success": true,
"mode": "range",
"start": 1716508800,
"end": 1717113600,
"deleted_stale": 145,
"new_entries": 152
}
These are ACCOUNT-level, not per shop, so they are NOT included in GET /finance/{shop_id}. To get profit after software, subtract total_cents from the shop's net_profit_cents.
━━━ WHAT YOU GET BACK (always returned) ━━━
start / end — the resolved window (unix seconds)
range — exact window: timezone, local-ISO bounds, label, server time
currency — the currency total_cents is in: your common currency from Finance settings, else the single currency all subscriptions share, else null (mixed)
common_currency — the common currency configured in Finance → Settings, or null
total_cents — everything charged inside the window, converted to `currency`
totals_by_currency — { "USD": 2598, "GBP": 999 } raw sums per native currency
charge_count — number of individual charges inside the window
subscription_count — number of subscriptions logged (all of them, not just active in window)
subscriptions[] — one entry per logged subscription:
id, name, amount_cents, currency, frequency (weekly | biweekly | monthly | onetime), start_date (YYYY-MM-DD), conversion_rate (native → common), amount_converted_cents, charges_in_range, total_in_range_cents (converted), next_charge_date (YYYY-MM-DD or null), issue (only present when the entry is broken and never bills — e.g. missing amount/date)
scope — reminder that these are account-level costs, not per shop
warnings[] — caveats, e.g. mixed currencies with no common currency set
hint — only when nothing is logged yet, with where to add subscriptions
All amounts are COSTS (money out) returned as POSITIVE cents. Divide by 100 for display.
━━━ HOW CHARGES ARE COUNTED ━━━
Each subscription bills from its start_date on its schedule: weekly every 7 days, biweekly every 14, monthly on the same day each month (clamped to shorter months — the 31st bills on the 30th/28th), onetime exactly once on start_date. A charge is counted when its calendar date falls inside the window. So "this month" for a $12.99 monthly subscription started on the 15th is 1299 cents; "last_7_days" may be 0 if the billing day is not in that week. Identical to the dashboard.
━━━ HOW TO PICK THE DATE WINDOW ━━━
EASIEST — pass period=this_month (the default), today, yesterday, last_7_days, last_30_days or last_month. Or start_date=YYYY-MM-DD & end_date=YYYY-MM-DD (inclusive calendar days). Add timezone=Europe/London to resolve the window in a specific zone — the default is your primary connected shop's timezone, else UTC. Raw unix start/end are accepted too (max 366 days). The response echoes the resolved window in `range`, so you never have to guess which days were counted.
━━━ OPTIONAL ━━━
include=charges — also return charges[]: every individual charge inside the window (date, subscription_id, name, frequency, amount_cents, currency, converted_cents), sorted by date. charges_truncated is true if the list was cut at 2,000 entries (totals are always complete).
━━━ NOTES ━━━
Read-only. Subscriptions are added and edited on the Finance dashboard (eto.tools/dashboard/finances → Settings → Subscriptions).
Only YOUR account's subscriptions are ever returned — there is no id to look up.
An empty subscriptions[] with total_cents 0 is a valid answer: nothing is logged yet (the response carries a hint saying so).
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| period | string | optional |
EASIEST — today, yesterday, last_7_days, last_30_days, this_month, last_month. Resolved server-side. Default: this_month.
Default:
this_month |
| start_date | string | optional | First calendar day "YYYY-MM-DD" (inclusive). |
| end_date | string | optional | Last calendar day "YYYY-MM-DD" (inclusive). Defaults to start_date. |
| timezone | string | optional | IANA timezone used to resolve period/dates into calendar days (default: your primary connected shop's timezone, else UTC). |
| include | string | optional | Set to "charges" to also list every individual charge in the window. |
| start | integer | optional | Advanced — unix timestamp, range start (inclusive). Prefer period/start_date. |
| end | integer | optional | Advanced — unix timestamp, range end (exclusive). Prefer period/end_date. |
Example
# ── This month (default) ──
curl -H "X-Eto-API-Key: eto_your_key" \
"https://eto.tools/api/v1/finance/software-expenses"
# ── Last month ──
curl -H "X-Eto-API-Key: eto_your_key" \
"https://eto.tools/api/v1/finance/software-expenses?period=last_month"
# ── A specific window, in your own timezone ──
curl -H "X-Eto-API-Key: eto_your_key" \
"https://eto.tools/api/v1/finance/software-expenses?start_date=2026-07-01&end_date=2026-07-31&timezone=Europe/London"
# ── This month + every individual charge ──
curl -H "X-Eto-API-Key: eto_your_key" \
"https://eto.tools/api/v1/finance/software-expenses?period=this_month&include=charges"
Response
{
"start": 1785542400,
"end": 1788220800,
"range": {
"start": 1785542400,
"end": 1788220800,
"start_local": "2026-08-01T00:00:00+01:00",
"end_local": "2026-09-01T00:00:00+01:00",
"timezone": "Europe/London",
"label": "this month (month-to-date)",
"server_now_unix": 1787788800,
"server_now_utc": "2026-08-23T00:00:00+00:00"
},
"currency": "GBP",
"common_currency": "GBP",
"total_cents": 2325,
"totals_by_currency": { "USD": 1299, "GBP": 1299 },
"charge_count": 2,
"subscription_count": 3,
"subscriptions": [
{
"id": "sub_1753000000000_ab12",
"name": "Eto",
"amount_cents": 1299,
"currency": "GBP",
"frequency": "monthly",
"start_date": "2026-03-05",
"conversion_rate": 1.0,
"amount_converted_cents": 1299,
"charges_in_range": 1,
"total_in_range_cents": 1299,
"next_charge_date": "2026-09-05"
},
{
"id": "sub_1751000000000_cd34",
"name": "Canva Pro",
"amount_cents": 1299,
"currency": "USD",
"frequency": "monthly",
"start_date": "2026-01-15",
"conversion_rate": 0.79,
"amount_converted_cents": 1026,
"charges_in_range": 1,
"total_in_range_cents": 1026,
"next_charge_date": "2026-09-15"
},
{
"id": "sub_1749000000000_ef56",
"name": "Printify Premium",
"amount_cents": 2499,
"currency": "USD",
"frequency": "monthly",
"start_date": "2026-08-28",
"conversion_rate": 0.79,
"amount_converted_cents": 1974,
"charges_in_range": 0,
"total_in_range_cents": 0,
"next_charge_date": "2026-08-28"
}
],
"scope": {
"level": "account",
"note": "Software expenses are logged per Eto account, not per shop, so they are NOT part of GET /api/v1/finance/{shop_id}. All amounts are costs (money out) returned as positive cents; subtract total_cents from a shop's net_profit_cents to get profit after software.",
"manage_at": "https://eto.tools/dashboard/finances (Settings → Subscriptions)"
},
"warnings": []
}
// ── With include=charges (extra keys) ──
{
"...": "...",
"charges": [
{ "date": "2026-08-05", "subscription_id": "sub_1753000000000_ab12", "name": "Eto", "frequency": "monthly", "amount_cents": 1299, "currency": "GBP", "converted_cents": 1299 },
{ "date": "2026-08-15", "subscription_id": "sub_1751000000000_cd34", "name": "Canva Pro", "frequency": "monthly", "amount_cents": 1299, "currency": "USD", "converted_cents": 1026 }
],
"charges_truncated": false
}
// ── Nothing logged yet ──
{
"...": "...",
"currency": null,
"total_cents": 0,
"subscription_count": 0,
"subscriptions": [],
"hint": "No software expenses are logged yet. Add them at eto.tools/dashboard/finances → Settings → Subscriptions and they will appear here."
}
Images & Media
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| listing_id | integer | REQUIRED | The listing ID |
| image | file | REQUIRED | Image file (JPEG, PNG, GIF) |
| rank | integer | optional | Image display order (1-10) |
Example
curl -X POST -H "X-Eto-API-Key: eto_your_key" -F "image=@photo.jpg" -F "rank=1" "https://eto.tools/api/v1/shops/12345678/listings/1234567890/images"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| listing_id | integer | REQUIRED | The listing ID |
| image_id | integer | REQUIRED | The image ID to delete |
Example
curl -X DELETE -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/listings/1234567890/images/987654321"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| listing_id | integer | REQUIRED | The listing ID |
| video | file | REQUIRED | Video file |
Example
curl -X POST -H "X-Eto-API-Key: eto_your_key" -F "video=@clip.mp4" "https://eto.tools/api/v1/shops/12345678/listings/1234567890/videos"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| listing_id | integer | REQUIRED | The listing ID |
| video_id | integer | REQUIRED | The video ID to delete |
Example
curl -X DELETE -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/listings/1234567890/videos/987654321"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| listing_id | integer | REQUIRED | The listing ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/listings/1234567890/variation-images"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| listing_id | integer | REQUIRED | The listing ID |
| file | file | REQUIRED | Digital file to upload |
| name | string | optional | Display name for the file |
Example
curl -X POST -H "X-Eto-API-Key: eto_your_key" -F "file=@design.pdf" "https://eto.tools/api/v1/shops/12345678/listings/1234567890/files"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| listing_id | integer | REQUIRED | The listing ID |
| file_id | integer | REQUIRED | The file ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/listings/1234567890/files/987654321"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| listing_id | integer | REQUIRED | The listing ID |
| image_id | integer | REQUIRED | The image ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/listings/1234567890/images/987654321"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| listing_id | integer | REQUIRED | The listing ID |
| video_id | integer | REQUIRED | The video ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/listings/1234567890/videos/987654321"
Listing Properties
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| listing_id | integer | REQUIRED | The listing ID |
| property_id | integer | REQUIRED | The property ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/listings/1234567890/properties/200"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| listing_id | integer | REQUIRED | The listing ID |
| property_id | integer | REQUIRED | The property ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/listings/1234567890/properties/200"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| listing_id | integer | REQUIRED | The listing ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/listings/1234567890/properties"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| listing_id | integer | REQUIRED | The listing ID |
| property_id | integer | REQUIRED | The property ID |
Example
curl -X DELETE -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/listings/1234567890/properties/200"
Shipping
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/shipping-profiles"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| profile_id | integer | REQUIRED | The shipping profile ID |
Example
curl -X PUT -H "X-Eto-API-Key: eto_your_key" -H "Content-Type: application/json" -d '{"title": "Updated"}' "https://eto.tools/api/v1/shops/12345678/shipping-profiles/111222333"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| profile_id | integer | REQUIRED | The shipping profile ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/shipping-profiles/111222333/destinations"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| profile_id | integer | REQUIRED | The shipping profile ID |
| destination_id | integer | REQUIRED | The destination ID |
Example
curl -X PUT -H "X-Eto-API-Key: eto_your_key" -H "Content-Type: application/json" -d '{"primary_cost": 500}' "https://eto.tools/api/v1/shops/12345678/shipping-profiles/111222333/destinations/77777"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| profile_id | integer | REQUIRED | The shipping profile ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/shipping-profiles/111222333/upgrades"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| profile_id | integer | REQUIRED | The shipping profile ID |
| upgrade_id | integer | REQUIRED | The upgrade ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/shipping-profiles/111222333/upgrades/88888"
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shipping-carriers"
Categories
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/categories"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| category_id | integer | REQUIRED | The category ID (from /categories) |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/categories/1/properties"
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/buyer-categories"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| category_id | integer | REQUIRED | The buyer category ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/buyer-categories/1/properties"
User
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/users/me"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| user_id | integer | REQUIRED | The Etsy user ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/users/123456789/shops"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| user_id | integer | REQUIRED | The Etsy user ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/users/123456789"
Shop Policies
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/return-policies"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/production-partners"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/listing-requirements"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
Example
curl -X POST -H "X-Eto-API-Key: eto_your_key" -H "Content-Type: application/json" -d '{"accepts_returns": true, "return_deadline": 30}' "https://eto.tools/api/v1/shops/12345678/return-policies"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| policy_id | integer | REQUIRED | The return policy ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/return-policies/54321"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
Example
curl -X POST -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/return-policies/consolidate"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| policy_id | integer | REQUIRED | The return policy ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/return-policies/54321/listings"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/holiday-preferences"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| holiday_id | integer | REQUIRED | The holiday ID |
Example
curl -X PUT -H "X-Eto-API-Key: eto_your_key" -H "Content-Type: application/json" -d '{"is_working": false}' "https://eto.tools/api/v1/shops/12345678/holiday-preferences/1"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| requirement_id | integer | REQUIRED | The requirement ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/listing-requirements/99999"
One Etsy API call per request. Response is a flat list — pick the shipping_profile_id you want.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your connected Etsy shop ID. Get the list from GET /api/v1/stores. |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/stores/12345678/shipping-profiles/live"
Response
{
"shop_id": "12345678",
"fetched_at": "2026-04-19T14:30:00Z",
"count": 2,
"shipping_profiles": [
{
"shipping_profile_id": 291257702631,
"title": "Standard Shipping",
"min_processing_days": 1,
"max_processing_days": 3,
"processing_days_display_label": "1-3 business days",
"origin_country_iso": "US",
"origin_postal_code": "10001",
"profile_type": "manual",
"domestic_handling_fee": 0.00,
"international_handling_fee": 0.00
}
]
}
One Etsy API call per request.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your connected Etsy shop ID. |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/stores/12345678/return-policies/live"
Response
{
"shop_id": "12345678",
"fetched_at": "2026-04-19T14:30:00Z",
"count": 1,
"return_policies": [
{
"return_policy_id": 1435074483195,
"accepts_returns": true,
"accepts_exchanges": true,
"return_deadline": 30
}
]
}
One Etsy API call per request.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your connected Etsy shop ID. |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/stores/12345678/processing-profiles/live"
Response
{
"shop_id": "12345678",
"fetched_at": "2026-04-19T14:30:00Z",
"count": 1,
"processing_profiles": [
{
"readiness_state_id": 1456101932490,
"readiness_state": "ready_to_ship",
"min_processing_days": 1,
"max_processing_days": 3,
"processing_days_display_label": "1-3 business days"
}
]
}
One Etsy API call per request.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your connected Etsy shop ID. |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/stores/12345678/shop-sections/live"
Response
{
"shop_id": "12345678",
"fetched_at": "2026-04-19T14:30:00Z",
"count": 2,
"shop_sections": [
{
"shop_section_id": 56909368,
"title": "New Arrivals",
"rank": 1,
"user_id": 99887766,
"active_listing_count": 15
}
]
}
Orders
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| limit | integer | optional |
Number of orders (max 100)
Default:
25 |
| offset | integer | optional |
Pagination offset
Default:
0 |
| min_created | integer | optional | Earliest order date (unix seconds) |
| max_created | integer | optional | Latest order date (unix seconds) |
| sort_on | string | optional |
Sort field
Default:
created |
| sort_order | string | optional |
Sort direction
Default:
desc |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/orders?limit=10"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| order_id | integer | REQUIRED | The order ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/orders/3344556677"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| order_id | integer | REQUIRED | The order ID |
| tracking_code | string | REQUIRED | Tracking number |
| carrier_name | string | REQUIRED | Shipping carrier name |
Example
curl -X POST -H "X-Eto-API-Key: eto_your_key" -H "Content-Type: application/json" -d '{"tracking_code": "1Z999AA10123456784", "carrier_name": "ups"}' "https://eto.tools/api/v1/shops/12345678/orders/3344556677/tracking"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| order_id | integer | REQUIRED | The order ID |
Example
curl -X PUT -H "X-Eto-API-Key: eto_your_key" -H "Content-Type: application/json" -d '{"was_shipped": true}' "https://eto.tools/api/v1/shops/12345678/orders/3344556677/update"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| order_id | integer | REQUIRED | The order ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/orders/3344556677/listings"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| order_id | integer | REQUIRED | The order ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/orders/3344556677/payments"
Finances
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| min_created | integer | optional | Earliest date (unix seconds) |
| max_created | integer | optional | Latest date (unix seconds) |
| limit | integer | optional |
Number of results (max 100)
Default:
25 |
| offset | integer | optional |
Pagination offset
Default:
0 |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/finance/transactions?limit=10"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| transaction_ids | string | REQUIRED | Comma-separated transaction IDs |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/finance/payments?transaction_ids=123,456"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| limit | integer | optional |
Number of sales (max 100)
Default:
25 |
| offset | integer | optional |
Pagination offset
Default:
0 |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/finance/sales?limit=10"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| listing_id | integer | REQUIRED | The listing ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/listings/1234567890/sales"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| order_id | integer | REQUIRED | The order ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/orders/3344556677/transactions"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| transaction_id | integer | REQUIRED | The transaction ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/finance/sales/4455667788"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
| entry_id | integer | REQUIRED | The ledger entry ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/finance/transactions/9988776655"
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/finance/all-payments"
Analytics
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
Example
curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shops/12345678/stats/traffic"
Connected Stores Eto
Check store connection status. Stores must be connected via the Eto dashboard.
Returns all Etsy stores connected to your account.
Response
{
"stores": [
{
"shop_id": "12345678",
"shop_name": "My Etsy Shop",
"is_connected": true,
"token_valid": true,
"connected_at": "2026-01-15T10:30:00Z"
}
]
}
Get detailed status for a specific connected store.
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop ID |
Orders Eto
Access order data through Eto. Every call syncs latest orders from Etsy into Eto's database automatically.
Syncs latest orders from Etsy, then returns from Eto's database with enriched fields. Each order includes an inline profit object (with cogs_cents, fees_cents, net_profit_cents) read from Eto's materialized snapshot — so you get cost/profit for a whole page in one call instead of one extra call per order. profit is null when no snapshot exists yet (run /sync or finance_sync, then retry); call the detail endpoint for the full fees_breakdown.
| Name | Type | Required | Description |
|---|---|---|---|
| shop_id | integer | REQUIRED | Your Etsy shop id, in the path. |
| period | string | optional | Named window, resolved in the shop’s timezone: today, yesterday, last_7_days, last_30_days, this_month, last_month. |
| start_date / end_date | string | optional | Calendar dates (YYYY-MM-DD), inclusive at both ends. |
| timezone | string | optional | IANA name (e.g. Europe/London) used to resolve the window. Defaults to the shop’s own timezone. |
| min_created / max_created | integer | optional | Raw Unix seconds, if you would rather compute the window yourself. |
| sort_on | string | optional | created, updated or receipt_id default: created |
| sort_order | string | optional | asc or desc default: desc |
| limit | integer | optional | Rows per page, clamped to 1–100 default: 25 |
| offset | integer | optional | Rows to skip default: 0 |
With no date arguments at all you get the most recent orders. An unknown period or timezone is refused with INVALID_REQUEST and a hint naming the accepted values.
Example
curl -H "X-Eto-API-Key: eto_your_key" \
"https://eto.tools/api/v1/orders/12345678?period=last_7_days&limit=25"
Response
{
"count": 128,
"results": [
{
"receipt_id": 987654321,
"created_timestamp": 1717150000,
"created_iso": "2026-05-31T10:26:40+00:00",
"created_local": "2026-05-31T11:26:40+01:00",
"profit": {
"currency": "USD",
"gross_sales_cents": 2599,
"fees_cents": 412,
"gross_profit_cents": 2187,
"cogs_cents": 800,
"net_profit_cents": 1387,
"has_refund": false
}
}
],
"timezone": "Europe/London",
"profit_note": "Each order's `profit` is its own gross sale minus its own fees and COGS…",
"server_now_unix": 1788720109,
"server_now_utc": "2026-09-06T18:41:49+00:00",
"range": { "start": 1788134400, "end": 1788739200, "label": "last 7 days" }
}
Every field Etsy returns on a receipt is passed through untouched; the fields above are the ones Eto adds. range appears only when you asked for a window.
Full order detail for one Etsy receipt: line items, shipments, refunds and the fees_breakdown behind the profit figure. receipt_id is Etsy’s receipt id, the same value the list endpoint returns.
Manually trigger an Etsy → Eto order sync.
Product Hunt Eto
Take your list of Etsy listings and let Eto add the one signal you can't get from the raw Etsy API: demand_24h — how many units were bought in the last 24 hours. You bring the listings, we add the demand.
Stateless — nothing is saved. Synchronous — waits and returns all results in one response (~30-90 seconds).
Three input modes — choose based on what you have:
Mode S — You give us a search term, we fetch & rank easiest
Send just a keyword (no listing IDs needed) and a few settings. Eto will:
- Search Etsy for that term and collect up to
amountproducts (optionally age-filtered) - Extract
demand_24hfor each — the popularity signal - Rank them: by demand, or — with
optimized— AI-scored by opportunity (addsai_score+ai_reason) - Return the ranked array
Use when: you only know a search term and want the same thing the Product Hunt page gives you.
Mode A — You give us IDs, we do everything
Send just a list of Etsy listing IDs. Eto will:
- Fetch full details for every listing (title, price, shop info, tags, etc.)
- Extract
demand_24h(units bought in last 24h) - Return a fully enriched array
Use when: You only have listing IDs (e.g. from our Etsy search endpoint) and want the complete picture.
Mode B — You give us full data, we just add demand
Send your existing listing objects (whatever fields you already have). Eto will:
- Extract
demand_24hfor each listing - Return your original objects with
demand_24hadded
Use when: You already have full listing data (from Etsy's API or our proxy) and just need the demand signal Etsy doesn't publicly expose.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| keyword | string | REQUIRED | Search term (max 200 chars). In Modes A/B it's context for popular detection; in Mode S it's the actual search query. |
| amount | integer | Mode S | Search: how many products to fetch & rank. 1–100, default 50. |
| max_listing_age | integer | Mode S | Search: only listings created within the last N months. 0 or omit = no limit (max 60). |
| optimized | boolean | Mode S | Search: AI-powered filtering & ranking. Results carry ai_score + ai_reason and are sorted by score. When true, full_details is ignored. |
| full_details | boolean | Mode S | Search (only when optimized is false): true returns full per-listing details; false returns listing_id + demand_24h only (lightest & cheapest). |
| listing_ids | array<int> | either/or | Mode A: Array of listing IDs (max 500). Eto will fetch everything. |
| listings | array<object> | either/or | Mode B: Array of listing objects with at minimum listing_id. Your fields are preserved and signals are added. |
Omit both listing_ids and listings to run a Mode S search. Otherwise provide either listing_ids or listings — not both. Max 500 listings (Modes A/B) / 100 products (Mode S) per request.
Mode S Example — "I have a search term, find & rank for me"
curl -X POST -H "X-Eto-API-Key: eto_your_key" \
-H "Content-Type: application/json" \
-d '{
"keyword": "shirt",
"amount": 100,
"max_listing_age": 6,
"optimized": true
}' \
"https://eto.tools/api/v1/product-hunt"
Mode S Response
{
"keyword": "shirt",
"mode": "search",
"params": {"amount": 100, "max_listing_age": 6, "optimized": true, "full_details": false},
"total_results": 100,
"results": [
{
"listing_id": 4472965081,
"title": "Rad Dad Society Shirt, Cool Dad Club Tee",
"price": {"amount": 1665, "divisor": 100, "currency_code": "USD"},
"views": 5511,
"favorites": 436,
"demand_24h": 21,
"listing_age_days": 77,
"shop_name": "CozyPrintsClothing",
"shop_sales": 72995,
"shop_age_days": 1421,
"ai_score": 88,
"ai_reason": "Exceptional demand on a proven shop; strong fav rate."
}
// ...ranked by ai_score (optimized) or demand_24h
]
}
Mode A Example — "I have IDs, give me everything"
curl -X POST -H "X-Eto-API-Key: eto_your_key" \
-H "Content-Type: application/json" \
-d '{
"keyword": "leather wallet",
"listing_ids": [1234567890, 9876543210, 1122334455]
}' \
"https://eto.tools/api/v1/product-hunt"
Mode A Response
{
"keyword": "leather wallet",
"mode": "ids_to_full",
"total_input": 3,
"total_results": 3,
"results": [
{
"listing_id": 1234567890,
"title": "Handmade Leather Bifold Wallet",
"description": "Beautiful handmade leather...",
"price": {"amount": 2499, "divisor": 100, "currency_code": "USD"},
"quantity": 50,
"views": 3240,
"favorites": 145,
"demand_24h": 5,
"is_digital": false,
"listing_type": "physical",
"has_variations": true,
"tags": ["wallet", "leather", "gift"],
"materials": ["leather", "thread"],
"created_timestamp": 1500000000,
"listing_age_days": 850,
"shop_name": "LeatherCraftCo",
"shop_sales": 2340,
"shop_age_days": 1200,
"shipping_origin_country": "US"
}
]
}
Mode B Example — "I have full data, just add signals"
curl -X POST -H "X-Eto-API-Key: eto_your_key" \
-H "Content-Type: application/json" \
-d '{
"keyword": "leather wallet",
"listings": [
{
"listing_id": 1234567890,
"title": "My Wallet",
"price": 24.99,
"my_custom_field": "whatever"
},
{
"listing_id": 9876543210,
"title": "Another Wallet"
}
]
}' \
"https://eto.tools/api/v1/product-hunt"
Mode B Response
Your original listing objects are returned with only demand_24h added. Any custom fields you sent are preserved:
{
"keyword": "leather wallet",
"mode": "data_to_signals",
"total_input": 2,
"total_results": 2,
"results": [
{
"listing_id": 1234567890,
"title": "My Wallet",
"price": 24.99,
"my_custom_field": "whatever",
"demand_24h": 5
},
{
"listing_id": 9876543210,
"title": "Another Wallet",
"demand_24h": null
}
]
}
Field Definitions
| Field | Type | Description |
|---|---|---|
| demand_24h | integer|null | Units bought in the last 24 hours. null if demand couldn't be extracted (e.g. listing unavailable). Added by Eto in both modes. |
| listing_id | integer | Etsy listing ID |
| title | string | Listing title (Mode A only, from Etsy API) |
| description | string | First 500 chars of description (Mode A) |
| price | object | Price as {amount, divisor, currency_code} (Mode A) |
| views | integer | Total listing views (Mode A) |
| favorites | integer | Users who favorited this (Mode A) |
| listing_age_days | integer | Days since first created (Mode A) |
| shop_name | string | Shop name (Mode A) |
| shop_sales | integer | Total sales by this shop (Mode A) |
| shop_age_days | integer | Days since shop created (Mode A) |
| tags | array | Listing keywords (Mode A) |
| materials | array | Materials used (Mode A) |
Edge Cases
| Scenario | Behavior |
|---|---|
| Both listing_ids and listings sent | Error — pick one. |
| Neither listing_ids nor listings | Error — must provide one. |
| More than 500 items | Error — max 500 per request. |
| Listing in Mode A has no details on Etsy (deleted) | Returns {"listing_id": X, "error": "enrichment_failed", "demand_24h": null} |
| Demand extraction fails for a listing | demand_24h: null for that specific listing. |
| Empty keyword | Error returned. |
Mode B listing missing listing_id | Error returned. |
AI Studio Eto
Generate titles, descriptions and product copy with your own AI credentials. Every AI request must name a provider in the JSON body, and the credentials for it come from your account, not from the request. Add them at eto.tools/settings.
Provider Options
| Provider | Value | Setup Required |
|---|---|---|
| Gemini API Key | "gemini" | Add your Google AI Studio API key in settings |
| Vertex AI | "vertex" | Add your GCP project ID + service account JSON in settings |
| Eto Credits | "eto_credits" | No setup — runs on Eto’s own Vertex AI. Enterprise plans only. |
Every AI request must include "provider": "gemini" or "provider": "vertex" in the JSON body.
Text chat with Gemini. Send a message and get a response.
Example
curl -X POST -H "X-Eto-API-Key: eto_your_key" \
-H "Content-Type: application/json" \
-d '{"message": "Make this title premium", "provider": "gemini", "context": {"draft_title": "Cotton Pillow"}}' \
"https://eto.tools/api/v1/ai/chat"
Response
{"status": "ok", "reply": "Premium Cotton Pillow Cover, Hand-Finished Linen Blend"}
| Name | Type | Required | Description |
|---|---|---|---|
| keyword | string | REQUIRED | Main keyword |
| product_description | string | optional | Brief product description |
| style | string | optional | professional, premium, casual default: professional |
| max_length | integer | optional | Max chars default: 140 |
Response
{"status": "ok", "title": "Premium Handmade Leather Bifold Wallet RFID Blocking", "length": 52}
Generate a compelling, SEO-friendly listing description.
501 with {"status": "error", "message": "Image generation via API is coming soon. Use eto.tools/dashboard for now."}. Generate images in the dashboard until it ships.
The parameters below are the contract it will answer to once it is live.
| Name | Type | Required | Description |
|---|---|---|---|
| prompt | string | REQUIRED | Image generation prompt |
| provider | string | REQUIRED | gemini, vertex or eto_credits |
| product_image | string | optional | Base64-encoded product image |
| type | string | optional | thumbnail, info, showcase |
Poll with ?job_id=xxx. Returns 202 and {"status": "pending"} while the job runs, 200 when it finishes, and 502 with an error string if it failed. An unknown or foreign job id returns SESSION_NOT_FOUND.
{"status": "ok", "image_url": "/media/api/generated/123/img.png", "elapsed_s": 12.5}
Analyze a product image — get descriptions, features, and keywords.
Webhooks Eto
Instead of polling for orders, let Eto push order events to your own server in real time. When an order on your connected Etsy shop is paid, shipped, canceled, or delivered, Eto enriches the event with the full order detail and sends an HTTP POST to a URL you choose.
Webhooks are an Enterprise feature. Set your destination URL, pick the events and stores, and read the signing secret in the API console under Webhooks. You only ever receive events for your own connected stores.
Events
| Event | Meaning |
|---|---|
| order.paid | The buyer completed payment for the order. |
| order.shipped | Shipping information was created / the order was marked shipped. |
| order.canceled | The seller canceled the order. |
| order.delivered | The order was marked delivered. |
Choose which events and which stores forward to your URL in settings. A store only forwards while its order notifications are enabled.
Request headers
| Header | Description |
|---|---|
| X-Eto-Event | The event type, e.g. order.paid. |
| X-Eto-Webhook-Id | Unique id for this delivery (e.g. evt_8842). Use it to de-duplicate retries. |
| X-Eto-Timestamp | Unix seconds when the delivery was sent. |
| X-Eto-Signature | v1,<base64 HMAC-SHA256> — optional integrity signature (see below). |
Payload
The body is JSON. The order object contains every detail Eto has for the receipt — buyer, full shipping address, all monetary amounts (with a computed decimal value), line items, and shipments.
{
"event": "order.paid",
"event_description": "The buyer completed payment for this order.",
"event_id": "evt_8842",
"source_webhook_id": "msg_2a1b...",
"sent_at": "2026-05-31T10:26:00+00:00",
"shop": { "shop_id": "12345678", "shop_name": "MyShop" },
"order": {
"receipt_id": 987654321,
"status": "paid",
"is_paid": true,
"is_shipped": false,
"is_gift": false,
"gift_message": "",
"buyer": { "name": "Jane Doe", "email": "jane@example.com", "phone": "", "buyer_user_id": 55512345 },
"shipping_address": {
"name": "Jane Doe", "first_line": "1 Main St", "second_line": "",
"city": "Austin", "state": "TX", "zip": "78701", "country_iso": "US",
"formatted_address": "1 Main St\nAustin, TX 78701"
},
"amounts": {
"grandtotal": { "amount": 2599, "divisor": 100, "currency_code": "USD", "value": 25.99 },
"subtotal": { "amount": 1999, "divisor": 100, "currency_code": "USD", "value": 19.99 },
"total_price": { "amount": 1999, "divisor": 100, "currency_code": "USD", "value": 19.99 },
"total_shipping_cost": { "amount": 400, "divisor": 100, "currency_code": "USD", "value": 4.00 },
"total_tax_cost": { "amount": 200, "divisor": 100, "currency_code": "USD", "value": 2.00 },
"total_vat_cost": null,
"discount": null,
"gift_wrap_price": null
},
"payment_method": "cc",
"message_from_buyer": "Please gift wrap.",
"items": [
{
"transaction_id": 333111,
"title": "Custom Ceramic Mug",
"description": "...",
"quantity": 1,
"sku": "MUG-RED-11OZ",
"listing_id": 1100110011,
"product_id": 2200220022,
"listing_image_id": 3300330033,
"is_digital": false,
"transaction_type": "listing",
"price": { "amount": 1999, "divisor": 100, "currency_code": "USD", "value": 19.99 },
"shipping_cost": { "amount": 400, "divisor": 100, "currency_code": "USD", "value": 4.00 },
"variations": [ { "property_id": 200, "formatted_name": "Color", "formatted_value": "Red" } ],
"shipping_profile_id": 9090,
"shipping_method": null,
"expected_ship_date": 1717500000,
"paid_timestamp": 1717150000,
"shipped_timestamp": null,
"created_timestamp": 1717150000
}
],
"shipments": [
{ "receipt_shipping_id": 7777, "carrier_name": "usps", "tracking_code": "94001...", "shipment_notification_timestamp": 1717300000 }
],
"created_timestamp": 1717150000,
"updated_timestamp": 1717150500
}
}
Money is given in Etsy's minor-unit form (amount ÷ divisor) plus a pre-computed decimal value for convenience. Fields with no value are null. For order.shipped / order.delivered / order.canceled the same shape is sent for the specific receipt that changed.
Verifying the signature (optional)
You don't have to verify anything — Eto only sends events for your own account. But if you want to be certain a request genuinely came from Eto (and wasn't spoofed by someone who discovered your URL), verify the X-Eto-Signature header. Your signing secret is shown in settings (whsec_…).
signed_content = X-Eto-Webhook-Id + "." + X-Eto-Timestamp + "." + raw_request_body
secret_bytes = base64_decode(your_secret without the "whsec_" prefix)
expected = base64( HMAC_SHA256(secret_bytes, signed_content) )
# valid if expected == X-Eto-Signature.split(",")[1]
import base64, hashlib, hmac
def verify(headers, raw_body, secret):
secret_bytes = base64.b64decode(secret.split("_", 1)[1])
signed = f"{headers['X-Eto-Webhook-Id']}.{headers['X-Eto-Timestamp']}.{raw_body}"
expected = base64.b64encode(
hmac.new(secret_bytes, signed.encode(), hashlib.sha256).digest()
).decode()
got = headers["X-Eto-Signature"].split(",", 1)[1]
return hmac.compare_digest(got, expected)
X-Eto-Timestamp is more than a few minutes old to guard against replays.
Fetch & retry from your own server
Every delivery is stored, so your backend can pull recent events or re-request a missed one programmatically — authenticated with your X-Eto-API-Key (same key as the rest of the API).
Returns your deliveries newest-first, each with its status and HTTP result.
| Name | Type | Required | Description |
|---|---|---|---|
| status | string | optional | Filter: success, failed, pending |
| event | string | optional | Filter by event type, e.g. order.paid |
| include_payload | boolean | optional | Include each full JSON payload default: false |
| limit | integer | optional | default: 25, max: 100 |
| offset | integer | optional | Pagination offset |
curl -H "X-Eto-API-Key: eto_your_key" \
"https://eto.tools/api/v1/webhooks/deliveries?status=failed&limit=50"
{
"success": true,
"total": 128,
"limit": 50,
"offset": 0,
"deliveries": [
{
"id": 8842,
"event_id": "evt_8842",
"event_type": "order.paid",
"status": "success",
"response_status_code": 200,
"attempts": 1,
"error": "",
"is_test": false,
"receipt_id": 987654321,
"target_url": "https://your-server.com/webhooks/eto",
"created_at": "2026-05-31T10:26:00.123456+00:00",
"last_attempt_at": "2026-05-31T10:26:00.456789+00:00"
},
{
"id": 8841,
"event_id": "evt_8841",
"event_type": "order.shipped",
"status": "failed",
"response_status_code": 404,
"attempts": 2,
"error": "HTTP 404 from your endpoint",
"is_test": false,
"receipt_id": 987654000,
"target_url": "https://your-server.com/webhooks/eto",
"created_at": "2026-05-31T09:10:00.000000+00:00",
"last_attempt_at": "2026-05-31T09:12:00.000000+00:00"
}
]
}
Add include_payload=true to embed each delivery's full payload (same shape as the single-delivery response below).
Returns a single delivery including the exact payload we sent and the response we received — the "ask again and get it" path for a missed event.
{
"success": true,
"delivery": {
"id": 8842,
"event_id": "evt_8842",
"event_type": "order.paid",
"status": "success",
"response_status_code": 200,
"attempts": 1,
"error": "",
"is_test": false,
"receipt_id": 987654321,
"target_url": "https://your-server.com/webhooks/eto",
"created_at": "2026-05-31T10:26:00.123456+00:00",
"last_attempt_at": "2026-05-31T10:26:00.456789+00:00",
"response_body": "{\"received\": true}",
"payload": {
"event": "order.paid",
"event_description": "The buyer completed payment for this order.",
"event_id": "evt_8842",
"source_webhook_id": "msg_2a1b3c...",
"sent_at": "2026-05-31T10:26:00+00:00",
"shop": { "shop_id": "12345678", "shop_name": "MyShop" },
"order": {
"receipt_id": 987654321,
"status": "paid",
"is_paid": true,
"is_shipped": false,
"is_gift": false,
"gift_message": "",
"buyer": { "name": "Jane Doe", "email": "jane@example.com", "phone": "", "buyer_user_id": 55512345 },
"shipping_address": {
"name": "Jane Doe", "first_line": "1 Main St", "second_line": "",
"city": "Austin", "state": "TX", "zip": "78701", "country_iso": "US",
"formatted_address": "1 Main St\nAustin, TX 78701"
},
"amounts": {
"grandtotal": { "amount": 2599, "divisor": 100, "currency_code": "USD", "value": 25.99 },
"subtotal": { "amount": 1999, "divisor": 100, "currency_code": "USD", "value": 19.99 },
"total_price": { "amount": 1999, "divisor": 100, "currency_code": "USD", "value": 19.99 },
"total_shipping_cost": { "amount": 400, "divisor": 100, "currency_code": "USD", "value": 4.00 },
"total_tax_cost": { "amount": 200, "divisor": 100, "currency_code": "USD", "value": 2.00 },
"total_vat_cost": null,
"discount": null,
"gift_wrap_price": null
},
"payment_method": "cc",
"message_from_buyer": "Please gift wrap.",
"items": [
{
"transaction_id": 333111,
"title": "Custom Ceramic Mug",
"description": "11oz glossy ceramic mug",
"quantity": 1,
"sku": "MUG-RED-11OZ",
"listing_id": 1100110011,
"product_id": 2200220022,
"listing_image_id": 3300330033,
"is_digital": false,
"transaction_type": "listing",
"price": { "amount": 1999, "divisor": 100, "currency_code": "USD", "value": 19.99 },
"shipping_cost": { "amount": 400, "divisor": 100, "currency_code": "USD", "value": 4.00 },
"variations": [ { "property_id": 200, "formatted_name": "Color", "formatted_value": "Red" } ],
"shipping_profile_id": 9090,
"shipping_method": null,
"expected_ship_date": 1717500000,
"paid_timestamp": 1717150000,
"shipped_timestamp": null,
"created_timestamp": 1717150000
}
],
"shipments": [
{ "receipt_shipping_id": 7777, "carrier_name": "usps", "tracking_code": "94001...", "shipment_notification_timestamp": 1717300000 }
],
"created_timestamp": 1717150000,
"updated_timestamp": 1717150500
}
}
}
}
Re-delivers exactly one delivery — the single id you pass — to your current URL, and returns the new outcome (success, response_status_code, error). It never re-sends anything else.
?status=failed) and POST a retry per id.
curl -X POST -H "X-Eto-API-Key: eto_your_key" \
"https://eto.tools/api/v1/webhooks/deliveries/8842/retry"
{
"success": true,
"response_status_code": 200,
"error": "",
"delivery": {
"id": 8842,
"event_id": "evt_8842",
"event_type": "order.paid",
"status": "success",
"response_status_code": 200,
"attempts": 2,
"error": "",
"is_test": false,
"receipt_id": 987654321,
"target_url": "https://your-server.com/webhooks/eto",
"created_at": "2026-05-31T10:26:00.123456+00:00",
"last_attempt_at": "2026-05-31T11:02:14.000000+00:00"
}
}
Responding, delivery & retries
There is no automatic retry today — if your endpoint is unavailable, the delivery is marked failed and kept so you can re-send it (or pull the data) whenever you're ready.
Bulk CSV / Excel Import Eto
Create hundreds of Etsy drafts at once from a spreadsheet. Open it from Single Research → New listing → Upload via CSV / Excel. Eto auto-detects your columns (even renamed or reordered), shows an organized preview where every listing is validated, then publishes the selected ones to draft.
How images & videos work
Put image and video links as URLs in the Photo 1…10 and optional Video 1… columns. Eto downloads each URL and uploads it to Etsy automatically when publishing — you don't upload files here. Any public https:// URL works (your cloud storage, a CDN, or existing Etsy image URLs). Photo 1 becomes the listing thumbnail.
Variations span multiple rows
A row with a Title starts a new listing. The rows directly below it with a blank Title are extra variation combinations of that same listing. Set the axis names once on the first row in Variation 1 / Variation 2 (e.g. Size, Color); each row then carries its own V1 Option, V2 Option, Var Price, Var Quantity, Var SKU and Var Visibility (On/Off).
Title | V1 Option | V2 Option | Var Price | Var Visibility
Extra Large Abstract Wall Art | 16×32in | Unframed | 140.00 | On
| 16×32in | Black Frame | 400.00 | On
| 20×40in | Unframed | 198.00 | On
Minimum required per listing
| Applies to | Required fields |
|---|---|
| ALL | Title, Description, Category, Who made it?, When was it made?, Product type, Price, Quantity, and at least one Photo URL |
| Physical | Also a Shipping profile, a Return policy, and a Processing profile. Add a Processing profile column (matched by its days label, e.g. 5-7 days) — or pick defaults in the importer that apply to any row that leaves them blank. |
| Digital | Also at least one digital file (digital import is lower priority and may be flagged). |
Character & count limits
| Field | Limit |
|---|---|
| Title | Up to 140 characters |
| Tags | Up to 13 tags, each ≤ 20 characters (comma-separated). Over-long tags are trimmed and flagged. |
| Materials | Up to 13 (comma-separated) |
How names are matched to your shop
| Column | Matched by |
|---|---|
| Category | Etsy's category tree — full path (e.g. Art & Collectibles > Painting > Oil), then the final category name. |
| Shipping profile / Section | Name match against the selected store. Blank or unmatched → the default you pick in the importer. |
| Processing profile | Matched by the processing-days label on your shop (e.g. 5-7 days). Blank or unmatched → the default you pick in the importer. |
| Return policy | Number of days in the label; otherwise the default. |
| Store | Optional column — sends specific rows to a different connected shop (matched by shop name). |
Friendly values we understand
| Field | Accepted values |
|---|---|
| Who made it? | I did, A member of my shop, Another company or person |
| When was it made? | Made To Order, 2020-2026, decade ranges like 1990s, or Before 2007 |
| Product type | Physical or Digital |
Column reference
Headers are matched case-insensitively and tolerate punctuation/spacing differences. The importer accepts Etsy's full bulk-edit export, including: Listing ID, Title, Description, Category, Who made it?, What is it?, When was it made?, Renewal options, Product type, Tags, Materials, Production partners, Section, Price, Quantity, SKU, Variation 1, V1 Option, Variation 2, V2 Option, Var Price, Var Quantity, Var SKU, Var Visibility, Var Photo, Shipping profile, Processing profile, Weight, Length, Width, Height, Return policy, Photo 1…10. An optional Store column and Video 1… columns are also supported.
Tip: grab the Download CSV template above (also available in the importer), fill it in, and upload.
Errors
Failures answer with the HTTP status and one JSON body, always the same shape: a stable code to branch on, a sentence for a human, a hint naming the fix, and a link back to this page.
{
"error": {
"code": "INVALID_API_KEY",
"status": 401,
"message": "Your API key is missing, invalid, or has been revoked.",
"hint": "Generate a new key in the API console at eto.tools/dashboard/api.",
"docs": "https://eto.tools/dev/docs#authentication"
}
}
Some codes add one field: VALIDATION_FAILED carries fields with the per-field problems, UPSTREAM_ERROR carries upstream with Etsy’s own response, and the two rate-limit codes set a Retry-After header.
Every code the API returns
Connect an AI client
The same account is reachable over MCP, the protocol Claude, ChatGPT and Perplexity use to call tools. The MCP server is a thin layer over the endpoints on this page: same key, same account, same limits.
https://mcp.eto.tools/mcp
Claude Code, or any client that sends headers
One command, with your key from the API console:
claude mcp add --transport http eto https://mcp.eto.tools/mcp \
--header "X-Eto-API-Key: eto_your_key"
Claude, ChatGPT and Perplexity apps
Add https://mcp.eto.tools/mcp as a custom connector and sign in with your Eto account — no key to paste. The client runs an OAuth 2.1 flow (dynamic client registration and PKCE) against Eto, you approve it on a consent screen, and it then calls the API with a bearer token. Step-by-step instructions per client are on the MCP setup page.
Where everything is
Every page of Eto, every section of every page, and every feature with the exact path to reach it. Paths read left to right from the page, so Listing Manager > Edit Storewide > Auto Quantity Control means: open Listing Manager, switch to Edit Storewide, and the control is in there. 1104 features across 16 pages.
The account home page: a store header, four tabs, a live order feed, a money statement with a chart, and boards for out-of-stock listings and listing performance.
| Feature | What it does | Where | API |
|---|---|---|---|
| Store switcher | Opens a menu to pick which connected store the whole page reports on. | Dashboard > store nameNeeds connected store | — |
| Switch store | The menu heading over the store list, with the line "Pick a store to load its numbers". | Dashboard > store nameNeeds connected store | — |
| Search stores | Filters the store menu by name as you type. | Dashboard > store name > Search storesNeeds connected store | — |
| Most sales | Sorts the store menu by lifetime sales, highest first. | Dashboard > store name > Most salesNeeds connected store | — |
| Least sales | Sorts the store menu by lifetime sales, lowest first. | Dashboard > store name > Most sales > Least salesNeeds connected store | — |
| A to Z | Sorts the store menu alphabetically by shop name. | Dashboard > store name > Most sales > A to ZNeeds connected store | — |
| Store stats line | Shows the selected store lifetime sales, its active listing count and a link out to the shop on Etsy. | Dashboard > store headerNeeds connected store | — |
| Refresh indicator | A spinner and label in the stats line saying that the store numbers are being re-synced right now. | Dashboard > store headerNeeds connected store | — |
| All stores | Switches the page to a combined view of every connected store instead of one. | Dashboard > All storesNeeds two or more stores | — |
| All stores currency settings | Opens the setup modal for the common currency and the per-store conversion rates. | Dashboard > All stores currency settingsNeeds two or more stores | — |
| Connect a store | The empty state shown when no store is connected, linking to the Stores page. | Dashboard > Connect a store | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Convert all to | Sets the three-letter currency every store is converted into for the combined view. | Dashboard > All stores currency settings > Convert all toNeeds two or more stores | — |
| Auto-fill rates | Fetches a conversion rate for each store currency into the common currency. | Dashboard > All stores currency settings > Auto-fill ratesNeeds two or more stores | — |
| Per-store rate list | Lists every store with its own rate field, and notes that stores without a rate are left out. | Dashboard > All stores currency settingsNeeds two or more stores | — |
| Save & View All Stores | Saves the currency and rates and switches the page into the combined all-stores view. | Dashboard > All stores currency settings > Save & View All StoresNeeds two or more stores | — |
| Cancel | Closes the setup modal without saving the currency or rates. | Dashboard > All stores currency settings > CancelNeeds two or more stores | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Home | The default tab: live updates, the money statement and chart, recent orders and latest listings. | Dashboard > Home | — |
| Issues | The tab that checks every connected store for broken or expired connections. | Dashboard > Issues | — |
| Listings | The tab listing every active listing sitting at zero stock, with a count badge on the tab itself. | Dashboard > Listings | — |
| Performance | The tab showing views, favourites and orders per listing over time from the capture history. | Dashboard > Performance | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| This store only | A toggle that limits the live cards to the store picked in the header. | Dashboard > Home > Live updates > This store only | — |
| Order events | A live-streamed list of order events as they arrive, with a connection dot and a running count. | Dashboard > Home > Order events | — |
| Clear | Removes every event currently listed in the Order events card. | Dashboard > Home > Order events > Clear | — |
| Needs fulfillment | Lists paid orders that have not shipped yet, and says "Every paid order is on its way" when there are none. | Dashboard > Home > Needs fulfillment | — |
| Inactive stores | A toggle that also lists unshipped orders from banned, disconnected or deleted stores. | Dashboard > Home > Needs fulfillment > Inactive stores | — |
| View All | Opens the Orders page filtered to unshipped physical orders. | Dashboard > Home > Needs fulfillment > View All | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Today | Reports the statement, the hero figure and the chart for today only. | Dashboard > Home > Today | — |
| Yesterday | Reports the money block for yesterday. | Dashboard > Home > Yesterday | — |
| Last 7 days | Reports the money block for the last seven days. | Dashboard > Home > Last 7 days | — |
| This Month | Reports the money block for the current calendar month. | Dashboard > Home > This Month | — |
| This Year | Reports the money block for the current calendar year. | Dashboard > Home > This Year | — |
| Custom | Opens a single-month calendar to pick one day or a date range for the money block. | Dashboard > Home > Custom | — |
| Calendar Apply | Applies the day or range picked in the custom calendar. | Dashboard > Home > Custom > Apply | — |
| Calendar Clear | Clears the custom date selection and returns to the preset periods. | Dashboard > Home > Custom > Clear | — |
| Settled | Shows money on the day it actually moved in the Etsy ledger. | Dashboard > Home > Settled | — |
| Outcome | Groups every order by its sale day and pulls later fees and refunds back onto that day. | Dashboard > Home > Outcome | — |
| Settled and Outcome help | A hover card that explains the difference between the Settled and Outcome lenses. | Dashboard > Home > Settled | — |
| Orders | Plots order counts on the dashboard chart. | Dashboard > Home > Orders | — |
| Sales | Plots sales money on the dashboard chart. | Dashboard > Home > Sales | — |
| COGS | Plots cost of goods on the dashboard chart. | Dashboard > Home > COGS | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Statement | The money block subtitled "Money in, fees out", running from gross sales down to net profit. | Dashboard > Home > Statement | — |
| Gross sales | The total money customers paid in the chosen period. | Dashboard > Home > Statement | — |
| Refunds | The money refunded to customers in the chosen period. | Dashboard > Home > Statement | — |
| Fees | The Etsy fees charged in the chosen period. | Dashboard > Home > Statement | — |
| Ads | The advertising spend in the chosen period. | Dashboard > Home > Statement | — |
| Software | The software costs subtracted in the chosen period. | Dashboard > Home > Statement | — |
| Gross profit | Gross sales minus refunds, fees, ads and software. | Dashboard > Home > Statement | — |
| COGS row | The cost of goods subtracted from gross profit. | Dashboard > Home > Statement | — |
| Net profit | The bottom line after cost of goods is taken off gross profit. | Dashboard > Home > Statement | — |
| Statement footer | A quiet line with the sale count, the average order value, net sales and the amount paid out. | Dashboard > Home > Statement | — |
| Open Finance page | Leaves the dashboard for the full finance breakdown. | Dashboard > Home > Statement > Open Finance page | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Net profit hero | The large net profit figure for the chosen window, with the change against the previous one. | Dashboard > Home | — |
| Verification line | A small line under the hero saying whether the figures were checked against Etsy, and which stores need reconnecting. | Dashboard > Home | — |
| Orders chart | The main dashboard chart drawing the chosen measure across the chosen period. | Dashboard > Home | — |
| Connect a store overlay | Covers the money block until at least one store is connected, with a link to the Stores page. | Dashboard > Home | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Recent orders | The last orders across every store, each row opening that order on the Orders page. | Dashboard > Home > Recent orders | — |
| All orders | Opens the Orders page from the Recent orders card. | Dashboard > Home > Recent orders > All orders | — |
| Latest listings | The most recently synced listings with price, views, favourites and state. | Dashboard > Home > Latest listings | — |
| Listing manager | Opens the Listing Manager from the Latest listings card. | Dashboard > Home > Latest listings > Listing manager | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Connection check | Walks every connected store one at a time and reports whether its Etsy connection still works. | Dashboard > Issues > Connection checkNeeds connected store | — |
| Check | Starts the connection check and turns into Stop while it runs. | Dashboard > Issues > CheckNeeds connected store | — |
| Check progress bar | A bar and an "n / total" counter showing how far through the stores the check is. | Dashboard > Issues > CheckNeeds connected store | — |
| Needs attention | Lists the stores that failed the check with the reason and a link to reconnect them. | Dashboard > Issues > Needs attentionNeeds connected store | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Out of stock | A per-store board of every active listing sitting at zero stock, with an estimate of the money the empty shelf has cost. | Dashboard > ListingsNeeds connected store | — |
| Search a listing title | Filters the out-of-stock board to listings whose title matches. | Dashboard > Listings > Search a listing titleNeeds connected store | — |
| 90 days | Prices each out-of-stock listing by what it earned in the last ninety days. | Dashboard > Listings > 90 daysNeeds connected store | — |
| Lifetime | Prices each out-of-stock listing by what it has earned for all time. | Dashboard > Listings > LifetimeNeeds connected store | — |
| Sort the stores | Orders the store groups by out of stock count, revenue, lifetime sales, listing count, store age or name. | Dashboard > Listings > Sort the storesNeeds two or more stores | — |
| Flip the sort order | Reverses the store ordering between highest first and lowest first. | Dashboard > Listings > Flip the sort orderNeeds two or more stores | — |
| Show more | Appends the next page of out-of-stock rows inside one store group without reloading the board. | Dashboard > Listings > Show moreNeeds connected store | — |
| Restock | Opens that listing in the editor with the quantity field already in view. | Dashboard > Listings > RestockNeeds connected store | — |
| Etsy link | Opens the out-of-stock listing on Etsy in a new tab. | Dashboard > Listings > EtsyNeeds connected store | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Listing performance | Views, favourites, listing counts and orders read off the six-hourly capture history. | Dashboard > PerformanceNeeds connected store | — |
| 24 hours | Reports listing performance over the last day. | Dashboard > Performance > 24 hoursNeeds connected store | — |
| 7 days | Reports listing performance over the last week. | Dashboard > Performance > 7 daysNeeds connected store | — |
| 30 days | Reports listing performance over the last month. | Dashboard > Performance > 30 daysNeeds connected store | — |
| Capture now | Records every listing on every store immediately, at most once every six hours. | Dashboard > Performance > Capture nowNeeds connected store | — |
| Figure strip | Five counters across the top: Views, Favourites, Listings, Sold out and Orders. | Dashboard > PerformanceNeeds connected store | — |
| Capture status line | A mono line saying what the running capture is doing, or when the last one ran and what it cost. | Dashboard > PerformanceNeeds connected store | — |
| Views and favourites over time | A chart of the capture series, hidden until there are at least two captures. | Dashboard > PerformanceNeeds connected store | — |
| Movement | Plots views gained, favourites gained and orders per capture. | Dashboard > Performance > MovementNeeds connected store | — |
| Totals | Plots the running total of views and favourites instead of the movement between captures. | Dashboard > Performance > TotalsNeeds connected store | — |
| Chart legend | Clickable series names that switch each line on the performance chart on or off. | Dashboard > PerformanceNeeds connected store | — |
| Per-store table | One row per store with active, sold out, views, favourites, orders, a views sparkline and the last capture time. | Dashboard > PerformanceNeeds connected store | — |
A ten-tab reporting page over orders, money, stores, listings and operations, with a KPI strip, a live event stream and an orders map.
| Feature | What it does | Where | API |
|---|---|---|---|
| Store switcher | Picks one connected store or All stores for every panel on the page. | Analytics > All stores | — |
| Search stores | Filters the store switcher list by shop name, with a match count beside it. | Analytics > All stores > Search stores | — |
| Today | Reports every panel over today only. | Analytics > Today | — |
| 7d | Reports every panel over the last seven days. | Analytics > 7d | — |
| 30d | Reports every panel over the last thirty days, the page default. | Analytics > 30d | — |
| 90d | Reports every panel over the last ninety days. | Analytics > 90d | — |
| YTD | Reports every panel from the start of the year to today. | Analytics > YTD | — |
| Custom | Reveals a start date, an end date and an Apply button for an arbitrary window. | Analytics > Custom | — |
| Compare against | Chooses what every KPI delta is measured against: the previous period, the same period last year, or nothing. | Analytics > vs previous period | — |
| Live indicator | Shows whether the page is connected to the live event stream, reconnecting, or paused. | Analytics > Live | — |
| Refresh | Throws away the cached answers and re-fetches every panel for the current store and period. | Analytics > Refresh | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Orders | The order count for the period, with its change against the comparison window. | Analytics > KPI strip | — |
| Revenue | Gross money taken in the period. | Analytics > KPI strip | — |
| Net profit | Revenue less fees, ads, refunds and cost of goods. | Analytics > KPI strip | — |
| COGS | The cost of goods for the orders in the period. | Analytics > KPI strip | — |
| Etsy fees | Every Etsy fee charged in the period. | Analytics > KPI strip | — |
| Ads | Advertising spend in the period. | Analytics > KPI strip | — |
| Average order | Revenue divided by the number of orders. | Analytics > KPI strip | — |
| Refund rate | The share of orders that were refunded, coloured so a rise reads as bad. | Analytics > KPI strip | — |
| Active listings | How many listings are active right now across the stores in view. | Analytics > KPI strip | — |
| Comparison caption | The single line under the strip naming the baseline window every delta is measured against. | Analytics > KPI strip | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Orders and money | The headline chart plotting orders, revenue and gross profit across the period. | Analytics > Overview > Orders and money | — |
| Both / Orders / Money | Switches the headline chart between both axes, order counts only, or money only. | Analytics > Overview > Orders and money > Both | — |
| This period | Total revenue and order count for the window, plus average order, days with ledger data, stores in view and order cost coverage. | Analytics > Overview > This period | — |
| Where the money goes | A ranked bar list of revenue, net profit, COGS, fees and ads. | Analytics > Overview > Where the money goes | — |
| Rates | Refund rate, fees, ads and COGS as shares of revenue, and the active listing count. | Analytics > Overview > Rates | — |
| Live updates | The event feed, prepending new orders and order events as the stream delivers them. | Analytics > Overview > Live updates | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Order volume | Orders, shipped orders and revenue across the period. | Analytics > Orders > Order volume | — |
| Count / Money | Switches the volume chart between order counts and revenue. | Analytics > Orders > Order volume > Count | — |
| Top products | The best selling products drawn as a ranked chart, with its own order-by menu. | Analytics > Orders > Top products | — |
| Needs fulfilment | How many paid orders are waiting to ship, with the oldest of them listed and linked. | Analytics > Orders > Needs fulfilment | — |
| By status | Order counts split by Paid, Completed, Open, Processing, Cancelled and Unknown. | Analytics > Orders > By status | — |
| By country | Order counts split by buyer country. | Analytics > Orders > By country | — |
| By store | Order counts split by shop. | Analytics > Orders > By store | — |
| Fulfilment | Average time to ship, lines shipped, orders shipped, shipped share and gift orders. | Analytics > Orders > Fulfilment | — |
| Money per order | Revenue, Etsy fees, COGS, net profit and refunded orders for the window. | Analytics > Orders > Money per order | — |
| Top products, in figures | The same products as a table of product, listing id, units and order lines. | Analytics > Orders > Top products, in figures | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Size by | Chooses whether places on the map are sized by Orders, Order value, Items or Average order. | Analytics > Map > Size byNeeds placed orders | — |
| Dots | Draws each place as a clustered dot. | Analytics > Map > DotsNeeds placed orders | — |
| Heat | Draws the orders as a heat surface instead of dots. | Analytics > Map > HeatNeeds placed orders | — |
| Countries | Fills whole countries by their share instead of plotting places. | Analytics > Map > CountriesNeeds placed orders | — |
| Flat | Draws the map as a flat projection. | Analytics > Map > FlatNeeds placed orders | — |
| 3D | Draws the map as a globe, with a starfield behind it. | Analytics > Map > 3DNeeds placed orders | — |
| Find a place | Searches the places currently on the map and flies to the one you pick. | Analytics > Map > Find a placeNeeds placed orders | — |
| Reload the map | Re-fetches the map points, spinning while anything is in flight. | Analytics > Map > Reload the mapNeeds placed orders | — |
| Fit the map to your orders | Zooms and pans so every placed order is on screen. | Analytics > Map > Fit the map to your ordersNeeds placed orders | — |
| Back to the whole world | Resets the camera to the default world view. | Analytics > Map > Back to the whole worldNeeds placed orders | — |
| Download these places as CSV | Saves the places on screen with orders, items, value, average order, share and coordinates as a CSV file. | Analytics > Map > Download these places as CSVNeeds placed orders | — |
| Show or hide the side panel | Collapses or reopens the details panel beside the map. | Analytics > Map > Show or hide the side panelNeeds placed orders | — |
| Fill the window | Expands the map to fill the browser window. | Analytics > Map > Fill the windowNeeds placed orders | — |
| Zoom in | Steps the map camera one level closer. | Analytics > Map > Zoom inNeeds placed orders | — |
| Zoom out | Steps the map camera one level back. | Analytics > Map > Zoom outNeeds placed orders | — |
| Place names | Turns the place-name labels on the map on or off. | Analytics > Map > Place namesNeeds placed orders | — |
| Resize the panel | A drag handle, also movable with the arrow keys, that sets how wide the side panel is. | Analytics > Map > Resize the panelNeeds placed orders | — |
| Place my orders on the map | Works out where past orders came from, offline from the addresses already stored, so the map has something to draw. | Analytics > Map > Place my orders on the mapNeeds account owner | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Overview | The panel tab counting the places reached, with the Reach, Top countries and Top places sections. | Analytics > Map > OverviewNeeds placed orders | — |
| Reach | Countries, new places this period, orders, items, order value, average order and how many orders were placed to a town. | Analytics > Map > Overview > ReachNeeds placed orders | — |
| Top countries | The countries with the most orders, each with how many distinct places it covers. | Analytics > Map > Overview > Top countriesNeeds placed orders | — |
| Top places | The individual towns and districts with the most orders. | Analytics > Map > Overview > Top placesNeeds placed orders | — |
| Place | The panel tab showing one place picked on the map in full. | Analytics > Map > PlaceNeeds placed orders | — |
| This period | Order value, average order, growth against the previous period, buyers, repeat buyers, first and last order, and how precisely the place was located. | Analytics > Map > Place > This periodNeeds placed orders | — |
| What it buys | The products that place buys, with each product share and its lift against the whole account. | Analytics > Map > Place > What it buysNeeds placed orders | — |
| Stores selling here | Which of your shops have sold into that place, and how many orders each. | Analytics > Map > Place > Stores selling hereNeeds placed orders | — |
| Insights | The panel tab ranking places into five lists with a Show button that flies the map to each. | Analytics > Map > InsightsNeeds placed orders | — |
| Biggest markets | The places bringing in the most money. | Analytics > Map > Insights > Biggest marketsNeeds placed orders | — |
| Growing fastest | The places whose order count rose most against the period before. | Analytics > Map > Insights > Growing fastestNeeds placed orders | — |
| Biggest baskets | The places with the highest average order value. | Analytics > Map > Insights > Biggest basketsNeeds placed orders | — |
| Barely served | Places that spend well but that only one of your stores, or none, reaches. | Analytics > Map > Insights > Barely servedNeeds placed orders | — |
| Gone quiet | Places that ordered last period and nothing this one. | Analytics > Map > Insights > Gone quietNeeds placed orders | — |
| What each country buys | A per-country product table added under the rankings, with each product lift for that country. | Analytics > Map > InsightsNeeds placed orders | — |
| Live | The panel tab counting orders in the last minute and listing each new one as it lands and pulses on the map. | Analytics > Map > LiveNeeds placed orders | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Revenue, profit and cost | The headline money chart plotting revenue, gross profit, COGS and net profit, with fees, ads and refunds available behind the legend. | Analytics > Finance > Revenue, profit and cost | — |
| Lines / Costs | Switches the money chart between the profit lines and the cost lines. | Analytics > Finance > Revenue, profit and cost > Lines | — |
| Money per store | Every store ranked as a chart, ordered by revenue, gross profit, fees, ads, sales or name. | Analytics > Finance > Money per store | — |
| Totals | Net profit as a hero figure over revenue, gross profit, COGS, Etsy fees, ads, refunds, cancelled and paid out to bank. | Analytics > Finance > Totals | — |
| Fees breakdown | Each kind of Etsy fee as its own bar. | Analytics > Finance > Fees breakdown | — |
| Ads breakdown | Each kind of advertising charge as its own bar. | Analytics > Finance > Ads breakdown | — |
| Taxes and other | Every remaining ledger movement that is not a fee or an ad. | Analytics > Finance > Taxes and other | — |
| Per store | A sortable, paged table of store, sales, revenue, fees, ads, refunds and gross profit. | Analytics > Finance > Per store | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Store comparison | Plots every store on two axes you choose, or reads the same stores as a ranked league table. | Analytics > Stores > Store comparison | — |
| X axis picker | Chooses which measure the comparison plot uses for its horizontal axis. | Analytics > Stores > Store comparison > X | — |
| Y axis picker | Chooses which measure the comparison plot uses for its vertical axis. | Analytics > Stores > Store comparison > Y | — |
| Top 10 / 25 / 50 / All stores | Limits the comparison plot to the leading stores by the Y measure, or shows every store. | Analytics > Stores > Store comparison > Top 25 | — |
| Revenue leaders | A fixed-height ranked list of shops by revenue for the period. | Analytics > Stores > Revenue leaders | — |
| Flags | The stores that need reconnecting, are on vacation, or are hidden from a page, each with a chip saying which. | Analytics > Stores > Flags | — |
| Store age against sales | Plots how old each store is against its lifetime sales. | Analytics > Stores > Store age against sales | — |
| Every store | A sortable, paged table of store, products, active, stock, views, favourites, orders, revenue, profit, lifetime sales and age. | Analytics > Stores > Every store | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Revenue per listing | Every listing ranked by what it earned, windowed so thousands of bars stay readable. | Analytics > Listings > Revenue per listing | — |
| Find a listing | Jumps the revenue ranking to the listing whose title or id matches. | Analytics > Listings > Revenue per listing > Find a listing | — |
| Revenue / Profit / Units / Orders | Chooses which measure the revenue-per-listing bars are drawn from. | Analytics > Listings > Revenue per listing > Revenue | — |
| Show 50 / 100 / 200 / 400 | Sets how many listings are on screen in one window of the ranking. | Analytics > Listings > Revenue per listing > Show 50 | — |
| Currency picker | Appears only when the stores in view price in more than one currency, and picks which one the ranking is drawn in. | Analytics > Listings > Revenue per listingNeeds two or more currencies | — |
| Ranking brush | A slider under the chart, also movable with the arrow keys, that scrolls the window along the full ranking. | Analytics > Listings > Revenue per listing | — |
| Zero-revenue band | The band at the end of the axis that opens a paged drawer of every listing that earned nothing in the period. | Analytics > Listings > Revenue per listing | — |
| Listings created | Plots listings created in each bucket against how many are now active and how many are still drafts. | Analytics > Listings > Listings created | — |
| Price spread | A histogram of what active listings are priced at. | Analytics > Listings > Price spread | — |
| Catalogue | Active listings as a hero figure over draft, inactive, expired, sold out, gone from Etsy, digital, with variations and units in stock. | Analytics > Listings > Catalogue | — |
| Low stock | Active listings nearly out of stock, each linked to its editor. | Analytics > Listings > Low stock | — |
| Engagement | Total views and favourites, favourites per hundred views, views per active listing and the number of listings tracked. | Analytics > Listings > Engagement | — |
| Most viewed | The listings with the most views, with their store, views and favourites. | Analytics > Listings > Most viewed | — |
| Least viewed | The listings with the fewest views, with their store, price and views. | Analytics > Listings > Least viewed | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Performance over time | The capture series for views, favourites and orders across the chosen window. | Analytics > Listing stats > Performance over time | — |
| Store picker | Narrows the performance chart to one store that has been captured, or all of them. | Analytics > Listing stats > Performance over time > All stores | — |
| Movement / Lifetime totals / Stock and orders | Switches the performance chart between movement per capture, running totals, and stock against orders. | Analytics > Listing stats > Performance over time > Movement | — |
| What to do | Read-off suggestions from the movement, each row opening the listing it refers to. | Analytics > Listing stats > What to do | — |
| Biggest movers | The listings that gained and lost the most views in the window. | Analytics > Listing stats > Biggest movers | — |
| Most favourited | The listings that gained and lost the most favourites in the window. | Analytics > Listing stats > Most favourited | — |
| Gone quiet | Active listings nobody has looked at in a month. | Analytics > Listing stats > Gone quiet | — |
| Sold out, still wanted | Listings with no stock left whose favourites are still rising. | Analytics > Listing stats > Sold out, still wanted | — |
| One listing over time | The history of a single listing with views, favourites, stock and the orders that landed against it. | Analytics > Listing stats > Every listing > a row | — |
| Every listing | A sortable, paged table of listing, store, state, views gained, favourites gained, orders, conversion, stock change, views and favourites. | Analytics > Listing stats > Every listing | — |
| Search a title or id | Filters the Every listing table to matching listings. | Analytics > Listing stats > Every listing > Search a title or id | — |
| Capture log | Every capture sweep with its six-hour window, what started it, orders in the window, stores, listings, Etsy calls, duration and result. | Analytics > Listing stats > Capture log | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Tracking submitted | Tracking entries suppliers have submitted through a share link, across the period. | Analytics > Suppliers > Tracking submitted | — |
| Supplier fulfilment | Orders marked done by suppliers, over orders shared, still open, with supplier tracking, active share links and link views. | Analytics > Suppliers > Supplier fulfilment | — |
| Tracking states | Tracking entries, how many name a carrier, how many have last-mile tracking, and how many of the period orders reached Etsy. | Analytics > Suppliers > Tracking states | — |
| Assignments | How many stores and products are assigned to a supplier, and the total share link count. | Analytics > Suppliers > Assignments | — |
| Open work by link | Each share link ranked by how many orders on it are still open. | Analytics > Suppliers > Open work by link | — |
| Share links | A table of every supplier link with its token, state, shared, done, open, views and last opened time. | Analytics > Suppliers > Share links | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Assistant activity | Assistant actions across the period, covering logins, order actions and uploads. | Analytics > VAs > Assistant activityNeeds account owner | — |
| Team | How many assistants are active, and how many stores each of the first eight can reach. | Analytics > VAs > TeamNeeds account owner | — |
| Actions per assistant | Action counts ranked by assistant. | Analytics > VAs > Actions per assistantNeeds account owner | — |
| What they did | Action counts ranked by the kind of action. | Analytics > VAs > What they didNeeds account owner | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| API calls | Eto API and Etsy API traffic across the period, with error series behind the legend. | Analytics > API > API callsNeeds account owner | — |
| All / Errors | Switches the traffic chart between all calls and errors only. | Analytics > API > API calls > AllNeeds account owner | — |
| Today's quota | Eto API calls left today over calls used, the daily limit, and the key prefix, state and last use. | Analytics > API > Today's quotaNeeds account owner | — |
| Eto API | Calls, errors, error rate and average response time for the Eto API in the period. | Analytics > API > Eto APINeeds account owner | — |
| Etsy API | Calls, errors, error rate and average response time for Etsy in the period. | Analytics > API > Etsy APINeeds account owner | — |
| Research tools used | Counts of product hunt searches, bulk research runs, keyword searches, quick product and keyword lookups and shop spy searches. | Analytics > API > Research tools usedNeeds account owner | — |
| Busiest Eto endpoints | A table of the Eto API endpoints with the most calls, their errors and their average response time. | Analytics > API > Busiest Eto endpointsNeeds account owner | — |
| Etsy calls by feature | A table of which Eto feature made the Etsy calls, with counts and errors. | Analytics > API > Etsy calls by featureNeeds account owner | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Line / Bar / Scatter | A per-chart switch that redraws that plot as a line, bars or a scatter, remembered for next visit. | Analytics > any chart panel | — |
| Order by | On a ranked chart, chooses which measure the ranking runs on, remembered per panel. | Analytics > any ranked chart > Order | — |
| Order direction | Flips a ranking between high to low, oldest first or A to Z depending on the measure. | Analytics > any ranked chart | — |
| Chart legend | Clickable series names that switch a line on the chart above them on or off. | Analytics > any chart panel | — |
| Column sorting | Clicking a table heading re-asks the server for that column, ordered high to low, then low to high, then cleared. | Analytics > any table panel | — |
| Table pager | Previous and next buttons that swap only the table panel, leaving the charts and the scroll position alone. | Analytics > any table panel | — |
One list of every Etsy order across your connected stores, with costs, tracking, notes and supplier sharing.
| Feature | What it does | Where | API |
|---|---|---|---|
| Store filter | Narrows the whole list to one store, and only appears once you have two or more connected. | Orders > All StoresNeeds connected store | — |
| Search anything | Searches orders by buyer name, email, phone, city, state, country, status, buyer message, gift message, shop name, product title or exact receipt number. | Orders > Search anything...Needs connected store | orders_list |
| Clear search | Empties the search box and reloads the unsearched list. | Orders > Search anything... > x | — |
| Share | Opens the dialog that turns your current filters into a supplier link or a CSV. | Orders > ShareNeeds connected store | — |
| Manage links | Opens the list of supplier links you have already created. | Orders > (link icon beside Share) | — |
| Sync Orders | Opens a date-range popover and then fetches fresh orders from Etsy for that window. | Orders > Sync OrdersNeeds connected store | orders_sync |
| Sync date presets | Syncs the last 7, 30, 90, 180 or 365 days from Etsy in one click. | Orders > Sync Orders > Last 30 daysNeeds connected store | orders_sync |
| Sync range calendar | Picks an exact start and end date to sync instead of a preset. | Orders > Sync Orders > (calendar) > Sync rangeNeeds connected store | orders_sync |
| No COGS | Toggles the list down to only the orders that have no cost of goods set. | Orders > No COGS | — |
| Sync Printify | Matches your orders to Printify orders and pulls their costs and tracking. | Orders > Sync PrintifyNeeds Printify connected | — |
| Import COGs | Opens the spreadsheet importer for bulk cost of goods entry. | Orders > Import COGs | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Date Range | Limits the list to orders from the last 7, 30 or 60 days. | Orders > Date Range | — |
| Custom dates | Opens a calendar to pick an exact from and to date for the list. | Orders > Custom dates | — |
| Fulfilled | Shows only fulfilled or only unfulfilled orders. | Orders > Fulfilled | — |
| Shipped | Shows only physical orders that have shipped, or only those that have not. | Orders > Shipped | — |
| Paid | Shows only paid or only unpaid orders. | Orders > Paid | — |
| Location | Splits the list into US only or non-US orders. | Orders > Location | — |
| Message | Shows only orders that carry a buyer message, or only those that do not. | Orders > Message | — |
| Gift | Shows only orders the buyer marked as a gift, or only those they did not. | Orders > Gift | — |
| Type | Splits the list into physical, digital or multi-item orders. | Orders > Type | — |
| Urgency | Filters by time left to ship: overdue, 1 day left, 2 days left or 2+ days. | Orders > Urgency | — |
| Tracking | Filters by supplier tracking state: no tracking, awaiting tracking, tracking ready or fulfilled. | Orders > Tracking | — |
| Status | Filters by order state, including cancelled only, refunded only, payment processing only, and the matching hide options. | Orders > Status | — |
| Recently Refunded | Shows refunded orders ordered by when the refund was issued rather than when the order was placed. | Orders > Status > Recently Refunded | — |
| Fulfilled via | Shows only the orders fulfilled through Printify. | Orders > Fulfilled via > Printify | — |
| Clear | Drops every active filter at once and reloads the full list. | Orders > Clear | — |
| Filter deep links | The page reads shipped, paid, us, message, gift, digital, shipped_physical, days_remaining, supplier_status, order_status_filter, fulfilled_via, date_from, date_to, days, shop_id and search or q from the URL so a filtered view can be linked to. | Orders > (URL query string) | orders_list |
| Order drawer deep link | A drawer query parameter opens that order detail drawer as soon as the page paints. | Orders > (URL query string) | order_detail |
| Feature | What it does | Where | API |
|---|---|---|---|
| Status count pills | Counts orders that are paid and not refunded or cancelled, paid and not refunded, paid and not cancelled, just paid, unpaid, and cancelled or refunded. | Orders > (pill row under the filters) | — |
| Top summary bar | Shows the total order count, page count and the date span of the orders on screen. | Orders > (bar above the list) | — |
| Top page arrows | Steps to the previous or next page from the bar above the list. | Orders > (bar above the list) > arrows | — |
| Pagination | Steps through pages from the bottom of the list and shows which range of orders is on screen. | Orders > Previous / Next | orders_list |
| Reconcile bar | Reports the background check against Etsy for recent order changes, and can be stopped. | Orders > Checking recent changes with Etsy...Needs connected store | — |
| No orders found | The empty state shown when the current filters match nothing. | Orders > (empty list) | — |
| No Store Connected | The empty state with a Connect Store button, shown when you have no Etsy store attached. | Orders > Connect Store | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Profit flow chips | Shows Subtotal, Fees, Gross Profit, COG, Net Profit and, when refunded, Refunded and Final Net on the row itself. | Orders > (order row) > profit chips | — |
| Profit chip popover | Clicking a chip opens the line-by-line breakdown behind that number. | Orders > (order row) > Fees | — |
| COG inline input | Types the cost of goods for the item straight into the row without opening the order. | Orders > (order row) > COG | — |
| SKU inline edit | Edits and saves the SKU for the item from the row, with the full Eto SKU shown when Etsy truncates it. | Orders > (order row) > SKU | — |
| Supplier picker | Assigns a supplier to the listing from the row, for the store or for that product. | Orders > (order row) > Supplier | — |
| Copy tracking | Copies the row tracking number to the clipboard. | Orders > (order row) > (copy icon) | — |
| Tracking status help | Opens the legend explaining No Tracking, Awaiting Tracking, Tracking Ready and Fulfilled. | Orders > (order row) > ? | — |
| Row indicators | Marks orders that carry a buyer Message, are a Gift, or include Custom personalisation. | Orders > (order row) > Message | — |
| Ship by countdown | Shows days, hours and minutes left to ship, or how long the order is overdue. | Orders > (order row) > Ship by | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Overview tab | Lists receipt id, type, order date, store, buyer, payment method, paid and shipped flags, gift flag and the full money breakdown down to refunds and adjusted total. | Orders > (order row) > Overview | order_detail |
| Edit buyer field | Edits a buyer detail such as name or address line in place from the Overview tab. | Orders > (order row) > Overview > (pencil icon) | — |
| Items tab | Lists each item with variations, quantity, SKU, price and shipping. | Orders > (order row) > Items | order_transactions |
| Total Cost | Records one cost of goods figure for an item, including its shipping and fees. | Orders > (order row) > Items > Total Cost | — |
| Enter per-unit costs | Switches a multi-quantity item to one cost box per unit and totals them for you. | Orders > (order row) > Items > Enter per-unit costs | — |
| Use single total | Collapses per-unit costs back to a single total for the item. | Orders > (order row) > Items > Use single total | — |
| Tracking tab | Shows the tracking state, Printify tracking, supplier tracking entries grouped by the link they came from, and Etsy shipments. | Orders > (order row) > Tracking | — |
| Submit to Etsy | Sends a supplier tracking entry to Etsy as the shipment for this order, with an optional buyer message and a self-notification toggle. | Orders > (order row) > Tracking > Submit to EtsyNeeds connected store | shop_order_tracking |
| Manual Submit | Types your own tracking number and carrier and submits it to Etsy. | Orders > (order row) > Tracking > Submit your own tracking to EtsyNeeds connected store | shop_order_tracking |
| Delete tracking entry | Removes a supplier tracking entry and its history from the order. | Orders > (order row) > Tracking > (x on an entry) | — |
| Shipping tab | Shows the shipping address, email, phone and SKU as copyable rows, plus supplier tracking and Etsy shipments. | Orders > (order row) > Shipping | — |
| Copy All | Copies the whole shipping address as one block. | Orders > (order row) > Shipping > Copy All | — |
| Printify / Gelato Format | Copies a US address already laid out the way Printify and Gelato expect it. | Orders > (order row) > Shipping > Copy AddressNeeds US order | — |
| Payment tab | Shows the price breakdown, payment info and every refund on the order. | Orders > (order row) > Payment | order_payments |
| Messages tab | Shows the gift information and the buyer message and personalisation text. | Orders > (order row) > Messages | — |
| Product tab | Shows the live listing behind the item: images, videos, title, description, details, personalisation, variations, tags and materials. | Orders > (order row) > ProductNeeds connected store | listing_detail |
| Product Source Link | Saves the supplier or AliExpress URL you buy this product from. | Orders > (order row) > Product > Product Source Link | — |
| Notes tab | Keeps a free-text note against the order and saves it as you type. | Orders > (order row) > Notes | — |
| Printify tab | Connects the Etsy order to a Printify order, or shows and disconnects the one already linked. | Orders > (order row) > PrintifyNeeds Printify connected | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Share with Supplier | Creates a public link that shows a supplier only the orders matching your current filters. | Orders > Share > Create LinkNeeds connected store | — |
| Link Name | Names the supplier link so you can tell it apart later. | Orders > Share > Link Name | — |
| Expires | Sets the supplier link to expire after 24h, 7d, 30d, or never. | Orders > Share > Expires | — |
| Download CSV | Exports the currently filtered orders as a CSV file. | Orders > Share > Download CSV | — |
| CSV Columns | Chooses which columns the CSV includes, with select all and deselect all. | Orders > Share > (gear icon) | — |
| Manage Links | Lists your active supplier links and the ones in the trash. | Orders > (link icon) > Active | — |
| Link trash | Holds deleted supplier links so they can be restored or removed permanently. | Orders > (link icon) > Trash | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Upload File | Takes a CSV or Excel sheet of product costs as the first import step. | Orders > Import COGs | — |
| Currency | Says which currency the sheet is in and sets the rate to your store currency. | Orders > Import COGs > Currency | — |
| Select Store | Picks which store the imported costs belong to. | Orders > Import COGs > Select StoreNeeds connected store | — |
| Preview Matches | Shows which sheet rows matched which orders before anything is written. | Orders > Import COGs > Preview Matches | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Supplier order list | The page your supplier opens from a share link, showing only the orders you shared and no seller data. | Orders > Share > Create Link > (open the link)Needs share link | — |
| Supplier search | Searches the shared orders by order number, name, SKU, product or tracking. | Orders > Share > Create Link > (open the link) > SearchNeeds share link | — |
| Supplier status tabs | Switches between pending, overdue, done and all shared orders. | Orders > Share > Create Link > (open the link) > pendingNeeds share link | — |
| Supplier filters | Narrows the shared list by country and by product. | Orders > Share > Create Link > (open the link) > (country select)Needs share link | — |
| Supplier sort | Orders the shared list by ship date, order value, order date, quantity or buyer name, in either direction. | Orders > Share > Create Link > (open the link) > Ship dateNeeds share link | — |
| Group by product | Groups the shared orders under the product they are for. | Orders > Share > Create Link > (open the link) > Group by productNeeds share link | — |
| Paste tracking | Bulk-fills tracking numbers by pasting one order number and tracking number per line. | Orders > Share > Create Link > (open the link) > Paste trackingNeeds share link | — |
| Supplier export CSV | Downloads the shared order list as a CSV. | Orders > Share > Create Link > (open the link) > Export CSVNeeds share link | — |
| Supplier bulk actions | With rows selected, marks them done or not done, copies their addresses, or exports just those rows. | Orders > Share > Create Link > (open the link) > Mark doneNeeds share link | — |
| Supplier save bar | Holds unsaved tracking edits and writes them back with Save or drops them with Discard. | Orders > Share > Create Link > (open the link) > SaveNeeds share link | — |
| Supplier keyboard shortcuts | Cmd or Ctrl plus S saves pending edits, the slash key jumps to search, and Escape closes the paste dialog. | Orders > Share > Create Link > (open the link)Needs share link | — |
| Supplier display controls | Switches to compact rows, changes the text size, flips the theme, or switches the page between English and Chinese. | Orders > Share > Create Link > (open the link) > A+Needs share link | — |
Your Etsy money by day or date range: balance, payouts, sales, fees, ads, refunds, COGS and profit, with the ledger behind every figure.
| Feature | What it does | Where | API |
|---|---|---|---|
| Fetch Financial Data | Backfills a store ledger from Etsy so Finance has something to report on. | Finance > Fetch Financial DataNeeds connected store | finance_sync |
| Backfill window | Chooses how far back the first fetch goes: 30, 60, 90 or 120 days. | Finance > 120 daysNeeds connected store | — |
| Set up later | Skips setup for the stores still pending so the overlay stops blocking the page. | Finance > Set up later | — |
| Don't track | Turns a store off for Finance, the same flag the Stores page toggle sets. | Finance > Don’t track | — |
| Retry | Retries the backfill for a store whose first fetch failed. | Finance > RetryNeeds connected store | finance_sync |
| Setup notice | A strip naming the stores that are not tracked in Finance yet, with Set up and Dismiss. | Finance > Set up | — |
| Set up skipped stores | Brings back the setup prompt for stores you dismissed earlier. | Finance > (gear icon) > Set up N skipped stores | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Store selector | Picks which store the page reports on, or All Stores to combine them. | Finance > (store name)Needs connected store | — |
| All Stores | Combines every unlocked store into one set of figures, converted into your target currency. | Finance > (store name) > All StoresNeeds two or more stores | — |
| Date button | Opens the calendar for picking a single day or a date range to report on. | Finance > (date label) | — |
| Calendar picker | Tap one day for a day view or two days for a range, then Apply, or Clear to reset. | Finance > (date label) > Apply | — |
| Export | Exports every ledger row in the selected window as a file. | Finance > Export | — |
| Export CSV | Downloads the window in Etsy statement layout: date, type, title, info, currency, amount, fees and taxes, net and tax details. | Finance > Export > CSV | finance |
| Export Excel workbook | Downloads an .xlsx with real number columns and one sheet per store. | Finance > Export > Excel workbook | finance |
| Copy JSON | Copies the figures currently on screen to the clipboard as JSON. | Finance > (copy icon) | finance |
| Feature | What it does | Where | API |
|---|---|---|---|
| Settled | Counts money on the day it actually moved. | Finance > Settled | — |
| Outcome | Counts what each day of sales eventually turned out to be worth after refunds and cancellations. | Finance > Outcome | — |
| Verification strip | Reports whether the window on screen has been checked against Etsy, and repairs missing entries when it finds them. | Finance > (strip above the figures)Needs connected store | — |
| Try again | Re-runs verification for stores that could not be checked. | Finance > (verification strip) > Try again | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Refresh Today | Re-fetches today from Etsy for the selected store and repaints the day. | Finance > (gear icon) > TodayNeeds connected store | finance_sync |
| Refresh Previous 7 Days | Re-fetches the last seven days from Etsy. | Finance > (gear icon) > Previous 7 DaysNeeds connected store | finance_sync |
| Refresh Previous 30 Days | Re-fetches the last thirty days from Etsy. | Finance > (gear icon) > Previous 30 DaysNeeds connected store | finance_sync |
| Refresh Range | Opens a day-by-day picker so you can re-fetch only the days you choose. | Finance > (gear icon) > Range...Needs connected store | finance_sync |
| Adjust ad spend timing | Moves ad charges onto the day they were incurred rather than the day Etsy billed them. | Finance > (gear icon) > Adjust ad spend timingNeeds single store selected | — |
| Remove all unpaid sales from data | Drops cancelled orders that were never paid out of every figure on the page. | Finance > (gear icon) > Remove all unpaid sales from data | — |
| Convert currency | Shows every figure in another currency at a rate you set. | Finance > (gear icon) > Convert currency | — |
| Configure rate | Sets the target currency code and the multiplier used for conversion. | Finance > (gear icon) > Configure rate | — |
| Delete all finance data | Wipes every ledger entry, fetch window, profit snapshot and cached day, after you type DELETE. | Finance > (gear icon) > Delete all finance data | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Currency settings | Opens the settings dialog used to combine stores that bill in different currencies. | Finance > (gear icon) > Currency settingsNeeds two or more stores | — |
| Target currency | Sets the single currency that All Stores figures are reported in. | Finance > (gear icon) > Currency settings > Target currency | — |
| Store rates | Sets the exchange rate used for each store currency. | Finance > (gear icon) > Currency settings > Store rates | — |
| Auto-fill rates | Fills in the per-store exchange rates for you. | Finance > (gear icon) > Currency settings > Auto-fill rates | — |
| Manage subscriptions | Records the tools and services you pay for outside Etsy so they count against All Stores profit. | Finance > (gear icon) > Manage subscriptions | finance_software_expenses |
| Add subscription | Adds a recurring or one-time software cost with a name, amount, currency, frequency and start date. | Finance > (gear icon) > Manage subscriptions > Add | finance_software_expenses |
| Feature | What it does | Where | API |
|---|---|---|---|
| Current Balance | Your Etsy payment account balance at the end of the selected day. | Finance > Current BalanceNeeds connected store | finance |
| Paid Out | What Etsy deposited to your bank on the selected day. | Finance > Paid Out | finance |
| Sales | Gross sales taken on the day, and the number of sales behind it. | Finance > Sales | finance |
| Orders not paid | Orders placed on the day that never produced any ledger activity. | Finance > Orders not paid | — |
| Refunds | Money refunded to buyers on the day. | Finance > Refunds | finance |
| Cancelled | Value of orders cancelled on the day. | Finance > Cancelled | finance |
| Recoupment | Money Etsy is recovering from your balance to cover a cancellation or refund. | Finance > Recoupment | finance |
| Credits | Refund credits Etsy returned to you. | Finance > Credits | finance |
| Subscription | Etsy subscription charges falling in the window. | Finance > Subscription | finance |
| Net Profit | Gross profit after cost of goods. | Finance > Net Profit | finance |
| COGS | Total cost of goods for the sales in the window, taken from the costs you entered on Orders. | Finance > COGS | finance |
| Gross Profit | Sales minus Etsy fees and ads, before cost of goods. | Finance > Gross Profit | finance |
| Fees Paid | Every Etsy fee charged in the window. | Finance > Fees Paid | finance |
| Ads Spent | Etsy ads and offsite ads charged in the window. | Finance > Ads Spent | finance |
| Metric breakdown | Opens the line-by-line entries behind any card that carries the breakdown button. | Finance > Net Profit > (breakdown icon) | — |
| Balance chart | Plots the running balance through the day against the selected metrics. | Finance > (chart under the cards) | — |
| Chart metric toggles | Turns Balance, Net Profit, Gross sales, COGS, Fees paid, Ads spent, Refunds, Cancelled, Payout and Sales lines on or off. | Finance > (chart) > Net Profit | — |
| Transaction groups | Lists every ledger entry for the day, grouped into the sale, fee and refund set it belongs to. | Finance > (list under the chart) | finance |
| Saved days | Opens days already stored in your database that are older than the last seven, with a search box. | Finance > Saved days | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| All 7 Days | Switches from one day to a seven day summary of the same figures. | Finance > All 7 Days | finance |
| All 30 Days | Switches to a thirty day summary once those days are loaded. | Finance > All 30 Days | finance |
| Range | Picks a custom start and end day for the summary, saved days included. | Finance > Range | finance |
| Trends chart | Plots the selected metrics day by day across the chosen range. | Finance > (trends chart) | — |
| Profit per product | Ranks listings over the range with sales, gross, fees, refunds, COGS, net and margin. | Finance > Profit per product | finance |
| Products view | Shows the range as one row per listing, and clicking a row opens that listing orders. | Finance > Profit per product > Products | — |
| All Transactions | Shows every transaction group in the range instead of the per-product rollup. | Finance > Profit per product > All Transactions | — |
| Issues | Lists the transaction groups that could not be categorised automatically so you can check them. | Finance > Profit per product > Issues | — |
| Table search | Filters the transaction or group table by description, type, date or amount. | Finance > Profit per product > All Transactions > Search transactions... | — |
| Table paging | Steps through the transaction and group tables a page at a time. | Finance > Profit per product > Next | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| All Stores tab | Shows the combined figures for every selected store as one set of cards. | Finance > (store name) > All Stores > All StoresNeeds two or more stores | finance |
| Per Store tab | Splits the same window back out into one row of figures per store. | Finance > (store name) > All Stores > Per StoreNeeds two or more stores | finance |
| Software Expense | The subscriptions you logged, charged against the selected window. | Finance > (store name) > All Stores > Software ExpenseNeeds two or more stores | finance_software_expenses |
| Software expenses breakdown | Opens the individual subscription charges that make up the Software Expense figure. | Finance > Software Expense > (breakdown icon) | finance_software_expenses |
| Per-store breakdown | Lists each store gross profit and its own cards under the combined totals. | Finance > (store name) > All Stores > Per-store breakdownNeeds two or more stores | finance |
| Multi-store refresh | Re-fetches every selected store from Etsy at once, with live per-store progress. | Finance > (store name) > All Stores > (gear icon) > Previous 7 DaysNeeds two or more stores | finance_sync |
Connect Etsy shops to Eto and control what each one shows on the rest of the app.
| Feature | What it does | Where | API |
|---|---|---|---|
| Add store | Starts the Etsy OAuth flow and opens the connect panel with the authorisation link. | Stores > Add store | — |
| Connect your Etsy store panel | Shows the generated Etsy authorisation link and waits for Etsy to call back. | Stores > Add store > Connect your Etsy store | — |
| Copy link | Copies the Etsy authorisation URL to the clipboard and starts polling for the callback. | Stores > Add store > Copy link | — |
| Cancel | Closes the connect panel and stops listening for the Etsy callback. | Stores > Add store > Cancel | — |
| Connected shop | Shows the shop name Etsy returned once the callback lands, then reloads the store list. | Stores > Add store > Connected shop | — |
| Store connection limit warning | Blocks a new connection and offers an upgrade when the plan store limit is already used up. | Stores > Add store | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Your stores | Lists every connected shop as a card with its icon, shop id and active listing count. | Stores | stores_list |
| Refresh from Etsy | Re-pulls the shop list from Etsy and updates the cards in place. | Stores > Refresh from EtsyNeeds connected store | store_sync |
| Search stores | Filters the cards by shop name as you type; only appears once two or more stores are connected. | Stores > Search stores... | — |
| Clear search | Empties the search field and shows every store again. | Stores > Search stores... > Clear search | — |
| All | Shows every connected store and carries a live count. | Stores > All | — |
| Select all | Ticks every store currently on screen, so a filter or search narrows what gets selected. | Stores > Select all | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Store name link | Opens the per-store detail page; only clickable once details have been loaded. | Stores > store card > shop name | store_detail |
| Load details | Fetches the shop profile from Etsy for a store that has never been synced. | Stores > store card > Load detailsNeeds connected store | store_sync |
| Refresh store details | Re-fetches that one shop profile from Etsy and updates its card. | Stores > store card > refresh iconNeeds connected store | store_sync |
| Disconnect store | Opens the disconnect confirmation for that store. | Stores > store card > close icon | — |
| Disconnect store? modal | Confirms removing the store from Eto; the card disappears at once and the cascade runs in the background. | Stores > store card > close icon > Disconnect | — |
| Order notifications | Switch that turns on a notification in Eto whenever that store takes an order. | Stores > store card > Order notificationsNeeds connected store | — |
| Visibility | Expands the per-store panel of switches that hide the shop from individual pages. | Stores > store card > Visibility | — |
| Hide on pages: Orders | Hides this store from the Orders page. | Stores > store card > Visibility > Hide on pages > Orders | — |
| Hide on pages: Finance | Hides this store from the Finance page. | Stores > store card > Visibility > Hide on pages > Finance | — |
| Hide on pages: Listings | Hides this store from the Listing Manager store chips. | Stores > store card > Visibility > Hide on pages > Listings | — |
| Hide on dashboard: Orders | Hides this store from the dashboard order feeds. | Stores > store card > Visibility > Hide on dashboard > Orders | — |
| Hide on dashboard: Finances | Hides this store from the dashboard finance figures. | Stores > store card > Visibility > Hide on dashboard > Finances | — |
| Hide on dashboard: Entire store | Hides the store from the dashboard completely and locks the two dashboard sub-switches on. | Stores > store card > Visibility > Hide on dashboard > Entire store | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Selected count bar | Floating bar that appears as soon as one store card is ticked. | Stores > store card checkbox | — |
| Select all | Selects every store that passes the current filter and search. | Stores > store card checkbox > Select all | — |
| Clear | Drops the whole selection. | Stores > store card checkbox > Clear | — |
| Notifications on | Turns order notifications on for every selected store at once. | Stores > store card checkbox > Notifications onNeeds connected store | — |
| Notifications off | Turns order notifications off for every selected store at once. | Stores > store card checkbox > Notifications offNeeds connected store | — |
| Visibility menu | Opens a menu that hides or shows every selected store on one page at a time. | Stores > store card checkbox > Visibility | — |
| Hide on pages rows | Show and Hide buttons that set Orders, Finance or Listings visibility for the whole selection. | Stores > store card checkbox > Visibility > Hide on pages | — |
| Hide on dashboard rows | Show and Hide buttons that set dashboard Orders, Finances or Entire store visibility for the whole selection. | Stores > store card checkbox > Visibility > Hide on dashboard | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Load Store Stats | Fetches the shop profile, stats and shipping profiles from Etsy for a store with no data yet. | Stores > store card > shop name > Load Store StatsNeeds connected store | store_sync |
| Refresh | Re-pulls this shop profile from Etsy and reloads the page with the fresh figures. | Stores > store card > shop name > RefreshNeeds connected store | store_sync |
| View on Etsy | Opens the public shop page on Etsy in a new tab. | Stores > store card > shop name > View on Etsy | — |
| Stats row | Shows active listings, total sales, favourers and review average for the shop. | Stores > store card > shop name | store_details_cached |
| Order Notifications | Switch that turns Etsy order webhooks for this store into Eto notifications. | Stores > store card > shop name > Order NotificationsNeeds connected store | — |
| Shop Information | Lists currency, shipping-from country, location, languages and the shop creation date. | Stores > store card > shop name > Shop Information | store_details_cached |
| Shop Status | Shows vacation mode, custom requests, Etsy Payments and Direct Checkout state. | Stores > store card > shop name > Shop Status | store_details_cached |
| Shipping Profiles | Lists each saved shipping profile with processing and delivery times, method, carrier and cost. | Stores > store card > shop name > Shipping ProfilesNeeds connected store | shipping_profiles_live |
| Shop Announcement | Shows the shop announcement text pulled from Etsy. | Stores > store card > shop name > Shop Announcement | store_details_cached |
| Digital Sale Message | Shows the message Etsy sends to buyers of digital items. | Stores > store card > shop name > Digital Sale Message | store_details_cached |
| Back to stores | Returns to the store list. | Stores > store card > shop name > back arrow | — |
Browse, filter and bulk edit every listing across your connected Etsy shops.
| Feature | What it does | Where | API |
|---|---|---|---|
| Default | Normal browsing mode where clicking a listing opens it. | Listing Manager > Default | — |
| Edit Products | Turns the grid into a selection surface and shows the bulk action bar. | Listing Manager > Edit Products | — |
| Edit Storewide | Replaces the grid with a store picker for settings that apply to a whole shop. | Listing Manager > Edit Storewide | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Refresh All | Re-pulls listings from Etsy for every unlocked store one after another with a per-store progress panel. | Listing Manager > Refresh AllNeeds connected store | store_sync |
| Rank stores | Re-orders the store chip row by Listings, Sales, Orders, Newest store, Oldest store or Name A-Z. | Listing Manager > Rank stores | — |
| Grid view | Shows listings as a grid of image cards. | Listing Manager > Grid view | — |
| List view | Shows listings as compact rows with inline action buttons. | Listing Manager > List view | — |
| Columns | Sets how many cards per row the grid uses, from 3 to 8, and remembers the choice. | Listing Manager > Columns | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Store chip | Selects a shop and loads its listings, showing the shop icon and its listing count. | Listing Manager > store chipNeeds connected store | stores_list |
| Locked store chip | Shows a padlock and an Upgrade Now link for shops beyond the plan store limit. | Listing Manager > store chip | — |
| Printify chip | Appears alongside the Etsy shops when a Printify API token and shop id are saved. | Listing Manager > Printify chipNeeds Printify API token | — |
| Load listings from Etsy | Manual retry that pulls this store from Etsy when nothing has loaded yet. | Listing Manager > store chip > Load listings from EtsyNeeds connected store | store_sync |
| Checking for updates | Runs by itself after picking a store and quietly adds new listings and state changes to the grid. | Listing Manager > store chipNeeds connected store | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| All / Active / Inactive / Draft | Status tabs that filter the grid and show a live count for each state. | Listing Manager > All | — |
| All Sections | Filters the grid to one Etsy shop section. | Listing Manager > All SectionsNeeds connected store | shop_sections_live |
| All Types | Filters to digital or physical listings. | Listing Manager > All Types | — |
| Sort by | Sorts the loaded listings by Quantity, Views, Favorites, Sold, Recently Bought, Price, Created Date or Modified Date. | Listing Manager > Sort by | — |
| Sort direction | Flips the sort between highest first and lowest first. | Listing Manager > Sort by > sort direction arrow | — |
| All Ages | Filters by listing age: last 7 days, 30 days, 90 days, last year or older than a year. | Listing Manager > All Ages | — |
| Search | Filters listings by title, with an instant dropdown of matches you can walk with the arrow keys and open with Enter. | Listing Manager > Search... | listings_search |
| Refresh | Re-pulls just the selected store from Etsy and streams the progress. | Listing Manager > RefreshNeeds connected store | store_sync |
| Previous / Next | Pages through the listings when a store has more than one page. | Listing Manager > Next | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| View on Etsy | Opens the live listing on Etsy in a new tab. | Listing Manager > listing card > Etsy icon | — |
| Edit listing | Opens the full edit workspace for that listing; ctrl or cmd click opens it in a new tab. | Listing Manager > listing card > EditNeeds connected store | listing_detail |
| Copy listing | Copies the listing into a new workspace draft, using media Eto has stored so it still works for a shop that is gone. | Listing Manager > listing card > Copy | — |
| Upload to Etsy | Publishes a single draft listing live on Etsy for $0.20. | Listing Manager > listing card > Upload to EtsyNeeds connected store | — |
| Delete from Etsy | Deletes that one listing from Etsy after a confirmation with a tick box. | Listing Manager > listing card > DeleteNeeds connected store | listing_delete |
| Sold count | Fills the sold figure on each card in the background after the grid renders. | Listing Manager > listing cardNeeds connected store | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Select All | Ticks every listing currently loaded for the store. | Listing Manager > Edit Products > Select All | — |
| Draft / Active / Inactive quick select | Selects every loaded listing in that state, and clicking the same button again clears the selection. | Listing Manager > Edit Products > Draft | — |
| Edit Processing Profiles | Changes the Etsy processing profile on every selected listing, with a progress bar and error list. | Listing Manager > Edit Products > Edit Processing ProfilesNeeds connected store | processing_profiles_live |
| Edit Quantity | Opens a per-listing stock editor for the selection, with a Set all to field and a Apply button. | Listing Manager > Edit Products > Edit QuantityNeeds connected store | listing_inventory_update |
| Show variations | Expands a listing inside Edit Quantity to set stock per variation instead of one number. | Listing Manager > Edit Products > Edit Quantity > chevronNeeds connected store | listing_inventory_update |
| Copy to Store | Copies the selected listings into another connected shop, applying that shop shipping profile, return policy and processing profile. | Listing Manager > Edit Products > Copy to StoreNeeds connected store | listing_create |
| Copy to store as draft | Destination option that creates the copies as free drafts on the target shop. | Listing Manager > Edit Products > Copy to Store > Copy to store as draftNeeds connected store | listing_create |
| Publish to store | Destination option that creates and activates the copies live on Etsy at $0.20 each. | Listing Manager > Edit Products > Copy to Store > Publish to storeNeeds connected store | listing_create |
| Activate on Etsy | Publishes every selected draft live on Etsy, and only turns on when the whole selection is drafts. | Listing Manager > Edit Products > Activate on EtsyNeeds connected store | — |
| Don't show this warning again | Hides the $0.20 activation warning on future bulk activations. | Listing Manager > Edit Products > Activate on Etsy > Don't show this warning again | — |
| Delete from Etsy | Deletes every selected listing from Etsy after ticking the cannot be undone box. | Listing Manager > Edit Products > Delete from EtsyNeeds connected store | listing_delete |
| Feature | What it does | Where | API |
|---|---|---|---|
| Select All Stores | Ticks every unlocked Etsy shop in the storewide list. | Listing Manager > Edit Storewide > Select All Stores | — |
| Store row | One row per shop with a tick box, listing count and the automation badge when a rule covers it. | Listing Manager > Edit Storewide > store rowNeeds connected store | — |
| Auto Quantity Control | Opens the automation that puts a listing quantity back up on its own after it sells down. | Listing Manager > Edit Storewide > Auto Quantity ControlNeeds connected store | — |
| Auto Listing Quantity Control | The rule window: it watches the selected shops and resets stock whenever an order drops a listing to the threshold. | Listing Manager > Edit Storewide > Auto Quantity Control > Auto Listing Quantity ControlNeeds connected store | — |
| Condition | Sets the quantity at or below which the rule fires, written as If listing quantity is less than or equal to a number. | Listing Manager > Edit Storewide > Auto Quantity Control > ConditionNeeds connected store | — |
| Action | Sets the quantity the listing is put back to, written as Set quantity to a number. | Listing Manager > Edit Storewide > Auto Quantity Control > ActionNeeds connected store | — |
| Affected Stores | Lists the shops the rule will run on, taken from the storewide selection. | Listing Manager > Edit Storewide > Auto Quantity Control > Affected StoresNeeds connected store | — |
| Automation Active | Green panel showing how many times the rule has fired and when it last fired. | Listing Manager > Edit Storewide > Auto Quantity Control > Automation ActiveNeeds connected store | — |
| Save Automation | Saves the rule; the target must be higher than the threshold and at least one store must be picked. | Listing Manager > Edit Storewide > Auto Quantity Control > Save AutomationNeeds connected store | — |
| Delete Rule | Removes the quantity automation entirely. | Listing Manager > Edit Storewide > Auto Quantity Control > Delete RuleNeeds connected store | — |
| Auto Qty badge | Chip on a store row showing the live rule as threshold to target, with edit and remove buttons. | Listing Manager > Edit Storewide > store rowNeeds connected store | — |
| Edit rule | Reopens the automation window for the shops the rule already covers. | Listing Manager > Edit Storewide > store row > edit iconNeeds connected store | — |
| Remove automation | Takes one shop out of the quantity rule without deleting the rule. | Listing Manager > Edit Storewide > store row > close iconNeeds connected store | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Listing detail | Read-only page for one listing with its images, price, status and saved fields. | Listing Manager > listing card | listing_detail |
| Thumbnail gallery | Swaps the main image when you click one of the listing thumbnails. | Listing Manager > listing card > thumbnail | listing_images |
| Etsy | Opens this listing on Etsy in a new tab, or shows a plain chip when there is no live URL. | Listing Manager > listing card > Etsy | — |
| Listing Info | Lists type, who made it, when made, supply, processing days, variations, auto-renew, language and listing id. | Listing Manager > listing card > Listing Info | listing_detail |
| Personalization | Shows whether the listing is personalisable or customisable, the character limit and the buyer instructions. | Listing Manager > listing card > Personalization | listing_personalization |
| Dimensions | Shows the item weight and length, width and height with their units. | Listing Manager > listing card > Dimensions | listing_detail |
| Description | Shows the saved listing description. | Listing Manager > listing card > Description | listing_detail |
| Tags | Shows every tag on the listing with a count. | Listing Manager > listing card > Tags | listing_detail |
| Materials | Shows the materials saved on the listing. | Listing Manager > listing card > Materials | listing_detail |
| Inventory | Lists each variation with its SKU, price and stock, or Unavailable when it is turned off. | Listing Manager > listing card > Inventory | listing_inventory_get |
| Timestamps | Shows when the listing was created, last modified and when it ends. | Listing Manager > listing card > Timestamps | listing_detail |
| Feature | What it does | Where | API |
|---|---|---|---|
| Editing listing | The full workspace opened in edit mode against a live Etsy listing, saving a local draft copy as you work. | Listing Manager > listing card > EditNeeds connected store | listing_detail |
| About | Tab for the title, photos, video, description and personalisation questions. | Listing Manager > listing card > Edit > AboutNeeds connected store | listing_image_upload |
| Add product image | Adds or replaces the listing photos in the About tab. | Listing Manager > listing card > Edit > About > Add product imageNeeds connected store | listing_image_upload |
| Personalisation question types | Choose a Text box, List of options, File upload or labelled File upload for buyer input. | Listing Manager > listing card > Edit > About > personalisationNeeds connected store | listing_personalization |
| Price & Inventory | Tab for price, quantity, SKU, shop discount and the variation grid. | Listing Manager > listing card > Edit > Price & InventoryNeeds connected store | listing_inventory_update |
| Details | Tab for category, category attributes, who made it, when made, tags and materials. | Listing Manager > listing card > Edit > DetailsNeeds connected store | category_properties |
| Settings | Section for the target stores, processing profile, shop section and production partners. | Listing Manager > listing card > Edit > SettingsNeeds connected store | shop_sections_live |
| Update Listing | Pushes the edits back to Etsy; the button reads Update Listing whenever the listing still exists there. | Listing Manager > listing card > Edit > Update ListingNeeds connected store | shop_listing_update |
| Activate Listing ($0.20) | Extra button on a draft listing that publishes it live on Etsy for $0.20. | Listing Manager > listing card > Edit > Activate Listing ($0.20)Needs connected store | — |
| Publish as Draft | Replaces Update Listing when the original was deleted from Etsy, rebuilding it as a new draft from Eto stored copy. | Listing Manager > listing card > Edit > Publish as DraftNeeds connected store | listing_create |
| Sanity strip | Running checklist across the top for at least one photo, a shipping profile and at least one store. | Listing Manager > listing card > EditNeeds connected store | — |
Build Etsy listings in Eto and push them to one or more connected stores as drafts.
| Feature | What it does | Where | API |
|---|---|---|---|
| Active | Shows listings already pushed to Etsy, with a count badge, and they are view only. | Quick upload > ActiveNeeds connected store | — |
| Drafts | Shows listings saved in Eto but not sent to Etsy yet, with a count badge. | Quick upload > Drafts | — |
| Scheduled | Shows single listings and bulk groups queued to publish at a set time. | Quick upload > Scheduled | — |
| New listing | Opens the create screen where you pick how the listing starts. | Quick upload > New listing | — |
| Select all | Ticks every listing card in the open tab so bulk actions apply to them. | Quick upload > Select all | — |
| Publish selected (n) | Publishes the ticked drafts to Etsy one at a time and turns into a Stop button while it runs. | Quick upload > Select all > Publish selectedNeeds connected store | listing_create |
| Delete selected (n) | Deletes every ticked listing from Eto in one call. | Quick upload > Select all > Delete selected | — |
| Columns | Sets how many listing cards sit in a row, from 2 up to 10. | Quick upload > Columns | — |
| Open on Etsy | Opens the published listing on Etsy in a new tab. | Quick upload > Active > Open on EtsyNeeds published listing | — |
| Copy | Duplicates the listing into a new draft and opens that draft. | Quick upload > Copy | — |
| Delete | Removes the listing from Eto without touching Etsy. | Quick upload > Delete | — |
| View group | Opens a modal listing every listing in a bulk group, marked Main or Variant, each with Open on Etsy and Delete. | Quick upload > Active > View groupNeeds bulk group | — |
| Delete group | Deletes every listing that belongs to a bulk group in one go. | Quick upload > Active > Delete groupNeeds bulk group | — |
| Cancel | Cancels a scheduled single listing and returns it to drafts. | Quick upload > Scheduled > CancelNeeds scheduled listing | — |
| Cancel schedule | Cancels a scheduled bulk group before it publishes. | Quick upload > Scheduled > Cancel scheduleNeeds scheduled bulk group | — |
| Bulk uploads in progress | Lists background bulk upload jobs with live progress, and failed jobs get a dismiss cross. | Quick uploadNeeds running bulk job | — |
| Edit & retry | Appears on a card that failed during bulk publish and opens that listing in the workspace. | Quick upload > Publish selected | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Enter Listing ID | Pulls an existing Etsy listing by its numeric ID and pre-fills a new draft from it. | Quick upload > New listing > Enter Listing ID > Continue | — |
| Digital Product | Creates a blank digital draft that asks for downloadable files instead of shipping. | Quick upload > New listing > Start from Scratch > Digital Product | — |
| Physical Product | Creates a blank physical draft that asks for shipping and processing profiles. | Quick upload > New listing > Start from Scratch > Physical Product | — |
| Upload spreadsheet | Starts the CSV or Excel import wizard for creating many listings at once. | Quick upload > New listing > Upload via CSV / Excel > Upload spreadsheet | — |
| Format guide | Opens the bulk CSV import section of the developer docs in a new tab. | Quick upload > New listing > Upload via CSV / Excel > Format guide | — |
| Your Favorites | Lists products you saved from Product Hunt so you can start a listing from one. | Quick upload > New listing > Your FavoritesNeeds saved favorite | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| About | Tab holding the title, photos, description and personalization fields. | Quick upload > open a listing > About | — |
| Title | Free text listing title with a live 0/140 character counter. | Quick upload > open a listing > About > Title | — |
| AI Magic | Writes the title with AI, and clicking it again opens a Special requirements box you send with Enter. | Quick upload > open a listing > About > Title > AI MagicNeeds AI provider configured | ai_generate_title |
| Undo AI title | Puts the previous title back after an AI rewrite. | Quick upload > open a listing > About > Title > Undo AI title | — |
| Photos & video | Twelve slot media grid where slot 1 is the primary photo and slot 2 is an optional video under 15 seconds. | Quick upload > open a listing > About > Photos & video | — |
| Add photo | Opens the file picker for that slot, accepting JPG, PNG or GIF up to 100MB and up to 20 photos. | Quick upload > open a listing > About > Photos & video > Add photo | file_upload |
| Add video | Uploads one MP4 or MOV into the video slot. | Quick upload > open a listing > About > Photos & video > Add video | file_upload |
| Add from Gallery | Picks a saved Gallery image straight into an empty photo slot. | Quick upload > open a listing > About > Photos & video > Add from GalleryNeeds saved gallery image | — |
| AI Image | Hover button on a photo that opens the per image AI generator. | Quick upload > open a listing > About > hover a photo > AI ImageNeeds AI provider configured | ai_generate_image |
| Preset | Chooses the AI image recipe: Custom, Thumbnail, Info or Showcase. | Quick upload > open a listing > About > hover a photo > AI Image > Preset | — |
| Model | Picks the image model between Gemini 3 Pro, Gemini 3.1 Flash and Gemini 2.5 Flash. | Quick upload > open a listing > About > hover a photo > AI Image > Model | — |
| Use Product Image | Switch that decides whether the AI works from your uploaded product photo or from the tile you clicked. | Quick upload > open a listing > About > hover a photo > AI Image > Use Product Image | — |
| Gallery | Hover button on a photo that swaps it for a saved Gallery image. | Quick upload > open a listing > About > hover a photo > GalleryNeeds saved gallery image | — |
| Download image | Item in the photo three dot menu that saves that image to your computer. | Quick upload > open a listing > About > hover a photo > More > Download image | — |
| Set as product image | Item in the photo three dot menu that promotes the image to the reference product image. | Quick upload > open a listing > About > hover a photo > More > Set as product image | — |
| Undo AI edit | Item in the photo three dot menu that steps back through AI edits of that photo. | Quick upload > open a listing > About > hover a photo > More > Undo AI editNeeds AI edit applied | — |
| Generate Slideshow Video | Turns the listing photos into an MP4 slideshow and drops it into the video slot. | Quick upload > open a listing > About > Generate Slideshow VideoNeeds at least one photo | — |
| Slideshow settings | Sets total video length, per image duration and which photos take part, with a Distribute equally shortcut. | Quick upload > open a listing > About > Slideshow settings | — |
| Product Image | Single square reference image the AI tools use as the source product. | Quick upload > open a listing > About > Product Image | — |
| + Add Custom Image | Uploads an extra named image, such as a sizing chart, that AI prompts can refer to by name. | Quick upload > open a listing > About > + Add Custom Image | — |
| Description | Long form listing description with its own AI Magic button and undo. | Quick upload > open a listing > About > Description | ai_generate_description |
| Add new field | Adds a personalization field of type Text box, List of options, File upload or File upload (labeled), up to five. | Quick upload > open a listing > About > Personalization > Add new field | — |
| Digital files | Drag and drop area for up to five downloadable files, 100MB each, on digital listings only. | Quick upload > open a digital listing > About > Digital filesNeeds digital listing | file_upload |
| Feature | What it does | Where | API |
|---|---|---|---|
| Price & Inventory | Tab holding price, quantity, SKU and the variations editor. | Quick upload > open a listing > Price & Inventory | — |
| Price | One price box per selected store, published in that store currency. | Quick upload > open a listing > Price & Inventory > PriceNeeds connected store | — |
| Shop discount | Percentage that back calculates the listed price so buyers see the price you typed. | Quick upload > open a listing > Price & Inventory > Shop discount | — |
| Quantity | Stock number for the listing, between 1 and 999. | Quick upload > open a listing > Price & Inventory > Quantity | — |
| SKU | Internal identifier where the first 32 characters go to Etsy and the full string stays in Eto. | Quick upload > open a listing > Price & Inventory > SKU | — |
| + Add Variation | Creates a variation such as Colour or Size, up to the Etsy maximum of two. | Quick upload > open a listing > Price & Inventory > + Add Variation | — |
| Prices vary for each | Switch that turns on a separate price per option combination. | Quick upload > open a listing > Price & Inventory > Variations > Prices vary for eachNeeds variations | — |
| Quantities vary for each | Switch that turns on a separate stock count per option combination. | Quick upload > open a listing > Price & Inventory > Variations > Quantities vary for eachNeeds variations | — |
| SKUs vary for each | Switch that turns on a separate SKU per option combination. | Quick upload > open a listing > Price & Inventory > Variations > SKUs vary for eachNeeds variations | — |
| Processing profiles vary for each | Switch that lets each option combination use its own processing profile. | Quick upload > open a listing > Price & Inventory > Variations > Processing profiles vary for eachNeeds variations | — |
| Photos vary for each | Switch that links a listing photo to each option value. | Quick upload > open a listing > Price & Inventory > Variations > Photos vary for eachNeeds variations | — |
| Generate SKUs | Describes your SKU format in plain text and lets AI fill every variation SKU, with an option to preserve hand written ones. | Quick upload > open a listing > Price & Inventory > Variations > SKU Generator > Generate SKUsNeeds AI provider configured | — |
| Swap variation order | Flips which variation is first and which is second. | Quick upload > open a listing > Price & Inventory > Variations > Swap variation orderNeeds two variations | — |
| Back to single price | Drops the variations and returns the listing to one price and quantity. | Quick upload > open a listing > Price & Inventory > Variations > Back to single priceNeeds variations | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Details | Tab holding category, category attributes, who and when made, tags and materials. | Quick upload > open a listing > Details | — |
| Category | Opens a searchable Etsy category tree and sets the listing taxonomy. | Quick upload > open a listing > Details > Category | categories |
| Category attributes | Shows the extra fields Etsy requires for the chosen category. | Quick upload > open a listing > Details > Category attributesNeeds category selected | category_properties |
| When was it made? | Sets the Etsy production era, from Made To Order through to vintage decades. | Quick upload > open a listing > Details > When was it made? | — |
| Tags | Adds up to 13 search tags of 20 characters each, comma separated. | Quick upload > open a listing > Details > Tags | — |
| Materials | Lists the materials the product is made from. | Quick upload > open a listing > Details > Materials | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Stores | Ticks which connected stores the listing publishes to, and locked rows link to Upgrade Now. | Quick upload > open a listing > Settings > StoresNeeds connected store | stores_list |
| Shipping profile | Picks a shipping profile per store, required for physical listings. | Quick upload > open a listing > Settings > Shipping profileNeeds physical listing | shipping_profiles_live |
| Processing profile | Picks a readiness profile per store, and Create processing profile makes a new one from a type and processing time. | Quick upload > open a listing > Settings > Processing profileNeeds physical listing | processing_profiles_live |
| Return policy | Picks a return policy per store, with a Refresh button after you add one on Etsy. | Quick upload > open a listing > Settings > Return policyNeeds connected store | return_policies_live |
| Shop section | Picks the shop section per store, and the Create box adds a new section to that shop. | Quick upload > open a listing > Settings > Shop sectionNeeds connected store | shop_sections_live |
| Production partners | Selects the Etsy production partners for each store. | Quick upload > open a listing > Settings > Production partnersNeeds connected store | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Publish draft | Creates the listing as a draft in each selected store and uploads its media and files. | Quick upload > open a listing > Publish draftNeeds connected store | listing_create |
| Missing | Bar at the top of the tabs naming the first requirement still blocking publish. | Quick upload > open a listing | — |
| Schedule 1 listing | Opens a date, time and timezone picker and queues this one listing to publish later. | Quick upload > open a listing > Schedule > Schedule 1 listingNeeds connected store | — |
| Schedule bulk group | Queues the whole generated bulk group to publish at a chosen date and time. | Quick upload > open a listing > Schedule > Schedule bulk groupNeeds bulk group built | — |
| AI provider badge | Shows which AI credentials are in use and tests the connection when clicked. | Quick upload > open a listing > AI provider badge | — |
| AI Generations | Collapsible panel listing every AI image job running on this listing with its status. | Quick upload > open a listing > AI GenerationsNeeds AI job running | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Bulk Upload | Button beside Publish draft that turns one finished listing into several near copies, enabled only once the listing is ready to publish. | Quick upload > open a listing > Bulk UploadNeeds listing ready to publish | — |
| Count | Sets how many extra variants to generate, between 2 and 20. | Quick upload > open a listing > Bulk Upload > Count | — |
| Image model | Chooses the model that draws the variant thumbnails, including a Custom model ID option. | Quick upload > open a listing > Bulk Upload > Image model | — |
| Custom image prompt | Replaces the default thumbnail prompt for the whole batch. | Quick upload > open a listing > Bulk Upload > Custom image prompt | — |
| Custom title prompt | Replaces the default title prompt for the whole batch. | Quick upload > open a listing > Bulk Upload > Custom title prompt | — |
| Continue | Opens the Bulk Upload Preview page and starts generating the variant images and titles in parallel. | Quick upload > open a listing > Bulk Upload > Continue | ai_generate_image |
| Bulk Upload Preview | Shows the Main (your custom) card next to the generated variant rows, each marked Generating, Ready or Error. | Quick upload > open a listing > Bulk Upload > Continue | — |
| Regenerate title | Redraws one variant title inside the variant edit modal. | Quick upload > open a listing > Bulk Upload > Continue > click a variant > Regenerate title | ai_generate_title |
| Regenerate image | Redraws one variant thumbnail, optionally from a short prompt you type. | Quick upload > open a listing > Bulk Upload > Continue > click a variant > Regenerate image | ai_generate_image |
| Variation Prices | Edits the price of each variation for a variant listing, applied to every selected shop. | Quick upload > open a listing > Bulk Upload > Continue > click a variant > Variation PricesNeeds variations | — |
| Upload all | Creates every variant plus the main listing as drafts in the selected stores in one background job. | Quick upload > open a listing > Bulk Upload > Continue > Upload allNeeds connected store | listing_create |
| Schedule bulk group | Queues the whole generated group to publish at a chosen date, time and timezone. | Quick upload > open a listing > Bulk Upload > Continue > Schedule bulk groupNeeds connected store | — |
| Retry failed | Regenerates only the variants whose image or title failed. | Quick upload > open a listing > Bulk Upload > Continue > Retry failedNeeds a failed variant | — |
| Back to listings | Leaves the builder and returns to the Quick upload list while the job keeps running. | Quick upload > open a listing > Bulk Upload > Continue > Back to listings | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Upload your spreadsheet | Step one of the wizard, where you drop a .csv, .xlsx or .xlsm file, including an Etsy bulk edit export. | Quick upload > New listing > Upload spreadsheet | — |
| Download template | Downloads eto_listing_import_template.csv with the canonical headers and two example rows. | Quick upload > New listing > Upload spreadsheet > Download template | — |
| Just a couple of details | Step that only appears when the file left out a store, shipping profile, processing profile or return policy, and applies your choice to every missing row. | Quick upload > New listing > Upload spreadsheet > Continue | — |
| Review & edit | Step three, showing every parsed listing with counts of ready, warnings and blocked rows sorted worst first. | Quick upload > New listing > Upload spreadsheet > Continue > Continue | — |
| Table | Review view with an editable cell per field: title, type, category, price, quantity, SKU, tags, materials, who made, when made, shipping, processing, return, section and photos. | Quick upload > New listing > Upload spreadsheet > Review & edit > Table | — |
| Cards | Review view showing each listing as a thumbnail card with its status badge and reasons. | Quick upload > New listing > Upload spreadsheet > Review & edit > Cards | — |
| Choose category | Fix button on a blocked row that opens a searchable Etsy category picker. | Quick upload > New listing > Upload spreadsheet > Review & edit > Choose categoryNeeds row with a category error | categories |
| Photo cell | Steps through each photo URL on a row and lets you edit or add one inline. | Quick upload > New listing > Upload spreadsheet > Review & edit > Table | — |
| Save changes | Revalidates your edits on the server before the wizard will let you upload. | Quick upload > New listing > Upload spreadsheet > Review & edit > Save changesNeeds unsaved edits | — |
| Select all ready listings | Ticks every row that passed validation so only those get uploaded. | Quick upload > New listing > Upload spreadsheet > Review & edit > Select all ready listings | — |
| Upload n to draft | Runs the import, creating each selected row as a draft listing with a live progress bar and per row result. | Quick upload > New listing > Upload spreadsheet > Review & edit > Upload n to draftNeeds connected store | listing_create |
| Open Quick upload | Ends the wizard and returns to the listing list once the import has finished. | Quick upload > New listing > Upload spreadsheet > Open Quick upload | — |
Create virtual assistant logins, set what each one may do per store, and review what they have done.
| Feature | What it does | Where | API |
|---|---|---|---|
| Search virtual assistants | Filters the assistant cards as you type. | VA Admin > Search virtual assistants | — |
| Add VA | Opens the form for creating a new assistant login. | VA Admin > Add VA | — |
| Assistant card | Shows the assistant name, email, active status, join date and a summary of their Orders, Products and Product Hunt access. | VA Admin | — |
| Edit | Opens that assistant for editing. | VA Admin > Edit | — |
| Delete | Asks to confirm, then removes the assistant and revokes their access to every store. | VA Admin > Delete | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Private Name | Names the assistant for your eyes only, so you can tell several apart. | VA Admin > Add VA > Identity | — |
| Display Name | Sets the name the assistant sees when they sign in. | VA Admin > Add VA > Identity | — |
| First Name and Last Name | Records the person behind the account. | VA Admin > Add VA > Identity | — |
| Email Address | Sets the address the assistant signs in with. | VA Admin > Add VA > Login Credentials | — |
| Password | Sets the assistant password, with a show/hide toggle and a live strength meter. | VA Admin > Add VA > Login Credentials | — |
| Gemini API Key | Optionally gives the assistant their own Gemini key instead of using the owner AI provider. | VA Admin > Add VA > VA API Keys | — |
| Product Hunt | Toggles whether the assistant may use the Etsy product research tool. | VA Admin > Add VA > Product Hunt | — |
| Store Permissions | Picks which stores the assistant can work in, with a running selected count. | VA Admin > Add VA > Store PermissionsNeeds connected store | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Details tab | Edits identity, password and the Gemini key; the email address is fixed after creation. | VA Admin > Edit > Details | — |
| Active toggle | Suspends or restores the assistant login without deleting the account. | VA Admin > Edit > Details > Account | — |
| Order Permissions card | Opens the per-store order permission editor and shows how many stores are covered. | VA Admin > Edit > Details > Order Permissions | — |
| Upload Permissions card | Opens the per-store upload permission editor and shows how many stores are covered. | VA Admin > Edit > Details > Upload Permissions | — |
| Product Hunt toggle | Turns the research tool on or off for this assistant. | VA Admin > Edit > Details > Product Hunt | — |
| Delete VA | Asks to confirm, then deletes the assistant and their store access. | VA Admin > Edit > Delete | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Login Status | Shows whether the assistant is signed in now and when they last were. | VA Admin > Edit > Activity > Login Status | — |
| Etsy Searches | Lists the product searches the assistant ran, with a count. | VA Admin > Edit > Activity > Etsy Searches | — |
| Listings Uploaded | Lists the listings the assistant published, with a count. | VA Admin > Edit > Activity > Listings Uploaded | — |
| Orders Fulfilled | Lists the orders the assistant completed, with a count. | VA Admin > Edit > Activity > Orders Fulfilled | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Search stores | Filters the store rows on the permission page. | VA Admin > Edit > Order Permissions > Search stores | — |
| Enable All | Turns every order permission on for every listed store. | VA Admin > Edit > Order Permissions > Enable All | — |
| Disable All | Turns every order permission off for every listed store. | VA Admin > Edit > Order Permissions > Disable All | — |
| View Orders | Lets the assistant see the order list and order details for that store. | VA Admin > Edit > Order Permissions | — |
| Create Links | Lets the assistant create supplier share links. | VA Admin > Edit > Order Permissions > Supplier | — |
| View Tracking | Lets the assistant see supplier tracking entries. | VA Admin > Edit > Order Permissions > Supplier | — |
| Delete Links | Lets the assistant remove supplier share links. | VA Admin > Edit > Order Permissions > Supplier | — |
| Delete Variations | Lets the assistant remove supplier tracking entries. | VA Admin > Edit > Order Permissions > Supplier | — |
| Complete Orders | Lets the assistant mark an order complete through a supplier. | VA Admin > Edit > Order Permissions > Supplier | — |
| Unsaved changes | Warns that permission edits are still pending, cleared by Save. | VA Admin > Edit > Order Permissions | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Upload Products | Lets the assistant upload single products to that store. | VA Admin > Edit > Upload Permissions | — |
| Bulk Upload | Lets the assistant upload many listings at once. | VA Admin > Edit > Upload Permissions | — |
| Product Type | Restricts the assistant to all products, digital only or physical only. | VA Admin > Edit > Upload Permissions | — |
| View Active Listings | Lets the assistant see the owner active listings for that store. | VA Admin > Edit > Upload Permissions | — |
| View Drafts | Lets the assistant see the owner draft listings. | VA Admin > Edit > Upload Permissions | — |
| View Scheduled | Lets the assistant see the owner scheduled listings. | VA Admin > Edit > Upload Permissions | — |
| Save | Writes the whole permission set for every store at once. | VA Admin > Edit > Upload Permissions > Save | — |
Searches the Etsy marketplace for a keyword, scores every listing for 24h demand, and shows the results as a filterable card grid.
| Feature | What it does | Where | API |
|---|---|---|---|
| Search Product Hunt listings | Text box for the keyword you want to research on Etsy. | Product Hunt > Search Product Hunt listingsNeeds connected store | product_hunt |
| Search button | Starts the hunt for the keyword in the box; pressing Enter in the box does the same. | Product Hunt > SearchNeeds connected store | product_hunt |
| Search settings | Icon button that opens the dropdown holding the four search options. | Product Hunt > Search settingsNeeds connected store | — |
| Amount of Products | Sets how many listings the hunt scans, from 1 up to 10000. | Product Hunt > Search settings > Amount of ProductsNeeds connected store | product_hunt |
| Max Listing Age (months) | Keeps only listings created within the last N months; blank means no age limit. | Product Hunt > Search settings > Max Listing Age (months)Needs connected store | product_hunt |
| Full Product Details | Switch that runs the slower deep scan so every card carries full listing data. | Product Hunt > Search settings > Full Product DetailsNeeds connected store | product_hunt |
| Optimized Mode | Switch, on by default, that lets the AI drop off-topic listings and rank the rest; it disables Full Product Details while on. | Product Hunt > Search settings > Optimized ModeNeeds connected store | product_hunt |
| Settings summary strip | One line under the search box repeating the amount, age limit and any mode that is on. | Product Hunt > Search settingsNeeds connected store | — |
| Progress bar | Bar that narrates each phase of the run, from collecting listings to pruning, demand and ranking. | Product Hunt > SearchNeeds connected store | — |
| No Store Connected empty state | Replaces the whole page with a Connect Store prompt when the account has no Etsy store. | Product Hunt | — |
| Daily limit reached popup | Blocks the search and shows how many hunts of the daily allowance are used when the plan limit is hit. | Product Hunt > Search | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Sort by | Orders the results by demand, listing age, shop age, price, favorites, views, rating, reviews, quantity, shop sales, estimated sales per month or estimated revenue per month. | Product Hunt > Sort byNeeds connected store | — |
| Ranked Score | Extra sort option added after an Optimized Mode run that orders cards by the AI opportunity score. | Product Hunt > Sort by > Ranked ScoreNeeds connected store | — |
| Sort direction | Flips the chosen sort between high to low and low to high. | Product Hunt > Sort byNeeds connected store | — |
| Type | Shows only digital or only physical listings. | Product Hunt > TypeNeeds connected store | — |
| Variations | Shows only listings with variations or only listings without them. | Product Hunt > VariationsNeeds connected store | — |
| Ships from | Country menu filled from the countries actually present in the results. | Product Hunt > Ships fromNeeds connected store | — |
| Search within results | Text box that narrows the visible cards to titles containing what you type. | Product Hunt > SearchNeeds connected store | — |
| Column count | Buttons 2 to 7 that set how many cards sit in a row, remembered in the browser. | Product Hunt > column buttonsNeeds connected store | — |
| Prev and Next | Page through the result grid using the pager above and below the cards. | Product Hunt > NextNeeds connected store | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Demand badge | Flame badge on each card showing units sold in the last 24 hours, tinted zero, low, medium or high. | Product Hunt > cardNeeds connected store | — |
| Ranked score badge | Second badge shown after an Optimized Mode run carrying the AI score out of 100, with its reason on hover. | Product Hunt > cardNeeds connected store | — |
| AI reason | Short sentence at the foot of the card explaining why the AI ranked that listing where it did. | Product Hunt > cardNeeds connected store | — |
| ID pill | Click the listing ID on a card to copy it to the clipboard. | Product Hunt > card > IDNeeds connected store | — |
| Etsy link | Corner link that opens the listing on Etsy in a new tab without opening the drawer. | Product Hunt > card > EtsyNeeds connected store | — |
| Favourite heart | Saves the listing to the Quick Thoughts favourites list in the sidebar. | Product Hunt > card > heartNeeds connected store | — |
| Card meta pills | Row of pills under each card holding created date, shop age, shop sales, ships-from country, views and favourites. | Product Hunt > cardNeeds connected store | — |
| Estimated sales and revenue pills | Two pills estimating monthly sales and revenue from demand, reviews, views and price, or two question marks when there is no demand reading. | Product Hunt > cardNeeds connected store | — |
| Pill tooltips | Hovering a pill shows the exact shop opening date, the full ships-from country name, or a warning that the estimates are approximate. | Product Hunt > cardNeeds connected store | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Open detail drawer | Clicking a card slides in a drawer with the full listing, closed with Escape or the close button. | Product Hunt > cardNeeds connected store | — |
| Drawer stats | Top block listing created date, shop age, shop sales, ships from, views, favorers and the two estimates. | Product Hunt > card > drawerNeeds connected store | — |
| Drawer facts | Definition list holding listing ID, type, quantity, price, last modified date and shop name. | Product Hunt > card > drawerNeeds connected store | — |
| Copy title, description, tags and materials | Each text section in the drawer has its own copy button. | Product Hunt > card > drawer > CopyNeeds connected store | — |
| Offerings | Collapsible table of every variation offering with its price, quantity and enabled state, plus a Retry when inventory has not loaded. | Product Hunt > card > drawer > OfferingsNeeds connected store | — |
| Images | Collapsible image slider with prev and next arrows, a counter and thumbnails. | Product Hunt > card > drawer > ImagesNeeds connected store | — |
| Reviews | Collapsible table of up to fifty reviews with rating, language and text. | Product Hunt > card > drawer > ReviewsNeeds connected store | — |
| Open on Etsy | Foot link that opens the listing page on Etsy. | Product Hunt > card > drawer > Open on EtsyNeeds connected store | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Always incognito | Product Hunt results are held in the browser only and never written to the database, so leaving or reloading the page loses them. | Product Hunt | — |
| Search summary saved to history | After a run the keyword and its headline numbers are pushed to the sidebar search history. | Product Hunt > SearchNeeds full tracking enabled on the account | — |
Takes any Etsy listing link and pulls that whole shop, then lets you sort and filter every active listing it has.
| Feature | What it does | Where | API |
|---|---|---|---|
| Paste an Etsy product URL or listing ID | Input that accepts a full Etsy listing link or the bare numeric listing ID. | Shop Spy > URL box | — |
| Analyse shop | Looks up the shop behind that listing and starts loading every active listing it has. | Shop Spy > Analyse shop | — |
| Progress bar | Reports the two loading phases, collecting listing IDs and then hydrating their details. | Shop Spy > Analyse shop | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Shop summary line | One row with the shop icon, name, listing count, sales, favourites, rating and review count. | Shop Spy > Analyse shop | — |
| Visit Shop | Opens the shop page on Etsy in a new tab. | Shop Spy > Visit Shop | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Sort by | Orders the shop listings by created date, price, views, favorites or quantity. | Shop Spy > Sort by | — |
| Sort direction | Flips the chosen sort between high to low and low to high. | Shop Spy > Sort by | — |
| Type | Shows only the digital or only the physical listings in the shop. | Shop Spy > Type | — |
| Variations | Shows only listings with variations or only listings without them. | Shop Spy > Variations | — |
| Search | Narrows the grid to listings whose title or description contains what you type. | Shop Spy > Search | — |
| Column count | Buttons 3 to 7 that set how many cards sit in a row. | Shop Spy > column buttons | — |
| Previous and Next | Pages through the listings 48 at a time using the pager above and below the grid. | Shop Spy > Next | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Listing card | Card per listing with image, title, price and pills for created date, views, favourites, quantity, digital or physical and whether it has variations. | Shop Spy > card | — |
| ID pill | Click the listing ID on a card to copy it to the clipboard. | Shop Spy > card > ID | — |
| Etsy link | Corner link that opens the listing on Etsy without opening the drawer. | Shop Spy > card > Etsy | — |
| Detail drawer | Clicking a card opens a drawer with listing ID, created and modified dates, price, type, quantity, favorers, views, who made, when made, language, full title and description. | Shop Spy > card | — |
| Offerings | Collapsible table in the drawer showing each offering with price, quantity and enabled state. | Shop Spy > card > Offerings | — |
| Images | Collapsible image slider in the drawer with arrows, a counter and thumbnails. | Shop Spy > card > Images | — |
| Reviews | Collapsible table in the drawer of up to fifty reviews with rating, language and text. | Shop Spy > card > Reviews | — |
| Open on Etsy | Link inside the drawer to the listing page on Etsy. | Shop Spy > card > Etsy Link | — |
Chat with Gemini to generate, edit and keep product imagery for your listings.
| Feature | What it does | Where | API |
|---|---|---|---|
| Auto | Reads what you typed and decides between a text answer and an image, triggering on words like generate, create, make, draw, design, render, image, photo, mockup or thumbnail. | Gallery > Auto | — |
| Text | Chats only and never generates an image. | Gallery > Text | ai_chat |
| Image | Treats every message as an image request, and is the default. | Gallery > Image | ai_generate_image |
| Compare | Runs every model at once and shows the results side by side in one row. | Gallery > Compare | — |
| Start with a prompt | Welcome screen with three ready made prompts: Product photo on linen, White-background cutout and Listing thumbnail. | Gallery | — |
| New Chat | Clears the transcript and starts a fresh conversation. | Gallery > New Chat | — |
| Load earlier messages | Prepends the previous page of 30 stored messages to the transcript. | Gallery > Load earlier messagesNeeds a longer chat | — |
| Thoughts | Collapsible block under a reply showing the model reasoning when the model returns it. | Gallery > Thoughts | — |
| Sources | Row of source links shown under a reply that used Google Search grounding. | Gallery > Web search > SourcesNeeds Web search on | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Files | Attaches up to four images to the message, and you can also paste or drag and drop them. | Gallery > Files | — |
| Settings | Opens the in card drawer holding Model, Aspect Ratio and Resolution. | Gallery > Settings | — |
| Model | Picks between 3 Pro Image, 3.1 Flash Image, 2.5 Flash Image, 2.5 Flash (text) and 2.5 Pro (text). | Gallery > Settings > Model | — |
| Aspect Ratio | Sets the output shape to 1:1, 16:9, 9:16, 4:3, 3:4, 3:2, 2:3 or 21:9. | Gallery > Settings > Aspect Ratio | — |
| Resolution | Sets the output size to 1K, 2K or 4K. | Gallery > Settings > Resolution | — |
| Web search | Lets the model check Google Search before answering a text question. | Gallery > Web search | — |
| Annotate Image | Opens the annotator so you can mark up an attached or generated image before asking for a change. | Gallery > Annotate ImageNeeds an attached or generated image | — |
| Send | Sends the message, and Enter does the same while Shift+Enter adds a new line. | Gallery > Send | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Draw circle | Circles an area of the image so you can describe what belongs there. | Gallery > Annotate Image > Draw circle | — |
| Draw rectangle | Boxes an area of the image. | Gallery > Annotate Image > Draw rectangle | — |
| Freehand draw | Draws a free shape on the image. | Gallery > Annotate Image > Freehand draw | — |
| Clear annotations | Wipes every mark you have drawn. | Gallery > Annotate Image > Clear annotations | — |
| Apply Annotations | Flattens the marked up image and adds it to the message attachments. | Gallery > Annotate Image > Apply Annotations | — |
| Select Image to Annotate | Picker shown when more than one image could be annotated, listing each Upload and the Last Generated image. | Gallery > Annotate ImageNeeds more than one candidate image | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Download | Saves the generated image to your computer as ai-studio-<timestamp>.png. | Gallery > hover a generated image > Download | — |
| Save | Stores the image in your saved gallery so other Eto pages can use it. | Gallery > hover a generated image > Save | — |
| Full size | Opens the image in the lightbox, which also has Download, Save to gallery and Use as reference. | Gallery > hover a generated image > Full size | — |
| Reference | Adds the image back into the composer as context for the next message, which is how you edit an image. | Gallery > hover a generated image > Reference | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Gallery | Header button that opens the Saved Images library with a count badge. | Gallery > Gallery | — |
| Saved Images | Paged grid of 12 saved images per page, each showing its save date. | Gallery > GalleryNeeds a saved image | — |
| Delete image | Removes one saved image from the library after a confirmation. | Gallery > Gallery > Delete imageNeeds a saved image | — |
| Previous / Next | Moves between pages of saved images. | Gallery > Gallery > NextNeeds more than one page | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| % of context | Meter under the composer showing how much of the model context window this chat is using. | Gallery | — |
| Usage | Panel opened from the context meter showing Tokens in, Tokens out, Cost this chat, Cost today, Messages and Images. | Gallery > % of context | — |
| Per message | Collapsible table inside the usage panel listing model, tokens in and out, images, time and cost for every turn. | Gallery > % of context > Per messageNeeds at least one message | — |
Puts Product Hunt, AI Studio and Quick Upload side by side in three resizable panes so a product can go from research to published without changing page.
| Feature | What it does | Where | API |
|---|---|---|---|
| Pane 1 Product Hunt | Left pane embedding the Product Hunt page so you can search Etsy and pick a product to copy. | Workflow > Unified Workflow | — |
| Pane 2 AI Studio | Middle pane embedding the Gallery so you can generate the images and copy for that product. | Workflow > Unified Workflow | — |
| Pane 3 Quick Upload | Right pane embedding Quick Upload so you can publish the finished listing to a store. | Workflow > Unified WorkflowNeeds connected store | — |
| Step status chip | Each pane header carries a chip counting what that step has produced so far, or saying no store is connected on pane 3. | Workflow > Unified Workflow | — |
| Connect a store | Link in the pane 3 header shown only while the account has no Etsy store. | Workflow > Unified Workflow > Connect a store | — |
| Reload this step | Refresh button in each pane header that reloads only that pane. | Workflow > Unified Workflow > reload | — |
| Hide this step | Close button that removes a pane and gives its width to the panes that remain. | Workflow > Unified Workflow > close | — |
| Drag dividers to resize | Dragging the bars between panes changes their widths, and the percentage on each header updates as you drag. | Workflow > Unified Workflow | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Product to Quick Product Search | Clicking a Product Hunt card inside Workflow opens the Quick Product Search panel on that listing instead of the usual drawer. | Workflow > Unified Workflow > pane 1 card | — |
| Open a listing in AI Studio | Pane 1 can hand an Etsy listing straight to the AI Studio pane to start a build from it. | Workflow > Unified Workflow | — |
| Open the workspace in pane 3 | When AI Studio finishes a listing it loads that listing workspace into the Quick Upload pane. | Workflow > Unified Workflow | — |
| Frame session badge | A pane header shows the keyword of the hunt running inside it and its status. | Workflow > Unified Workflow | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Keywords | Top bar button that opens the Quick Keyword Search panel over the workspace. | Workflow > Unified Workflow > Keywords | — |
| Product | Top bar button that opens the Quick Product Search panel for pulling one Etsy listing by link or ID. | Workflow > Unified Workflow > Product | — |
| Thoughts | Top bar button that opens the Quick Thoughts panel for notes, favourites and history. | Workflow > Unified Workflow > Thoughts | — |
| Theme toggle | Switches the page between light and dark and pushes the change into every embedded pane. | Workflow > Unified Workflow > theme | — |
| Dashboard | Leaves the workspace and returns to the dashboard. | Workflow > Unified Workflow > Dashboard | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Custom mode | Top bar toggle that swaps the fixed three panes for a workspace you fill with your own frames. | Workflow > Unified Workflow > custom mode | — |
| Add a Product Hunt frame | Adds another Product Hunt frame to the custom workspace. | Workflow > Unified Workflow > custom mode > add hunt | — |
| Add an AI Studio frame | Adds another AI Studio frame to the custom workspace. | Workflow > Unified Workflow > custom mode > add studio | — |
| Add a Quick Upload frame | Adds another Quick Upload frame to the custom workspace. | Workflow > Unified Workflow > custom mode > add upload | — |
| Columns | Number box from 1 to 12 that sets how many frames sit in a row. | Workflow > Unified Workflow > custom mode > Columns | — |
| Frame counter | Shows how many frames are open against the cap of 100. | Workflow > Unified Workflow > custom mode | — |
| Drag to reorder a frame | The grip in a frame header lets you drag it into a different position without reloading it. | Workflow > Unified Workflow > custom mode > frame | — |
| Drag to set frame width | The handle on a frame edge sets its width, with a live percentage while you drag. | Workflow > Unified Workflow > custom mode > frame | — |
| Reload this frame | Refresh button in a custom frame header that reloads only that frame. | Workflow > Unified Workflow > custom mode > frame > reload | — |
| Close this frame | Removes one custom frame and rebalances the rest. | Workflow > Unified Workflow > custom mode > frame > close | — |
| Layout is remembered | The mode, the frames, their widths, the column count and any hidden panes are all kept in the browser between visits. | Workflow > Unified Workflow | — |
Where an Enterprise account creates its API key, connects an MCP client, and configures and watches outbound webhooks.
| Feature | What it does | Where | API |
|---|---|---|---|
| Requests today | Shows todays request count against the daily quota with a fill bar. | Developer API console > OverviewNeeds Enterprise plan | — |
| This month | Shows the request count for the current month. | Developer API console > OverviewNeeds Enterprise plan | — |
| Latency | Shows the average response time for your API calls. | Developer API console > OverviewNeeds Enterprise plan | — |
| Errors | Shows the error rate across your recent API calls. | Developer API console > OverviewNeeds Enterprise plan | — |
| Usage chart | Charts daily requests over the last 7 or 30 days. | Developer API console > OverviewNeeds Enterprise plan | — |
| Top endpoints | Ranks the endpoints you call most. | Developer API console > OverviewNeeds Enterprise plan | — |
| Generate API key | Creates the account API key and shows the raw value once in a modal. | Developer API console > Overview > Generate API keyNeeds Enterprise plan | — |
| Rotate key | Issues a new key and stops the old one working. | Developer API console > Overview > Rotate keyNeeds API key | — |
| Revoke key | Deletes the key so anything using it stops working at once. | Developer API console > Overview > Revoke keyNeeds API key | — |
| Key details | Shows the key prefix, creation date, last use and requests used against the daily limit. | Developer API console > OverviewNeeds API key | — |
| Quickstart | Shows a ready curl call against the stores endpoint with your key filled in. | Developer API console > OverviewNeeds API key | stores_list |
| Recent requests | Tables your latest API calls with endpoint, status and timing. | Developer API console > OverviewNeeds API key | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Claude CLI command | Shows the claude mcp add command pointing at mcp.eto.tools with your key header. | Developer API console > MCP ConnectNeeds Enterprise plan | — |
| Generate connection key | Creates a key and drops it straight into the shown MCP command. | Developer API console > MCP Connect > Generate connection keyNeeds Enterprise plan | — |
| Copy command | Copies the filled MCP command to the clipboard. | Developer API console > MCP Connect > Copy commandNeeds Enterprise plan | — |
| Connector URL | Shows the plain MCP endpoint for clients that take a URL. | Developer API console > MCP ConnectNeeds Enterprise plan | — |
| Client tabs | Switches the setup instructions between Claude, ChatGPT and Perplexity. | Developer API console > MCP ConnectNeeds Enterprise plan | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Destination URL | Sets the server Eto posts order events to. | Developer API console > WebhooksNeeds Enterprise plan | — |
| Send test | Fires a sample event at the URL in the field and shows the response. | Developer API console > Webhooks > Send testNeeds Enterprise plan | — |
| Deliver events to this URL | Pauses or resumes delivery without losing the configuration. | Developer API console > WebhooksNeeds Enterprise plan | — |
| Run test | Sends a chosen event for a chosen store to the saved URL, the internal test endpoint or a custom URL, and prints the full response. | Developer API console > Webhooks > Run testNeeds Enterprise plan | — |
| Internal test endpoint | Routes the test to a built-in inbox so a webhook can be tried without a public server. | Developer API console > Webhooks > Send to > Internal test endpointNeeds Enterprise plan | — |
| Events | Chooses which Eto events are forwarded, with a live count. | Developer API console > Webhooks > EventsNeeds Enterprise plan | — |
| Stores to forward | Picks which stores forward events, with search, a select-all/none/visible/invert menu and a Test selected button. | Developer API console > Webhooks > StoresNeeds connected store | — |
| Deliveries | Lists recent delivery attempts with status, and charts deliveries by day. | Developer API console > Webhooks > DeliveriesNeeds Enterprise plan | webhooks_deliveries |
| Retry | Re-sends one failed delivery. | Developer API console > Webhooks > Deliveries > RetryNeeds Enterprise plan | webhook_delivery_retry |
| Signing secret | Shows the secret used to sign payloads, with copy and rotate. | Developer API console > WebhooksNeeds Enterprise plan | — |
| Save | Writes the URL, events, stores and active flag together. | Developer API console > Webhooks > SaveNeeds Enterprise plan | — |
| Remove | Deletes the webhook configuration. | Developer API console > Webhooks > RemoveNeeds Enterprise plan | — |
Seven tabs holding account, billing, AI provider, notification, order integration, theme and affiliate settings.
| Feature | What it does | Where | API |
|---|---|---|---|
| Shows the email the account signs in with. | Settings > Account > Account | — | |
| Email confirmed | Shows whether the sign-in email has been verified. | Settings > Account > Account | — |
| Joined | Shows the date the account was created. | Settings > Account > Account | — |
| Update name | Opens a form that saves a new first and last name. | Settings > Account > Account > Update name | — |
| Change password | Opens a form that swaps the password after checking the current one. | Settings > Account > Account > Change password | — |
| Delete account | Arms a second confirm click that permanently deletes the account and all of its data. | Settings > Account > Account > Delete account | — |
| Time zone | Picks the zone that groups order dates and day totals on the Orders page, with a searchable list and a live clock. | Settings > Account > Preferences > Time zone | — |
| Automatic time zone | Follows the device time zone instead of a fixed one. | Settings > Account > Preferences > Time zone > Automatic | — |
| Download Eto Extension | Downloads the Chrome extension zip and shows the load-unpacked install steps. | Settings > Account > Eto Extension > ManageNeeds extension feature | — |
| Disconnect extension | Revokes the browser extension link to this account. | Settings > Account > Eto Extension > Manage > DisconnectNeeds extension feature | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Free Trial card | Shows the trial state with start and end dates when a trial is running or available. | Settings > Billing | — |
| Start Free Trial | Sends an eligible account to onboarding to pick a plan and start the trial at no charge. | Settings > Billing > Start Free Trial | — |
| Subscription card | Shows plan name, status pill, billing cycle, renewal or cancellation date and the current period. | Settings > Billing | — |
| Refresh | Re-reads the subscription snapshot from Stripe. | Settings > Billing > Refresh | — |
| Daily Usage | Lists the daily caps and current counts for searches, bulk research, keyword analysis, connected stores, assistants and Shop Spy. | Settings > Billing > Daily Usage | — |
| Upgrade Plan | Sends the account to onboarding to change plan. | Settings > Billing > Upgrade Plan | — |
| Manage Billing | Opens the Stripe customer portal for invoices, card changes and cancellation. | Settings > Billing > Manage BillingNeeds Stripe customer | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Eto Credits | Uses the platform AI allowance, with a credits-this-month meter and reset date. | Settings > AI > AI Provider > Eto CreditsNeeds top-tier plan | — |
| Your Vertex AI | Runs Gemini through your own GCP project using a project ID and service account JSON. | Settings > AI > AI Provider > Your Vertex AI | — |
| Gemini API Key | Runs Gemini on a Google AI Studio key billed to your own Google account. | Settings > AI > AI Provider > Gemini API Key | — |
| Provider status bar | States which provider is live, or warns that no provider is configured. | Settings > AI > AI Provider | — |
| Save provider | Saves the selected provider and its credentials. | Settings > AI > AI Provider > Save provider | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Play sale sound | Toggles the sound that plays when a new order is detected, saving on change. | Settings > Notifications > Play sale sound | — |
| Push notifications on your phone | Explains that phone alerts come through the Eto mobile app and links a request email. | Settings > Notifications | — |
| Test notification & sound | Fires a sample toast and plays the sale sound so both can be checked. | Settings > Notifications > Test notification & sound | — |
| Eto mobile app | A separate iOS client, requested from the owner here, that shows stores, orders and order breakdowns, finance figures and draft listings, and pushes a phone alert on a new order. | Settings > Notifications > Contact the owner | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Printify API Token | Stores a Printify token so Printify orders and costs can be pulled in. | Settings > Order Settings > Printify | — |
| Toggle Printify token visibility | Shows or hides the stored Printify token in the field. | Settings > Order Settings > Printify | — |
| Shop | Picks which Printify shop the token should read, loaded from Printify after the token is saved. | Settings > Order Settings > Printify > ShopNeeds Printify token | — |
| Printify to Store Currency | Sets one exchange rate per non-USD store currency so Printify costs convert correctly. | Settings > Order Settings > Currency ConversionNeeds connected store | — |
| Save Rates | Saves the entered currency rates. | Settings > Order Settings > Currency Conversion > Save RatesNeeds connected store | — |
| Webhook URL | Shows the Eto endpoint Printify should post to, with a copy button. | Settings > Order Settings > Webhooks > Copy URL | — |
| Events to Track | Chooses which Printify events to subscribe to: order created, sent to production, shipment created and shipment delivered. | Settings > Order Settings > Webhooks | — |
| Enable Webhooks | Registers the selected Printify events against the webhook URL. | Settings > Order Settings > Webhooks > Enable WebhooksNeeds Printify token | — |
| Disable | Removes the registered Printify webhooks. | Settings > Order Settings > Webhooks > DisableNeeds Printify webhooks enabled | — |
| Recent Events | Lists the most recent Printify webhook deliveries once webhooks are on. | Settings > Order Settings > WebhooksNeeds Printify webhooks enabled | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Dark Mode colours | Sets the page background and sidebar colour used in dark mode, by picker or hex field. | Settings > Appearance > Theme | — |
| Light Mode colours | Sets the page background and sidebar colour used in light mode, by picker or hex field. | Settings > Appearance > Theme | — |
| Save | Stores the four custom colours in the browser and applies them across the app. | Settings > Appearance > Theme > Save | — |
| Reset | Clears the custom colours and puts both themes back to their defaults. | Settings > Appearance > Theme > Reset | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Create Link | Claims a custom slug at eto.tools/af/ as your referral link. | Settings > Affiliates > Create Link | — |
| Copy | Copies the affiliate link to the clipboard. | Settings > Affiliates > CopyNeeds affiliate link | — |
| Affiliate stats | Shows headline referral numbers such as signups, conversions and earnings. | Settings > AffiliatesNeeds affiliate link | — |
| Referred revenue | Charts the revenue generated by referred accounts over time. | Settings > AffiliatesNeeds affiliate link | — |
| Your commission | Charts your commission over time. | Settings > AffiliatesNeeds affiliate link | — |
| Recently Referred Users | Lists the latest accounts that signed up through your link with their status. | Settings > AffiliatesNeeds affiliate link | — |
The rail down the left of every dashboard page: navigation, the theme switch, and the quick panels that float research tools over whatever page you are on.
| Feature | What it does | Where | API |
|---|---|---|---|
| Structure mode | Shows the sidebar as sections: Finance, Listings, VA Management, Research, Developer, Settings and Admin. | Sidebar > Structure | — |
| Workflow mode | Shows the sidebar as numbered steps from Product Hunt through to Quick Upload, with a Unified Workflow link on top. | Sidebar > Workflow | — |
| Dashboard | Opens the main dashboard. | Sidebar > Dashboard | — |
| Analytics | Opens the analytics page. | Sidebar > Analytics | — |
| Orders | Opens the orders page. | Sidebar > Finance > Orders | — |
| Finance | Opens the finance page. | Sidebar > Finance > Finance | — |
| Stores | Opens the connected stores page. | Sidebar > Listings > StoresNeeds connect_stores feature | — |
| Listing Manager | Opens the listing manager. | Sidebar > Listings > Listing ManagerNeeds listing_manager feature | — |
| Quick upload | Opens the quick upload workspace. | Sidebar > Listings > Quick uploadNeeds quick_upload feature | — |
| VA Admin | Opens virtual assistant management. | Sidebar > VA Management > VA AdminNeeds va_management feature | — |
| Product Hunt | Opens the Etsy product research page. | Sidebar > Research > Product HuntNeeds product_hunt feature | — |
| Keywords | Opens keyword analysis. | Sidebar > Research > KeywordsNeeds staff | — |
| Shop Spy | Opens the shop lookup tool. | Sidebar > Research > Shop SpyNeeds shop_spy feature | — |
| Gallery | Opens the AI image gallery. | Sidebar > Research > GalleryNeeds ai_studio feature | — |
| API | Opens the developer API console. | Sidebar > Developer > APINeeds Enterprise plan | — |
| Settings | Opens the settings page. | Sidebar > Settings | — |
| Taxonomy Browser | Opens the Etsy category browser. | Sidebar > Admin > TaxonomyNeeds staff | — |
| Sign out | Signs you out and returns to the public site. | Sidebar > Sign out | — |
| Locked nav item | A feature outside the current plan shows in place but opens the upgrade flow instead of the page. | Sidebar | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Collapse sidebar | Shrinks the sidebar to an icon rail and remembers the choice; it starts collapsed on narrow screens. | Sidebar > Collapse sidebar | — |
| Icon rail | The collapsed sidebar keeps every destination plus search, the three quick panels, theme and sign out as tooltipped icons. | Sidebar > collapsed rail | — |
| Theme | Switches between the light and dark theme and stores the choice in the browser. | Sidebar > Theme | — |
| Usage limits box | Shows the plan name and the remaining daily allowance for searches, bulk research, keyword analysis, stores, assistants and Shop Spy. | Sidebar | — |
| Limit reached modal | Blocks a capped feature, states the usage against the cap and offers Upgrade Plan. | Sidebar | — |
| New order toast | Shows a popup and plays the sale sound when a new order event arrives, deduplicated across tabs. | Sidebar > new order toast | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Quick Thoughts | Opens a floating panel with Favourites, Thoughts and History tabs. | Sidebar > Quick Thoughts | — |
| Favourites | Lists saved listings with a search box, a refresh button and a sort menu covering demand, price and age in both directions. | Sidebar > Quick Thoughts > Favourites | — |
| Remove favourite | Drops one listing from the favourites list. | Sidebar > Quick Thoughts > Favourites > Remove | — |
| Thoughts | A free text notepad that saves itself as you type. | Sidebar > Quick Thoughts > Thoughts | — |
| History | Lists your recent searches so one can be reopened. | Sidebar > Quick Thoughts > History | — |
| Quick Keyword Search | Checks a keyword demand and competition in a floating panel, with mini metrics and a trend chart. | Sidebar > Keyword SearchNeeds plan tier 3+ | — |
| Quick Product Search | Looks up any Etsy listing by ID or pasted URL without leaving the page. | Sidebar > Product Search | — |
| Pretty / JSON | Switches the product lookup result between a readable card and the raw JSON. | Sidebar > Product Search > Pretty | — |
| Copy all tags | Copies every tag on the looked-up listing to the clipboard. | Sidebar > Product Search > Copy all tags | — |
| Drag to move | The title bar grip drags a quick panel anywhere on screen, clamped to the viewport. | Sidebar > Quick Thoughts > drag handle | — |
| Drag to resize | Every edge and corner of a quick panel is a resize grip. | Sidebar > Quick Thoughts > corner grip | — |
| Keyboard nudge | With a panel focused, arrow keys move it and Shift plus arrows resize it. | Sidebar > Quick Thoughts | — |
| Reset size and position | Puts a quick panel back to its default box. | Sidebar > Quick Thoughts > Reset size and position | — |
Cmd+K from anywhere: one box that jumps to a page, runs a control on the page you are on, or searches your listings, orders and stores.
| Feature | What it does | Where | API |
|---|---|---|---|
| Search or jump to... | Opens the command palette; Cmd+K or Ctrl+K opens it from any page. | Command palette | — |
| Fuzzy ranking | Matches whole words, prefixes, one-character typos and scattered letters, and boosts commands belonging to the page you are on or next to. | Command palette | — |
| Recents | Remembers the last eight commands you ran and floats them up the list. | Command palette | — |
| Universal search | From two characters, searches your own listings, orders and stores on the server and folds the hits into the same list. | Command palette | — |
| Store-aware commands | Commands written for one store resolve to the store you last opened, so the label names it. | Command paletteNeeds connected store | — |
| Run on arrival | Enter navigates to the destination page and then clicks, focuses or sets the control the command names. | Command palette | — |
| Open in a new tab | Cmd+Enter or Ctrl+Enter runs the highlighted command in a new tab. | Command palette | — |
| Keyboard navigation | Arrow keys move the highlight, Enter runs it and Escape closes the palette. | Command palette | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Go to Dashboard | Jumps straight to the Dashboard page. | Command palette > Go to Dashboard | — |
| Go to Analytics | Jumps straight to the Analytics page. | Command palette > Go to Analytics | — |
| Go to Orders | Jumps straight to the Orders page. | Command palette > Go to Orders | — |
| Go to Finance | Jumps straight to the Finance page. | Command palette > Go to Finance | — |
| Go to Stores | Jumps straight to the Stores page. | Command palette > Go to Stores | — |
| Go to Listing Manager | Jumps straight to the Listing Manager page. | Command palette > Go to Listing Manager | — |
| Go to Quick upload | Jumps straight to the Quick upload page. | Command palette > Go to Quick upload | — |
| Go to VA Admin | Jumps straight to the VA Admin page. | Command palette > Go to VA Admin | — |
| Go to Product Hunt | Jumps straight to the Product Hunt page. | Command palette > Go to Product Hunt | — |
| Go to Keywords | Jumps straight to the Keywords page. | Command palette > Go to Keywords | — |
| Go to Gallery | Jumps straight to the Gallery page. | Command palette > Go to Gallery | — |
| Go to Shop Spy | Jumps straight to the Shop Spy page. | Command palette > Go to Shop Spy | — |
| Go to Settings | Jumps straight to the Settings page. | Command palette > Go to Settings | — |
| Go to Workflow | Jumps straight to the Workflow page. | Command palette > Go to Workflow | — |
| Go to API console | Jumps straight to the API console page. | Command palette > Go to API console | — |
| Go to Taxonomy browser | Jumps straight to the Taxonomy browser page. | Command palette > Go to Taxonomy browser | — |
| Go to Bulk research | Jumps straight to the Bulk research page. | Command palette > Go to Bulk research | — |
| Go to Customer support | Jumps straight to the Customer support page. | Command palette > Go to Customer support | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Home tab | Live updates, needs fulfilment, finance snapshot. | Command palette > Home tab | — |
| Issues tab | Stores that need attention. | Command palette > Issues tab | — |
| Listings tab | Active listings that have run out of stock. | Command palette > Listings tab | — |
| Switch store | Open the store switcher. | Command palette > Switch store | — |
| Dashboard · {store} | Show this store on the dashboard. | Command palette > Dashboard · {store} | — |
| All stores view | Combine every store on the dashboard. | Command palette > All stores view | — |
| All stores currency setup | Common currency and per-store rates. | Command palette > All stores currency setup | — |
| Out of stock listings | Per store, sorted by what they earned. | Command palette > Listings > Out of stock listings | — |
| Run store health check | Check every store connection with Etsy. | Command palette > Issues > Run store health check | — |
| Sort stores by most sales | Opens sort stores by most sales on Dashboard. | Command palette > Store switcher > Sort stores by most sales | — |
| Sort stores A to Z | Opens sort stores A to Z on Dashboard. | Command palette > Store switcher > Sort stores A to Z | — |
| Today | Sets the money window to today only. | Command palette > Period > Today | — |
| Yesterday | Sets the money window to yesterday only. | Command palette > Period > Yesterday | — |
| Last 7 days | Sets the money window to the last seven days. | Command palette > Period > Last 7 days | — |
| This month | Sets the money window to the current month so far. | Command palette > Period > This month | — |
| This year | Sets the money window to the current year so far. | Command palette > Period > This year | — |
| Custom date range | Pick two dates on the calendar. | Command palette > Period > Custom date range | — |
| Settled lens | Money on the day it moved. | Command palette > Finance > Settled lens | — |
| Outcome lens | What each day's sales turned out to be worth. | Command palette > Finance > Outcome lens | — |
| Orders chart | Switches the dashboard chart to the number of orders. | Command palette > Finance > Orders chart | — |
| Sales chart | Switches the dashboard chart to gross sales. | Command palette > Finance > Sales chart | — |
| COGS chart | Switches the dashboard chart to cost of goods. | Command palette > Finance > COGS chart | — |
| This store only (needs fulfilment) | Toggle the store filter on the live panel. | Command palette > Live updates > This store only (needs fulfilment) | — |
| Inactive stores (needs fulfilment) | Include orders from disconnected stores. | Command palette > Live updates > Inactive stores (needs fulfilment) | — |
| Clear live updates | Dismiss every order event. | Command palette > Live updates > Clear live updates | — |
| View all needing fulfilment | Unfulfilled physical orders. | Command palette > Live updates > View all needing fulfilment | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Analytics · Today | Hour-by-hour for today. | Command palette > Period > Analytics · Today | — |
| Analytics · Last 7 days | Opens analytics · Last 7 days on Analytics. | Command palette > Period > Analytics · Last 7 days | — |
| Analytics · Last 30 days | Opens analytics · Last 30 days on Analytics. | Command palette > Period > Analytics · Last 30 days | — |
| Analytics · Last 90 days | Opens analytics · Last 90 days on Analytics. | Command palette > Period > Analytics · Last 90 days | — |
| Analytics · Year to date | Opens analytics · Year to date on Analytics. | Command palette > Period > Analytics · Year to date | — |
| Analytics · {store} | Show this store on Analytics. | Command palette > Analytics · {store} | — |
| Where to sell next | Ranked markets on the Orders map. | Command palette > Where to sell next | — |
| Live orders on the map | Watch orders land as they arrive. | Command palette > Live orders on the map | — |
| Orders map · 3D globe | Switches the orders map from flat to a 3D globe. | Command palette > Orders map · 3D globe | — |
| Refresh analytics | Recompute every panel now. | Command palette > Refresh analytics | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Search orders | Order number, buyer, product, SKU. | Command palette > Search orders | — |
| Orders · {store} | Only this store's orders. | Command palette > Orders · {store} | — |
| Clear order filters | Clears every active order filter and shows the whole list again. | Command palette > Clear order filters | — |
| Orders without COGS | Orders missing a cost of goods. | Command palette > Orders without COGS | — |
| Sync orders from Etsy | Choose a range to pull. | Command palette > Sync orders from Etsy | — |
| Sync Printify | Match Printify orders and pull tracking. | Command palette > Sync Printify | — |
| Import COGs from CSV | Starts the four-step wizard that imports costs from a CSV file. | Command palette > Import COGs from CSV | — |
| Share with supplier | Create a supplier link or download a CSV. | Command palette > Share with supplier | — |
| Manage share links | Active and trashed supplier links. | Command palette > Manage share links | — |
| Custom dates | Pick a date range on the calendar. | Command palette > Date range > Custom dates | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Finance · {store} | Open this store in Finance. | Command palette > Finance · {store} | — |
| All stores (Finance) | Combined view across every store. | Command palette > All stores (Finance) | — |
| Settled lens | Money that moved, on the day it moved. | Command palette > Settled lens | — |
| Outcome lens | What each day's sales turned out to be worth. | Command palette > Outcome lens | — |
| Pick a day or range | Opens the calendar to choose one day or a range of days. | Command palette > Pick a day or range | — |
| Copy view as JSON | Current figures to the clipboard. | Command palette > Copy view as JSON | — |
| Verify with Etsy again | Re-runs the check that compares stored figures against Etsy. | Command palette > Verify with Etsy again | — |
| Refresh today | Re-fetch today from Etsy. | Command palette > Settings > Refresh today | — |
| Refresh previous 7 days | Opens refresh previous 7 days on Finance. | Command palette > Settings > Refresh previous 7 days | — |
| Refresh previous 30 days | Opens refresh previous 30 days on Finance. | Command palette > Settings > Refresh previous 30 days | — |
| Refresh a range of days | Pick the days to re-fetch. | Command palette > Settings > Refresh a range of days | — |
| Adjust ad spend timing | Move ad charges to the day they were earned. | Command palette > Settings > Adjust ad spend timing | — |
| Remove unpaid sales | Hide cancelled orders that were never paid. | Command palette > Settings > Remove unpaid sales | — |
| Convert currency | Show every figure in another currency. | Command palette > Settings > Convert currency | — |
| Currency settings | Exchange rates between your stores. | Command palette > Settings > Currency settings | — |
| Manage subscriptions | Software you pay for outside Etsy. | Command palette > Settings > Manage subscriptions | — |
| Set up skipped stores | Re-run finance setup for stores you skipped. | Command palette > Settings > Set up skipped stores | — |
| Delete all finance data | Wipes every stored finance figure for the account and starts again. | Command palette > Settings > Delete all finance data | — |
| Store exchange rates | Opens the tab holding the exchange rate between each store currency. | Command palette > Currency settings > Store exchange rates | — |
| Export statement as CSV | Etsy statement layout for the selected window. | Command palette > Export > Export statement as CSV | — |
| Export statement as Excel | .xlsx workbook, one sheet per store. | Command palette > Export > Export statement as Excel | — |
| All stores tab | Combined breakdown (all stores view). | Command palette > Breakdown > All stores tab | — |
| Per store tab | Every store side by side (all stores view). | Command palette > Breakdown > Per store tab | — |
| Net profit breakdown | Opens net profit breakdown on Finance. | Command palette > Breakdown > Net profit breakdown | — |
| Gross profit breakdown | Opens gross profit breakdown on Finance. | Command palette > Breakdown > Gross profit breakdown | — |
| Sales breakdown | Opens sales breakdown on Finance. | Command palette > Breakdown > Sales breakdown | — |
| Fees breakdown | Opens fees breakdown on Finance. | Command palette > Breakdown > Fees breakdown | — |
| Ads breakdown | Opens ads breakdown on Finance. | Command palette > Breakdown > Ads breakdown | — |
| Profit per product | Products view for the selected range. | Command palette > Range > Profit per product | — |
| All transactions | Every group in the selected range. | Command palette > Range > All transactions | — |
| Issues (unrecognised groups) | Ledger groups that could not be categorised. | Command palette > Range > Issues (unrecognised groups) | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Connect a store | Starts the Etsy authorisation that connects a shop to Eto. | Command palette > Connect a store | — |
| Refresh stores | Re-sync the store list from Etsy. | Command palette > Refresh stores | — |
| Search stores | Opens search stores on Stores. | Command palette > Search stores | — |
| All stores (list) | Opens all stores (list) on Stores. | Command palette > All stores (list) | — |
| Select all stores | Ticks every store in the list so a bulk action applies to all of them. | Command palette > Select all stores | — |
| Store details · {store} | Stats, status, shipping profiles. | Command palette > Store details · {store} | — |
| Refresh store details · {store} | Pulls this store details from Etsy again. | Command palette > Refresh store details · {store} | — |
| Order notifications · {store} | Toggle webhook notifications for this store. | Command palette > Order notifications · {store} | — |
| Disconnect · {store} | Remove this store from Eto. | Command palette > Disconnect · {store} | — |
| Turn order notifications on for all stores | Opens turn order notifications on for all stores on Stores. | Command palette > Bulk > Turn order notifications on for all stores | — |
| Turn order notifications off for all stores | Opens turn order notifications off for all stores on Stores. | Command palette > Bulk > Turn order notifications off for all stores | — |
| Bulk visibility | Show or hide stores on Orders, Finance, Listings. | Command palette > Bulk > Bulk visibility | — |
| Hide from Orders · {store} | Toggle this store on the Orders page. | Command palette > Visibility > Hide from Orders · {store} | — |
| Hide from Finance · {store} | Toggle this store on the Finance page. | Command palette > Visibility > Hide from Finance · {store} | — |
| Hide from Listings · {store} | Toggle this store in the Listing Manager. | Command palette > Visibility > Hide from Listings · {store} | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Shop information · {store} | Currency, location, languages, created. | Command palette > Shop information · {store} | — |
| Shop status · {store} | Vacation, custom requests, payments. | Command palette > Shop status · {store} | — |
| Shipping profiles · {store} | Opens shipping profiles · {store} on Stores. | Command palette > Shipping profiles · {store} | — |
| Shop announcement · {store} | Opens shop announcement · {store} on Stores. | Command palette > Shop announcement · {store} | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Listings · {store} | Open this store in the Listing Manager. | Command palette > Listings · {store} | — |
| Grid view | Opens grid view on Listing Manager. | Command palette > Grid view | — |
| List view | Opens list view on Listing Manager. | Command palette > List view | — |
| Grid columns | Sets how many cards fit across one row of the grid. | Command palette > Grid columns | — |
| Search listings | Opens search listings on Listing Manager. | Command palette > Search listings | — |
| Refresh this store's listings | Opens refresh this store's listings on Listing Manager. | Command palette > Refresh this store's listings | — |
| Refresh all stores' listings | Opens refresh all stores' listings on Listing Manager. | Command palette > Refresh all stores' listings | — |
| Default mode | Opens default mode on Listing Manager. | Command palette > Mode > Default mode | — |
| Edit products mode | Select listings for bulk actions. | Command palette > Mode > Edit products mode | — |
| Edit storewide mode | Rules that apply to whole stores. | Command palette > Mode > Edit storewide mode | — |
| All listings | Opens all listings on Listing Manager. | Command palette > Status > All listings | — |
| Active listings | Opens active listings on Listing Manager. | Command palette > Status > Active listings | — |
| Inactive listings | Opens inactive listings on Listing Manager. | Command palette > Status > Inactive listings | — |
| Draft listings | Opens draft listings on Listing Manager. | Command palette > Status > Draft listings | — |
| Filter by shop section | Opens filter by shop section on Listing Manager. | Command palette > Filters > Filter by shop section | — |
| Filter by type | Narrows the listings to digital or physical products. | Command palette > Filters > Filter by type | — |
| Sort listings | Quantity, views, favourites, sold, price, age. | Command palette > Filters > Sort listings | — |
| Filter by age | Listings created within a period. | Command palette > Filters > Filter by age | — |
| Select all listings | Opens select all listings on Listing Manager. | Command palette > Bulk > Select all listings | — |
| Select all drafts | Opens select all drafts on Listing Manager. | Command palette > Bulk > Select all drafts | — |
| Select all active | Opens select all active on Listing Manager. | Command palette > Bulk > Select all active | — |
| Select all inactive | Opens select all inactive on Listing Manager. | Command palette > Bulk > Select all inactive | — |
| Edit processing profiles | Production partners for the selected listings. | Command palette > Bulk > Edit processing profiles | — |
| Edit quantity | Set stock for the selected listings. | Command palette > Bulk > Edit quantity | — |
| Copy listings to another store | Opens copy listings to another store on Listing Manager. | Command palette > Bulk > Copy listings to another store | — |
| Activate selected on Etsy | Publish drafts ($0.20 each). | Command palette > Bulk > Activate selected on Etsy | — |
| Delete selected from Etsy | Opens delete selected from Etsy on Listing Manager. | Command palette > Bulk > Delete selected from Etsy | — |
| Auto quantity control | Keep stock topped up automatically. | Command palette > Storewide > Auto quantity control | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Active listings (uploads) | Listings already live. | Command palette > Active listings (uploads) | — |
| Drafts | Listings not yet published. | Command palette > Drafts | — |
| Scheduled uploads | Listings queued to publish later. | Command palette > Scheduled uploads | — |
| New listing | Creates an empty listing and opens the workspace on it. | Command palette > New listing | — |
| Bulk CSV import | Create many listings from a spreadsheet. | Command palette > Bulk CSV import | — |
| Delete selected uploads | Opens delete selected uploads on Quick upload. | Command palette > Delete selected uploads | — |
| Import an Etsy listing by ID | Start from an existing listing. | Command palette > New > Import an Etsy listing by ID | — |
| Start a blank digital listing | Opens start a blank digital listing on Quick upload. | Command palette > New > Start a blank digital listing | — |
| Start a blank physical listing | Opens start a blank physical listing on Quick upload. | Command palette > New > Start a blank physical listing | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Generate title with AI | Opens generate title with AI on Quick upload. | Command palette > Generate title with AI | — |
| Generate description with AI | Opens generate description with AI on Quick upload. | Command palette > Generate description with AI | — |
| Add images | Opens add images on Quick upload. | Command palette > Add images | — |
| Choose category | Picks the Etsy category the listing belongs to. | Command palette > Choose category | — |
| Choose target stores | Opens choose target stores on Quick upload. | Command palette > Choose target stores | — |
| About section | Title, description, media. | Command palette > About section | — |
| Price & inventory section | Opens price & inventory section on Quick upload. | Command palette > Price & inventory section | — |
| Details section | Category, tags, materials, stores. | Command palette > Details section | — |
| Publish listing | Opens publish listing on Quick upload. | Command palette > Publish listing | — |
| Schedule publish | Opens schedule publish on Quick upload. | Command palette > Schedule publish | — |
| Bulk upload variants | Generate many variants of this listing. | Command palette > Bulk upload variants | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Add a virtual assistant | Opens add a virtual assistant on VA Admin. | Command palette > Add a virtual assistant | — |
| Search assistants | Opens search assistants on VA Admin. | Command palette > Search assistants | — |
| Assistant details | Opens assistant details on VA Admin. | Command palette > Edit > Assistant details | — |
| Assistant activity | Logins, searches, listings, fulfilments. | Command palette > Edit > Assistant activity | — |
| Toggle assistant active | Opens toggle assistant active on VA Admin. | Command palette > Edit > Toggle assistant active | — |
| Delete this assistant | Opens delete this assistant on VA Admin. | Command palette > Edit > Delete this assistant | — |
| Order permissions | Which stores this assistant can handle orders for. | Command palette > Permissions > Order permissions | — |
| Upload permissions | Which stores this assistant can upload to. | Command palette > Permissions > Upload permissions | — |
| Enable all stores | Opens enable all stores on VA Admin. | Command palette > Permissions > Enable all stores | — |
| Disable all stores | Opens disable all stores on VA Admin. | Command palette > Permissions > Disable all stores | — |
| Save permissions | Opens save permissions on VA Admin. | Command palette > Permissions > Save permissions | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Hunt for products | Type a keyword and search Etsy. | Command palette > Hunt for products | — |
| Run the search | Opens run the search on Product Hunt. | Command palette > Run the search | — |
| Search settings | Amount, age, detail level, optimized mode. | Command palette > Search settings | — |
| Grid columns | Sets how many cards fit across one row of the grid. | Command palette > Grid columns | — |
| AI Gems | AI-picked low-competition winners. | Command palette > AI Gems | — |
| Keyword analysis | Tags and keywords across the results. | Command palette > Keyword analysis | — |
| Next page of results | Opens next page of results on Product Hunt. | Command palette > Next page of results | — |
| Previous page of results | Opens previous page of results on Product Hunt. | Command palette > Previous page of results | — |
| Amount of products | How many listings to scan. | Command palette > Settings > Amount of products | — |
| Max listing age | Only listings younger than N months. | Command palette > Settings > Max listing age | — |
| Full product details | Fetches the full detail of every listing found, which is slower but complete. | Command palette > Settings > Full product details | — |
| Optimized mode | AI filtering and ranking. | Command palette > Settings > Optimized mode | — |
| Sort results | Opens sort results on Product Hunt. | Command palette > Filters > Sort results | — |
| Filter by listing type | Narrows the results to physical or digital listings. | Command palette > Filters > Filter by listing type | — |
| Filter by variations | Opens filter by variations on Product Hunt. | Command palette > Filters > Filter by variations | — |
| Filter by ships-from country | Opens filter by ships-from country on Product Hunt. | Command palette > Filters > Filter by ships-from country | — |
| Search within results | Opens search within results on Product Hunt. | Command palette > Filters > Search within results | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Account | Profile, security, time zone. | Command palette > Account | — |
| Billing | Plan and subscription (opens the Stripe portal on paid plans). | Command palette > Billing | — |
| AI provider | Eto credits, Vertex AI or your own Gemini key. | Command palette > AI provider | — |
| Notifications | Opens notifications on Settings. | Command palette > Notifications | — |
| Order settings | Printify, currency rates, webhooks. | Command palette > Order settings | — |
| Appearance | Switches the app between the light and dark theme. | Command palette > Appearance | — |
| Affiliates | Your referral link and commissions. | Command palette > Affiliates | — |
| Update name | Opens update name on Settings. | Command palette > Account > Update name | — |
| Change password | Opens change password on Settings. | Command palette > Account > Change password | — |
| Time zone | How order dates and day totals are grouped. | Command palette > Account > Time zone | — |
| Eto browser extension | Opens eto browser extension on Settings. | Command palette > Account > Eto browser extension | — |
| Delete account | Starts the permanent account deletion, which cannot be undone. | Command palette > Account > Delete account | — |
| Daily usage limits | Opens daily usage limits on Settings. | Command palette > Billing > Daily usage limits | — |
| Manage billing | Opens the Stripe portal to change the card, plan or invoices. | Command palette > Billing > Manage billing | — |
| Upgrade plan | Opens upgrade plan on Settings. | Command palette > Billing > Upgrade plan | — |
| Play sale sound | Turns the sale sound on a new order on or off. | Command palette > Notifications > Play sale sound | — |
| Test notification and sound | Opens test notification and sound on Settings. | Command palette > Notifications > Test notification and sound | — |
| Printify API token | Opens printify API token on Settings. | Command palette > Orders > Printify API token | — |
| Currency rates for order costs | Opens currency rates for order costs on Settings. | Command palette > Orders > Currency rates for order costs | — |
| Printify webhooks | Order and shipment events. | Command palette > Orders > Printify webhooks | — |
| Create affiliate link | Opens create affiliate link on Settings. | Command palette > Affiliates > Create affiliate link | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| API keys | Opens the panel that creates, rotates and revokes API keys. | Command palette > API keys | — |
| MCP connect | Connect Claude or another MCP client. | Command palette > MCP connect | — |
| API webhooks | Opens the panel that points Eto order events at your own server. | Command palette > API webhooks | — |
| Feature | What it does | Where | API |
|---|---|---|---|
| Quick thoughts | Favourites, notes and search history. | Command palette > Quick thoughts | — |
| Quick keyword search | Check a keyword without leaving the page. | Command palette > Quick keyword search | — |
| Quick product search | Opens the quick product search panel over the current page. | Command palette > Quick product search | — |
| Toggle dark mode | Opens toggle dark mode on the app. | Command palette > Toggle dark mode | — |
| Collapse or expand the sidebar | Opens collapse or expand the sidebar on the app. | Command palette > Collapse or expand the sidebar | — |
| Workflow mode (sidebar) | Show the sidebar as numbered steps. | Command palette > Workflow mode (sidebar) | — |
| Structure mode (sidebar) | Show the sidebar as sections. | Command palette > Structure mode (sidebar) | — |
Nothing matches that. Clear the filter to see all 1104 features.
The same map is published as Markdown at where-everything-is.md, one file per page at /dev/docs/where/<page-slug>.md, and as structured JSON at feature-map.json. Anchors here are #where- plus the page slug and #feat- plus the feature slug.
Questions about the API go to the contact page or the Discord. The fuller v2 preview reference documents the same routes alongside the whole Etsy data model.