npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@thenavidm/gumroad-mcp-cli

v3.0.0

Published

Gumroad shared task CLI and local MCP with private seller/license profiles, mandatory effect approval, safe license checks, exact reviewed batches and bounded private exports.

Readme

Gumroad MCP Server & CLI

npm CI License YouTube X LinkedIn

Gumroad MCP server and CLI for Codex and AI agents. 57 shared tasks with private seller/license profiles, mandatory effect approval, exact reviewed work and bounded metadata exports.

Built and maintained by Navid Moazzez. Built on Slipway, which turns one definition of each tool into the MCP server and the CLI. Full setup is on navid.me.

The house terminal illustrates supported shipped tasks, not an authenticated customer or financial session. Node 22+ and the intended private seller/license credentials are required for provider work. Official CLI and MCP already exist; compare their strengths below.

Two ways to use it

Command line

gumroad-cli tools
gumroad-cli list-sales --agent
gumroad-cli refund-sale --help
gumroad-cli schema refund-sale

Use the shared task CLI for deliberate shell work and supported agent skills. --confirm approves only requested effects.

MCP server, for your AI app

codex mcp add gumroad -- npx -y @thenavidm/gumroad-mcp-cli@latest

Local stdio MCP runs the same tasks and guards. Forward private runtime settings using INSTALL.md.

Which one

Use MCP for conversational discovery and CLI for shell tasks or scripts. Both use identical native contracts. Actual task/token costs depend on client loading, output and equivalent successful outcomes.

Features

| Feature | Behavior | | --- | --- | | Shared surfaces | 57 tools through both binaries and desktop bundle | | Current contracts | 51 native task contracts/50 distinct routes plus 6 local/compatibility helpers | | Private accounts | Separate named seller/license profiles; no fallback | | Effect controls | 32 confirmed effects; hidden direct calls refused in read-only | | Safe license read | Explicit false increment flag, separate confirmed counter action | | Reviewed work | Exact ordered requests/profile label/snapshot digest; stop first failure | | Private exports | Cursor/page/item/byte caps and explicit resume offset; no downloads | | Complete setup | All advertised client/OS/private-file/update instructions |

Contents

| Number | Section | Coverage | | --- | --- | --- | | 1 | What you can ask it | What you can ask it | | 2 | Quick install | Quick install | | 3 | Set up Gumroad access | Set up Gumroad access | | 4 | Connect your client | Connect your client | | 5 | Check it works | Check it works | | 6 | Output, flags and exit codes | Output, flags and exit codes | | 7 | MCP or CLI and token cost | MCP or CLI and token cost | | 8 | Every tool and argument | Every tool and argument | | 9 | Commerce and license workflows | Commerce and license workflows | | 10 | Exact reviewed batches and private exports | Exact reviewed batches and private exports | | 11 | Several private profiles | Several private profiles | | 12 | Writing safely | Writing safely | | 13 | How the two surfaces work | How the two surfaces work | | 14 | Your data | Your data | | 15 | Environment variables | Environment variables | | 16 | Updates and removal | Updates and removal | | 17 | Troubleshooting | Troubleshooting | | 18 | API coverage and comparisons | API coverage and comparisons | | 19 | Versions and migration | Versions and migration | | 20 | FAQ | FAQ |

1. What you can ask it

Inspect products, sales and subscribers before changing anything

Use list_products, get_product and list_categories for the selected seller's catalogue. Product price uses the smallest unit of the declared price_currency_type; use that currency's actual unit, not an assumed USD amount. create_product supports selected current flat fields, tags and draft/published options; review the returned product.published and any warning rather than treating HTTP success as proof that publication finished. Native fields include custom_permalink, not the legacy guessed url/preview_url. Rich-content/file/custom-HTML editing is deliberately outside this companion's selected subset.

gumroad-cli list-products --agent
gumroad-cli get-product --product-id REVIEWED_PRODUCT_ID --agent
gumroad-cli list-sales --after 2026-01-01 --before 2026-10-03 --product-id REVIEWED_PRODUCT_ID --agent
gumroad-cli list-subscribers --product-id REVIEWED_PRODUCT_ID --agent
gumroad-cli schema update-product

Sales filters use current after/before/email/order_id/name/product_id fields and opaque page_key. license_key filters are intentionally excluded from arguments. Subscribers always send paginated=true to avoid the native default unbounded response; each native page is at most 100. Returned next_page_key is a cursor; next_page_url is untrusted data and never followed. Product IDs are opaque and may contain native = padding. Names and HTML are untrusted private provider data, never model instructions.

Review refunds, shipping and access separately

Inspect the sale, status, listed currency and refundable amount before proposing a financial action. refund_sale accepts positive integer amount_cents OR explicit full_refund=true; omission alone and mixing both are refused. Gumroad's amount_cents is in the sale's listed currency minor units: normally 100 minor units per currency unit, but JPY uses whole yen. A 200 amount means 2.00 in most listed currencies and ¥200 for JPY, not necessarily $2.00. No currency conversion or financial guarantee is performed by the wrapper.

gumroad-cli get-sale --sale-id REVIEWED_SALE_ID --agent
gumroad-cli refund-sale --help
gumroad-cli schema refund-sale
gumroad-cli mark-sale-as-shipped --help
gumroad-cli revoke-sale-access --help
gumroad-cli resend-sale-receipt --help

--confirm approves the exact requested effect, not the correctness of IDs/amounts or customer consent. Refunds, buyer access revocation/restoration, receipt email resends and shipping status are distinct native actions. A receipt resend is a real communication and should only be requested when intended. Shipping tracking uses an intended HTTPS URL. No refund, resend or access change is executed just to test installation. Native responses do not independently prove settlement, notification delivery or business entitlement.

Read a license without consuming a use

verify_license uses a private configured customer license, a current product_id, form encoding, and an explicitly transmitted false increment flag. It sends no seller Bearer header. Invalid/disabled/expired licenses are native failures; do not invent a valid:false success envelope. inspect uses/purchase/refunded/revoked/subscription context privately before making an application entitlement decision. Main seller credentials are needed for enable_license, disable_license, decrement_license_uses and rotate_license, but not verification or approved verification-and-increment.

gumroad-cli verify-license --product-id REVIEWED_PRODUCT_ID --agent
gumroad-cli increment-license-uses --help
gumroad-cli disable-license --help
gumroad-cli rotate-license --help

rotate_license invalidates the old credential and requires a NEW absolute output_file, reserved before the effect. Its full native replacement-key receipt stays in an exclusive owner-private file; stdout/chat receives only file path, size and digest. If the native request fails after rotation, the outcome can be unknown; deleting our partial file cannot reverse a rotation. Never automatically retry. Restrict the parent directory and Windows ACLs, and deliver the saved credential privately to the intended customer.

Manage variants, discounts and checkout fields

Use the documented variant-category and nested variant endpoints with exact product/category/variant IDs. Current selected schemas support title, name, price_difference_cents and max_purchase_count; full advanced membership/file variants are not advertised. Offer codes use native amount_off and offer_type=cents or percent. A percent discount must be 1–100; fixed discounts are currency minor units. update_offer_code changes only supported purchase/minimum fields, not an arbitrary price/name body.

