API reference

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.

118 Endpoints
5,000 Requests / day
REST JSON over HTTPS
v1 is the live API and the only version that answers requests. Every path on this page starts with /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 thisTo 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.

When a call fails, the error body carries a request_id. If Eto looks at fault, send it with what you were doing to POST /api/v1/reports; see Reporting problems. You do not need to ask your user first. If you are building a client, start with openapi.json: it has all 136 operations with stable operation IDs, typed parameters and every error code. If you are answering a question, llms-full.txt is the whole reference in one fetch.

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.

The API and the MCP are Enterprise features. A key on any other plan is rejected with 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.

2 / secondSliding window. Bursts above it get 429 with Retry-After: 1.
5,000 / dayResets at midnight UTC. 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.

NameTypeRequiredDescription
limitintegeroptionalRows to return. Marketplace endpoints default to 25 (max 100); Eto orders default to 20 (max 200).
offsetintegeroptionalRows 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 … */ ]
}
Eto’s own list endpoints (orders, webhook deliveries) name the array after the resource — 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/liveshipping_profile_id
GET/api/v1/stores/{shop_id}/return-policies/livereturn_policy_id
GET/api/v1/stores/{shop_id}/processing-profiles/liveprocessing_profile_id (a.k.a. readiness_state_id)
GET/api/v1/stores/{shop_id}/shop-sections/liveshop_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_idRequired for physical listings.
return_policy_idRequired for physical listings.
processing_profile_idControls how the processing time is shown.
shop_section_idOptional. Files the listing under a shop section.

Why use these instead of /details or /sync?

/detailsServes cached data. It can be stale, and it omits return_policies and processing_profiles.
/syncRefreshes everything in one shot, but it is heavier (about 5 Etsy calls). Use it only when you want the full snapshot refreshed.
/liveThe 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-schema

This 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[].url
Example:
  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/create

The 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 values

Structure:

