Skill: byungkyu/gumroad (version 1.0.4)

--- name: gumroad description: | Gumroad API integration with managed OAuth. Access products, sales, subscribers, licenses, and webhooks for your digital storefront. Use this skill when users want to manage their Gumroad products, verify licenses, view sales data, or set up webhook notifications. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway). Requires network access and valid Maton API key. metadata: author: maton version: "1.0" clawdbot: emoji: 🧠 requires: env: - MATON_API_KEY --- # Gumroad Access the Gumroad API with managed OAuth authentication. Manage products, view sales, verify licenses, and set up webhooks for your digital storefront. ## Quick Start ```bash # Get current user info python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://api.maton.ai/gumroad/v2/user') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ``` ## Base URL ``` https://api.maton.ai/gumroad/v2/{resource} ``` Maton proxies requests to `api.gumroad.com/v2` and automatically injects your OAuth token. ## Authentication All requests require the Maton API key in the Authorization header: ``` Authorization: Bearer $MATON_API_KEY ``` **Environment Variable:** Set your API key as `MATON_API_KEY`: ```bash export MATON_API_KEY="YOUR_API_KEY" ``` ### Getting Your API Key 1. Sign in or create an account at [maton.ai](https://maton.ai) 2. Go to [maton.ai/settings](https://maton.ai/settings) 3. Copy your API key ## Connection Management Manage your Gumroad OAuth connections at `https://api.maton.ai`. ### List Connections ```bash python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://api.maton.ai/connections?app=gumroad&status=ACTIVE') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ``` ### Create Connection ```bash python <<'EOF' import urllib.request, os, json data = json.dumps({'app': 'gumroad'}).encode() req = urllib.request.Request('https://api.maton.ai/connections', data=data, method='POST') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') req.add_header('Content-Type', 'application/json') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ``` ### Get Connection ```bash python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ``` **Response:** ```json { "connection": { "connection_id": "{connection_id}", "status": "ACTIVE", "creation_time": "2026-02-08T06:22:48.654579Z", "last_updated_time": "2026-02-08T06:23:07.420381Z", "url": "https://connect.maton.ai/?session_token=...", "app": "gumroad", "metadata": {} } } ``` Open the returned `url` in a browser to complete OAuth authorization. ### Delete Connection ```bash python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}', method='DELETE') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ``` ### Specifying Connection If you have multiple Gumroad connections, specify which one to use with the `Maton-Connection` header: ```bash python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://api.maton.ai/gumroad/v2/products') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') req.add_header('Maton-Connection', '{connection_id}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ``` If you have multiple connections, always include this header to ensure requests go to the intended account. ## Security & Permissions - Access is scoped to products, sales, subscribers, licenses, and webhooks for your digital storefront within the connected Gumroad account. - **All write operations require explicit user approval.** Before executing any create, update, or delete call, confirm the target resource and intended effect with the user. ## API Reference ### User Info #### Get Current User ```bash GET /gumroad/v2/user ``` **Response:** ```json { "success": true, "user": { "name": "Chris", "currency_type": "usd", "bio": null, "twitter_handle": null, "id": "1690942847664", "user_id": "QmTtTnViFSoocHAexgLuJw==", "url": "https://chriswave1246.gumroad.com", "profile_url": "https://public-files.gumroad.com/...", "email": "[REDACTED_SECRET]", "display_name": "Chris" } } ``` ### Product Operations #### List Products ```bash GET /gumroad/v2/products ``` **Response:** ```json { "success": true, "products": [ { "id": "ABC123", "name": "My Product", "price": 500, "currency": "usd", "short_url": "https://gumroad.com/l/abc", "sales_count": 10, "sales_usd_cents": 5000 } ] } ``` #### Get Product ```bash GET /gumroad/v2/products/{product_id} ``` #### Update Product ```bash PUT /gumroad/v2/products/{product_id} Content-Type: application/x-www-form-urlencoded name=Updated%20Name&price=1000 ``` #### Enable/Disable Product ```bash PUT /gumroad/v2/products/{product_id}/disable Content-Type: application/x-www-form-urlencoded disabled=true ``` #### Delete Product ```bash DELETE /gumroad/v2/products/{product_id} ``` **Note:** Creating new products via API is not supported. Products must be created through the Gumroad website. ### Offer Code Operations #### List Offer Codes ```bash GET /gumroad/v2/products/{product_id}/offer_codes ``` #### Get Offer Code ```bash GET /gumroad/v2/products/{product_id}/offer_codes/{offer_code_id} ``` #### Create Offer Code ```bash POST /gumroad/v2/products/{product_id}/offer_codes Content-Type: application/x-www-form-urlencoded name=SUMMER20&amount_off=20 ``` Parameters: - `name` - The code customers enter (required) - `amount_off` - Cents or percentage off (required) - `offer_type` - "cents" or "percent" (default: "cents") - `max_purchase_count` - Maximum uses (optional) #### Update Offer Code ```bash PUT /gumroad/v2/products/{product_id}/offer_codes/{offer_code_id} Content-Type: application/x-www-form-urlencoded max_purchase_count=100 ``` #### Delete Offer Code ```bash DELETE /gumroad/v2/products/{product_id}/offer_codes/{offer_code_id} ``` ### Sales Operations #### List Sales ```bash GET /gumroad/v2/sales ``` Query parameters: - `after` - Only sales after this date (YYYY-MM-DD) - `before` - Only sales before this date (YYYY-MM-DD) - `page` - Page number for pagination **Example with filters:** ```bash GET /gumroad/v2/sales?after=2026-01-01&before=2026-12-31 ``` **Response:** ```json { "success": true, "sales": [ { "id": "sale_abc123", "email": "[REDACTED_SECRET]", "seller_id": "seller123", "product_id": "prod123", "product_name": "My Product", "price": 500, "currency_symbol": "$", "created_at": "2026-01-15T10:30:00Z" } ] } ``` #### Get Sale ```bash GET /gumroad/v2/sales/{sale_id} ``` ### Subscriber Operations #### List Subscribers ```bash GET /gumroad/v2/products/{product_id}/subscribers ``` #### Get Subscriber ```bash GET /gumroad/v2/subscribers/{subscriber_id} ``` **Response:** ```json { "success": true, "subscriber": { "id": "sub123", "product_id": "prod123", "product_name": "Monthly Subscription", "user_id": "user123", "user_email": "[REDACTED_SECRET]", "status": "alive", "created_at": "2026-01-01T00:00:00Z" } } ``` ### License Operations #### Verify License ```bash POST /gumroad/v2/licenses/verify Content-Type: application/x-www-form-urlencoded product_id={product_id}&license_key={license_key} ``` Parameters: - `product_id` - The product ID (required) - `license_key` - The license key to verify (required) - `increment_uses_count` - Increment the use count (default: true) **Response (success):** ```json { "success": true, "uses": 1, "purchase": { "seller_id": "seller123", "product_id": "prod123", "product_name": "My Product", "permalink": "abc", "email": "[REDACTED_SECRET]", "license_key": "ABC-123-DEF", "quantity": 1, "created_at": "2026-01-15T00:00:00Z" } } ``` **Response (failure):** ```json { "success": false, "message": "That license does not exist for the provided product." } ``` #### Enable License ```bash PUT /gumroad/v2/licenses/enable Content-Type: application/x-www-form-urlencoded product_id={product_id}&license_key={license_key} ``` #### Disable License ```bash PUT /gumroad/v2/licenses/disable Content-Type: application/x-www-form-urlencoded product_id={product_id}&license_key={license_key} ``` #### Decrement License Uses ```bash PUT /gumroad/v2/licenses/decrement_uses_count Content-Type: application/x-www-form-urlencoded product_id={product_id}&license_key={license_key} ``` ### Resource Subscriptions (Webhooks) Subscribe to notifications for sales and other events. #### List Resource Subscriptions ```bash GET /gumroad/v2/resource_subscriptions?resource_name=sale ``` Parameters: - `resource_name` - Required. One of: `sale`, `refund`, `dispute`, `dispute_won`, `cancellation`, `subscription_updated`, `subscription_ended`, `subscription_restarted` **Response:** ```json { "success": true, "resource_subscriptions": [ { "id": "wX43hzi-s7W4JfYFkxyeiQ==", "resource_name": "sale", "post_url": "https://example.com/webhook" } ] } ``` #### Delete Resource Subscription ```bash DELETE /gumroad/v2/resource_subscriptions/{resource_subscription_id} ``` **Response:** ```json { "success": true, "message": "The resource_subscription was deleted successfully." } ``` ### Variant Categories #### List Variant Categories ```bash GET /gumroad/v2/products/{product_id}/variant_categories ``` #### Get Variant Category ```bash GET /gumroad/v2/products/{product_id}/variant_categories/{variant_category_id} ``` #### Create Variant Category ```bash POST /gumroad/v2/products/{product_id}/variant_categories Content-Type: application/x-www-form-urlencoded title=Size ``` #### Delete Variant Category ```bash DELETE /gumroad/v2/products/{product_id}/variant_categories/{variant_category_id} ``` ### Variants #### List Variants ```bash GET /gumroad/v2/products/{product_id}/variant_categories/{variant_category_id}/variants ``` #### Create Variant ```bash POST /gumroad/v2/products/{product_id}/variant_categories/{variant_category_id}/variants Content-Type: application/x-www-form-urlencoded name=Large&price_difference=200 ``` #### Update Variant ```bash PUT /gumroad/v2/products/{product_id}/variant_categories/{variant_category_id}/variants/{variant_id} Content-Type: application/x-www-form-urlencoded name=Extra%20Large ``` #### Delete Variant ```bash DELETE /gumroad/v2/products/{product_id}/variant_categories/{variant_category_id}/variants/{variant_id} ``` ### Custom Fields #### List Custom Fields ```bash GET /gumroad/v2/products/{product_id}/custom_fields ``` #### Create Custom Field ```bash POST /gumroad/v2/products/{product_id}/custom_fields Content-Type: application/x-www-form-urlencoded name=Company%20Name&required=true ``` #### Update Custom Field ```bash PUT /gumroad/v2/products/{product_id}/custom_fields/{name} Content-Type: application/x-www-form-urlencoded required=false ``` #### Delete Custom Field ```bash DELETE /gumroad/v2/products/{product_id}/custom_fields/{name} ``` ## Pagination Gumroad uses page-based pagination for endpoints that return lists: ```bash GET /gumroad/v2/sales?page=1 GET /gumroad/v2/sales?page=2 ``` Continue incrementing the page number until you receive an empty list. ## Code Examples ### JavaScript ```javascript const response = await fetch( 'https://api.maton.ai/gumroad/v2/products', { headers: { 'Authorization': `Bearer ${process.env.MATON_API_KEY}` } } ); const data = await response.json(); ``` ### Python ```python import os import requests response = requests.get( 'https://api.maton.ai/gumroad/v2/products', headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'} ) data = response.json() ``` ### Python (Verify License) ```python import os import requests response = requests.post( 'https://api.maton.ai/gumroad/v2/licenses/verify', headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}, data={ 'product_id': 'your_product_id', 'license_key': 'CUSTOMER-LICENSE-KEY' } ) result = response.json() if result['success']: print(f"License valid! Uses: {result['uses']}") else: print(f"Invalid: {result['message']}") ``` ## Notes - All responses include a `success` boolean field - Product creation is not available via API - products must be created through the Gumroad website - POST/PUT requests use [REDACTED_SECRET] content type (not JSON) - Prices are in cents (e.g., 500 = $5.00) - License keys are case-insensitive - Resource subscription webhooks send POST requests to your specified URL - IMPORTANT: When piping curl output to `jq` or other commands, environment variables like `$MATON_API_KEY` may not expand correctly in some shell environments ## Error Handling | Status | Meaning | |--------|---------| | 400 | Missing Gumroad connection or bad request | | 401 | Invalid or missing Maton API key | | 404 | Resource not found (returned with `success: false`) | | 429 | Rate limited | | 4xx/5xx | Passthrough error from Gumroad API | Gumroad errors typically return HTTP 404 with a JSON body: ```json { "success": false, "message": "Error description" } ``` ### Troubleshooting: API Key Issues 1. Check that the `MATON_API_KEY` environment variable is set: ```bash echo $MATON_API_KEY ``` 2. Verify the API key is valid by listing connections: ```bash python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://api.maton.ai/connections') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ``` ### Troubleshooting: Invalid App Name 1. Ensure your URL path starts with `gumroad`. For example: - Correct: `https://api.maton.ai/gumroad/v2/user` - Incorrect: `https://api.maton.ai/v2/user` ## Resources - [Gumroad API Overview](https://gumroad.com/api) - [Create API Application](https://help.gumroad.com/article/280-create-application-api) - [License Keys Help](https://help.gumroad.com/article/76-license-keys) - [Maton Community](https://discord.com/invite/dBfFAcefs2) - [Maton Support](mailto:[REDACTED_SECRET])


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)