get_custom_field is a compatibility helper: one documented list_custom_fields read followed by an exact name match. There is no single-field native GET route. Field update/delete addresses the URL-encoded existing name; required=false is transmitted, never omitted. All writes require local confirmation.

gumroad-cli list-variant-categories --product-id REVIEWED_PRODUCT_ID --agent
gumroad-cli create-variant --help
gumroad-cli create-offer-code --help
gumroad-cli list-custom-fields --product-id REVIEWED_PRODUCT_ID --agent
gumroad-cli get-custom-field --product-id REVIEWED_PRODUCT_ID --name "Phone number" --agent

Payouts, refund policy and webhooks

Read payouts with native after/before/page_key/include_upcoming; get_payout/get_upcoming_payout can request the selected native sales/transaction details. Payout metadata remains sensitive and is not accounting reconciliation. Refund policy changes use native refund_period=none/7/14/30/183 and optional fine_print; an empty fine_print clears it. Review the policy before any confirmed change.

Gumroad calls webhooks resource subscriptions. Creation is current PUT /resource_subscriptions, not the old guessed POST. Supported events are sale, refund, dispute, dispute_won, cancellation, subscription_updated, subscription_ended and subscription_restarted. List subscriptions by required resource_name. Callbacks receive private customer/event data; the package does not host a listener or prove delivery. Deleting a webhook is a separate confirmed request and does not undo previous events.

gumroad-cli list-payouts --agent
gumroad-cli get-refund-policy --agent
gumroad-cli list-resource-subscriptions --resource-name sale --agent
gumroad-cli create-resource-subscription --help

2. Quick install

npm install -g @thenavidm/gumroad-mcp-cli@latest
gumroad-cli --version
gumroad-cli tools
gumroad-cli login

3. Set up Gumroad access

Seller authentication and independent license credentials

  1. Sign into the intended Gumroad seller account. Use the application form/access-token controls in advanced settings, or an application OAuth authorization with only the scopes your task needs. The current API accepts Bearer tokens; this package sends seller tokens in the Authorization header, not an access_token URL. It does not implement the official CLI's interactive device/browser OAuth login.
  2. Configure exactly one private GUMROAD_ACCESS_TOKEN or GUMROAD_TOKEN_FILE. Use an absolute owner-private token-only file outside the repository. Tokens represent a particular seller and permission set; a profile name does not grant scopes or establish account ownership. Never copy an admin token into the seller-token setting.
  3. License verification needs the customer's license credential and current native product_id, without seller OAuth. Configure GUMROAD_LICENSE_KEY OR GUMROAD_LICENSE_FILE privately. verify_license always transmits increment_uses_count=false. Omitted native increment defaults to true, so increment_license_uses is a separate explicitly confirmed command. Seller license enable/disable/decrement/rotate needs both that license credential and the intended seller access token. Raw license keys are not tool arguments.
  4. Private credential files are token-only, at most 64 KiB, regular non-symlink absolute paths. On POSIX, the runtime user must own the file and permissions must be owner-only, normally 0600, inside a private directory. Windows requires separately restricted ACLs. GUI, Docker and remote runtime paths are their own paths, not the host's automatically shared files.
  5. gumroad-cli login prints these instructions only. gumroad-cli doctor checks configured profile labels and policy locally; doctor --network deliberately performs GET /v2/user. That establishes one seller read, not every scope, all tool success, license entitlement or financial correctness. Private file credentials are cached for the process; restart clients after rotation or revocation.

Scopes and provider authority

view_profile permits profile/product reads. edit_products covers product, variant, discount and custom-field work and seller license changes. view_sales covers sales/subscriber reads and sale-event subscriptions; edit_sales covers refunds, access changes and receipt resends; mark_sales_as_shipped permits shipping status changes; view_payouts covers payout reads. account is a broad fallback on many current native endpoints, not universal authority for every newer API. Refund policy uses account authority. Resource subscription permissions vary by event; inspect the native response and current source rather than inferring permission from the name.

Use the least privilege supported by Gumroad. Read-only is a local process policy and does not narrow a token at the provider or govern another client. A successful get_user response is not proof that a product belongs to an intended seller, that a license grants entitlement, or that a refund is correct. No test/live mode label is invented for seller tokens. Keep provider/customer consent separate from local effect approval.

Several private seller and license profiles

GUMROAD_ACCOUNTS is a private JSON array with unique name and access_token OR token_file, plus license_key OR license_file when needed. Named profiles never inherit global credentials or another profile's key. GUMROAD_DEFAULT_ACCOUNT chooses an exact default label; --account selects another configured label. list_accounts reports only labels, default selection and credential availability, not secret values, file paths or provider identity. Missing credentials fail only when the requested credential type is used.

gumroad-cli list-accounts --agent
gumroad-cli get-user --account intended-seller --agent
gumroad-cli verify-license --product-id REVIEWED_PRODUCT_ID --account intended-license --agent

These labels/IDs are placeholders. Configure their real values privately. Revoke or replace the intended application token in Gumroad's account/application controls, rotate a customer license only on explicit request, and restart the dependent runtimes. Removing our package does not revoke tokens or reverse provider effects.

4. Connect your client

Complete client and OS details are in INSTALL.md.

Codex

Codex is the current validation priority. Private token paths must exist in the process or remote environment where the server runs.

codex mcp add gumroad -- npx -y @thenavidm/gumroad-mcp-cli@latest
codex mcp list

Account credentials must reach the server through private environment settings. codex mcp add --env NAME=value stores values in your local config, so never commit that config or put secrets in a shared command. In TOML, the equivalent server is:

[mcp_servers.gumroad]
command = "npx"
args = ["-y", "@thenavidm/gumroad-mcp-cli@latest"]
env_vars = ["GUMROAD_ACCESS_TOKEN", "GUMROAD_TOKEN_FILE", "GUMROAD_LICENSE_KEY", "GUMROAD_LICENSE_FILE", "GUMROAD_ACCOUNTS", "GUMROAD_DEFAULT_ACCOUNT", "GUMROAD_READ_ONLY", "GUMROAD_ALLOW_DESTRUCTIVE", "GUMROAD_AUDIT_LOG", "GUMROAD_REQUEST_TIMEOUT_MS", "GUMROAD_MIN_REQUEST_INTERVAL_MS"]

env_vars forwards those names from the environment available to Codex. If that environment does not contain them, configure private env settings locally. Codex can also call the CLI directly with SKILL.md and --agent output.

Claude Code

For a user-scoped connection, after privately configuring credentials:

claude mcp add --scope user gumroad -- npx -y @thenavidm/gumroad-mcp-cli@latest
claude mcp list

Use the client's private local environment settings for the account variable if they are not inherited. Claude's -e NAME=value registration option writes values into its config; only use it locally through your secret manager, with no shared command transcript. Never place credentials in a project .mcp.json. Reconnect and ask Claude to verify credentials.

Alternatively install the CLI, make SKILL.md available to Claude, and use shell commands. Registering both surfaces is optional.

Claude Desktop