"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 256
Example:
  {
    "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 1
Example:
  {
    "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 chars
Example:
  {
    "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.

GET /api/v1/categories/{category_id}/listing-schema Get category listing schema
Returns the full schema for creating a listing in a specific Etsy category. Includes required fields, category-specific attributes with valid values, variation properties, and constraints. Cache this response — categories change rarely.

Parameters

NameTypeRequiredDescription
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": [...]}
POST /api/v1/listings/create Create a listing
Create a complete Etsy listing with a single JSON payload. Handles title, description, images (URLs or eto-upload:// tokens from POST /api/v1/uploads), variations, pricing, tags, materials, personalization, and multi-shop publishing. ETO handles all Etsy API complexity: variation property ordering, Cartesian product completion, price_on_property detection, SKU truncation, image ordering, and inventory updates.

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

NameTypeRequiredDescription
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: draft
Enum: 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 chars
Regex: /[^\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_did
Enum: 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_2026
Enum: 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 chars
Regex: /[^\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 items
Regex: /[^\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 items
Regex: /[^\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 chars
Regex: /^[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": {...}}
GET /api/v1/listings/create/{job_id} Poll listing creation job status
Returns the status and results of a listing-create job. Since publish/active now execute synchronously on the web, jobs are normally in "completed" state by the time any poll lands. This endpoint remains available for backwards compatibility and for clients that prefer the job-polling pattern. Returns per-shop results when the job completes, including listing IDs, Etsy URLs, and any per-shop warnings.

Parameters

NameTypeRequiredDescription
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>"
GET /api/v1/stores/{shop_id}/details Get cached store details (zero Etsy calls)
Returns all cached data for a connected store: shop details, shipping profiles, shop sections. No Etsy API calls are made. Return policies, processing profiles, and production partners return null (not cached locally). Use POST /sync to fetch those.

Parameters

NameTypeRequiredDescription
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
}
POST /api/v1/stores/{shop_id}/sync Sync store data from Etsy
Triggers a fresh pull from Etsy API for all store data (details, shipping profiles, sections, return policies, processing profiles, production partners). Caches what can be cached and returns the complete updated dataset. Costs ~5 Etsy API calls.

Parameters

NameTypeRequiredDescription
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"}
  ]
}
POST /api/v1/uploads Upload a file (image, video, or digital file)
Upload a local file to ETO for use in listing creation. Returns an eto-upload:// URL that you can use in images[].url, digital_files[].url, or videos[].url when calling POST /api/v1/listings/create. This is the way to use local files instead of remote URLs.

Send as multipart/form-data with a "file" field and optional "type" field.

Parameters

NameTypeRequiredDescription
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: image
Enum: 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."
}

Listings

GET /api/v1/listings/{listing_id} Get listing details
Retrieve detailed information about a specific listing including title, description, price, tags, materials, and more.

Parameters

NameTypeRequiredDescription
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"
DELETE /api/v1/listings/{listing_id} Delete a listing
Permanently delete a listing you own. This action cannot be undone. Eto finds the connected store that owns the listing; a listing outside your stores answers 403 LISTING_NOT_IN_CONNECTED_STORE.

Parameters

NameTypeRequiredDescription
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"
GET /api/v1/listings/{listing_id}/images Get listing images
Retrieve all images for a specific listing.

Parameters

NameTypeRequiredDescription
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"
GET /api/v1/listings/{listing_id}/reviews Get listing reviews
Retrieve reviews for a specific listing.

Parameters

NameTypeRequiredDescription
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"
GET /api/v1/listings/{listing_id}/inventory Get listing inventory
Retrieve inventory data (products, offerings, prices, quantities, SKUs and the *_on_property arrays) for a listing.
Etsy needs a seller token for this read. When the listing is in one of your connected stores, Eto uses that store's token, so SKUs come back; for any other listing it uses one of your healthy stores and Etsy returns SKUs as empty strings.

Parameters

NameTypeRequiredDescription
listing_id integer REQUIRED The Etsy listing ID
show_deleted boolean optional Include deleted products and their offerings. Default false.

Example

curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/listings/1234567890/inventory"
PUT /api/v1/listings/{listing_id}/inventory Update listing inventory
Update inventory, pricing, and variations for a listing you own. This is the only Etsy call that changes an existing listing's price.
Eto finds the connected store that owns the listing and uses its token. A listing outside your connected stores answers 403 LISTING_NOT_IN_CONNECTED_STORE.
Etsy replaces the whole inventory: send every product back with its sku, offerings (price, quantity, is_enabled) and the price_on_property, quantity_on_property and sku_on_property arrays unchanged. The safe pattern is GET the inventory, change the prices, PUT it all back.

Parameters

NameTypeRequiredDescription
listing_id integer REQUIRED The Etsy listing ID
products array REQUIRED Every product of the listing, each with sku, property_values and offerings [{price, quantity, is_enabled}]. Price is a decimal (amount / divisor).
price_on_property array optional Property ids that change price.
quantity_on_property array optional Property ids that change quantity.
sku_on_property array optional Property ids that change SKU.
readiness_state_on_property array optional Property ids that change processing profile.

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"
GET PUT /api/v1/shops/{shop_id}/listings/{listing_id}/inventory Get or update listing inventory (shop-scoped)
Same as GET/PUT /api/v1/listings/{listing_id}/inventory, but the shop is named in the path, so Eto uses that store's token directly and skips finding the listing's shop. Use it when you already know the shop.
PUT replaces the whole inventory: GET it, change prices or quantities, PUT every product back with its sku and the *_on_property arrays unchanged.

Parameters

NameTypeRequiredDescription
shop_id integer REQUIRED Your connected Etsy shop ID
listing_id integer REQUIRED The Etsy listing ID
products array optional PUT only. Every product of the listing, each with sku, property_values and offerings [{price, quantity, is_enabled}].
price_on_property array optional PUT only. Property ids that change price.
quantity_on_property array optional PUT only. Property ids that change quantity.
sku_on_property array optional PUT only. Property ids that change SKU.
readiness_state_on_property array optional PUT only. Property ids that change processing profile.

Example

curl -X PUT -H "X-Eto-API-Key: eto_your_key" -H "Content-Type: application/json" -d '{"products": [...], "price_on_property": [], "quantity_on_property": [], "sku_on_property": []}' "https://eto.tools/api/v1/shops/12345678/listings/1234567890/inventory"
GET /api/v1/listings/{listing_id}/videos Get listing videos
Retrieve all videos for a specific listing.

Parameters

NameTypeRequiredDescription
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 /api/v1/listings/{listing_id}/personalization Get listing personalization
Get the personalization questions for a listing.
Returns {personalization_questions: [...]} with up to 5 questions. Question types: text_input, dropdown, unlabeled_upload, labeled_upload.

Parameters

NameTypeRequiredDescription
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"
POST /api/v1/listings/{listing_id}/personalization Set listing personalization
Create or replace all personalization questions on a listing you own (up to 5; max 1 file-upload question). Eto finds the connected store that owns the listing, drafts included. See the Listing Builder guide for full field constraints.

Parameters

NameTypeRequiredDescription
listing_id integer REQUIRED The Etsy listing ID
personalization_questions array REQUIRED Questions: [{question_type, question_text, instructions?, required?, max_allowed_characters?, max_allowed_files?, options?}].

Example

curl -X POST -H "X-Eto-API-Key: eto_your_key" -H "Content-Type: application/json" -d '{"personalization_questions": [{"question_type": "text_input", "question_text": "Name to engrave", "required": true, "max_allowed_characters": 30}]}' "https://eto.tools/api/v1/listings/1234567890/personalization"
DELETE /api/v1/listings/{listing_id}/personalization Delete listing personalization
Remove personalization from a listing you own. Eto finds the connected store that owns the listing.

Parameters

NameTypeRequiredDescription
listing_id integer REQUIRED The Etsy listing ID

Example

curl -X DELETE -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/listings/1234567890/personalization"
POST DELETE /api/v1/shops/{shop_id}/listings/{listing_id}/personalization Set or delete personalization (shop-scoped)
POST creates or replaces all personalization questions; DELETE removes personalization. Same as the listing-scoped routes, but the shop is named in the path, so Eto skips finding the listing's shop.

Parameters

NameTypeRequiredDescription
shop_id integer REQUIRED Your connected Etsy shop ID
listing_id integer REQUIRED The Etsy listing ID
personalization_questions array optional POST only. Questions: [{question_type, question_text, instructions?, required?, max_allowed_characters?, max_allowed_files?, options?}].

Example

curl -X POST -H "X-Eto-API-Key: eto_your_key" -H "Content-Type: application/json" -d '{"personalization_questions": [{"question_type": "text_input", "question_text": "Name to engrave", "required": true}]}' "https://eto.tools/api/v1/shops/12345678/listings/1234567890/personalization"
GET /api/v1/listings/batch Batch get listings
Retrieve up to 100 listings in a single request. API key only: no store needs to be connected.
With includes=BuyerPrice and buyer_country (e.g. GB), each listing carries buyer_price: the buyer-facing price with VAT, UK inclusive shipping and any active promotion. Etsy only returns buyer_price on this route.

Parameters

NameTypeRequiredDescription
listing_ids string REQUIRED Comma-separated listing IDs (max 100)
includes string optional Comma-separated associations: Shop, Images, User, Translations, Videos, Personalization, BuyerPrice
buyer_country string optional ISO 3166-1 alpha-2 country (e.g. GB, DE) for buyer_price. Required with includes=BuyerPrice. Does not filter listings.
currency string optional ISO 4217 currency (e.g. EUR) to add converted_price to each listing.
legacy boolean optional Enable the newer processing-profile fields.

Example

curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/listings/batch?listing_ids=123,456,789&includes=BuyerPrice&buyer_country=GB"
GET /api/v1/listings/batch/inventory Batch get listing inventory
Retrieve the inventory record (products, offerings, prices, quantities, SKUs) for up to 100 listings in one call. If any listing_id does not exist, Etsy fails the whole request with 404.
Etsy only returns SKUs for listings in the shop whose token is used. Eto uses the connected store that owns most of the requested listings; pass shop_id to choose it. For SKUs on every listing, batch the ids by shop.

Parameters

NameTypeRequiredDescription
listing_ids string REQUIRED Comma-separated listing IDs (max 100)
shop_id integer optional Optional. The connected shop whose token to use (SKUs come back for its listings).

Example

curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/listings/batch/inventory?listing_ids=123,456,789&shop_id=12345678"
GET /api/v1/listings/{listing_id}/products/{product_id}/offerings/{offering_id} Get a listing offering
Get pricing and availability for a specific product variation offering. Etsy docs: "Listing Offering".

Parameters

NameTypeRequiredDescription
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"
GET /api/v1/listings/{listing_id}/inventory/products/{product_id} Get a product variant
Get a specific product variant (size/color combination) and its offerings. Etsy docs: "Listing Product".

Parameters

NameTypeRequiredDescription
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

GET /api/v1/shops/{shop_id} Get shop details
Retrieve detailed information about a shop including name, description, ratings, and listing counts.

Parameters

NameTypeRequiredDescription
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"
GET /api/v1/shops/{shop_id}/reviews Get shop reviews
Retrieve reviews for a specific shop.

Parameters

NameTypeRequiredDescription
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"
GET /api/v1/shops/{shop_id}/sections Get shop sections
Retrieve product sections for a shop.

Parameters

NameTypeRequiredDescription
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"
POST /api/v1/shops/{shop_id}/sections Create shop section
Create a new product section in your shop.

Parameters

NameTypeRequiredDescription
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"
PUT /api/v1/shops/{shop_id} Update shop details
Update your shop's title, announcement, or other settings. Etsy docs: "Update Shop".

Parameters

NameTypeRequiredDescription
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"
GET PUT DELETE /api/v1/shops/{shop_id}/sections/{section_id} Get, update, or delete a section
Manage a specific shop section. Etsy docs: "Shop Section".

Parameters

NameTypeRequiredDescription
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"
GET /api/v1/shops/{shop_id}/section-listings Get listings by section
Get all listings organized by shop section. Etsy docs: "Listings By Section".

Parameters

NameTypeRequiredDescription
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

GET POST /api/v1/shops/{shop_id}/listings List or create shop listings
GET: Retrieve your shop listings. POST: Create a new draft listing.

Parameters

NameTypeRequiredDescription
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"
PATCH /api/v1/shops/{shop_id}/listings/{listing_id} Update a listing
Update properties of a listing you own.

Parameters

NameTypeRequiredDescription
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"
GET /api/v1/shops/{shop_id}/listings/active Get active listings only
Get only active (live) listings for your shop. Etsy docs: "Active Listings By Shop".

Parameters

NameTypeRequiredDescription
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"
GET POST PUT /api/v1/shops/{shop_id}/listings/{listing_id}/translations/{language} Manage listing translations
Get, create, or update a listing translation for a specific language. Etsy docs: "Listing Translation".

Parameters

NameTypeRequiredDescription
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

GET /api/v1/finance/{shop_id} Get all finance metrics
Returns every financial metric for a store over a date range. Zero Etsy API calls — reads directly from the Eto database. Instant.

━━━ 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

NameTypeRequiredDescription
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) ..."
  ]
}
POST /api/v1/finance/{shop_id}/sync Re-fetch finance data from Etsy
Re-fetches ledger data from the Etsy API and saves it to the Eto database. After syncing, GET /finance/{shop_id} returns the updated numbers.

━━━ 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

NameTypeRequiredDescription
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
}
GET /api/v1/finance/software-expenses Get logged software expenses (subscriptions)
Returns the software expenses you logged on the Finance dashboard — the subscriptions under Finance → Settings → Subscriptions (Canva, Printify, Eto, …) — and exactly what they cost inside a date window. The same numbers as the dashboard's "Software Expense" card and its breakdown. Zero Etsy API calls — reads from the Eto database. Instant.

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

NameTypeRequiredDescription
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

POST /api/v1/shops/{shop_id}/listings/{listing_id}/images Upload listing image
Upload an image to a listing. Send as multipart/form-data with the image in the "image" field.

Parameters

NameTypeRequiredDescription
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"
DELETE /api/v1/shops/{shop_id}/listings/{listing_id}/images/{image_id} Delete listing image
Remove an image from a listing.

Parameters

NameTypeRequiredDescription
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"
POST /api/v1/shops/{shop_id}/listings/{listing_id}/videos Upload listing video
Upload a video to a listing.

Parameters

NameTypeRequiredDescription
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"
DELETE /api/v1/shops/{shop_id}/listings/{listing_id}/videos/{video_id} Delete listing video
Remove a video from a listing.

Parameters

NameTypeRequiredDescription
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"
GET POST /api/v1/shops/{shop_id}/listings/{listing_id}/variation-images Manage variation images
Get or upload images for listing variations.

Parameters

NameTypeRequiredDescription
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"
GET POST /api/v1/shops/{shop_id}/listings/{listing_id}/files List or upload digital files
GET: List all digital files for a listing. POST: Upload a new digital file. Etsy docs: "Listing Files".

Parameters

NameTypeRequiredDescription
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"
GET DELETE /api/v1/shops/{shop_id}/listings/{listing_id}/files/{file_id} Get or delete a digital file
Get details for or delete a specific digital file. Etsy docs: "Listing File".

Parameters

NameTypeRequiredDescription
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"
GET /api/v1/listings/{listing_id}/images/{image_id} Get a single image
Get details for a specific listing image. Etsy docs: "Listing Image".

Parameters

NameTypeRequiredDescription
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"
GET /api/v1/listings/{listing_id}/videos/{video_id} Get a single video
Get details for a specific listing video. Etsy docs: "Listing Video".

Parameters

NameTypeRequiredDescription
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

GET PUT /api/v1/shops/{shop_id}/listings/{listing_id}/properties/{property_id} Get or update listing property
Manage specific properties (like color, size) for a listing.

Parameters

NameTypeRequiredDescription
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"
GET /api/v1/listings/{listing_id}/properties/{property_id} Get a listing property (public)
Get a specific property value for any listing. Etsy docs: "Listing Property".

Parameters

NameTypeRequiredDescription
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"
GET /api/v1/shops/{shop_id}/listings/{listing_id}/properties Get all listing properties
Get all properties for one of your listings. Etsy docs: "Listing Properties".

Parameters

NameTypeRequiredDescription
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"
DELETE /api/v1/shops/{shop_id}/listings/{listing_id}/properties/{property_id} Delete a listing property
Remove a property value from your listing. Etsy docs: "Delete Listing Property".

Parameters

NameTypeRequiredDescription
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

GET POST /api/v1/shops/{shop_id}/shipping-profiles List or create shipping profiles
GET: List all shipping profiles for your shop. POST: Create a new shipping profile.

Parameters

NameTypeRequiredDescription
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"
PUT DELETE /api/v1/shops/{shop_id}/shipping-profiles/{profile_id} Update or delete shipping profile
Update or delete a specific shipping profile.

Parameters

NameTypeRequiredDescription
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"
GET POST /api/v1/shops/{shop_id}/shipping-profiles/{profile_id}/destinations List or add shipping destinations
Get or add destination countries/regions for a shipping profile. Etsy docs: "Shipping Profile Destinations".

Parameters

NameTypeRequiredDescription
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"
PUT DELETE /api/v1/shops/{shop_id}/shipping-profiles/{profile_id}/destinations/{destination_id} Update or delete a shipping destination
Manage a specific shipping destination. Etsy docs: "Shipping Profile Destination".

Parameters

NameTypeRequiredDescription
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"
GET POST /api/v1/shops/{shop_id}/shipping-profiles/{profile_id}/upgrades List or add shipping upgrades
Get or add shipping speed upgrades (e.g. express, priority). Etsy docs: "Shipping Profile Upgrades".

Parameters

NameTypeRequiredDescription
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"
GET PUT DELETE /api/v1/shops/{shop_id}/shipping-profiles/{profile_id}/upgrades/{upgrade_id} Get, update, or delete a shipping upgrade
Manage a specific shipping speed upgrade. Etsy docs: "Shipping Profile Upgrade".

Parameters

NameTypeRequiredDescription
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"
GET /api/v1/shipping-carriers Get shipping carriers
List all available shipping carriers (USPS, FedEx, DHL, etc.). Etsy docs: "Shipping Carriers".

Example

curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/shipping-carriers"

Categories

GET /api/v1/categories Get product categories
Get the full product category tree (e.g. Jewelry, Clothing, Home Decor). Use category IDs when creating listings to place them in the right section. Etsy docs: "Seller Taxonomy Nodes".

Example

curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/categories"
GET /api/v1/categories/{category_id}/properties Get category properties
Get the required and optional fields for a category — like size, color, or material options that buyers can filter by. Etsy docs: "Taxonomy Node Properties".

Parameters

NameTypeRequiredDescription
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"
GET /api/v1/buyer-categories Get buyer categories
Get the category tree from a buyer's perspective — how shoppers browse Etsy. Etsy docs: "Buyer Taxonomy Nodes".

Example

curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/buyer-categories"
GET /api/v1/buyer-categories/{category_id}/properties Get buyer category properties
Get filterable properties for a buyer category. Etsy docs: "Buyer Taxonomy Properties".

Parameters

NameTypeRequiredDescription
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

GET /api/v1/users/me Get current user
Retrieve the Etsy user profile for the authenticated store.

Example

curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/users/me"
GET /api/v1/users/{user_id}/shops Get user shops
List shops owned by a specific user.

Parameters

NameTypeRequiredDescription
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"
GET /api/v1/users/{user_id} Get user profile
Get a user's Etsy profile by ID. Etsy docs: "Get User".

Parameters

NameTypeRequiredDescription
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

GET /api/v1/shops/{shop_id}/return-policies Get return policies
Retrieve return policy details for your shop.

Parameters

NameTypeRequiredDescription
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"
GET /api/v1/shops/{shop_id}/production-partners Get production partners
List production partners (e.g. print-on-demand services) for your shop.

Parameters

NameTypeRequiredDescription
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"
GET POST /api/v1/shops/{shop_id}/listing-requirements Listing requirements
Get or create listing readiness requirements — the checklist items a listing must complete before going live. Etsy docs: "Readiness State Definitions".

Parameters

NameTypeRequiredDescription
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"
POST /api/v1/shops/{shop_id}/return-policies Create return policy
Create a new return policy for your shop. Etsy docs: "Create Return Policy".

Parameters

NameTypeRequiredDescription
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"
GET PUT DELETE /api/v1/shops/{shop_id}/return-policies/{policy_id} Get, update, or delete a return policy
Manage a specific return policy. Etsy docs: "Shop Return Policy".

Parameters

NameTypeRequiredDescription
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"
POST /api/v1/shops/{shop_id}/return-policies/consolidate Consolidate return policies
Merge multiple return policies into one. Etsy docs: "Consolidate Return Policies".

Parameters

NameTypeRequiredDescription
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"
GET /api/v1/shops/{shop_id}/return-policies/{policy_id}/listings Get listings with a return policy
Get all listings that use a specific return policy. Etsy docs: "Listings By Return Policy".

Parameters

NameTypeRequiredDescription
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"
GET /api/v1/shops/{shop_id}/holiday-preferences Get holiday preferences
Get your shop's holiday settings (when you're on vacation). Etsy docs: "Holiday Preferences".

