API, MCP & CLI

API: Command-line tool

Install the listingview command-line tool, sign in with an API key, run every API route as a command, rehearse with dry runs, stage Etsy drafts, and script it safely with JSON output, exit codes and safe re-runs.

Updated

Connect Claude, ChatGPT or Cursor to ListingView to research what's selling on Etsy, update your Etsy shop, manage your listings.

listingview runs the ListingView API from your terminal, your scripts and your agents. Every API route is a command. The command list comes from the API itself, so the two always match.

You need an API key first. API: Getting started shows how to make one, and Using the ListingView API, MCP server & CLI explains which kind of key to choose.

Install

You need Node.js 18.3 or newer. The CLI has no other dependencies.

npm install -g @listingview/cli
listingview --help

Or run it without installing:

npx @listingview/cli --help

The examples below use listingview. With npx, write npx @listingview/cli instead.

Sign in

For agents, scripts and CI, put the key in the environment:

export LISTINGVIEW_API_KEY=lv_live_…
listingview auth status

On your own computer you can save the key instead:

listingview auth login

auth login asks for the key without showing it, or reads it from stdin: printf %s "$KEY" | listingview auth login --key-stdin. It checks the key with GET /api/v1/ping before it saves it (skip that with --no-verify). The key is saved in ~/.listingview/credentials, readable only by you.

Check which key is in use

listingview auth status shows which key is in use, where it came from, which API it talks to and the key's scopes. It prints only the start of the key, never the whole key. Add --offline to skip the call to the API.

When more than one key is around, the first match wins:

  1. --api-key <key>. This works, but the CLI warns you: it ends up in your shell history.

  2. --profile <name>

  3. LISTINGVIEW_API_KEY

  4. The saved profile named by LISTINGVIEW_PROFILE, or default.

Profiles keep several keys side by side: listingview auth login --profile drafts, then listingview --profile drafts …. Drafting and publishing never share a key, so save a Drafting Agent key and a Publisher key under two profiles. A test key can have its own profile too, for example --profile test.

listingview auth logout removes the saved key from this computer. It doesn't revoke the key. Revoke keys in ListingView under Settings → API Keys.

Environment variables

Variable

Default

What it does

LISTINGVIEW_API_KEY

none

The API key.

LISTINGVIEW_BASE_URL

https://api.listingview.io

The API origin.

LISTINGVIEW_PROFILE

default

Which saved profile to use.

LISTINGVIEW_CONFIG_DIR

~/.listingview

Where the saved keys and the command cache live.

LISTINGVIEW_DESCRIBE_FILE

none

Use this file as the command list.

LISTINGVIEW_TIMEOUT

60

Seconds per request.

--base-url overrides LISTINGVIEW_BASE_URL. The CLI sends your key only over https://; plain http:// is refused except for localhost.

Commands

The command list comes from the API's describe output. Nobody writes it by hand.

listingview --help                              # every command
listingview etsy-drafts --help                  # the commands under one word
listingview catalog listings list --help        # one command's arguments
listingview describe --json                     # the full machine-readable list
listingview describe --refresh                  # fetch the latest list with your key

describe --refresh fetches the live list with your key, saves it, and marks which commands your key can call. Without it, the CLI uses the list it was installed with.

Each command maps to one API route and, where there is one, to an MCP tool. Each line below reads: command · REST route · MCP tool. --help on a command's first word, such as listingview etsy-drafts --help, shows the exact words your installed list has. The API reference documents every route.

Account and discovery

  • listingview ping · GET /api/v1/ping · no MCP tool

  • listingview describe · GET /api/v1/describe · no MCP tool

  • listingview usage get · GET /api/v1/usage · get_account_usage

  • listingview usage ai-tokens · GET /api/v1/usage/ai-tokens · get_account_usage

Market research

Every research route is a command under listingview research. Run listingview research --help to list them. Each maps to one of the research tools in API: Connect AI apps.

Your shop

  • listingview my-shop · GET /api/v1/my-shop · my_shop_performance

  • listingview my-shop performance · GET /api/v1/my-shop/performance · my_shop_performance

  • listingview my-shop listing-scores · GET /api/v1/my-shop/listing-scores · my_shop_performance

Listings in ListingView

  • listingview catalog listings list · GET /api/v1/catalog/listings · list_my_listings

  • listingview catalog listings get · GET /api/v1/catalog/listings/{listing_id} · get_listing

  • listingview catalog listings resolve · GET /api/v1/catalog/listings/resolve · get_listing

  • listingview catalog listings publish-checklist · GET /api/v1/catalog/listings/{listing_id}/publish-checklist · get_listing

  • listingview catalog listings create · POST /api/v1/catalog/listings · create_local_listing

  • listingview catalog listings update · PUT /api/v1/catalog/listings/{listing_id} · update_listing

  • listingview catalog listings images set · PUT /api/v1/catalog/listings/{listing_id}/images · update_listing

  • listingview catalog listings ai-enhance · POST /api/v1/catalog/listings/{listing_id}/ai-enhance · enhance_listing_with_ai

  • listingview catalog listings lookup · POST /api/v1/catalog/listings/lookup · get_listing with etsy_listing_ids: up to 100 Etsy listing ids at once, with live state, print-on-demand prices or live inventory

Bulk jobs and AI copy

  • listingview catalog bulk create · POST /api/v1/catalog/bulk/create · bulk_edit_listings. It requires an idempotency key, so a re-run of the same command returns the same job

  • listingview catalog bulk edit · POST /api/v1/catalog/bulk/edit · bulk_edit_listings

  • listingview catalog bulk jobs status · GET /api/v1/catalog/bulk/jobs/{job_id} · get_bulk_job_status. It also reads reprice jobs (lbj_…)

  • listingview ai listing-copy · POST /api/v1/ai/listing-copy · enhance_listing_with_ai