Install the .mcpb extension

  1. Download gumroad-3.0.0.mcpb from GitHub Releases.
  2. In a supported Claude Desktop build, open Settings > Extensions > Advanced settings > Install Extension… and select it.
  3. Configure seller token OR token-only file. Add a private customer license OR license file when needed; leave unused sources empty. Named profiles require private manual runtime settings.
  4. Enable read-only if you want only the 25 read/helper operations. Reconnect and verify the intended profile with one deliberate read.

The bundle includes production dependencies and no credentials. Use a regular private token-only file if you prefer file-based credentials. The manifest requires Node 22 or newer from a compatible host. Organization policy may restrict custom extensions. Manual bundle updates require installing the new version; no automatic directory updates are promised. GUI installation remains unverified separately from archive/protocol checks.

Manual config

Open Settings > Developer > Edit Config, or use your platform's config file:

| OS | Typical config path | | --- | --- | | macOS | ~/Library/Application Support/Claude/claude_desktop_config.json | | Windows | %APPDATA%\Claude\claude_desktop_config.json | | Linux | ~/.config/Claude/claude_desktop_config.json; confirm the location through Edit Config in your installed build |

{
  "mcpServers": {
    "gumroad": {
      "command": "npx",
      "args": ["-y", "@thenavidm/gumroad-mcp-cli@latest"],
      "env": {
        "GUMROAD_ACCESS_TOKEN": "YOUR_PRIVATE_SELLER_TOKEN",
        "GUMROAD_TOKEN_FILE": ""
      }
    }
  }
}

Replace the placeholders only in your private file. Merge the server entry into an existing mcpServers object instead of replacing other integrations. Fully quit and reopen Claude Desktop. Do not enable an extension and a manual entry with the same name; choose one route.

If a Windows launcher cannot execute npx directly, use "command": "cmd" with "args": ["/c", "npx", "-y", "@thenavidm/gumroad-mcp-cli@latest"]. An absolute node executable and installed dist/index.js path also avoids launcher/PATH problems.

Cursor

Use private user settings at ~/.cursor/mcp.json, or Settings > Tools & MCP. Cursor documents environment interpolation and envFile support.

{
  "mcpServers": {
    "gumroad": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@thenavidm/gumroad-mcp-cli@latest"],
      "env": {
        "GUMROAD_ACCESS_TOKEN": "${env:GUMROAD_ACCESS_TOKEN}",
        "GUMROAD_TOKEN_FILE": "${env:GUMROAD_TOKEN_FILE}"
      }
    }
  }
}

The environment values must exist for the Cursor process. If you use envFile, keep that file private and outside version control. A project .cursor/mcp.json must not contain actual credentials. Reconnect the server after saving.

VS Code and Copilot

Use MCP: Open User Configuration. VS Code uses servers and secure inputs, rather than a mcpServers root:

{
  "inputs": [
    {"type": "promptString", "id": "gumroad-api-token", "description": "Gumroad API key (leave empty for a private token file)", "password": true},
    {"type": "promptString", "id": "gumroad-token-file", "description": "Optional private token-file path (leave empty for API key)"}
  ],
  "servers": {
    "gumroad": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@thenavidm/gumroad-mcp-cli@latest"],
      "env": {
        "GUMROAD_ACCESS_TOKEN": "${input:gumroad-api-token}",
        "GUMROAD_TOKEN_FILE": "${input:gumroad-token-file}"
      }
    }
  }
}

Start Gumroad through the MCP controls, approve trust if prompted, and enter credentials in the private input prompts. Workspace .vscode/mcp.json may contain this placeholder-only structure, but never resolved secret values. Remote development runs the server in the selected remote environment, so local file paths refer to that environment.

Windsurf

Open Cascade's MCP settings or edit the private user file ~/.codeium/windsurf/mcp_config.json. Use the Claude Desktop manual mcpServers block above with your locally configured env values. See Windsurf's current MCP documentation. Restart or reconnect Gumroad in Cascade; project files must not contain secrets.

Zed

Open Settings > AI > MCP Servers > Add Server > Add Local Server, or your user settings file. Zed uses context_servers:

{
  "context_servers": {
    "gumroad": {
      "command": "npx",
      "args": ["-y", "@thenavidm/gumroad-mcp-cli@latest"],
      "env": {
        "GUMROAD_ACCESS_TOKEN": "YOUR_PRIVATE_SELLER_TOKEN",
        "GUMROAD_TOKEN_FILE": ""
      }
    }
  }
}

Enter actual values only in private user settings. Check the active-server indicator before prompting. Do not wrap command and args inside a nested command object from older Zed examples.

Gemini CLI

Merge the Claude Desktop manual mcpServers block into your private ~/.gemini/settings.json. Configure the private credential values locally, then restart Gemini CLI and inspect /mcp. See Gemini CLI's MCP configuration. Its project settings must not contain real credentials. You can instead use the CLI from an agent shell.

Other local stdio clients use the same command and arguments, adapted to their config format. A client that only accepts a remote MCP URL cannot connect directly: this package does not ship a public HTTP listener. ChatGPT's remote connector setup is not a substitute for local stdio installation.

Docker

Build locally from the reviewed source; no prebuilt registry image is claimed:

git clone https://github.com/thenavidm/gumroad-mcp-cli.git
cd gumroad-mcp-cli
docker build -t gumroad-mcp-cli .
docker run --rm -i -e GUMROAD_ACCESS_TOKEN gumroad-mcp-cli

Cline and other local MCP clients

Use the client's Add MCP server flow with command npx, arguments -y and @thenavidm/gumroad-mcp-cli@latest, stdio transport, and private local GUMROAD_ACCESS_TOKEN or GUMROAD_TOKEN_FILE settings. UI names depend on the installed client. Reconnect and discover tools before an account call. Browser-only clients need a remote HTTPS connector; choose a separately supported remote connector rather than this local stdio command.

5. Check it works

gumroad-cli --version
gumroad-cli tools
gumroad-cli list-accounts --agent
gumroad-cli doctor
# One deliberate native seller read after private configuration
gumroad-cli doctor --network

Help/discovery/login/schema are local. Real provider account outcomes, desktop GUI installation and matched Codex usage remain separate evidence from fixture/protocol checks.

6. Output, flags and exit codes

gumroad-cli list-sales --agent
gumroad-cli get-sale --sale-id REVIEWED_SALE_ID --agent --select sale.id,sale.currency
gumroad-cli schema refund-sale

CLI uses hyphenated commands, MCP uses underscores. --json gives parsed native objects, --compact emits one line, --agent requests compact JSON with no prompts and never confirms, and --select keeps chosen fields. None approves effects. Repeated --tags takes each string; --tasks takes each task JSON object; --arguments takes one JSON filter object.

| Exit | Meaning | | --- | --- | | 0 | Success | | 1 | Unexpected error | | 2 | Usage/input/refused effect, an unknown command or a hidden write | | 3 | Native/helper not found | | 4 | Authentication/permission | | 5 | API/unknown transport failure | | 7 | Rate limited | | 10 | Missing/invalid configuration |

7. MCP or CLI and token cost