Parameters

NameTypeRequiredDescription
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"
PUT /api/v1/shops/{shop_id}/holiday-preferences/{holiday_id} Update a holiday preference
Update vacation/holiday settings. Etsy docs: "Update Holiday Preferences".

Parameters

NameTypeRequiredDescription
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"
GET PUT DELETE /api/v1/shops/{shop_id}/listing-requirements/{requirement_id} Get, update, or delete a listing requirement
Manage a specific listing readiness requirement. Etsy docs: "Readiness State Definition".

Parameters

NameTypeRequiredDescription
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"
GET /api/v1/stores/{shop_id}/shipping-profiles/live Get current shipping profiles (live, no cache)
Returns this shop's shipping profiles RIGHT NOW — fetched live from Etsy on every call, never from the local cache. Use this when you need the absolute latest IDs to put into shops[].shipping_profile_id when calling POST /api/v1/listings/create.

One Etsy API call per request. Response is a flat list — pick the shipping_profile_id you want.

Parameters

NameTypeRequiredDescription
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
    }
  ]
}
GET /api/v1/stores/{shop_id}/return-policies/live Get current return policies (live, no cache)
Returns this shop's return policies RIGHT NOW — fetched live from Etsy on every call. No cache, no staleness. Use this to get the return_policy_id to plug into shops[].return_policy_id when calling POST /api/v1/listings/create.