Asset library

  • listingview assets upload · runs the whole upload: begin, upload, finalize, wait (see API: Uploads). --purpose digital_file uploads delivery files · no MCP tool

  • listingview assets uploads begin · POST /api/v1/assets/uploads · add_assets

  • listingview assets uploads finalize · POST /api/v1/assets/uploads/finalize · add_assets

  • listingview assets images import · POST /api/v1/assets/images/import · add_assets

  • listingview assets images list · GET /api/v1/assets/images · list_assets. --kind deliverable lists delivery files

  • listingview assets files get · GET /api/v1/assets/files · list_assets. --ids looks up to 50 files by id, of any type

  • listingview assets files update · PATCH /api/v1/assets/files/{file_id} · organize_assets

  • listingview assets files duplicate · POST /api/v1/assets/files/{file_id}/duplicate · organize_assets

  • listingview assets files membership · POST /api/v1/assets/files/membership · organize_assets

  • listingview assets collections · GET /api/v1/assets/collections · list_assets

  • listingview assets collections create · POST /api/v1/assets/collections · organize_assets

  • listingview assets collections rename · PATCH /api/v1/assets/collections/{collection_id} · organize_assets

  • listingview assets collections move · POST /api/v1/assets/collections/{collection_id}/move · organize_assets

Presets

  • listingview presets list · GET /api/v1/presets · list_presets

  • listingview presets get · GET /api/v1/presets/{preset_id} · list_presets. --include adds sections; --include spec returns the full preset as a create body

  • listingview presets create · POST /api/v1/presets · manage_preset

  • listingview presets update · PATCH /api/v1/presets/{preset_id} · manage_preset

  • listingview presets copy · POST /api/v1/presets/{preset_id}/copy · manage_preset

  • listingview presets delete · DELETE /api/v1/presets/{preset_id} · delete_preset_or_draft with kind: "preset"

Preset building blocks

  • listingview pod-products list · GET /api/v1/pod-products · list_presets with view: "pod_products"

  • listingview pod-products get · GET /api/v1/pod-products/{product_id} · list_presets with view: "pod_products" and product_id

  • listingview pod-products providers get · GET /api/v1/pod-products/{product_id}/providers/{provider_id} · list_presets with view: "pod_products", product_id and provider_id

  • listingview etsy-taxonomy properties · GET /api/v1/etsy-taxonomy/{taxonomy_id}/properties · list_presets with view: "category_attributes"

  • listingview my-shop profiles · GET /api/v1/my-shop/profiles · list_presets with view: "shop_profiles"

  • listingview mockup-templates list · GET /api/v1/mockup-templates · list_presets with view: "mockup_templates"

Etsy drafts

  • listingview etsy-drafts create · POST /api/v1/etsy-drafts · create_etsy_drafts. --stage stages the batch instead (operation: "stage" over MCP)

  • listingview etsy-drafts jobs status · GET /api/v1/etsy-drafts/jobs/{job_id} · get_bulk_job_status

  • listingview etsy-drafts jobs list · GET /api/v1/etsy-drafts/jobs · get_bulk_job_status with list: "jobs": your Etsy-draft job history

  • listingview etsy-drafts staged list · GET /api/v1/etsy-drafts/staged · get_bulk_job_status with list: "staged": your open staged batches

  • listingview etsy-drafts staged get · GET /api/v1/etsy-drafts/staged/{draft_id} · get_bulk_job_status with draft_id: one batch as it is now

  • listingview etsy-drafts staged update · PATCH /api/v1/etsy-drafts/staged/{draft_id} · create_etsy_drafts with operation: "update"

  • listingview etsy-drafts staged submit · POST /api/v1/etsy-drafts/staged/{draft_id}/submit · create_etsy_drafts with operation: "submit"

  • listingview etsy-drafts staged delete · DELETE /api/v1/etsy-drafts/staged/{draft_id} · delete_preset_or_draft with kind: "staged_batch"

  • listingview catalog listings delete · DELETE /api/v1/catalog/listings/{listing_id} · delete_preset_or_draft with kind: "etsy_draft": deletes an Etsy draft that ListingView made

Publishing

The CLI doesn't have live-change commands yet: publishing, pushing and repricing aren't in its command list. Use the REST routes or the push_listing_live MCP tool, which Publish and reprice live listings covers.

Arguments

  • Path parameters come first, in order: listingview catalog listings get 91234.

  • Everything else is a flag: --status draft or --status=draft. Booleans take --flag or --no-flag. Repeat a flag to send a list: --ids 88123 --ids 88207.

  • JSON arguments take inline JSON, @file.json, or - to read stdin.

  • --input takes the whole input as JSON. Flags override its keys.

The CLI checks types, required arguments, unknown flags and the API's published size limits before it sends anything. A mistake exits with code 2 and costs nothing.

JSON output for agents

  • When stdout isn't a terminal (a pipe, a script, an agent), stdout carries exactly one JSON document: the API's answer, or the error object {"error": {…}}. Notes and warnings go to stderr.

  • In a terminal you get a readable layout. --json or --no-json picks one explicitly.

  • --quiet hides notes. --verbose logs each request and its timing to stderr, never the headers, so your key stays out of logs.

  • API commands never prompt, so an agent never waits for a keypress.

listingview catalog listings list --status draft --json | jq '.listings[].title'

The error object is the same one the REST API returns. API: Getting started explains its fields and the retry rules for agents, and every code is on the errors page.

Exit codes

Code

Name

Meaning

0

ok

Success.

1

error

Any other failure: not found, a conflict or precondition on your data, or an internal error. Quote the request_id to support.

2

validation

The request was malformed or out of bounds (VALIDATION_FAILED). Fix the input and re-run.

3

auth

The API key is missing, invalid, revoked or expired.

4

access

The key's scopes or the account's plan don't allow this call, or the feature is off right now.

5

limit

A budget or rate limit was hit. Wait for the reset (retry_after) or raise the plan.

6

confirmation_required

A live change on Etsy printed its preview and is waiting for you: run the printed line with --confirm <id>. Also used when a confirmation was refused because it expired, changed or was already used. Live-change commands aren't in the CLI yet.

7

external

Etsy, Printify, the AI provider or a ListingView dependency failed or is unavailable. Retry later.

8

partial

A batch finished with some items failed. The CLI prints a per-item table.

9

needs_review

Some items have an unknown outcome. Check the shop before retrying, and never resubmit them.

10

wait_timeout

--wait gave up before the job finished. The job keeps running.