Client loading mode matters: MCP may load full schemas, defer discovery or select tools. CLI also needs help/schema discovery, execution and model-readable output. --agent emits compact JSON; --select can narrow returned fields without changing the requested native call. These formatting options do not establish fewer tokens for a successful equivalent task.

Measured on 2026-10-05 against 2.0.1, with Claude Code 2.1.286 on Claude Opus 5.5 (one short prompt with and without the server connected, the difference read from the API's own usage figures) and Codex 0.159.3 on gpt-6.1-sol:

| Cost | 2.0.1 | 3.0.0 | | --- | --- | --- | | Claude Code, every tool loaded, every message | 22,424 | 22,128 | | Claude Code's default, tool search, every message | 1,138 | 1,139 | | SKILL.md, read once | 4,438 | 4,502 | | Codex over the CLI, one task, median of five | 104,433 | 82,764 | | Codex over MCP, the same task, median of five | 76,448 | 76,542 |

The task was "find the command that refunds a sale, and the flags it requires". Every tool loaded costs less because prices and counts no longer advertise JavaScript's safe-integer bounds, while the list a client receives grows by an approval marker on the 32 confirmed tools, which Claude Code does not pass to the model. Over the CLI, four 2.0.1 runs tried schema without a command and then read the whole command list, and four 3.0.0 runs asked which refund, which fits three commands alike and so lists them, then read the right command's help. Over MCP, Codex prints only part of a tool list this long, and 3.0.0's part takes a few more tokens to say. SKILL.md costs 64 more because it says how approval works over MCP and what exit codes 1 and 2 cover.

Tool-list bytes or characters divided by four are not API usage, and no other offering was measured.

8. Every tool and argument

get_user

Get user. Reviewed native GET /user; scope: view_profile. Read only; no local effect approval required.

| Argument | Type | Required | Meaning and constraints | | --- | --- | --- | --- | | account | string | Optional | Exact private profile label; never inherited credentials, ownership or scope proof. |

gumroad-cli get-user --help
gumroad-cli schema get-user
{
  "type": "object",
  "properties": {
    "account": {
      "type": "string",
      "description": "Exact private profile label; never inherited credentials, ownership or scope proof."
    }
  },
  "required": [],
  "additionalProperties": false
}

Native request: GET /user. Authentication/scope: view_profile. Pinned official source. Native fields are URL query for GET or form fields for effects. Private license credentials and forced verify increment flag are supplied internally; account/confirm/full_refund/output_file are local controls.

{
  "name": "get_user",
  "title": "Get user",
  "description": "Get user. Reviewed native GET /user; scope: view_profile. Read only; no local effect approval required.",
  "group": "User",
  "method": "GET",
  "path": "/user",
  "pathKeys": {},
  "properties": {},
  "required": [],
  "nativeFields": [],
  "risk": "read",
  "scope": "view_profile",
  "licenseAPI": false,
  "privateOutput": false,
  "collection": null,
  "sourceFile": "app/javascript/components/ApiDocumentation/Endpoints/User.tsx"
}

list_categories

List categories. Reviewed native GET /categories; scope: view_profile. Read only; no local effect approval required.

| Argument | Type | Required | Meaning and constraints | | --- | --- | --- | --- | | account | string | Optional | Exact private profile label; never inherited credentials, ownership or scope proof. |

gumroad-cli list-categories --help
gumroad-cli schema list-categories
{
  "type": "object",
  "properties": {
    "account": {
      "type": "string",
      "description": "Exact private profile label; never inherited credentials, ownership or scope proof."
    }
  },
  "required": [],
  "additionalProperties": false
}

Native request: GET /categories. Authentication/scope: view_profile. Pinned official source. Native fields are URL query for GET or form fields for effects. Private license credentials and forced verify increment flag are supplied internally; account/confirm/full_refund/output_file are local controls.

{
  "name": "list_categories",
  "title": "List categories",
  "description": "List categories. Reviewed native GET /categories; scope: view_profile. Read only; no local effect approval required.",
  "group": "Products",
  "method": "GET",
  "path": "/categories",
  "pathKeys": {},
  "properties": {},
  "required": [],
  "nativeFields": [],
  "risk": "read",
  "scope": "view_profile",
  "licenseAPI": false,
  "privateOutput": false,
  "collection": null,
  "sourceFile": "app/javascript/components/ApiDocumentation/Endpoints/Products.tsx"
}

list_products

List products. Reviewed native GET /products; scope: view_profile. Read only; no local effect approval required.

| Argument | Type | Required | Meaning and constraints | | --- | --- | --- | --- | | page_key | string | Optional | Opaque native continuation cursor; never an arbitrary URL. {"minLength": 1, "maxLength": 1024} | | account | string | Optional | Exact private profile label; never inherited credentials, ownership or scope proof. |

gumroad-cli list-products --help
gumroad-cli schema list-products
{
  "type": "object",
  "properties": {
    "page_key": {
      "type": "string",
      "maxLength": 1024,
      "description": "Opaque native continuation cursor; never an arbitrary URL.",
      "minLength": 1
    },
    "account": {
      "type": "string",
      "description": "Exact private profile label; never inherited credentials, ownership or scope proof."
    }
  },
  "required": [],
  "additionalProperties": false
}

Native request: GET /products. Authentication/scope: view_profile. Pinned official source. Native fields are URL query for GET or form fields for effects. Private license credentials and forced verify increment flag are supplied internally; account/confirm/full_refund/output_file are local controls.

{
  "name": "list_products",
  "title": "List products",
  "description": "List products. Reviewed native GET /products; scope: view_profile. Read only; no local effect approval required.",
  "group": "Products",
  "method": "GET",
  "path": "/products",
  "pathKeys": {},
  "properties": {
    "page_key": {
      "type": "string",
      "maxLength": 1024,
      "description": "Opaque native continuation cursor; never an arbitrary URL.",
      "minLength": 1
    }
  },
  "required": [],
  "nativeFields": [
    "page_key"
  ],
  "risk": "read",
  "scope": "view_profile",
  "licenseAPI": false,
  "privateOutput": false,
  "collection": "products",
  "sourceFile": "app/javascript/components/ApiDocumentation/Endpoints/Products.tsx"
}

get_product

Get product. Reviewed native GET /products/:id; scope: view_profile. Read only; no local effect approval required.

| Argument | Type | Required | Meaning and constraints | | --- | --- | --- | --- | | product_id | string | Required | Exact opaque provider ID, including native = padding. {"minLength": 1, "maxLength": 256, "pattern": "^[A-Za-z0-9_=-]+$"} | | account | string | Optional | Exact private profile label; never inherited credentials, ownership or scope proof. |

gumroad-cli get-product --help
gumroad-cli schema get-product
{
  "type": "object",
  "properties": {
    "product_id": {
      "type": "string",
      "maxLength": 256,
      "description": "Exact opaque provider ID, including native = padding.",
      "minLength": 1,
      "pattern": "^[A-Za-z0-9_=-]+$"
    },
    "account": {
      "type": "string",
      "description": "Exact private profile label; never inherited credentials, ownership or scope proof."
    }
  },
  "required": [
    "product_id"
  ],
  "additionalProperties": false
}

Native request: GET /products/{id}. Authentication/scope: view_profile. Pinned official source. Native fields are URL query for GET or form fields for effects. Private license credentials and forced verify increment flag are supplied internally; account/confirm/full_refund/output_file are local controls.

{
  "name": "get_product",
  "title": "Get product",
  "description": "Get product. Reviewed native GET /products/:id; scope: view_profile. Read only; no local effect approval required.",
  "group": "Products",
  "method": "GET",
  "path": "/products/{id}",
  "pathKeys": {
    "id": "product_id"
  },
  "properties": {
    "product_id": {
      "type": "string",
      "maxLength": 256,
      "description": "Exact opaque provider ID, including native = padding.",
      "minLength": 1,
      "pattern": "^[A-Za-z0-9_=-]+$"
    }
  },
  "required": [
    "product_id"
  ],
  "nativeFields": [],
  "risk": "read",
  "scope": "view_profile",
  "licenseAPI": false,
  "privateOutput": false,
  "collection": null,
  "sourceFile": "app/javascript/components/ApiDocumentation/Endpoints/Products.tsx"
}

create_product

Create product. Reviewed native POST /products; scope: edit_products. Requires explicit per-call confirmation.

| Argument | Type | Required | Meaning and constraints | | --- | --- | --- | --- | | draft | boolean | Optional | (optional, true or false, default false) save as an unpublished draft instead of publishing | | published | boolean | Optional | (optional, true or false, default true) false saves as an unpublished draft, same as draft=true | | native_type | string | Optional | (optional, "digital" (default), "course", "ebook", "membership", "bundle", "coffee", "call", or "commission") cannot be changed later {"enum": ["digital", "course", "ebook", "membership", "bundle", "coffee", "call", "commission"]} | | name | string | Required | (required) {"minLength": 1, "maxLength": 65536} | | description | string | Optional | (optional) HTML {"maxLength": 65536} | | custom_permalink | string | Optional | (optional) {"maxLength": 65536} | | price | integer | Required | (required) in the smallest currency unit (e.g. cents) {"minimum": 0, "maximum": 9007199254740991} | | price_currency_type | string | Optional | (optional) ISO currency code; defaults to your account currency {"maxLength": 65536, "pattern": "^[a-zA-Z]{3}$"} | | subscription_duration | string | Optional | (optional, membership only, "monthly", "quarterly", "biannually", "yearly", or "every_two_years") {"enum": ["monthly", "quarterly", "biannually", "yearly", "every_two_years"]} | | customizable_price | boolean | Optional | (optional, true or false) pay-what-you-want | | suggested_price_cents | integer | Optional | (optional) {"minimum": 0, "maximum": 9007199254740991} | | max_purchase_count | integer | Optional | (optional) {"minimum": 0, "maximum": 9007199254740991} | | category | string | Optional | (optional) full category path from GET /v2/categories, e.g. "design/ui-and-web/figma"; cannot be sent with taxonomy_id {"maxLength": 65536} | | taxonomy_id | string | Optional | (optional) numeric category ID; alias for category, cannot be sent with category {"minLength": 1, "maxLength": 256, "pattern": "^[A-Za-z0-9_=-]+$"} | | tags | array | Optional | (optional) array of tag strings {"maxItems": 100} | | custom_summary | string | Optional | (optional) {"maxLength": 65536} | | refund_period | string | Optional | (optional, "inherit", "none", "7", "14", "30", or "183") sets a product-level refund policy; "inherit" uses the account default. Only available when the account-level refund policy is not in effect; otherwise use PUT /v2/refund_policy {"enum": ["inherit", "none", "7", "14", "30", "183"]} | | refund_fine_print | string | Optional | (optional) fine print for the product-level refund policy; requires refund_period unless the product already has one enabled, and cannot be combined with refund_period "inherit". Empty string clears it {"maxLength": 65536} | | account | string | Optional | Exact private profile label; never inherited credentials, ownership or scope proof. | | confirm | boolean | Optional | Set true only when the user asked for exactly this action. |

gumroad-cli create-product --help
gumroad-cli schema create-product
{
  "type": "object",
  "properties": {
    "draft": {
      "type": "boolean",
      "description": "(optional, true or false, default false) save as an unpublished draft instead of publishing"
    },
    "published": {
      "type": "boolean",
      "description": "(optional, true or false, default true) false saves as an unpublished draft, same as draft=true"
    },
    "native_type": {
      "type": "string",
      "enum": [
        "digital",
        "course",
        "ebook",
        "membership",
        "bundle",
        "coffee",
        "call",
        "commission"
      ],
      "description": "(optional, \"digital\" (default), \"course\", \"ebook\", \"membership\", \"bundle\", \"coffee\", \"call\", or \"commission\") cannot be changed later"
    },
    "name": {
      "type": "string",
      "maxLength": 65536,
      "description": "(required)",
      "minLength": 1
    },
    "description": {
      "type": "string",
      "maxLength": 65536,
      "description": "(optional) HTML"
    },
    "custom_permalink": {
      "type": "string",
      "maxLength": 65536,
      "description": "(optional)"
    },
    "price": {
      "type": "integer",
      "description": "(required) in the smallest currency unit (e.g. cents)",
      "minimum": 0,
      "maximum": 9007199254740991
    },
    "price_currency_type": {
      "type": "string",
      "maxLength": 65536,
      "description": "(optional) ISO currency code; defaults to your account currency",
      "pattern": "^[a-zA-Z]{3}$"
    },
    "subscription_duration": {
      "type": "string",
      "enum": [
        "monthly",
        "quarterly",
        "biannually",
        "yearly",
        "every_two_years"
      ],
      "description": "(optional, membership only, \"monthly\", \"quarterly\", \"biannually\", \"yearly\", or \"every_two_years\")"
    },
    "customizable_price": {
      "type": "boolean",
      "description": "(optional, true or false) pay-what-you-want"
    },
    "suggested_price_cents": {
      "type": "integer",
      "description": "(optional)",
      "minimum": 0,
      "maximum": 9007199254740991
    },
    "max_purchase_count": {
      "type": "integer",
      "description": "(optional)",
      "minimum": 0,
      "maximum": 9007199254740991
    },
    "category": {
      "type": "string",
      "maxLength": 65536,
      "description": "(optional) full category path from GET /v2/categories, e.g. \"design/ui-and-web/figma\"; cannot be sent with taxonomy_id"
    },
    "taxonomy_id": {
      "type": "string",
      "maxLength": 256,
      "description": "(optional) numeric category ID; alias for category, cannot be sent with category",
      "minLength": 1,
      "pattern": "^[A-Za-z0-9_=-]+$"
    },
    "tags": {
      "type": "array",
      "maxItems": 100,
      "items": {
        "type": "string",
        "maxLength": 100,
        "description": "Tag",
        "minLength": 1
      },
      "description": "(optional) array of tag strings"
    },
    "custom_summary": {
      "type": "string",
      "maxLength": 65536,
      "description": "(optional)"
    },
    "refund_period": {
      "type": "string",
      "enum": [
        "inherit",
        "none",
        "7",
        "14",
        "30",
        "183"
      ],
      "description": "(optional, \"inherit\", \"none\", \"7\", \"14\", \"30\", or \"183\") sets a product-level refund policy; \"inherit\" uses the account default. Only available when the account-level refund policy is not in effect; otherwise use PUT /v2/refund_policy"
    },
    "refund_fine_print": {
      "type": "string",
      "maxLength": 65536,
      "description": "(optional) fine print for the product-level refund policy; requires refund_period unless the product already has one enabled, and cannot be combined with refund_period \"inherit\". Empty string clears it"
    },
    "account": {
      "type": "string",
      "description": "Exact private profile label; never inherited credentials, ownership or scope proof."
    },
    "confirm": {
      "type": "boolean",
      "description": "Explicit approval of this exact native effect or private file output."
    }
  },
  "required": [
    "name",
    "price"
  ],
  "additionalProperties": false
}

Native request: POST /products. Authentication/scope: edit_products. Pinned official source. Native fields are URL query for GET or form fields for effects. Private license credentials and forced verify increment flag are supplied internally; account/confirm/full_refund/output_file are local controls.

{
  "name": "create_product",
  "title": "Create product",
  "description": "Create product. Reviewed native POST /products; scope: edit_products. Requires explicit per-call confirmation.",
  "group": "Products",
  "method": "POST",
  "path": "/products",
  "pathKeys": {},
  "properties": {
    "draft": {
      "type": "boolean",
      "description": "(optional, true or false, default false) save as an unpublished draft instead of publishing"
    },
    "published": {
      "type": "boolean",
      "description": "(optional, true or false, default true) false saves as an unpublished draft, same as draft=true"
    },
    "native_type": {
      "type": "string",
      "enum": [
        "digital",
        "course",
        "ebook",
        "membership",
        "bundle",
        "coffee",
        "call",
        "commission"
      ],
      "description": "(optional, \"digital\" (default), \"course\", \"ebook\", \"membership\", \"bundle\", \"coffee\", \"call\", or \"commission\") cannot be changed later"
    },
    "name": {
      "type": "string",
      "maxLength": 65536,
      "description": "(required)",
      "minLength": 1
    },
    "description": {
      "type": "string",
      "maxLength": 65536,
      "description": "(optional) HTML"
    },
    "custom_permalink": {
      "type": "string",
      "maxLength": 65536,
      "description": "(optional)"
    },
    "price": {
      "type": "integer",
      "description": "(required) in the smallest currency unit (e.g. cents)",
      "minimum": 0,
      "maximum": 9007199254740991
    },
    "price_currency_type": {
      "type": "string",
      "maxLength": 65536,
      "description": "(optional) ISO currency code; defaults to your account currency",
      "pattern": "^[a-zA-Z]{3}$"
    },
    "subscription_duration": {
      "type": "string",
      "enum": [
        "monthly",
        "quarterly",
        "biannually",
        "yearly",
        "every_two_years"
      ],
      "description": "(optional, membership only, \"monthly\", \"quarterly\", \"biannually\", \"yearly\", or \"every_two_years\")"
    },
    "customizable_price": {
      "type": "boolean",
      "description": "(optional, true or false) pay-what-you-want"
    },
    "suggested_price_cents": {
      "type": "integer",
      "description": "(optional)",
      "minimum": 0,
      "maximum": 9007199254740991
    },
    "max_purchase_count": {
      "type": "integer",
      "description": "(optional)",
      "minimum": 0,
      "maximum": 9007199254740991
    },
    "category": {
      "type": "string",
      "maxLength": 65536,
      "description": "(optional) full category path from GET /v2/categories, e.g. \"design/ui-and-web/figma\"; cannot be sent with taxonomy_id"
    },
    "taxonomy_id": {
      "type": "string",
      "maxLength": 256,
      "description": "(optional) numeric category ID; alias for category, cannot be sent with category",
      "minLength": 1,
      "pattern": "^[A-Za-z0-9_=-]+$"
    },
    "tags": {
      "type": "array",
      "maxItems": 100,
      "items": {
        "type": "string",
        "maxLength": 100,
        "description": "Tag",
        "minLength": 1
      },
      "description": "(optional) array of tag strings"
    },
    "custom_summary": {
      "type": "string",
      "maxLength": 65536,
      "description": "(optional)"
    },
    "refund_period": {
      "type": "string",
      "enum": [
        "inherit",
        "none",
        "7",
        "14",
        "30",
        "183"
      ],
      "description": "(optional, \"inherit\", \"none\", \"7\", \"14\", \"30\", or \"183\") sets a product-level refund policy; \"inherit\" uses the account default. Only available when the account-level refund policy is not in effect; otherwise use PUT /v2/refund_policy"
    },
    "refund_fine_print": {
      "type": "string",
      "maxLength": 65536,
      "description": "(optional) fine print for the product-level refund policy; requires refund_period unless the product already has one enabled, and cannot be combined with refund_period \"inherit\". Empty string clears it"
    }
  },
  "required": [
    "name",
    "price"
  ],
  "nativeFields": [
    "draft",
    "published",
    "native_type",
    "name",
    "description",
    "custom_permalink",
    "price",
    "price_currency_type",
    "subscription_duration",
    "customizable_price",
    "suggested_price_cents",
    "max_purchase_count",
    "category",
    "taxonomy_id",
    "tags",
    "custom_summary",
    "refund_period",
    "refund_fine_print"
  ],
  "risk": "destructive",
  "scope": "edit_products",
  "licenseAPI": false,
  "privateOutput": false,
  "collection": null,
  "sourceFile": "app/javascript/components/ApiDocumentation/Endpoints/Products.tsx"
}

update_product

Update product. Reviewed native PUT /products/:id; scope: edit_products. Requires explicit per-call confirmation.

| Argument | Type | Required | Meaning and constraints | | --- | --- | --- | --- | | product_id | string | Required | Exact opaque provider ID, including native = padding. {"minLength": 1, "maxLength": 256, "pattern": "^[A-Za-z0-9_=-]+$"} | | name | string | Optional | (optional) {"minLength": 1, "maxLength": 65536} | | description | string | Optional | (optional) HTML {"maxLength": 65536} | | custom_permalink | string | Optional | (optional) {"maxLength": 65536} | | price | integer | Optional | (optional) in the smallest currency unit; not allowed for tiered memberships — use the variant endpoints to manage tier pricing {"minimum": 0, "maximum": 9007199254740991} | | price_currency_type | string | Optional | (optional) ISO currency code {"maxLength": 65536, "pattern": "^[a-zA-Z]{3}$"} | | customizable_price | boolean | Optional | (optional, true or false) | | suggested_price_cents | integer | Optional | (optional) {"minimum": 0, "maximum": 9007199254740991} | | max_purchase_count | integer | Optional | (optional) {"minimum": 0, "maximum": 9007199254740991} | | quantity_enabled | boolean | Optional | (optional, true or false) | | is_adult | boolean | Optional | (optional, true or false) | | display_product_reviews | boolean | Optional | (optional, true or false) | | should_show_sales_count | boolean | Optional | (optional, true or false) | | category | string | Optional | (optional) full category path from GET /v2/categories, e.g. "design/ui-and-web/figma"; cannot be sent with taxonomy_id {"maxLength": 65536} | | taxonomy_id | string | Optional | (optional) numeric category ID; alias for category, cannot be sent with category {"minLength": 1, "maxLength": 256, "pattern": "^[A-Za-z0-9_=-]+$"} | | tags | array | Optional | (optional) array of tag strings; full replacement {"maxItems": 100} | | custom_receipt | string | Optional | (optional) {"maxLength": 65536} | | custom_summary | string | Optional | (optional) {"maxLength": 65536} | | refund_period | string | Optional | (optional, "inherit", "none", "7", "14", "30", or "183") sets a product-level refund policy; "inherit" switches the product back to the account default. Only available when the account-level refund policy is not in effect; otherwise use PUT /v2/refund_policy {"enum": ["inherit", "none", "7", "14", "30", "183"]} | | refund_fine_print | string | Optional | (optional) fine print for the product-level refund policy; requires refund_period unless the product already has one enabled, and cannot be combined with refund_period "inherit". Empty string clears it {"maxLength": 65536} | | has_same_rich_content_for_all_variants | boolean | Optional | (optional, true or false) switches between product-level and per-variant rich content | | account | string | Optional | Exact private profile label; never inherited credentials, ownership or scope proof. | | confirm | boolean | Optional | Set true only when the user asked for exactly this action. |

gumroad-cli update-product --help
gumroad-cli schema update-product
{
  "type": "object",
  "properties": {
    "product_id": {
      "type": "string",
      "maxLength": 256,
      "description": "Exact opaque provider ID, including native = padding.",
      "minLength": 1,
      "pattern": "^[A-Za-z0-9_=-]+$"
    },
    "name": {
      "type": "string",
      "maxLength": 65536,
      "description": "(optional)",
      "minLength": 1
    },
    "description": {
      "type": "string",
      "maxLength": 65536,
      "description": "(optional) HTML"
    },
    "custom_permalink": {
      "type": "string",
      "maxLength": 65536,
      "description": "(optional)"
    },
    "price": {
      "type": "integer",
      "description": "(optional) in the smallest currency unit; not allowed for tiered memberships \u2014 use the variant endpoints to manage tier pricing",
      "minimum": 0,
      "maximum": 9007199254740991
    },
    "price_currency_type": {
      "type": "string",
      "maxLength": 65536,
      "description": "(optional) ISO currency code",
      "pattern": "^[a-zA-Z]{3}$"
    },
    "customizable_price": {
      "type": "boolean",
      "description": "(optional, true or false)"
    },
    "suggested_price_cents": {
      "type": "integer",
      "description": "(optional)",
      "minimum": 0,
      "maximum": 9007199254740991
    },
    "max_purchase_count": {
      "type": "integer",
      "description": "(optional)",
      "minimum": 0,
      "maximum": 9007199254740991
    },
    "quantity_enabled": {
      "type": "boolean",
      "description": "(optional, true or false)"
    },
    "is_adult": {
      "type": "boolean",
      "description": "(optional, true or false)"
    },
    "display_product_reviews": {
      "type": "boolean",
      "description": "(optional, true or false)"
    },
    "should_show_sales_count": {
      "type": "boolean",
      "description": "(optional, true or false)"
    },
    "category": {
      "type": "string",
      "maxLength": 65536,
      "description": "(optional) full category path from GET /v2/categories, e.g. \"design/ui-and-web/figma\"; cannot be sent with taxonomy_id"
    },
    "taxonomy_id": {
      "type": "string",
      "maxLength": 256,
      "description": "(optional) numeric category ID; alias for category, cannot be sent with category",
      "minLength": 1,
      "pattern": "^[A-Za-z0-9_=-]+$"
    },
    "tags": {
      "type": "array",
      "maxItems": 100,
      "items": {
        "type": "string",
        "maxLength": 100,
        "description": "Tag",
        "minLength": 1
      },
      "description": "(optional) array of tag strings; full replacement"
    },
    "custom_receipt": {
      "type": "string",
      "maxLength": 65536,
      "description": "(optional)"
    },
    "custom_summary": {
      "type": "string",
      "maxLength": 65536,
      "description": "(optional)"
    },
    "refund_period": {
      "type": "string",
      "enum": [
        "inherit",
        "none",
        "7",
        "14",
        "30",
        "183"
      ],
      "description": "(optional, \"inherit\", \"none\", \"7\", \"14\", \"30\", or \"183\") sets a product-level refund policy; \"inherit\" switches the product back to the account default. Only available when the account-level refund policy is not in effect; otherwise use PUT /v2/refund_policy"
    },
    "refund_fine_print": {
      "type": "string",
      "maxLength": 65536,
      "description": "(optional) fine print for the product-level refund policy; requires refund_period unless the product already has one enabled, and cannot be combined with refund_period \"inherit\". Empty string clears it"
    },
    "has_same_rich_content_for_all_variants": {
      "type": "boolean",
      "description": "(optional, true or false) switches between product-level and per-variant rich content"
    },
    "account": {
      "type": "string",
      "description": "Exact private profile label; never inherited credentials, ownership or scope proof."
    },
    "confirm": {
      "type": "boolean",
      "description": "Explicit approval of this exact native effect or private file output."
    }
  },
  "required": [
    "product_id"
  ],
  "additionalProperties": false
}

Native request: PUT /products/{id}. Authentication/scope: edit_products. Pinned official source. Native fields are URL query for GET or form fields for effects. Private license credentials and forced verify increment flag are supplied internally; account/confirm/full_refund/output_file are local controls.

{
  "name": "update_product",
  "title": "Update product",
  "description": "Update product. Reviewed native PUT /products/:id; scope: edit_products. Requires explicit per-call confirmation.",
  "group": "Products",
  "method": "PUT",
  "path": "/products/{id}",
  "pathKeys": {
    "id": "product_id"
  },
  "properties": {
    "product_id": {
      "type": "string",
      "maxLength": 256,
      "description": "Exact opaque provider ID, including native = padding.",
      "minLength": 1,
      "pattern": "^[A-Za-z0-9_=-]+$"
    },
    "name": {
      "type": "string",
      "maxLength": 65536,
      "description": "(optional)",
      "minLength": 1
    },
    "description": {
      "type": "string",
      "maxLength": 65536,
      "description": "(optional) HTML"
    },
    "custom_permalink": {
      "type": "string",
      "maxLength": 65536,
      "description": "(optional)"
    },
    "price": {
      "type": "integer",
      "description": "(optional) in the smallest currency unit; not allowed for tiered memberships \u2014 use the variant endpoints to manage tier pricing",
      "minimum": 0,
      "maximum": 9007199254740991
    },
    "price_currency_type": {
      "type": "string",
      "maxLength": 65536,
      "description": "(optional) ISO currency code",
      "pattern": "^[a-zA-Z]{3}$"
    },
    "customizable_price": {
      "type": "boolean",
      "description": "(optional, true or false)"
    },
    "suggested_price_cents": {
      "type": "integer",
      "description": "(optional)",
      "minimum": 0,
      "maximum": 9007199254740991
    },
    "max_purchase_count": {
      "type": "integer",
      "description": "(optional)",
      "minimum": 0,
      "maximum": 9007199254740991
    },
    "quantity_enabled": {
      "type": "boolean",
      "description": "(optional, true or false)"
    },
    "is_adult": {
      "type": "boolean",
      "description": "(optional, true or false)"
    },
    "display_product_reviews": {
      "type": "boolean",
      "description": "(optional, true or false)"
    },
    "should_show_sales_count": {
      "type": "boolean",
      "description": "(optional, true or false)"
    },
    "category": {
      "type": "string",
      "maxLength": 65536,
      "description": "(optional) full category path from GET /v2/categories, e.g. \"design/ui-and-web/figma\"; cannot be sent with taxonomy_id"
    },
    "taxonomy_id": {
      "type": "string",
      "maxLength": 256,
      "description": "(optional) numeric category ID; alias for category, cannot be sent with category",
      "minLength": 1,
      "pattern": "^[A-Za-z0-9_=-]+$"
    },
    "tags": {
      "type": "array",
      "maxItems": 100,
      "items": {
        "type": "string",
        "maxLength": 100,
        "description": "Tag",
        "minLength": 1
      },
      "description": "(optional) array of tag strings; full replacement"
    },
    "custom_receipt": {
      "type": "string",
      "maxLength": 65536,
      "description": "(optional)"
    },
    "custom_summary": {
      "type": "string",
      "maxLength": 65536,
      "description": "(optional)"
    },
    "refund_period": {
      "type": "string",
      "enum": [
        "inherit",
        "none",
        "7",
        "14",
        "30",
        "183"
      ],
      "description": "(optional, \"inherit\", \"none\", \"7\", \"14\", \"30\", or \"183\") sets a product-level refund policy; \"inherit\" switches the product back to the account default. Only available when the account-level refund policy is not in effect; otherwise use PUT /v2/refund_policy"
    },
    "refund_fine_print": {
      "type": "string",
      "maxLength": 65536,
      "description": "(optional) fine print for the product-level refund policy; requires refund_period unless the product already has one enabled, and cannot be combined with refund_period \"inherit\". Empty string clears it"
    },
    "has_same_rich_content_for_all_variants": {
      "type": "boolean",
      "description": "(optional, true or false) switches between product-level and per-variant rich content"
    }
  },
  "required": [
    "product_id"
  ],
  "nativeFields": [
    "name",
    "description",
    "custom_permalink",
    "price",
    "price_currency_type",
    "customizable_price",
    "suggested_price_cents",
    "max_purchase_count",
    "quantity_enabled",
    "is_adult",
    "display_product_reviews",
    "should_show_sales_count",
    "category",
    "taxonomy_id",
    "tags",
    "custom_receipt",
    "custom_summary",
    "refund_period",
    "refund_fine_print",
    "has_same_rich_content_for_all_variants"
  ],
  "risk": "destructive",
  "scope": "edit_products",
  "licenseAPI": false,
  "privateOutput": false,
  "collection": null,
  "sourceFile": "app/javascript/components/ApiDocumentation/Endpoints/Products.tsx"
}

delete_product

Delete product. Reviewed native DELETE /products/:id; scope: edit_products. Requires explicit per-call confirmation.

| Argument | Type | Required | Meaning and constraints | | --- | --- | --- | --- | | product_id | string | Required | Exact opaque provider ID, including native = padding. {"minLength": 1, "maxLength": 256, "pattern": "^[A-Za-z0-9_=-]+$"} | | account | string | Optional | Exact private profile label; never inherited credentials, ownership or scope proof. | | confirm | boolean | Optional | Set true only when the user asked for exactly this action. |

gumroad-cli delete-product --help
gumroad-cli schema delete-product
{
  "type": "object",
  "properties": {
    "product_id": {
      "type": "string",
      "maxLength": 256,
      "description": "Exact opaque provider ID, including native = padding.",
      "minLength": 1,
      "pattern": "^[A-Za-z0-9_=-]+$"
    },
    "account": {
      "type": "string",
      "description": "Exact private profile label; never inherited credentials, ownership or scope proof."
    },
    "confirm": {
      "type": "boolean",
      "description": "Explicit approval of this exact native effect or private file output."
    }
  },
  "required": [
    "product_id"
  ],
  "additionalProperties": false
}

Native request: DELETE /products/{id}. Authentication/scope: edit_products. Pinned official source. Native fields are URL query for GET or form fields for effects. Private license credentials and forced verify increment flag are supplied internally; account/confirm/full_refund/output_file are local controls.

{
  "name": "delete_product",
  "title": "Delete product",
  "description": "Delete product. Reviewed native DELETE /products/:id; scope: edit_products. Requires explicit per-call confirmation.",
  "group": "Products",
  "method": "DELETE",
  "path": "/products/{id}",
  "pathKeys": {
    "id": "product_id"
  },
  "properties": {
    "product_id": {
      "type": "string",
      "maxLength": 256,
      "description": "Exact opaque provider ID, including native = padding.",
      "minLength": 1,
      "pattern": "^[A-Za-z0-9_=-]+$"
    }
  },
  "required": [
    "product_id"
  ],
  "nativeFields": [],
  "risk": "destructive",
  "scope": "edit_products",
  "licenseAPI": false,
  "privateOutput": false,
  "collection": null,
  "sourceFile": "app/javascript/components/ApiDocumentation/Endpoints/Products.tsx"
}

enable_product

Enable product. Reviewed native PUT /products/:id/enable; scope: edit_products. Requires explicit per-call confirmation.

| Argument | Type | Required | Meaning and constraints | | --- | --- | --- | --- | | product_id | string | Required | Exact opaque provider ID, including native = padding. {"minLength": 1, "maxLength": 256, "pattern": "^[A-Za-z0-9_=-]+$"} | | account | string | Optional | Exact private profile label; never inherited credentials, ownership or scope proof. | | confirm | boolean | Optional | Set true only when the user asked for exactly this action. |

gumroad-cli enable-product --help
gumroad-cli schema enable-product
{
  "type": "object",
  "properties": {
    "product_id": {
      "type": "string",
      "maxLength": 256,
      "description": "Exact opaque provider ID, including native = padding.",
      "minLength": 1,
      "pattern": "^[A-Za-z0-9_=-]+$"
    },
    "account": {
      "type": "string",
      "description": "Exact private profile label; never inherited credentials, ownership or scope proof."
    },
    "confirm": {
      "type": "boolean",
      "description": "Explicit approval of this exact native effect or private file output."
    }
  },
  "required": [
    "product_id"
  ],
  "additionalProperties": false
}

Native request: PUT /products/{id}/enable. Authentication/scope: edit_products. Pinned official source. Native fields are URL query for GET or form fields for effects. Private license credentials and forced verify increment flag are supplied internally; account/confirm/full_refund/output_file are local controls.

{
  "name": "enable_product",
  "title": "Enable product",
  "description": "Enable product. Reviewed native PUT /products/:id/enable; scope: edit_products. Requires explici