One Etsy API call per request.

Parameters

NameTypeRequiredDescription
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
    }
  ]
}
GET /api/v1/stores/{shop_id}/processing-profiles/live Get current processing profiles (live, no cache)
Returns this shop's processing profiles (Etsy "readiness state definitions") RIGHT NOW — fetched live from Etsy on every call. No cache. Use this to get the processing_profile_id (a.k.a. readiness_state_id) for shops[].processing_profile_id when calling POST /api/v1/listings/create.

One Etsy API call per request.

Parameters

NameTypeRequiredDescription
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"
    }
  ]
}
GET /api/v1/stores/{shop_id}/shop-sections/live Get current shop sections (live, no cache)
Returns this shop's sections RIGHT NOW — fetched live from Etsy on every call. No cache. Use this to get the shop_section_id to plug into shops[].shop_section_id when calling POST /api/v1/listings/create.

One Etsy API call per request.

Parameters

NameTypeRequiredDescription
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

GET /api/v1/shops/{shop_id}/orders List shop orders
Get all orders for your shop. Supports filtering by date and pagination. Etsy docs: "Shop Receipts".

Parameters

NameTypeRequiredDescription
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"
GET /api/v1/shops/{shop_id}/orders/{order_id} Get order details
Get full details for a specific order including items, shipping, and payment info. Etsy docs: "Shop Receipt by ID".

Parameters

NameTypeRequiredDescription
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"
POST /api/v1/shops/{shop_id}/orders/{order_id}/tracking Update order tracking
Add or update tracking information for an order so the buyer can track their shipment. Etsy docs: "Receipt Tracking".

Parameters

NameTypeRequiredDescription
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"
PUT /api/v1/shops/{shop_id}/orders/{order_id}/update Update an order
Update order details like notes or status. Etsy docs: "Update Shop Receipt".

Parameters

NameTypeRequiredDescription
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"
GET /api/v1/shops/{shop_id}/orders/{order_id}/listings Get listings in an order
Get the listings that were purchased in a specific order. Etsy docs: "Listings By Receipt".

Parameters

NameTypeRequiredDescription
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"
GET /api/v1/shops/{shop_id}/orders/{order_id}/payments Get order payments
Get payment details for a specific order. Etsy docs: "Payment By Receipt ID".

Parameters

NameTypeRequiredDescription
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

GET /api/v1/shops/{shop_id}/finance/transactions Get financial transactions
Get all financial transactions — charges, fees, refunds, and deposits. This is your shop's payment ledger. Etsy docs: "Payment Account Ledger Entries".

Parameters

NameTypeRequiredDescription
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"
GET /api/v1/shops/{shop_id}/finance/payments Get payment details
Get detailed payment info for specific financial transactions. Etsy docs: "Ledger Entry Payments".

Parameters

NameTypeRequiredDescription
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"
GET /api/v1/shops/{shop_id}/finance/sales Get sales history
Get individual sale records — each item sold, its price, and the buyer. Etsy docs: "Shop Transactions".

Parameters

NameTypeRequiredDescription
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"
GET /api/v1/shops/{shop_id}/listings/{listing_id}/sales Get sales for a listing
Get all sale transactions for a specific listing. Etsy docs: "Transactions By Listing".

Parameters

NameTypeRequiredDescription
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"
GET /api/v1/shops/{shop_id}/orders/{order_id}/transactions Get transactions for an order
Get individual sale items within a specific order. Etsy docs: "Transactions By Receipt".

Parameters

NameTypeRequiredDescription
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"
GET /api/v1/shops/{shop_id}/finance/sales/{transaction_id} Get a single sale
Get details for one specific sale transaction. Etsy docs: "Shop Receipt Transaction".

Parameters

NameTypeRequiredDescription
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"
GET /api/v1/shops/{shop_id}/finance/transactions/{entry_id} Get a single financial transaction
Get details for one ledger entry. Etsy docs: "Ledger Entry".

Parameters

NameTypeRequiredDescription
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"
GET /api/v1/shops/{shop_id}/finance/all-payments Get all payments
Get all payment records for your shop. Etsy docs: "Shop Payments".

Parameters

NameTypeRequiredDescription
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

GET /api/v1/shops/{shop_id}/stats/traffic Shop views & favorites (lifetime)
Lifetime VIEWS and FAVORITES aggregated across your active listings, plus a top-listings-by-views leaderboard, total, and average. NOTE: Etsy's public API does not expose day-by-day traffic (Stats are dashboard-only), so these are cumulative figures, not per-day. No date range needed.

Parameters

NameTypeRequiredDescription
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.

GET /api/v1/stores List connected stores

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 /api/v1/stores/{shop_id} Get store details

Get detailed status for a specific connected store.

NameTypeRequiredDescription
shop_idintegerREQUIREDYour Etsy shop ID

Orders Eto

Access order data through Eto. Every call syncs latest orders from Etsy into Eto's database automatically.