Retries and idempotency

  • Only retryable errors are retried. The CLI retries only errors the API marks retryable. It waits as long as retry_after asks, up to 30 seconds, and makes at most --retries extra attempts (default 2). If the API asks for a longer wait, the CLI stops with the error instead, so run the command again later.

  • Every change carries an idempotency key. Pass --idempotency-key <key> to make re-runs safe. For commands that require a key, such as etsy-drafts create, assets uploads begin and catalog bulk create, the CLI makes one from the command and its input when you don't pass one and prints it on stderr. Running the same command again then returns the first result instead of repeating the work. Any other change gets a new random key on each run, which protects only that run's own retries.

  • No clear answer means exit code 9. If a change ends without a clear answer, the CLI stops with exit code 9 and prints the idempotency key to retry with. Re-run with that key: if the first attempt went through, you get its result back instead of a second change.

Dry runs

With an lv_test_ key, every change is a dry run. The answer shows what would happen, with "dry_run": true, and nothing is written, sent to Etsy or charged. Reads still run for real and use credits as usual.

--dry-run makes sure of it. It needs an lv_test_ key and refuses to run with a live key, so it can never write by mistake:

listingview --profile test etsy-drafts create --stage --shop-id 38123456 --preset-id 1667 --items items.json --dry-run

See Rehearse with a test key in API: Getting started for what a test key checks for real and what comes back unverified.

Upload designs and delivery files

assets upload runs the whole upload protocol from API: Uploads and waits until each file is ready:

