A reference guide for building AI agents: every method, how to authenticate, and the permissions each one needs.
The Gumroad API is how an app or AI agent works with a seller's Gumroad account: listing products, creating offer codes, reading sales, refunding a sale, or verifying a license key. Access is granted through an OAuth 2.0 access token whose scopes decide what a call can read or write, from view_sales for reading sales up to account for full access. Gumroad can also push events like a sale or a refund to a registered URL through a resource subscription.
How an app or AI agent connects to Gumroad determines what it can reach. There is a route for making calls and a route for receiving events, and each is governed by the access token behind it and the scopes that token carries.
The REST API answers at https://api.gumroad.com, with every method under the /v2 path. It takes form-encoded or JSON request bodies and returns JSON, where each response carries a success boolean. A call authenticates with an OAuth 2.0 access token, sent as an Authorization: Bearer header or as an access_token parameter.
A resource subscription registers a post_url that Gumroad sends an HTTP POST to whenever a chosen event fires, like a sale, a refund, a dispute, or a membership cancellation. A subscription is created through the API with the view_sales scope and is tied to the OAuth application that created it. The post_url must be a public HTTP or HTTPS URL.
Gumroad uses OAuth 2.0. A seller authorizes an application at gumroad.com/oauth/authorize, and the application exchanges the returned code for an access token at api.gumroad.com/oauth/token. The token is sent on each call as an Authorization: Bearer header or as an access_token parameter, and it carries the scopes the seller approved.
A seller can generate an access token for their own application directly in Gumroad's settings, without running the full authorization redirect. The token still carries scopes and is used the same way as an OAuth token, which suits an integration that only ever acts on the seller's own account.
The Gumroad API is split into areas an agent can act on, like products, offer codes, sales, subscribers, and licenses. Each area maps to its own scopes, and some scopes give access to far more than others.
List and read products, create and update them, enable or disable a product, and delete one.
List, create, read, update, and delete variant categories on a product and the variants inside each category.
List, read, create, update, and delete the discount codes attached to a product.
List, create, update, and delete the custom fields a product asks buyers to fill in.
List a seller's sales, read a single sale, mark a sale as shipped, refund a sale, and resend a purchase receipt.
List the subscribers of a membership product and read a single subscriber.
Verify a license key, and enable or disable a license.
List, create, and delete resource subscriptions, the webhooks Gumroad posts to when an event fires.
Read the authenticated seller's account information.
Filter by method, access, or permission, or search any path. Select a row for version detail, rate limits, the related webhook event, and the source.
| Method | Endpoint | What it does | Access | Permission | Version | |
|---|---|---|---|---|---|---|
ProductsList and read products, create and update them, enable or disable a product, and delete one.7 | ||||||
| GET | /v2/products | List all products owned by the authenticated seller, newest first. | read | view_profile | Current | |
Needs view_profile (or account). The sales_count and sales_usd_cents fields appear only when the token also has view_sales. Acts onproduct Permission (capability) view_profileVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v2/products/:id | Retrieve a single product by its id. | read | view_profile | Current | |
Needs view_profile (or account). Acts onproduct Permission (capability) view_profileVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v2/products | Create a new product. | write | edit_products | Current | |
Needs edit_products (or account). Acts onproduct Permission (capability) edit_productsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /v2/products/:id | Update an existing product. | write | edit_products | Current | |
Needs edit_products (or account). Acts onproduct Permission (capability) edit_productsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /v2/products/:id/enable | Enable (publish) a product so it can be bought. | write | edit_products | Current | |
Needs edit_products (or account). Acts onproduct Permission (capability) edit_productsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /v2/products/:id/disable | Disable (unpublish) a product so it can no longer be bought. | write | edit_products | Current | |
Needs edit_products (or account). Acts onproduct Permission (capability) edit_productsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v2/products/:id | Permanently delete a product. | write | edit_products | Current | |
Needs edit_products (or account). Irreversible. Acts onproduct Permission (capability) edit_productsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Variant categories & variantsList, create, read, update, and delete variant categories on a product and the variants inside each category.10 | ||||||
| GET | /v2/products/:product_id/variant_categories | List the variant categories on a product (a variant category is a group of options, like Size). | read | edit_products | Current | |
Needs edit_products (or account); variant categories live under the edit_products scope. Acts onvariant_category Permission (capability) edit_productsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v2/products/:product_id/variant_categories | Create a variant category on a product. | write | edit_products | Current | |
Needs edit_products (or account). Acts onvariant_category Permission (capability) edit_productsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v2/products/:product_id/variant_categories/:id | Retrieve a single variant category. | read | edit_products | Current | |
Needs edit_products (or account). Acts onvariant_category Permission (capability) edit_productsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /v2/products/:product_id/variant_categories/:id | Update a variant category. | write | edit_products | Current | |
Needs edit_products (or account). Acts onvariant_category Permission (capability) edit_productsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v2/products/:product_id/variant_categories/:id | Delete a variant category. | write | edit_products | Current | |
Needs edit_products (or account). Acts onvariant_category Permission (capability) edit_productsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v2/products/:product_id/variant_categories/:variant_category_id/variants | List the variants inside a variant category. | read | edit_products | Current | |
Needs edit_products (or account). Acts onvariant Permission (capability) edit_productsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v2/products/:product_id/variant_categories/:variant_category_id/variants | Create a variant inside a variant category. | write | edit_products | Current | |
Needs edit_products (or account). Acts onvariant Permission (capability) edit_productsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v2/products/:product_id/variant_categories/:variant_category_id/variants/:id | Retrieve a single variant. | read | edit_products | Current | |
Needs edit_products (or account). Acts onvariant Permission (capability) edit_productsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /v2/products/:product_id/variant_categories/:variant_category_id/variants/:id | Update a variant. | write | edit_products | Current | |
Needs edit_products (or account). Acts onvariant Permission (capability) edit_productsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v2/products/:product_id/variant_categories/:variant_category_id/variants/:id | Delete a variant. | write | edit_products | Current | |
Needs edit_products (or account). Acts onvariant Permission (capability) edit_productsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Offer codesList, read, create, update, and delete the discount codes attached to a product.5 | ||||||
| GET | /v2/products/:product_id/offer_codes | List the offer codes (discount codes) on a product. | read | view_profile | Current | |
Reads need view_profile (or account); creating, updating, and deleting an offer code need edit_products. Acts onoffer_code Permission (capability) view_profileVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v2/products/:product_id/offer_codes/:id | Retrieve a single offer code. | read | view_profile | Current | |
Reads need view_profile (or account). Acts onoffer_code Permission (capability) view_profileVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v2/products/:product_id/offer_codes | Create an offer code on a product. | write | edit_products | Current | |
Needs edit_products (or account). Acts onoffer_code Permission (capability) edit_productsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /v2/products/:product_id/offer_codes/:id | Update an offer code, for example its discount or maximum number of uses. | write | edit_products | Current | |
Needs edit_products (or account). Acts onoffer_code Permission (capability) edit_productsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v2/products/:product_id/offer_codes/:id | Delete an offer code. | write | edit_products | Current | |
Needs edit_products (or account). Acts onoffer_code Permission (capability) edit_productsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Custom fieldsList, create, update, and delete the custom fields a product asks buyers to fill in.4 | ||||||
| GET | /v2/products/:product_id/custom_fields | List the custom fields a product asks buyers to fill in. | read | edit_products | Current | |
Custom fields live under the edit_products scope (or account), for reads as well as writes. Acts oncustom_field Permission (capability) edit_productsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v2/products/:product_id/custom_fields | Create a custom field on a product. | write | edit_products | Current | |
Needs edit_products (or account). Acts oncustom_field Permission (capability) edit_productsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /v2/products/:product_id/custom_fields/:id | Update a custom field on a product. | write | edit_products | Current | |
Needs edit_products (or account). Acts oncustom_field Permission (capability) edit_productsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v2/products/:product_id/custom_fields/:id | Delete a custom field from a product. | write | edit_products | Current | |
Needs edit_products (or account). Acts oncustom_field Permission (capability) edit_productsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
SalesList a seller's sales, read a single sale, mark a sale as shipped, refund a sale, and resend a purchase receipt.5 | ||||||
| GET | /v2/sales | List the authenticated seller's successful sales across all products, newest first. | read | view_sales | Current | |
Needs view_sales (or account). Returns up to 10 sales per page and can be filtered by date, email, product, or order. Use the next_page_key cursor to page. Acts onsale Permission (capability) view_salesVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v2/sales/:id | Retrieve a single sale by its id. | read | view_sales | Current | |
Needs view_sales (or account). Acts onsale Permission (capability) view_salesVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /v2/sales/:id/mark_as_shipped | Mark a sale of a physical product as shipped, optionally with tracking. | write | mark_sales_as_shipped | Current | |
Needs the mark_sales_as_shipped scope specifically; view_sales alone is not enough. Acts onsale Permission (capability) mark_sales_as_shippedVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /v2/sales/:id/refund | Refund a sale, fully or partially. | write | edit_sales | Current | |
Needs the edit_sales scope, which grants refunding sales and resending receipts. This moves real money back to the buyer. Acts onsale Permission (capability) edit_salesVersionAvailable since the API’s base version Webhook event refundRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /v2/sales/:id/resend_receipt | Resend the purchase receipt email for a sale. | write | edit_sales | Current | |
Needs the edit_sales scope. Acts onsale Permission (capability) edit_salesVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
SubscribersList the subscribers of a membership product and read a single subscriber.2 | ||||||
| GET | /v2/products/:product_id/subscribers | List the subscribers of a membership or recurring product. | read | view_sales | Current | |
Needs view_sales (or account); subscriber data sits under the view_sales scope. Acts onsubscriber Permission (capability) view_salesVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v2/subscribers/:id | Retrieve a single subscriber by its id. | read | view_sales | Current | |
Needs view_sales (or account). Acts onsubscriber Permission (capability) view_salesVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
LicensesVerify a license key, and enable or disable a license.3 | ||||||
| POST | /v2/licenses/verify | Verify a license key for a product and read its details. | read | — | Current | |
No OAuth scope or access token required; it takes the product_id and license_key. By default each verify increments the uses count, unless increment_uses_count is set to false. Acts onlicense Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /v2/licenses/enable | Enable a license key so it verifies as valid again. | write | edit_products | Current | |
Needs edit_products (or account); takes the product_id and license_key. Acts onlicense Permission (capability) edit_productsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /v2/licenses/disable | Disable a license key so it no longer verifies as valid. | write | edit_products | Current | |
Needs edit_products (or account); takes the product_id and license_key. Acts onlicense Permission (capability) edit_productsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Resource subscriptions (webhooks)List, create, and delete resource subscriptions, the webhooks Gumroad posts to when an event fires.3 | ||||||
| GET | /v2/resource_subscriptions | List the resource subscriptions for a given resource_name, like sale or refund. | read | view_sales | Current | |
Needs view_sales (or account). A resource_name query parameter selects which event's subscriptions to list. Each subscription is tied to the OAuth application that created it. Acts onresource_subscription Permission (capability) view_salesVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /v2/resource_subscriptions | Create a resource subscription so Gumroad posts to a URL when the chosen event fires. | write | view_sales | Current | |
Needs view_sales (or account). Takes a resource_name and a post_url, which must be a public HTTP or HTTPS URL, not localhost, 127.0.0.1, or 0.0.0.0. Acts onresource_subscription Permission (capability) view_salesVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v2/resource_subscriptions/:id | Delete a resource subscription so its event is no longer posted. | write | view_sales | Current | |
Needs view_sales (or account). Only the OAuth application that created a subscription can delete it. Acts onresource_subscription Permission (capability) view_salesVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
UserRead the authenticated seller's account information.1 | ||||||
| GET | /v2/user | Retrieve the authenticated seller's account information. | read | view_profile | Current | |
Needs view_profile (or account). Acts onuser Permission (capability) view_profileVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Gumroad can notify an app when something happens in a seller's account, like a sale being made, a sale being refunded, or a membership being cancelled. A resource subscription registers a URL that Gumroad posts to when the chosen event fires, so an agent learns about activity without polling.
| Event | What it signals | Triggered by |
|---|---|---|
sale | Fires when a product is sold, carrying the sale details. This is the primary signal to fulfill an order. | In-app only |
refund | Fires when a sale is refunded, fully or partially. | /v2/sales/:id/refund |
dispute | Fires when a buyer opens a chargeback dispute on a sale. | In-app only |
dispute_won | Fires when a chargeback dispute is resolved in the seller's favor. | In-app only |
cancellation | Fires when a buyer cancels a membership or subscription. | In-app only |
subscription_updated | Fires when a subscription changes, like an upgrade, a downgrade, or a tier change. | In-app only |
subscription_ended | Fires when a subscription ends, whether it ran to completion or was cancelled and lapsed. | In-app only |
subscription_restarted | Fires when a previously cancelled or ended subscription is restarted. | In-app only |
Gumroad limits how fast an app or AI agent can call. The published documentation states that going over the limit returns an HTTP 429 response, without committing to a specific request-per-minute number.
Gumroad's documentation states that the API applies rate limiting and that going over it returns an HTTP 429 Too Many Requests response, but it does not publish a specific requests-per-minute number. The practical approach is to watch for a 429, back off, and retry after a delay rather than assume a fixed ceiling.
Listing endpoints page through results with a cursor. A list response, such as for sales, returns up to 10 records and includes a next_page_key, an opaque cursor passed back as page_key to fetch the next page. The older offset-based page parameter is deprecated and can time out on large result sets.
A sales list page returns up to 10 sales. The documentation does not state a fixed maximum request or response payload size.
The status codes an agent should handle, and what to do about each.
| Status | Code | Meaning | What to do |
|---|---|---|---|
| 200 | success: false | Gumroad signals many failures in the response body rather than only by HTTP status. The body carries a success boolean set to false and a message describing the problem, like 'The product was not found.' | Check the success field on every response, not just the HTTP status, and read the message before retrying. |
| 401 | Unauthorized | The access token is missing, invalid, or expired. | Send a valid access token in the Authorization: Bearer header, and re-run the OAuth flow if the token has been revoked. |
| 403 | Forbidden | The token is valid but lacks the scope the request needs, for example calling a write method with a read-only scope. | Grant the required scope, like edit_products or edit_sales, and re-authorize the application. |
| 404 | Not Found | The requested resource does not exist or is not visible to this token. | Confirm the id is correct and belongs to the authenticated seller. |
| 422 | Unprocessable Entity | The request was well-formed but a parameter is missing or invalid. | Read the message, correct the named parameter, and resend. |
| 429 | Too Many Requests | The request rate limit was exceeded. | Back off and retry after a delay, and smooth the request rate. |
Gumroad serves a single version of its API, v2, with no dated version string to pin. Changes are rolled out in place, like the move to cursor pagination for listing endpoints.
Gumroad serves a single version of its API, v2, reached through the /v2 path. There is no dated version header to pin, so changes are rolled out in place and an integration tracks them through the API documentation. A notable in-place change is the move to cursor pagination for listing endpoints: the offset-based page parameter is deprecated in favor of an opaque next_page_key cursor, because the old parameter can time out on large result sets.
For products created on or after 9 January 2023, the license verify method must be called with the product_id rather than the older product_permalink. An integration verifying licenses for newer products identifies the product by product_id.
There is no version header to set, so an integration tracks changes through the API documentation.
Gumroad API documentation ↗Bollard AI sits between a team's AI agents and Gumroad. Grant each agent exactly the access it needs, read or write, resource by resource, and every call is checked and logged.