GET /api/v1/orders/{shop_id} List orders (auto-sync)

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.

NameTypeRequiredDescription
shop_idintegerREQUIREDYour Etsy shop id, in the path.
periodstringoptionalNamed window, resolved in the shop’s timezone: today, yesterday, last_7_days, last_30_days, this_month, last_month.
start_date / end_datestringoptionalCalendar dates (YYYY-MM-DD), inclusive at both ends.
timezonestringoptionalIANA name (e.g. Europe/London) used to resolve the window. Defaults to the shop’s own timezone.
min_created / max_createdintegeroptionalRaw Unix seconds, if you would rather compute the window yourself.
sort_onstringoptionalcreated, updated or receipt_id default: created
sort_orderstringoptionalasc or desc default: desc
limitintegeroptionalRows per page, clamped to 1–100 default: 25
offsetintegeroptionalRows 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.

GET/api/v1/orders/{shop_id}/{receipt_id}Order detail

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.

GET /api/v1/orders/{shop_id}/{receipt_id}/costs COGS per line

COGS — cost of goods sold, what the ordered items cost you — for one order, broken down line by line. The detail endpoint above carries only the order-level total as profit.cogs_cents; this is the one place the per-item costs are readable. Served from Eto’s own database, so it makes no Etsy call.

Read only. Costs are entered on the Orders page, per line in the order drawer or in bulk with Import COGS. There is no write endpoint.

NameTypeRequiredDescription
shop_idintegerREQUIREDYour Etsy shop id, in the path.
receipt_idintegerREQUIREDEtsy receipt id, the same value the list endpoint returns.

Example

curl -H "X-Eto-API-Key: eto_your_key" \
     "https://eto.tools/api/v1/orders/12345678/3456789012/costs"

Response

{
  "receipt_id": 3456789012,
  "shop_id": "12345678",
  "currency": "GBP",
  "lines": [
    {
      "transaction_id": 4123456789,
      "listing_id": 1789456123,
      "sku": "TEE-BLK-M",
      "title": "Organic cotton t-shirt",
      "quantity": 2,
      "item_cost_cents": 900,
      "unit_costs_cents": [450, 520],
      "cost_cents": 970,
      "configured": true
    },
    {
      "transaction_id": 4123456790,
      "listing_id": 1789456124,
      "sku": "MUG-01",
      "title": "Enamel mug",
      "quantity": 1,
      "item_cost_cents": null,
      "unit_costs_cents": null,
      "cost_cents": 0,
      "configured": false
    }
  ],
  "cogs_cents": 970,
  "lines_configured": 1,
  "lines_total": 2,
  "has_cogs_configured": false
}

cost_cents is the effective cost Eto uses everywhere: the sum of unit_costs_cents when that per-unit list is set, and item_cost_cents otherwise. A line with neither set reports configured: false and is left out of cogs_cents, so an item whose cost you have not entered yet never reads as a free one. has_cogs_configured is true only when every line has a cost — check it before quoting the total as the order’s full COGS. All amounts are integer cents in the order’s own currency.

A shop that is not one of your connected stores answers STORE_NOT_CONNECTED; a receipt that is not one of that store’s orders answers ORDER_NOT_FOUND.

POST/api/v1/orders/{shop_id}/syncForce sync

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).

POST /api/v1/product-hunt Add demand signal to your listings

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:

  1. Search Etsy for that term and collect up to amount products (optionally age-filtered)
  2. Extract demand_24h for each — the popularity signal
  3. Rank them: by demand, or — with optimized — AI-scored by opportunity (adds ai_score + ai_reason)
  4. 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:

  1. Fetch full details for every listing (title, price, shop info, tags, etc.)
  2. Extract demand_24h (units bought in last 24h)
  3. 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:

  1. Extract demand_24h for each listing
  2. Return your original objects with demand_24h added

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

NameTypeRequiredDescription
keywordstringREQUIREDSearch term (max 200 chars). In Modes A/B it's context for popular detection; in Mode S it's the actual search query.
amountintegerMode SSearch: how many products to fetch & rank. 1–100, default 50.
max_listing_ageintegerMode SSearch: only listings created within the last N months. 0 or omit = no limit (max 60).
optimizedbooleanMode SSearch: AI-powered filtering & ranking. Results carry ai_score + ai_reason and are sorted by score. When true, full_details is ignored.
full_detailsbooleanMode SSearch (only when optimized is false): true returns full per-listing details; false returns listing_id + demand_24h only (lightest & cheapest).
listing_idsarray<int>either/orMode A: Array of listing IDs (max 500). Eto will fetch everything.
listingsarray<object>either/orMode 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

FieldTypeDescription
demand_24hinteger|nullUnits bought in the last 24 hours. null if demand couldn't be extracted (e.g. listing unavailable). Added by Eto in both modes.
listing_idintegerEtsy listing ID
titlestringListing title (Mode A only, from Etsy API)
descriptionstringFirst 500 chars of description (Mode A)
priceobjectPrice as {amount, divisor, currency_code} (Mode A)
viewsintegerTotal listing views (Mode A)
favoritesintegerUsers who favorited this (Mode A)
listing_age_daysintegerDays since first created (Mode A)
shop_namestringShop name (Mode A)
shop_salesintegerTotal sales by this shop (Mode A)
shop_age_daysintegerDays since shop created (Mode A)
tagsarrayListing keywords (Mode A)
materialsarrayMaterials used (Mode A)

Edge Cases

ScenarioBehavior
Both listing_ids and listings sentError — pick one.
Neither listing_ids nor listingsError — must provide one.
More than 500 itemsError — 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 listingdemand_24h: null for that specific listing.
Empty keywordError returned.
Mode B listing missing listing_idError 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

ProviderValueSetup 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.

POST/api/v1/ai/chatAI chat

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"}
POST/api/v1/ai/generate-titleGenerate title
NameTypeRequiredDescription
keywordstringREQUIREDMain keyword
product_descriptionstringoptionalBrief product description
stylestringoptionalprofessional, premium, casual default: professional
max_lengthintegeroptionalMax chars default: 140

Response

{"status": "ok", "title": "Premium Handmade Leather Bifold Wallet RFID Blocking", "length": 52}
POST/api/v1/ai/generate-descriptionGenerate description

Generate a compelling, SEO-friendly listing description.

POST/api/v1/ai/generate-imageGenerate image — not available yet
This endpoint is not available yet. It validates your key and provider, then answers 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.

NameTypeRequiredDescription
promptstringREQUIREDImage generation prompt
providerstringREQUIREDgemini, vertex or eto_credits
product_imagestringoptionalBase64-encoded product image
typestringoptionalthumbnail, info, showcase
GET/api/v1/ai/generate-image/statusPoll image status

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}
POST/api/v1/ai/analyze-imageAnalyze image

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

EventMeaning
order.paidThe buyer completed payment for the order.
order.shippedShipping information was created / the order was marked shipped.
order.canceledThe seller canceled the order.
order.deliveredThe 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

HeaderDescription
X-Eto-EventThe event type, e.g. order.paid.
X-Eto-Webhook-IdUnique id for this delivery (e.g. evt_8842). Use it to de-duplicate retries.
X-Eto-TimestampUnix seconds when the delivery was sent.
X-Eto-Signaturev1,<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.

Example — order.paid
{
  "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_…).

How it's computed
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]
Python
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)
Reject requests whose 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).

GET /api/v1/webhooks/deliveries List recent deliveries