listingview assets upload front.png back.png --collection 311
listingview assets upload designs/*.png --json | jq '.[] | select(.ready) | .file_id'
listingview assets upload --purpose digital_file printable-planner-2027.pdf
  • --purpose says what you're uploading: design (the default), or digital_file for the files a digital listing delivers to buyers. Delivery files have their own file types and size limit (see API: Uploads).

  • For designs, it checks each file before uploading and refuses anything that isn't PNG, JPEG or WebP. The type is read from the file's bytes, not its name.

  • Your key is never sent to storage, and upload URLs are never printed.

  • It waits until every file is ready. --no-wait returns right after the upload; --wait-timeout <seconds> changes how long it waits.

  • Running the same command again is safe. Files already in your library show "already in library" and aren't uploaded or counted twice.

  • Exit codes: 0 every file is ready, 2 a file was refused, quarantined or failed, 8 some files didn't upload (running it again is safe), 10 the wait ran out (the files keep processing).

Etsy drafts

With a Drafting Agent key, turn a preset and your designs into Etsy drafts:

listingview presets list
listingview presets get 1667                  # in a terminal: the design slots (A, B, …) to fill
listingview presets get 1667 --include spec   # the whole preset, in the shape presets create accepts
listingview etsy-drafts create --shop-id 38123456 --preset-id 1667 --items items.json --wait
listingview etsy-drafts jobs status edj_48213 --watch
  • --items reads a JSON array of items from a file, or from stdin with -.

  • Without --idempotency-key, the key is made from the shop, the preset and the items. Running the same command again, even much later, returns the same job instead of making new drafts. Pass a new --idempotency-key to make a second batch on purpose.

  • --wait follows the job until it finishes. --watch also prints each item as it lands.

  • Exit codes: 0 every item became a draft, 8 some items failed, were skipped or were cancelled, 9 an item's outcome is unknown (check your shop and never resubmit it), 10 the wait ran out (the job keeps running).

Stage a batch for review

Add --stage to save the batch for review in ListingView instead of drafting it at once. Nothing reaches Etsy yet.

listingview etsy-drafts create --stage --shop-id 38123456 --preset-id 1667 --items items.json \
  --idempotency-key stage-2026-10-26-batch-01
  • The answer has the batch's draft_id, its revision and a review_url that opens Saved listings in ListingView.

  • Keep the idempotency key. If the answer is lost, running the same command with the same key returns the same batch while it is open.

  • Staging takes the copy you already have. Inline AI copy is refused when you stage, so write it first with listingview ai listing-copy.

  • Then read, edit, submit or discard the batch with etsy-drafts staged get, update, submit and delete; etsy-drafts staged list lists your open batches. A submit sends the batch as it is now, including edits made in ListingView, and returns a job_id that etsy-drafts jobs status follows.

Stage Etsy drafts, review them in ListingView, then submit walks through the whole loop, including edits and conflicts.

Drafts are hidden from shoppers. Publish them with a Publisher key, or with the Publish button in ListingView. For the checks ListingView runs before any draft reaches Etsy, see Using the ListingView API, MCP server & CLI.

Live changes on Etsy

The CLI doesn't publish, push or reprice live listings yet. Publish drafts with the Publish button in ListingView, or through the REST API or MCP with a Publisher key. Publish and reprice live listings covers the confirm step those calls go through.

Related features

listingview runs the ListingView API from your terminal, your scripts and your agents. Every API route is a command. The command list comes from the API itself, so the two always match.

You need an API key first. API: Getting started shows how to make one, and Using the ListingView API, MCP server & CLI explains which kind of key to choose.

Install

You need Node.js 18.3 or newer. The CLI has no other dependencies.

npm install -g @listingview/cli
listingview --help

Or run it without installing:

npx @listingview/cli --help

The examples below use listingview. With npx, write npx @listingview/cli instead.

Sign in

For agents, scripts and CI, put the key in the environment:

export LISTINGVIEW_API_KEY=lv_live_…
listingview auth status

On your own computer you can save the key instead:

listingview auth login

auth login asks for the key without showing it, or reads it from stdin: printf %s "$KEY" | listingview auth login --key-stdin. It checks the key with GET /api/v1/ping before it saves it (skip that with --no-verify). The key is saved in ~/.listingview/credentials, readable only by you.

Check which key is in use

listingview auth status shows which key is in use, where it came from, which API it talks to and the key's scopes. It prints only the start of the key, never the whole key. Add --offline to skip the call to the API.

When more than one key is around, the first match wins:

  1. --api-key <key>. This works, but the CLI warns you: it ends up in your shell history.

  2. --profile <name>

  3. LISTINGVIEW_API_KEY

  4. The saved profile named by LISTINGVIEW_PROFILE, or default.

Profiles keep several keys side by side: listingview auth login --profile drafts, then listingview --profile drafts …. Drafting and publishing never share a key, so save a Drafting Agent key and a Publisher key under two profiles. A test key can have its own profile too, for example --profile test.

listingview auth logout removes the saved key from this computer. It doesn't revoke the key. Revoke keys in ListingView under Settings → API Keys.

Environment variables

Variable

Default

What it does

LISTINGVIEW_API_KEY

none

The API key.

LISTINGVIEW_BASE_URL

https://api.listingview.io

The API origin.

LISTINGVIEW_PROFILE

default

Which saved profile to use.

LISTINGVIEW_CONFIG_DIR

~/.listingview

Where the saved keys and the command cache live.

LISTINGVIEW_DESCRIBE_FILE

none

Use this file as the command list.

LISTINGVIEW_TIMEOUT

60

Seconds per request.

--base-url overrides LISTINGVIEW_BASE_URL. The CLI sends your key only over https://; plain http:// is refused except for localhost.

Commands

The command list comes from the API's describe output. Nobody writes it by hand.

listingview --help                              # every command
listingview etsy-drafts --help                  # the commands under one word
listingview catalog listings list --help        # one command's arguments
listingview describe --json                     # the full machine-readable list
listingview describe --refresh                  # fetch the latest list with your key

describe --refresh fetches the live list with your key, saves it, and marks which commands your key can call. Without it, the CLI uses the list it was installed with.

Each command maps to one API route and, where there is one, to an MCP tool. Each line below reads: command · REST route · MCP tool. --help on a command's first word, such as listingview etsy-drafts --help, shows the exact words your installed list has. The API reference documents every route.

Account and discovery

  • listingview ping · GET /api/v1/ping · no MCP tool

  • listingview describe · GET /api/v1/describe · no MCP tool

  • listingview usage get · GET /api/v1/usage · get_account_usage

  • listingview usage ai-tokens · GET /api/v1/usage/ai-tokens · get_account_usage

Market research

Every research route is a command under listingview research. Run listingview research --help to list them. Each maps to one of the research tools in API: Connect AI apps.

Your shop

  • listingview my-shop · GET /api/v1/my-shop · my_shop_performance

  • listingview my-shop performance · GET /api/v1/my-shop/performance · my_shop_performance

  • listingview my-shop listing-scores · GET /api/v1/my-shop/listing-scores · my_shop_performance

Listings in ListingView

  • listingview catalog listings list · GET /api/v1/catalog/listings · list_my_listings

  • listingview catalog listings get · GET /api/v1/catalog/listings/{listing_id} · get_listing

  • listingview catalog listings resolve · GET /api/v1/catalog/listings/resolve · get_listing

  • listingview catalog listings publish-checklist · GET /api/v1/catalog/listings/{listing_id}/publish-checklist · get_listing

  • listingview catalog listings create · POST /api/v1/catalog/listings · create_local_listing

  • listingview catalog listings update · PUT /api/v1/catalog/listings/{listing_id} · update_listing

  • listingview catalog listings images set · PUT /api/v1/catalog/listings/{listing_id}/images · update_listing

  • listingview catalog listings ai-enhance · POST /api/v1/catalog/listings/{listing_id}/ai-enhance · enhance_listing_with_ai

  • listingview catalog listings lookup · POST /api/v1/catalog/listings/lookup · get_listing with etsy_listing_ids: up to 100 Etsy listing ids at once, with live state, print-on-demand prices or live inventory

Bulk jobs and AI copy

  • listingview catalog bulk create · POST /api/v1/catalog/bulk/create · bulk_edit_listings. It requires an idempotency key, so a re-run of the same command returns the same job

  • listingview catalog bulk edit · POST /api/v1/catalog/bulk/edit · bulk_edit_listings

  • listingview catalog bulk jobs status · GET /api/v1/catalog/bulk/jobs/{job_id} · get_bulk_job_status. It also reads reprice jobs (lbj_…)

  • listingview ai listing-copy · POST /api/v1/ai/listing-copy · enhance_listing_with_ai

Asset library

  • listingview assets upload · runs the whole upload: begin, upload, finalize, wait (see API: Uploads). --purpose digital_file uploads delivery files · no MCP tool

  • listingview assets uploads begin · POST /api/v1/assets/uploads · add_assets

  • listingview assets uploads finalize · POST /api/v1/assets/uploads/finalize · add_assets

  • listingview assets images import · POST /api/v1/assets/images/import · add_assets

  • listingview assets images list · GET /api/v1/assets/images · list_assets. --kind deliverable lists delivery files

  • listingview assets files get · GET /api/v1/assets/files · list_assets. --ids looks up to 50 files by id, of any type

  • listingview assets files update · PATCH /api/v1/assets/files/{file_id} · organize_assets

  • listingview assets files duplicate · POST /api/v1/assets/files/{file_id}/duplicate · organize_assets

  • listingview assets files membership · POST /api/v1/assets/files/membership · organize_assets

  • listingview assets collections · GET /api/v1/assets/collections · list_assets

  • listingview assets collections create · POST /api/v1/assets/collections · organize_assets

  • listingview assets collections rename · PATCH /api/v1/assets/collections/{collection_id} · organize_assets

  • listingview assets collections move · POST /api/v1/assets/collections/{collection_id}/move · organize_assets

Presets

  • listingview presets list · GET /api/v1/presets · list_presets

  • listingview presets get · GET /api/v1/presets/{preset_id} · list_presets. --include adds sections; --include spec returns the full preset as a create body

  • listingview presets create · POST /api/v1/presets · manage_preset

  • listingview presets update · PATCH /api/v1/presets/{preset_id} · manage_preset

  • listingview presets copy · POST /api/v1/presets/{preset_id}/copy · manage_preset

  • listingview presets delete · DELETE /api/v1/presets/{preset_id} · delete_preset_or_draft with kind: "preset"

Preset building blocks

  • listingview pod-products list · GET /api/v1/pod-products · list_presets with view: "pod_products"

  • listingview pod-products get · GET /api/v1/pod-products/{product_id} · list_presets with view: "pod_products" and product_id

  • listingview pod-products providers get · GET /api/v1/pod-products/{product_id}/providers/{provider_id} · list_presets with view: "pod_products", product_id and provider_id

  • listingview etsy-taxonomy properties · GET /api/v1/etsy-taxonomy/{taxonomy_id}/properties · list_presets with view: "category_attributes"

  • listingview my-shop profiles · GET /api/v1/my-shop/profiles · list_presets with view: "shop_profiles"

  • listingview mockup-templates list · GET /api/v1/mockup-templates · list_presets with view: "mockup_templates"

Etsy drafts

  • listingview etsy-drafts create · POST /api/v1/etsy-drafts · create_etsy_drafts. --stage stages the batch instead (operation: "stage" over MCP)

  • listingview etsy-drafts jobs status · GET /api/v1/etsy-drafts/jobs/{job_id} · get_bulk_job_status

  • listingview etsy-drafts jobs list · GET /api/v1/etsy-drafts/jobs · get_bulk_job_status with list: "jobs": your Etsy-draft job history

  • listingview etsy-drafts staged list · GET /api/v1/etsy-drafts/staged · get_bulk_job_status with list: "staged": your open staged batches

  • listingview etsy-drafts staged get · GET /api/v1/etsy-drafts/staged/{draft_id} · get_bulk_job_status with draft_id: one batch as it is now

  • listingview etsy-drafts staged update · PATCH /api/v1/etsy-drafts/staged/{draft_id} · create_etsy_drafts with operation: "update"

  • listingview etsy-drafts staged submit · POST /api/v1/etsy-drafts/staged/{draft_id}/submit · create_etsy_drafts with operation: "submit"

  • listingview etsy-drafts staged delete · DELETE /api/v1/etsy-drafts/staged/{draft_id} · delete_preset_or_draft with kind: "staged_batch"

  • listingview catalog listings delete · DELETE /api/v1/catalog/listings/{listing_id} · delete_preset_or_draft with kind: "etsy_draft": deletes an Etsy draft that ListingView made

Publishing

The CLI doesn't have live-change commands yet: publishing, pushing and repricing aren't in its command list. Use the REST routes or the push_listing_live MCP tool, which Publish and reprice live listings covers.

Arguments

  • Path parameters come first, in order: listingview catalog listings get 91234.

  • Everything else is a flag: --status draft or --status=draft. Booleans take --flag or --no-flag. Repeat a flag to send a list: --ids 88123 --ids 88207.

  • JSON arguments take inline JSON, @file.json, or - to read stdin.

  • --input takes the whole input as JSON. Flags override its keys.

The CLI checks types, required arguments, unknown flags and the API's published size limits before it sends anything. A mistake exits with code 2 and costs nothing.

JSON output for agents

  • When stdout isn't a terminal (a pipe, a script, an agent), stdout carries exactly one JSON document: the API's answer, or the error object {"error": {…}}. Notes and warnings go to stderr.

  • In a terminal you get a readable layout. --json or --no-json picks one explicitly.

  • --quiet hides notes. --verbose logs each request and its timing to stderr, never the headers, so your key stays out of logs.

  • API commands never prompt, so an agent never waits for a keypress.

listingview catalog listings list --status draft --json | jq '.listings[].title'

The error object is the same one the REST API returns. API: Getting started explains its fields and the retry rules for agents, and every code is on the errors page.

Exit codes

Code

Name

Meaning

0

ok

Success.

1

error

Any other failure: not found, a conflict or precondition on your data, or an internal error. Quote the request_id to support.

2

validation

The request was malformed or out of bounds (VALIDATION_FAILED). Fix the input and re-run.

3

auth

The API key is missing, invalid, revoked or expired.

4

access

The key's scopes or the account's plan don't allow this call, or the feature is off right now.

5

limit

A budget or rate limit was hit. Wait for the reset (retry_after) or raise the plan.

6

confirmation_required

A live change on Etsy printed its preview and is waiting for you: run the printed line with --confirm <id>. Also used when a confirmation was refused because it expired, changed or was already used. Live-change commands aren't in the CLI yet.

7

external

Etsy, Printify, the AI provider or a ListingView dependency failed or is unavailable. Retry later.

8

partial

A batch finished with some items failed. The CLI prints a per-item table.

9

needs_review

Some items have an unknown outcome. Check the shop before retrying, and never resubmit them.

10

wait_timeout

--wait gave up before the job finished. The job keeps running.

Retries and idempotency

  • Only retryable errors are retried. The CLI retries only errors the API marks retryable. It waits as long as retry_after asks, up to 30 seconds, and makes at most --retries extra attempts (default 2). If the API asks for a longer wait, the CLI stops with the error instead, so run the command again later.

  • Every change carries an idempotency key. Pass --idempotency-key <key> to make re-runs safe. For commands that require a key, such as etsy-drafts create, assets uploads begin and catalog bulk create, the CLI makes one from the command and its input when you don't pass one and prints it on stderr. Running the same command again then returns the first result instead of repeating the work. Any other change gets a new random key on each run, which protects only that run's own retries.

  • No clear answer means exit code 9. If a change ends without a clear answer, the CLI stops with exit code 9 and prints the idempotency key to retry with. Re-run with that key: if the first attempt went through, you get its result back instead of a second change.

Dry runs

With an lv_test_ key, every change is a dry run. The answer shows what would happen, with "dry_run": true, and nothing is written, sent to Etsy or charged. Reads still run for real and use credits as usual.

--dry-run makes sure of it. It needs an lv_test_ key and refuses to run with a live key, so it can never write by mistake:

listingview --profile test etsy-drafts create --stage --shop-id 38123456 --preset-id 1667 --items items.json --dry-run

See Rehearse with a test key in API: Getting started for what a test key checks for real and what comes back unverified.

Upload designs and delivery files

assets upload runs the whole upload protocol from API: Uploads and waits until each file is ready:

listingview assets upload front.png back.png --collection 311
listingview assets upload designs/*.png --json | jq '.[] | select(.ready) | .file_id'
listingview assets upload --purpose digital_file printable-planner-2027.pdf
  • --purpose says what you're uploading: design (the default), or digital_file for the files a digital listing delivers to buyers. Delivery files have their own file types and size limit (see API: Uploads).

  • For designs, it checks each file before uploading and refuses anything that isn't PNG, JPEG or WebP. The type is read from the file's bytes, not its name.

  • Your key is never sent to storage, and upload URLs are never printed.

  • It waits until every file is ready. --no-wait returns right after the upload; --wait-timeout <seconds> changes how long it waits.

  • Running the same command again is safe. Files already in your library show "already in library" and aren't uploaded or counted twice.

  • Exit codes: 0 every file is ready, 2 a file was refused, quarantined or failed, 8 some files didn't upload (running it again is safe), 10 the wait ran out (the files keep processing).

Etsy drafts

With a Drafting Agent key, turn a preset and your designs into Etsy drafts:

listingview presets list
listingview presets get 1667                  # in a terminal: the design slots (A, B, …) to fill
listingview presets get 1667 --include spec   # the whole preset, in the shape presets create accepts
listingview etsy-drafts create --shop-id 38123456 --preset-id 1667 --items items.json --wait
listingview etsy-drafts jobs status edj_48213 --watch
  • --items reads a JSON array of items from a file, or from stdin with -.

  • Without --idempotency-key, the key is made from the shop, the preset and the items. Running the same command again, even much later, returns the same job instead of making new drafts. Pass a new --idempotency-key to make a second batch on purpose.

  • --wait follows the job until it finishes. --watch also prints each item as it lands.

  • Exit codes: 0 every item became a draft, 8 some items failed, were skipped or were cancelled, 9 an item's outcome is unknown (check your shop and never resubmit it), 10 the wait ran out (the job keeps running).

Stage a batch for review

Add --stage to save the batch for review in ListingView instead of drafting it at once. Nothing reaches Etsy yet.

listingview etsy-drafts create --stage --shop-id 38123456 --preset-id 1667 --items items.json \
  --idempotency-key stage-2026-10-26-batch-01
  • The answer has the batch's draft_id, its revision and a review_url that opens Saved listings in ListingView.

  • Keep the idempotency key. If the answer is lost, running the same command with the same key returns the same batch while it is open.

  • Staging takes the copy you already have. Inline AI copy is refused when you stage, so write it first with listingview ai listing-copy.

  • Then read, edit, submit or discard the batch with etsy-drafts staged get, update, submit and delete; etsy-drafts staged list lists your open batches. A submit sends the batch as it is now, including edits made in ListingView, and returns a job_id that etsy-drafts jobs status follows.

Stage Etsy drafts, review them in ListingView, then submit walks through the whole loop, including edits and conflicts.

Drafts are hidden from shoppers. Publish them with a Publisher key, or with the Publish button in ListingView. For the checks ListingView runs before any draft reaches Etsy, see Using the ListingView API, MCP server & CLI.

Live changes on Etsy

The CLI doesn't publish, push or reprice live listings yet. Publish drafts with the Publish button in ListingView, or through the REST API or MCP with a Publisher key. Publish and reprice live listings covers the confirm step those calls go through.

Related features

listingview runs the ListingView API from your terminal, your scripts and your agents. Every API route is a command. The command list comes from the API itself, so the two always match.

You need an API key first. API: Getting started shows how to make one, and Using the ListingView API, MCP server & CLI explains which kind of key to choose.

Install

You need Node.js 18.3 or newer. The CLI has no other dependencies.

npm install -g @listingview/cli
listingview --help

Or run it without installing:

npx @listingview/cli --help

The examples below use listingview. With npx, write npx @listingview/cli instead.

Sign in

For agents, scripts and CI, put the key in the environment:

export LISTINGVIEW_API_KEY=lv_live_…
listingview auth status

On your own computer you can save the key instead:

listingview auth login

auth login asks for the key without showing it, or reads it from stdin: printf %s "$KEY" | listingview auth login --key-stdin. It checks the key with GET /api/v1/ping before it saves it (skip that with --no-verify). The key is saved in ~/.listingview/credentials, readable only by you.

Check which key is in use

listingview auth status shows which key is in use, where it came from, which API it talks to and the key's scopes. It prints only the start of the key, never the whole key. Add --offline to skip the call to the API.

When more than one key is around, the first match wins:

  1. --api-key <key>. This works, but the CLI warns you: it ends up in your shell history.

  2. --profile <name>

  3. LISTINGVIEW_API_KEY

  4. The saved profile named by LISTINGVIEW_PROFILE, or default.

Profiles keep several keys side by side: listingview auth login --profile drafts, then listingview --profile drafts …. Drafting and publishing never share a key, so save a Drafting Agent key and a Publisher key under two profiles. A test key can have its own profile too, for example --profile test.

listingview auth logout removes the saved key from this computer. It doesn't revoke the key. Revoke keys in ListingView under Settings → API Keys.

Environment variables

Variable

Default

What it does

LISTINGVIEW_API_KEY

none

The API key.

LISTINGVIEW_BASE_URL

https://api.listingview.io

The API origin.

LISTINGVIEW_PROFILE

default

Which saved profile to use.

LISTINGVIEW_CONFIG_DIR

~/.listingview

Where the saved keys and the command cache live.

LISTINGVIEW_DESCRIBE_FILE

none

Use this file as the command list.

LISTINGVIEW_TIMEOUT

60

Seconds per request.

--base-url overrides LISTINGVIEW_BASE_URL. The CLI sends your key only over https://; plain http:// is refused except for localhost.

Commands

The command list comes from the API's describe output. Nobody writes it by hand.

listingview --help                              # every command
listingview etsy-drafts --help                  # the commands under one word
listingview catalog listings list --help        # one command's arguments
listingview describe --json                     # the full machine-readable list
listingview describe --refresh                  # fetch the latest list with your key

describe --refresh fetches the live list with your key, saves it, and marks which commands your key can call. Without it, the CLI uses the list it was installed with.

Each command maps to one API route and, where there is one, to an MCP tool. Each line below reads: command · REST route · MCP tool. --help on a command's first word, such as listingview etsy-drafts --help, shows the exact words your installed list has. The API reference documents every route.

Account and discovery

  • listingview ping · GET /api/v1/ping · no MCP tool

  • listingview describe · GET /api/v1/describe · no MCP tool

  • listingview usage get · GET /api/v1/usage · get_account_usage

  • listingview usage ai-tokens · GET /api/v1/usage/ai-tokens · get_account_usage

Market research

Every research route is a command under listingview research. Run listingview research --help to list them. Each maps to one of the research tools in API: Connect AI apps.

Your shop

  • listingview my-shop · GET /api/v1/my-shop · my_shop_performance

  • listingview my-shop performance · GET /api/v1/my-shop/performance · my_shop_performance

  • listingview my-shop listing-scores · GET /api/v1/my-shop/listing-scores · my_shop_performance

Listings in ListingView

  • listingview catalog listings list · GET /api/v1/catalog/listings · list_my_listings

  • listingview catalog listings get · GET /api/v1/catalog/listings/{listing_id} · get_listing

  • listingview catalog listings resolve · GET /api/v1/catalog/listings/resolve · get_listing

  • listingview catalog listings publish-checklist · GET /api/v1/catalog/listings/{listing_id}/publish-checklist · get_listing

  • listingview catalog listings create · POST /api/v1/catalog/listings · create_local_listing

  • listingview catalog listings update · PUT /api/v1/catalog/listings/{listing_id} · update_listing

  • listingview catalog listings images set · PUT /api/v1/catalog/listings/{listing_id}/images · update_listing

  • listingview catalog listings ai-enhance · POST /api/v1/catalog/listings/{listing_id}/ai-enhance · enhance_listing_with_ai

  • listingview catalog listings lookup · POST /api/v1/catalog/listings/lookup · get_listing with etsy_listing_ids: up to 100 Etsy listing ids at once, with live state, print-on-demand prices or live inventory

Bulk jobs and AI copy

  • listingview catalog bulk create · POST /api/v1/catalog/bulk/create · bulk_edit_listings. It requires an idempotency key, so a re-run of the same command returns the same job

  • listingview catalog bulk edit · POST /api/v1/catalog/bulk/edit · bulk_edit_listings

  • listingview catalog bulk jobs status · GET /api/v1/catalog/bulk/jobs/{job_id} · get_bulk_job_status. It also reads reprice jobs (lbj_…)

  • listingview ai listing-copy · POST /api/v1/ai/listing-copy · enhance_listing_with_ai

Asset library

  • listingview assets upload · runs the whole upload: begin, upload, finalize, wait (see API: Uploads). --purpose digital_file uploads delivery files · no MCP tool

  • listingview assets uploads begin · POST /api/v1/assets/uploads · add_assets

  • listingview assets uploads finalize · POST /api/v1/assets/uploads/finalize · add_assets

  • listingview assets images import · POST /api/v1/assets/images/import · add_assets

  • listingview assets images list · GET /api/v1/assets/images · list_assets. --kind deliverable lists delivery files

  • listingview assets files get · GET /api/v1/assets/files · list_assets. --ids looks up to 50 files by id, of any type

  • listingview assets files update · PATCH /api/v1/assets/files/{file_id} · organize_assets

  • listingview assets files duplicate · POST /api/v1/assets/files/{file_id}/duplicate · organize_assets

  • listingview assets files membership · POST /api/v1/assets/files/membership · organize_assets

  • listingview assets collections · GET /api/v1/assets/collections · list_assets

  • listingview assets collections create · POST /api/v1/assets/collections · organize_assets

  • listingview assets collections rename · PATCH /api/v1/assets/collections/{collection_id} · organize_assets

  • listingview assets collections move · POST /api/v1/assets/collections/{collection_id}/move · organize_assets

Presets

  • listingview presets list · GET /api/v1/presets · list_presets

  • listingview presets get · GET /api/v1/presets/{preset_id} · list_presets. --include adds sections; --include spec returns the full preset as a create body

  • listingview presets create · POST /api/v1/presets · manage_preset

  • listingview presets update · PATCH /api/v1/presets/{preset_id} · manage_preset

  • listingview presets copy · POST /api/v1/presets/{preset_id}/copy · manage_preset

  • listingview presets delete · DELETE /api/v1/presets/{preset_id} · delete_preset_or_draft with kind: "preset"

Preset building blocks

  • listingview pod-products list · GET /api/v1/pod-products · list_presets with view: "pod_products"

  • listingview pod-products get · GET /api/v1/pod-products/{product_id} · list_presets with view: "pod_products" and product_id

  • listingview pod-products providers get · GET /api/v1/pod-products/{product_id}/providers/{provider_id} · list_presets with view: "pod_products", product_id and provider_id

  • listingview etsy-taxonomy properties · GET /api/v1/etsy-taxonomy/{taxonomy_id}/properties · list_presets with view: "category_attributes"

  • listingview my-shop profiles · GET /api/v1/my-shop/profiles · list_presets with view: "shop_profiles"

  • listingview mockup-templates list · GET /api/v1/mockup-templates · list_presets with view: "mockup_templates"

Etsy drafts

  • listingview etsy-drafts create · POST /api/v1/etsy-drafts · create_etsy_drafts. --stage stages the batch instead (operation: "stage" over MCP)

  • listingview etsy-drafts jobs status · GET /api/v1/etsy-drafts/jobs/{job_id} · get_bulk_job_status

  • listingview etsy-drafts jobs list · GET /api/v1/etsy-drafts/jobs · get_bulk_job_status with list: "jobs": your Etsy-draft job history

  • listingview etsy-drafts staged list · GET /api/v1/etsy-drafts/staged · get_bulk_job_status with list: "staged": your open staged batches

  • listingview etsy-drafts staged get · GET /api/v1/etsy-drafts/staged/{draft_id} · get_bulk_job_status with draft_id: one batch as it is now

  • listingview etsy-drafts staged update · PATCH /api/v1/etsy-drafts/staged/{draft_id} · create_etsy_drafts with operation: "update"

  • listingview etsy-drafts staged submit · POST /api/v1/etsy-drafts/staged/{draft_id}/submit · create_etsy_drafts with operation: "submit"

  • listingview etsy-drafts staged delete · DELETE /api/v1/etsy-drafts/staged/{draft_id} · delete_preset_or_draft with kind: "staged_batch"

  • listingview catalog listings delete · DELETE /api/v1/catalog/listings/{listing_id} · delete_preset_or_draft with kind: "etsy_draft": deletes an Etsy draft that ListingView made

Publishing

The CLI doesn't have live-change commands yet: publishing, pushing and repricing aren't in its command list. Use the REST routes or the push_listing_live MCP tool, which Publish and reprice live listings covers.

Arguments

  • Path parameters come first, in order: listingview catalog listings get 91234.

  • Everything else is a flag: --status draft or --status=draft. Booleans take --flag or --no-flag. Repeat a flag to send a list: --ids 88123 --ids 88207.

  • JSON arguments take inline JSON, @file.json, or - to read stdin.

  • --input takes the whole input as JSON. Flags override its keys.

The CLI checks types, required arguments, unknown flags and the API's published size limits before it sends anything. A mistake exits with code 2 and costs nothing.

JSON output for agents

  • When stdout isn't a terminal (a pipe, a script, an agent), stdout carries exactly one JSON document: the API's answer, or the error object {"error": {…}}. Notes and warnings go to stderr.

  • In a terminal you get a readable layout. --json or --no-json picks one explicitly.

  • --quiet hides notes. --verbose logs each request and its timing to stderr, never the headers, so your key stays out of logs.

  • API commands never prompt, so an agent never waits for a keypress.

listingview catalog listings list --status draft --json | jq '.listings[].title'

The error object is the same one the REST API returns. API: Getting started explains its fields and the retry rules for agents, and every code is on the errors page.

Exit codes

Code

Name

Meaning

0

ok

Success.

1

error

Any other failure: not found, a conflict or precondition on your data, or an internal error. Quote the request_id to support.

2

validation

The request was malformed or out of bounds (VALIDATION_FAILED). Fix the input and re-run.

3

auth

The API key is missing, invalid, revoked or expired.

4

access

The key's scopes or the account's plan don't allow this call, or the feature is off right now.

5

limit

A budget or rate limit was hit. Wait for the reset (retry_after) or raise the plan.

6

confirmation_required

A live change on Etsy printed its preview and is waiting for you: run the printed line with --confirm <id>. Also used when a confirmation was refused because it expired, changed or was already used. Live-change commands aren't in the CLI yet.

7

external

Etsy, Printify, the AI provider or a ListingView dependency failed or is unavailable. Retry later.

8

partial

A batch finished with some items failed. The CLI prints a per-item table.

9

needs_review

Some items have an unknown outcome. Check the shop before retrying, and never resubmit them.

10

wait_timeout

--wait gave up before the job finished. The job keeps running.

Retries and idempotency

  • Only retryable errors are retried. The CLI retries only errors the API marks retryable. It waits as long as retry_after asks, up to 30 seconds, and makes at most --retries extra attempts (default 2). If the API asks for a longer wait, the CLI stops with the error instead, so run the command again later.

  • Every change carries an idempotency key. Pass --idempotency-key <key> to make re-runs safe. For commands that require a key, such as etsy-drafts create, assets uploads begin and catalog bulk create, the CLI makes one from the command and its input when you don't pass one and prints it on stderr. Running the same command again then returns the first result instead of repeating the work. Any other change gets a new random key on each run, which protects only that run's own retries.

  • No clear answer means exit code 9. If a change ends without a clear answer, the CLI stops with exit code 9 and prints the idempotency key to retry with. Re-run with that key: if the first attempt went through, you get its result back instead of a second change.

Dry runs

With an lv_test_ key, every change is a dry run. The answer shows what would happen, with "dry_run": true, and nothing is written, sent to Etsy or charged. Reads still run for real and use credits as usual.

--dry-run makes sure of it. It needs an lv_test_ key and refuses to run with a live key, so it can never write by mistake:

listingview --profile test etsy-drafts create --stage --shop-id 38123456 --preset-id 1667 --items items.json --dry-run

See Rehearse with a test key in API: Getting started for what a test key checks for real and what comes back unverified.

Upload designs and delivery files

assets upload runs the whole upload protocol from API: Uploads and waits until each file is ready:

listingview assets upload front.png back.png --collection 311
listingview assets upload designs/*.png --json | jq '.[] | select(.ready) | .file_id'
listingview assets upload --purpose digital_file printable-planner-2027.pdf
  • --purpose says what you're uploading: design (the default), or digital_file for the files a digital listing delivers to buyers. Delivery files have their own file types and size limit (see API: Uploads).

  • For designs, it checks each file before uploading and refuses anything that isn't PNG, JPEG or WebP. The type is read from the file's bytes, not its name.

  • Your key is never sent to storage, and upload URLs are never printed.

  • It waits until every file is ready. --no-wait returns right after the upload; --wait-timeout <seconds> changes how long it waits.

  • Running the same command again is safe. Files already in your library show "already in library" and aren't uploaded or counted twice.

  • Exit codes: 0 every file is ready, 2 a file was refused, quarantined or failed, 8 some files didn't upload (running it again is safe), 10 the wait ran out (the files keep processing).

Etsy drafts

With a Drafting Agent key, turn a preset and your designs into Etsy drafts:

listingview presets list
listingview presets get 1667                  # in a terminal: the design slots (A, B, …) to fill
listingview presets get 1667 --include spec   # the whole preset, in the shape presets create accepts
listingview etsy-drafts create --shop-id 38123456 --preset-id 1667 --items items.json --wait
listingview etsy-drafts jobs status edj_48213 --watch
  • --items reads a JSON array of items from a file, or from stdin with -.

  • Without --idempotency-key, the key is made from the shop, the preset and the items. Running the same command again, even much later, returns the same job instead of making new drafts. Pass a new --idempotency-key to make a second batch on purpose.

  • --wait follows the job until it finishes. --watch also prints each item as it lands.

  • Exit codes: 0 every item became a draft, 8 some items failed, were skipped or were cancelled, 9 an item's outcome is unknown (check your shop and never resubmit it), 10 the wait ran out (the job keeps running).

Stage a batch for review

Add --stage to save the batch for review in ListingView instead of drafting it at once. Nothing reaches Etsy yet.

listingview etsy-drafts create --stage --shop-id 38123456 --preset-id 1667 --items items.json \
  --idempotency-key stage-2026-10-26-batch-01
  • The answer has the batch's draft_id, its revision and a review_url that opens Saved listings in ListingView.

  • Keep the idempotency key. If the answer is lost, running the same command with the same key returns the same batch while it is open.

  • Staging takes the copy you already have. Inline AI copy is refused when you stage, so write it first with listingview ai listing-copy.

  • Then read, edit, submit or discard the batch with etsy-drafts staged get, update, submit and delete; etsy-drafts staged list lists your open batches. A submit sends the batch as it is now, including edits made in ListingView, and returns a job_id that etsy-drafts jobs status follows.

Stage Etsy drafts, review them in ListingView, then submit walks through the whole loop, including edits and conflicts.

Drafts are hidden from shoppers. Publish them with a Publisher key, or with the Publish button in ListingView. For the checks ListingView runs before any draft reaches Etsy, see Using the ListingView API, MCP server & CLI.

Live changes on Etsy

The CLI doesn't publish, push or reprice live listings yet. Publish drafts with the Publish button in ListingView, or through the REST API or MCP with a Publisher key. Publish and reprice live listings covers the confirm step those calls go through.

Related features

Still need help?

Can’t find what you’re looking for? Our team is happy to help.

A.I. Summary