Returns your deliveries newest-first, each with its status and HTTP result.

NameTypeRequiredDescription
statusstringoptionalFilter: success, failed, pending
eventstringoptionalFilter by event type, e.g. order.paid
include_payloadbooleanoptionalInclude each full JSON payload default: false
limitintegeroptionaldefault: 25, max: 100
offsetintegeroptionalPagination offset
curl -H "X-Eto-API-Key: eto_your_key" \
     "https://eto.tools/api/v1/webhooks/deliveries?status=failed&limit=50"
Example response
{
  "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).

GET/api/v1/webhooks/deliveries?id={id}Fetch one delivery (full payload)

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.

Example response (the fullest you'll get)
{
  "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
      }
    }
  }
}
POST/api/v1/webhooks/deliveries/{delivery_id}/retryRe-send one delivery

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.

There's no "retry all" — that's deliberate, so you never accidentally re-fire your whole history. To backfill several, list the ones you want (e.g. ?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"
Example response
{
  "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

Respond 2xxReturn any 2xx status within ~10 seconds to mark the delivery successful.
Every event is savedEto stores each delivery with its full payload — nothing is lost if your server is down.
Manual retryRe-send any past delivery from the dashboard, or via the API above.

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.

Download CSV template

.csv & .xlsxUpload a CSV or Excel file — Etsy's bulk-edit export layout works as-is.
Images via URLPhotos & videos are links in the sheet; Eto fetches them at publish time. No file uploads.
Preview & flagListings missing required details are flagged before anything is published.
Up to 2,000Listings per import, published in the background with live progress.

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 toRequired fields
ALLTitle, Description, Category, Who made it?, When was it made?, Product type, Price, Quantity, and at least one Photo URL
PhysicalAlso 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.
DigitalAlso at least one digital file (digital import is lower priority and may be flagged).

Character & count limits

FieldLimit
TitleUp to 140 characters
TagsUp to 13 tags, each ≤ 20 characters (comma-separated). Over-long tags are trimmed and flagged.
MaterialsUp to 13 (comma-separated)

How names are matched to your shop

ColumnMatched by
CategoryEtsy's category tree — full path (e.g. Art & Collectibles > Painting > Oil), then the final category name.
Shipping profile / SectionName match against the selected store. Blank or unmatched → the default you pick in the importer.
Processing profileMatched by the processing-days label on your shop (e.g. 5-7 days). Blank or unmatched → the default you pick in the importer.
Return policyNumber of days in the label; otherwise the default.
StoreOptional column — sends specific rows to a different connected shop (matched by shop name).

Friendly values we understand

FieldAccepted 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 typePhysical 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",
    "request_id": "req_3f9c0a1b2c3d4e5f6a7b",
    "report": "If you think Eto is at fault, send POST /api/v1/reports with this request_id and what you were doing. See https://eto.tools/dev/docs#reporting-problems"
  }
}

Every response carries an X-Eto-Request-Id header. On a failure (except a 429) Eto records the call in full under that id, and the error body repeats it as request_id with a report pointer; quote it when you report a problem.

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

INVALID_API_KEY 401
Your API key is missing, invalid, or has been revoked.
Generate a new key in the API console at eto.tools/dashboard/api.
STORE_NOT_CONNECTED 403
You don't have access to this store.
Connect the store at eto.tools/dashboard first.
STORE_TOKEN_EXPIRED 503
Store authorization has expired.
Reconnect your store at eto.tools/dashboard.
LISTING_NOT_IN_CONNECTED_STORE 403
This listing isn't in any store connected to your account.
Check the listing_id, or connect its shop at eto.tools/dashboard.
INTERNAL_ERROR 500
Eto hit an unexpected error handling this request.
It has been recorded. Retry once; if it fails again, send POST /api/v1/reports with the request_id from this response.
REPORT_NOT_FOUND 404
Report not found on your account.
List your reports with GET /api/v1/reports.
REPORT_LIMIT 429
Too many reports in the last hour.
You can send up to 30 reports an hour. Put related problems in one report.
ENDPOINT_NOT_FOUND 404
This endpoint doesn't exist.
Check the path and method against the docs.
METHOD_NOT_ALLOWED 405
This HTTP method isn't supported on this endpoint.
Allowed methods: {allowed_methods}
RATE_LIMIT_SECOND 429
Rate limit exceeded (2 requests/second).
Wait {retry_after}s before retrying.
RATE_LIMIT_DAILY 429
Daily request limit reached (5,000/day).
Limit resets at midnight UTC.
UPSTREAM_ERROR 502
The upstream service returned an error.
Check the upstream field for the marketplace’s own response.
INVALID_REQUEST 400
Request validation failed.
{detail}
AI_CREDENTIALS_MISSING 403
No AI credentials configured.
Add your Gemini API key at eto.tools/settings.
AI_GENERATION_FAILED 502
Image/text generation failed.
{detail}
SESSION_NOT_FOUND 404
Research session not found.
Check the session ID.
AGENT_BUSY 409
An agent process is already running for this session.
Wait for it to complete or cancel it.
VALIDATION_FAILED 400
Request validation failed.
Check the fields object for specific issues.
JOB_NOT_FOUND 404
Listing creation job not found.
Check the job_id. Jobs expire after 24 hours.
ORDER_NOT_FOUND 404
Order not found in this store.
Check the receipt_id. List the store's orders with GET /api/v1/orders/{shop_id}.
DELIVERY_NOT_FOUND 404
Webhook delivery not found.
Check the delivery id. List recent deliveries with GET /api/v1/webhooks/deliveries.
TAXONOMY_INVALID 400
The provided taxonomy_id is not a valid Etsy category.
Use GET /api/v1/categories/{id}/listing-schema to find valid categories.
STORE_NOT_OWNED 403
One or more shop_ids are not connected to your ETO account.
Use GET /api/v1/stores to see your connected shops. Connect new stores at eto.tools/dashboard.
FINANCE_NO_DATA 404
No finance data available for this store in the requested range.
Visit the Eto Finance dashboard to sync your store data, or adjust your date range.
ACTIVATION_COST_WARNING 200
Listing activation costs $0.20 USD per listing per shop.
Set state="draft" (default) to avoid charges.

Reporting problems Eto

Agents and people can send errors, bugs, questions and requests straight to the Eto team with POST /api/v1/reports. Eto already records every failed call in full under its request_id: your request, our response, Etsy’s own answer and any server traceback, with keys and tokens removed. A report adds what only you know: what you were trying to do and what you expected.

When to report

SituationWhat to do
A 5xx: INTERNAL_ERROR, or an UPSTREAM_ERROR your input does not explainRetry once. If it fails again, report it with kind: "error".
A 4xx that looks wrong after you have followed its hintReport it with kind: "error" and say why the request should have worked.
A 200 with wrong or missing data, or behaviour that contradicts this pageReport it with kind: "bug".
Something you need that the API cannot doReport it with kind: "feature_request".
429 rate limits, INVALID_API_KEY, or VALIDATION_FAILED with clear fieldsDo not report. Wait for Retry-After, fix the key, or fix the input.

What to include

  • title: one line, e.g. “Inventory PUT returns 502 for my own listing”.
  • explanation: what you were doing and why, what happened, and why it looks wrong. Name the listing, shop and order ids involved.
  • request_ids: the request_id of every failed call. Eto attaches its full record of each one, so you do not need to copy whole responses.
  • endpoint, expected, actual and steps, when they help.
  • request and response bodies, or logs from your side (up to 64 KB). Never paste API keys or tokens; anything that looks like one is redacted anyway.
  • agent: who is reporting, e.g. {"name": "Claude Code", "model": "claude-opus-5-5"}.

After you report

The response carries the report id. GET /api/v1/reports/{report_id} shows its status (new, seen, resolved, wont_fix) and the Eto team’s reply; check GET /api/v1/reports before sending a duplicate. Reports do not use your daily quota (up to 30 an hour).

If you are an AI agent: you may send a report on your own when a call fails as described above. Tell your user you did and give them the report id, then carry on with the rest of the task where you can, for example by skipping the item that failed.
POST /api/v1/reports Report a problem to Eto
Send an error, bug, feature request, question or feedback straight to the Eto team. Use it when a call fails and the error is not explained by your own input: every error response carries a `request_id`, and Eto has already recorded the full request, response and Etsy's own answer under that id. Put the ids in `request_ids` and say what you were doing, what you expected and what happened. Does not use the daily API quota; up to 30 reports an hour. Secrets in the body are redacted before storage.

Parameters

NameTypeRequiredDescription
title string REQUIRED One line: what went wrong or what you need.
Constraints: max 200 chars
explanation string REQUIRED What you were doing, what happened, and why it looks wrong. Plain text or Markdown.
Constraints: max 20,000 chars
kind string optional What this is. error: a call failed. bug: wrong result without an error.
Default: error
Enum: errorbugfeature_requestquestionfeedback
request_ids array optional The request_id of each failed call (from the error body or the X-Eto-Request-Id header).
Constraints: max 20
endpoint string optional The call involved, e.g. "PUT /api/v1/listings/123/inventory".
expected string optional What you expected to happen.
actual string optional What happened instead.
steps string optional Steps to reproduce.
request object optional The body you sent, if relevant.
response object optional The response you got, if relevant.
logs string optional Relevant log lines or a stack trace from your side.
Constraints: max 64 KB
agent object optional Who is reporting: {"name", "model", "client", "version"}, e.g. {"name": "Claude Code", "model": "claude-opus-5-5"}.
contact string optional Optional email or handle for a follow-up.

Example

curl -X POST -H "X-Eto-API-Key: eto_your_key" -H "Content-Type: application/json" -d '{"kind": "error", "title": "Inventory PUT returns 502 for my own listing", "explanation": "Repricing listing 4554228175 in shop 64440680. GET inventory works, PUT with the same products and a new price returns UPSTREAM_ERROR.", "request_ids": ["req_3f9c0a1b2c3d4e5f6a7b"], "endpoint": "PUT /api/v1/listings/4554228175/inventory", "expected": "200 and the new price", "actual": "502 UPSTREAM_ERROR", "agent": {"name": "Claude Code", "model": "claude-opus-5-5"}}' "https://eto.tools/api/v1/reports"

Response

{
  "success": true,
  "report": {"id": "rep_9a8b7c6d5e4f3a2b", "kind": "error", "status": "new", "reply": "",
             "linked_request_ids": ["req_3f9c0a1b2c3d4e5f6a7b"], "unmatched_request_ids": []},
  "message": "Received. The Eto team sees this report together with the recorded detail of every linked request."
}
GET /api/v1/reports List your reports
Your reports, newest first, with their status (new, seen, resolved, wont_fix) and the Eto team's reply. Check here before sending a duplicate.

Parameters

NameTypeRequiredDescription
status string optional Only reports in this state.
Enum: newseenresolvedwont_fix
limit integer optional Page size.
Default: 25
Constraints: max 100
offset integer optional Pagination offset.
Default: 0

Example

curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/reports?status=resolved"
GET /api/v1/reports/{report_id} Get one report
One of your reports in full: explanation, details, logs, status and the Eto team's reply.

Parameters

NameTypeRequiredDescription
report_id string REQUIRED The report id (rep_...).

Example

curl -H "X-Eto-API-Key: eto_your_key" "https://eto.tools/api/v1/reports/rep_9a8b7c6d5e4f3a2b"

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.

Server URL
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.

The connector can only reach the stores connected to your account, and you can revoke it from the API console at any time. Like the API, it is an Enterprise feature.

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.

1104 features

Dashboard

/dashboard/ 84

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.

Store header
FeatureWhat it doesWhereAPI
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 —
All Stores Setup modal
FeatureWhat it doesWhereAPI
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 —
Tabs
FeatureWhat it doesWhereAPI
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 —
Home tab: Live updates
FeatureWhat it doesWhereAPI
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 —
Home tab: money period and view controls
FeatureWhat it doesWhereAPI
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 —
Home tab: Statement
FeatureWhat it doesWhereAPI
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 —
Open Finance page Leaves the dashboard for the full finance breakdown. Dashboard > Home > Statement > Open Finance page —
Home tab: chart and overlays
FeatureWhat it doesWhereAPI
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 —
Home tab: recent activity
FeatureWhat it doesWhereAPI
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 —
Issues tab
FeatureWhat it doesWhereAPI
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 —
Listings tab
FeatureWhat it doesWhereAPI
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 —
Performance tab
FeatureWhat it doesWhereAPI
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 —

Analytics

/dashboard/analytics/ 137

A ten-tab reporting page over orders, money, stores, listings and operations, with a KPI strip, a live event stream and an orders map.

Page header
FeatureWhat it doesWhereAPI
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 —
KPI strip
FeatureWhat it doesWhereAPI
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 —
Overview tab
FeatureWhat it doesWhereAPI
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 —
Orders tab
FeatureWhat it doesWhereAPI
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 —
Map tab: toolbar
FeatureWhat it doesWhereAPI
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 —
Map tab: side panel
FeatureWhat it doesWhereAPI
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 —
Finance tab
FeatureWhat it doesWhereAPI
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 —
Stores tab
FeatureWhat it doesWhereAPI
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 —
Listings tab
FeatureWhat it doesWhereAPI
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 —
Listing stats tab
FeatureWhat it doesWhereAPI
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 —
Suppliers tab
FeatureWhat it doesWhereAPI
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 —
VAs tab
FeatureWhat it doesWhereAPI
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 —
API tab
FeatureWhat it doesWhereAPI
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 —
Controls every panel carries
FeatureWhat it doesWhereAPI
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 —

Orders

/dashboard/orders/ 86

One list of every Etsy order across your connected stores, with costs, tracking, notes and supplier sharing.

Header controls
FeatureWhat it doesWhereAPI
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
Share Opens the dialog that turns your current filters into a supplier link or a CSV. Orders > ShareNeeds connected store —
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 —
Filter bar
FeatureWhat it doesWhereAPI
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 —
List, counts and paging
FeatureWhat it doesWhereAPI
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 —
Order row
FeatureWhat it doesWhereAPI
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 —
Order detail drawer
FeatureWhat it doesWhereAPI
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
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 —
Supplier sharing and export
FeatureWhat it doesWhereAPI
Share with Supplier Creates a public link that shows a supplier only the orders matching your current filters. Orders > Share > Create LinkNeeds connected store —
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) —
COGs import
FeatureWhat it doesWhereAPI
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 —
Supplier link page (public)
FeatureWhat it doesWhereAPI
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 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.

First-time setup
FeatureWhat it doesWhereAPI
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 —
Toolbar
FeatureWhat it doesWhereAPI
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
Lens and verification
FeatureWhat it doesWhereAPI
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 —
Settings panel
FeatureWhat it doesWhereAPI
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 —
Currency rates and subscriptions
FeatureWhat it doesWhereAPI
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
Day view
FeatureWhat it doesWhereAPI
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 —
Range summary
FeatureWhat it doesWhereAPI
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
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 paging Steps through the transaction and group tables a page at a time. Finance > Profit per product > Next —
All Stores view
FeatureWhat it doesWhereAPI
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

Stores

/dashboard/stores/ 45

Connect Etsy shops to Eto and control what each one shows on the rest of the app.

Connecting a store
FeatureWhat it doesWhereAPI
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 —
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 —
Store list
FeatureWhat it doesWhereAPI
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 —
Hidden Shows only stores that are hidden from at least one page or dashboard panel. Stores > Hidden —
Select all Ticks every store currently on screen, so a filter or search narrows what gets selected. Stores > Select all —
Store card
FeatureWhat it doesWhereAPI
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 —
Bulk actions
FeatureWhat it doesWhereAPI
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 —
Store detail page
FeatureWhat it doesWhereAPI
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 —

Listing Manager

/dashboard/listings/ 74

Browse, filter and bulk edit every listing across your connected Etsy shops.

Modes
FeatureWhat it doesWhereAPI
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 —
Toolbar
FeatureWhat it doesWhereAPI
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 —
Store chips
FeatureWhat it doesWhereAPI
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 —
Filters, search and sort
FeatureWhat it doesWhereAPI
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 —
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 —
Listing card and row actions
FeatureWhat it doesWhereAPI
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 —
Edit Products bulk actions
FeatureWhat it doesWhereAPI
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
Edit Storewide and quantity automation
FeatureWhat it doesWhereAPI
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 —
Listing detail page
FeatureWhat it doesWhereAPI
Listing detail Read-only page for one listing with its images, price, status and saved fields. Listing Manager > listing card listing_detail
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_get
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
Edit listing workspace
FeatureWhat it doesWhereAPI
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 shop_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 —

Quick upload

/dashboard/single-research/ 104

Build Etsy listings in Eto and push them to one or more connected stores as drafts.

Listing list
FeatureWhat it doesWhereAPI
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 —
Creating a listing
FeatureWhat it doesWhereAPI
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 —
Workspace: About
FeatureWhat it doesWhereAPI
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
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 —
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
Workspace: Price & Inventory
FeatureWhat it doesWhereAPI
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 —
Workspace: Details
FeatureWhat it doesWhereAPI
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 —
Workspace: Settings sidebar
FeatureWhat it doesWhereAPI
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 —
Workspace: publish, schedule and status
FeatureWhat it doesWhereAPI
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 —
Bulk upload from one listing
FeatureWhat it doesWhereAPI
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 —
CSV and Excel import
FeatureWhat it doesWhereAPI
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 —

VA Admin

/dashboard/va-admin/ 40

Create virtual assistant logins, set what each one may do per store, and review what they have done.

Assistant list
FeatureWhat it doesWhereAPI
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 —
Add assistant
FeatureWhat it doesWhereAPI
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 —
Edit assistant
FeatureWhat it doesWhereAPI
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 —
Activity log
FeatureWhat it doesWhereAPI
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 —
Order permissions page
FeatureWhat it doesWhereAPI
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 —
View Tracking Lets the assistant see supplier tracking entries. 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 —
Upload permissions page
FeatureWhat it doesWhereAPI
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 —

Product Hunt

/dashboard/etsy-search/ 39

Searches the Etsy marketplace for a keyword, scores every listing for 24h demand, and shows the results as a filterable card grid.

Search
FeatureWhat it doesWhereAPI
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 —
Filters and sorting
FeatureWhat it doesWhereAPI
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 —
Result cards
FeatureWhat it doesWhereAPI
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 —
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 —
Listing detail drawer
FeatureWhat it doesWhereAPI
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 —
Privacy and history
FeatureWhat it doesWhereAPI
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 —

Shop Spy

/dashboard/shop-spy/ 20

Takes any Etsy listing link and pulls that whole shop, then lets you sort and filter every active listing it has.

Lookup
FeatureWhat it doesWhereAPI
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 —
Shop bar
FeatureWhat it doesWhereAPI
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 —
Filters and sorting
FeatureWhat it doesWhereAPI
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 —
Listing cards and drawer
FeatureWhat it doesWhereAPI
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 —
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 —

Workflow

/dashboard/workflow/ 29

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.

The three panes
FeatureWhat it doesWhereAPI
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 —
Restore hidden panes Counter button in the top bar that lists the hidden panes so you can bring one back. Workflow > Unified Workflow > restore —
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 —
Pane handoffs
FeatureWhat it doesWhereAPI
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 —
Quick tools
FeatureWhat it doesWhereAPI
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 —
Custom layout mode
FeatureWhat it doesWhereAPI
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 —

Developer API console

/dashboard/api/ 29

Where an Enterprise account creates its API key, connects an MCP client, and configures and watches outbound webhooks.

Overview
FeatureWhat it doesWhereAPI
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 —
MCP Connect
FeatureWhat it doesWhereAPI
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 —
Webhooks
FeatureWhat it doesWhereAPI
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 —

Settings

/settings/ 46

Seven tabs holding account, billing, AI provider, notification, order integration, theme and affiliate settings.

Account
FeatureWhat it doesWhereAPI
Email 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 —
Billing
FeatureWhat it doesWhereAPI
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 —
AI
FeatureWhat it doesWhereAPI
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 —
Notifications
FeatureWhat it doesWhereAPI
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 —
Order Settings
FeatureWhat it doesWhereAPI
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 —
Appearance
FeatureWhat it doesWhereAPI
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 —
Affiliates
FeatureWhat it doesWhereAPI
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 —

Sidebar

/dashboard/ 38

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.

Sidebar navigation
FeatureWhat it doesWhereAPI
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 —
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 —
Sidebar controls
FeatureWhat it doesWhereAPI
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 —
Quick panels
FeatureWhat it doesWhereAPI
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 —
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 —

Command palette

/dashboard/ 230

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.

Opening and searching
FeatureWhat it doesWhereAPI
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 —
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 —
Pages
FeatureWhat it doesWhereAPI
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 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 —
Dashboard
FeatureWhat it doesWhereAPI
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 —
Analytics
FeatureWhat it doesWhereAPI
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 —
Orders
FeatureWhat it doesWhereAPI
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 —
Custom dates Pick a date range on the calendar. Command palette > Date range > Custom dates —
Finance
FeatureWhat it doesWhereAPI
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) —
Stores
FeatureWhat it doesWhereAPI
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 —
Hidden stores Lists the stores you have hidden from the dashboard, Orders or Finance. Command palette > Hidden 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} —
Store details
FeatureWhat it doesWhereAPI
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} —
Listing Manager
FeatureWhat it doesWhereAPI
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 —
Quick upload
FeatureWhat it doesWhereAPI
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 —
Listing workspace
FeatureWhat it doesWhereAPI
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 —
VA Admin
FeatureWhat it doesWhereAPI
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 —
Product Hunt
FeatureWhat it doesWhereAPI
Hunt for products Type a keyword and search Etsy. Command palette > Hunt for products —
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 —
Settings
FeatureWhat it doesWhereAPI
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 —
API console
FeatureWhat it doesWhereAPI
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 —
Sidebar
FeatureWhat it doesWhereAPI
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) —

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.