REST API reference
Payhip API
15 endpoints for Payhip. Each one is a POST with a JSON body, called with your API key.
- Base URL
- https://cotlet.dev/api/v1/payhip
- Connects with
- Your own Payhip seller account
- Integration page
- Payhip
| Endpoint | Access | Description |
|---|---|---|
| list_orders | read | Orders from the Customers page with buyer email, items, amounts, status and date. |
| get_order | read | One order: items, gross and net amount, fees, coupon, checkout answers and your private order notes. |
| list_products | read | Your products with type, price, visibility and link. |
| get_sales_stats | read | Daily views, daily sales and sales by product from the Analytics page. |
| get_sales_report | read | The monthly report from the Sales Report tab: VAT, fees, taxes, products sold and affiliate payouts. |
| list_subscribers | read | Subscribers to your subscription, course, coaching and membership plans with status and start date. |
| list_coupons | read | Coupon codes with discount, scope, uses, usage limit and expiry date. |
| create_coupon | write | Coupon code for the whole order, one product or one collection. |
| create_product | write | New digital product from a file URL, with title, price, description and visibility. |
| update_product | write | Change the title, price, description or visibility of a product. |
| add_order_note | write | Private note on an order. Only you see it. |
| reset_download_credits | write | Reset a buyer's download attempts to your store's download limit. |
| resend_receipt | write | Email the receipt and download link to the buyer again. |
| cancel_subscription | write | Cancel a subscriber's plan. Billing stops and access ends. |
| block_customer | write | Add an order's buyer to your Blocked List so they cannot buy again. |
List orders
readPOST https://cotlet.dev/api/v1/payhip/list_orders
Returns the same filters as the Filter Orders button on the Customers page: email, product, order date, order ID, status and shipping. Orders come newest first and every date is in UTC. Pass the cursor to read the next page.
Parameters
| Name | Type | Description |
|---|---|---|
| string | Buyer email. | |
| order_id | string | Find one order by ID. |
| product_id | string | Only orders that include this product. |
| status | enum | completed, refunded or partially_refunded. |
| shipping | enum | unshipped (orders with unshipped items) or shipped (fully shipped), for physical products. |
| from | date | Orders on or after this date (UTC). |
| to | date | Orders on or before this date (UTC). |
| limit | integer | 1 to 100. Default: 25. |
| cursor | string | Next page cursor from the previous call. |
Request
curl -X POST https://cotlet.dev/api/v1/payhip/list_orders \
-H "Authorization: Bearer $COTLET_API_KEY" result = client.call("payhip", "list_orders") const result = await cotlet.call('payhip', 'list_orders'); cotlet call payhip list_orders Example response
{
"orders": [
{
"order_id": "ord_7K2mQx",
"email": "client@example.com",
"items": [
{
"product_id": "RGsF",
"name": "Notion Budget Template",
"quantity": 1
}
],
"amount_gross": "12.00",
"currency": "USD",
"status": "completed",
"coupon_code": null,
"date": "2026-10-09T14:22:00Z"
}
],
"next_cursor": null
} Get order
readPOST https://cotlet.dev/api/v1/payhip/get_order
Returns the amounts Payhip exports for an order: gross, net after tax and transaction fees, the Stripe or PayPal fee, the Payhip fee, the coupon applied and the buyer's answers to your checkout questions. It also returns your order notes, which only you can see.
Parameters
| Name | Type | Description |
|---|---|---|
| order_id required | string | Order ID from list_orders. |
Request
curl -X POST https://cotlet.dev/api/v1/payhip/get_order \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"order_id":"order_8c41d2"}' result = client.call("payhip", "get_order", {"order_id":"order_8c41d2"}) const result = await cotlet.call('payhip', 'get_order', {"order_id":"order_8c41d2"}); cotlet call payhip get_order --data '{"order_id":"order_8c41d2"}' Example response
{
"order_id": "ord_7K2mQx",
"email": "client@example.com",
"status": "completed",
"payment_type": "stripe",
"currency": "USD",
"items": [
{
"product_id": "RGsF",
"name": "Notion Budget Template",
"quantity": 1
}
],
"amount_gross": "12.00",
"processor_fee": "0.65",
"payhip_fee": "0.60",
"amount_net": "10.75",
"coupon_code": null,
"checkout_responses": [],
"notes": [],
"date": "2026-10-09T14:22:00Z"
} List products
readPOST https://cotlet.dev/api/v1/payhip/list_products
Returns the product IDs the other tools take. Visible products are listed on your store; invisible ones only you can see while logged in; unlisted ones only open from a direct link. Prices are shown as on the product page.
Parameters
| Name | Type | Description |
|---|---|---|
| type | enum | digital, course, coaching, membership or physical. Default: all. |
| visibility | enum | visible, invisible or unlisted. Default: all. |
Request
curl -X POST https://cotlet.dev/api/v1/payhip/list_products \
-H "Authorization: Bearer $COTLET_API_KEY" result = client.call("payhip", "list_products") const result = await cotlet.call('payhip', 'list_products'); cotlet call payhip list_products Example response
{
"products": [
{
"product_id": "RGsF",
"name": "Notion Budget Template",
"type": "digital",
"price": "12.00",
"visibility": "visible",
"url": "https://payhip.com/b/RGsF"
},
{
"product_id": "mVT0",
"name": "Freelancer Contract Pack",
"type": "digital",
"price": "24.00",
"visibility": "unlisted",
"url": "https://payhip.com/b/mVT0"
}
]
} Get sales stats
readPOST https://cotlet.dev/api/v1/payhip/get_sales_stats
Returns the 3 graphs of the Analytics page as numbers. Visits from logged-in users are not counted in views, and all dates are in UTC. Only the sales breakdown is split by product.
Parameters
| Name | Type | Description |
|---|---|---|
| from required | date | Start date (UTC). |
| to required | date | End date (UTC). |
Request
curl -X POST https://cotlet.dev/api/v1/payhip/get_sales_stats \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"from":"2026-10-05","to":"2026-10-11"}' result = client.call("payhip", "get_sales_stats", {"from":"2026-10-05","to":"2026-10-11"}) const result = await cotlet.call('payhip', 'get_sales_stats', {"from":"2026-10-05","to":"2026-10-11"}); cotlet call payhip get_sales_stats --data '{"from":"2026-10-05","to":"2026-10-11"}' Example response
{
"daily_views": [
{
"date": "2026-10-05",
"views": 142
},
{
"date": "2026-10-06",
"views": 98
},
{
"date": "2026-10-07",
"views": 176
},
{
"date": "2026-10-08",
"views": 120
},
{
"date": "2026-10-09",
"views": 87
},
{
"date": "2026-10-10",
"views": 64
},
{
"date": "2026-10-11",
"views": 203
}
],
"daily_sales": [
{
"date": "2026-10-05",
"amount": "24.00"
},
{
"date": "2026-10-06",
"amount": "0.00"
},
{
"date": "2026-10-07",
"amount": "36.00"
},
{
"date": "2026-10-08",
"amount": "12.00"
},
{
"date": "2026-10-09",
"amount": "0.00"
},
{
"date": "2026-10-10",
"amount": "0.00"
},
{
"date": "2026-10-11",
"amount": "48.00"
}
],
"sales_by_product": [
{
"product_id": "RGsF",
"name": "Notion Budget Template",
"amount": "72.00"
},
{
"product_id": "mVT0",
"name": "Freelancer Contract Pack",
"amount": "48.00"
}
]
} POST https://cotlet.dev/api/v1/payhip/get_sales_report
Returns the 7 items of a Payhip monthly report: EU and UK VAT, Stripe and PayPal fees, Payhip fees, custom taxes, products sold, affiliate commission and affiliate sales. Reports are monthly, so a month that has not ended yet is incomplete.
Parameters
| Name | Type | Description |
|---|---|---|
| month required | string | Month as YYYY-MM. |
Request
curl -X POST https://cotlet.dev/api/v1/payhip/get_sales_report \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"month":"month"}' result = client.call("payhip", "get_sales_report", {"month":"month"}) const result = await cotlet.call('payhip', 'get_sales_report', {"month":"month"}); cotlet call payhip get_sales_report --data '{"month":"month"}' Example response
{
"month": "2026-09",
"eu_uk_vat": "4.20",
"processor_fees": "31.80",
"payhip_fees": "25.00",
"custom_taxes": "0.00",
"products_sold": [
{
"name": "Notion Budget Template",
"items": 38
},
{
"name": "Freelancer Contract Pack",
"items": 12
}
],
"affiliate_commission": "12.00",
"affiliate_sales": 3
} List subscribers
readPOST https://cotlet.dev/api/v1/payhip/list_subscribers
Returns the Subscribers tab of the Customers page. Buyers keep access while past_due and lose it on cancelled, incomplete and incomplete_expired. Payhip moves a subscription to cancelled on its own after a 20-day grace period of failed payments.
Parameters
| Name | Type | Description |
|---|---|---|
| status | enum | active, trialing, cancelled, paused, unpaid, past_due, incomplete or incomplete_expired. |
| string | Find one subscriber by email. | |
| limit | integer | 1 to 100. Default: 25. |
| cursor | string | Next page cursor from the previous call. |
Request
curl -X POST https://cotlet.dev/api/v1/payhip/list_subscribers \
-H "Authorization: Bearer $COTLET_API_KEY" result = client.call("payhip", "list_subscribers") const result = await cotlet.call('payhip', 'list_subscribers'); cotlet call payhip list_subscribers Example response
{
"subscribers": [
{
"subscription_id": "sub_3Hf9aD",
"email": "client@example.com",
"product_name": "Design Club",
"plan_name": "Monthly",
"status": "active",
"started": "2026-08-14"
}
],
"next_cursor": null
} List coupons
readPOST https://cotlet.dev/api/v1/payhip/list_coupons
Returns the coupons from Marketing > Coupons with how often each was used. Expiry dates are in UTC. Notes are your private notes and buyers never see them.
Parameters
| Name | Type | Description |
|---|---|---|
| limit | integer | 1 to 100. Default: 25. |
| cursor | string | Next page cursor from the previous call. |
Request
curl -X POST https://cotlet.dev/api/v1/payhip/list_coupons \
-H "Authorization: Bearer $COTLET_API_KEY" result = client.call("payhip", "list_coupons") const result = await cotlet.call('payhip', 'list_coupons'); cotlet call payhip list_coupons Example response
{
"coupons": [
{
"coupon_id": "cpn_9d2e41",
"code": "LAUNCH25",
"discount_type": "percentage",
"amount": "25",
"applies_to": "product",
"product_id": "RGsF",
"uses": 0,
"usage_limit": 50,
"expires_on": "2026-11-01",
"notes": "Newsletter launch"
}
],
"next_cursor": null
} POST https://cotlet.dev/api/v1/payhip/create_coupon
A percentage applies to the original price and a fixed amount is deducted from it. Payhip has no per-buyer limit, so use a product-specific code or single-use codes for that. The coupon works at checkout right away. By default you confirm each call; you can switch that off for this tool.
Parameters
| Name | Type | Description |
|---|---|---|
| code | string | Code buyers type at checkout. Omit to let Payhip generate one. |
| discount_type required | enum | percentage or fixed. |
| amount required | string | Percent off or amount off. |
| applies_to required | enum | total_order, product or collection. |
| product_id | string | Required when applies_to is product. |
| collection_id | string | Required when applies_to is collection. |
| usage_limit | integer | Total uses across all buyers, not per buyer. |
| expires_on | date | Expires at 00:00 UTC on this date. |
| notes | string | Private note. Buyers never see it. |
Request
curl -X POST https://cotlet.dev/api/v1/payhip/create_coupon \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"code":"LAUNCH25","discount_type":"percentage","amount":"25","applies_to":"product","product_id":"RGsF","usage_limit":50,"expires_on":"2026-11-01","notes":"Newsletter launch"}' result = client.call("payhip", "create_coupon", {"code":"LAUNCH25","discount_type":"percentage","amount":"25","applies_to":"product","product_id":"RGsF","usage_limit":50,"expires_on":"2026-11-01","notes":"Newsletter launch"}) const result = await cotlet.call('payhip', 'create_coupon', {"code":"LAUNCH25","discount_type":"percentage","amount":"25","applies_to":"product","product_id":"RGsF","usage_limit":50,"expires_on":"2026-11-01","notes":"Newsletter launch"}); cotlet call payhip create_coupon --data '{"code":"LAUNCH25","discount_type":"percentage","amount":"25","applies_to":"product","product_id":"RGsF","usage_limit":50,"expires_on":"2026-11-01","notes":"Newsletter launch"}' Example response
{
"coupon_id": "cpn_9d2e41",
"code": "LAUNCH25",
"discount_type": "percentage",
"amount": "25",
"applies_to": "product",
"product_id": "RGsF",
"usage_limit": 50,
"uses": 0,
"expires_on": "2026-11-01",
"expires_at": "2026-11-01T00:00:00Z",
"notes": "Newsletter launch"
} POST https://cotlet.dev/api/v1/payhip/create_product
Creates a digital product only; courses, coaching, memberships and physical products are not created by this tool. Each file can be up to 5 GB. The default is invisible, so nothing goes on your store until you set visible or unlisted. By default you confirm each call; you can switch that off for this tool.
Parameters
| Name | Type | Description |
|---|---|---|
| title required | string | Product title. |
| price required | string | Price, e.g. 12. Add + for pay what you want: 5+ means at least 5, 0+ means any amount including free. |
| file_url required | string | Public URL of the file to sell, up to 5 GB. |
| description | string | Product description. |
| cover_image_url | string | Cover image shown on the product page. |
| visibility | enum | visible, invisible or unlisted. Default: invisible. |
Request
curl -X POST https://cotlet.dev/api/v1/payhip/create_product \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title":"title","price":"price","file_url":"https://example.com"}' result = client.call("payhip", "create_product", {"title":"title","price":"price","file_url":"https://example.com"}) const result = await cotlet.call('payhip', 'create_product', {"title":"title","price":"price","file_url":"https://example.com"}); cotlet call payhip create_product --data '{"title":"title","price":"price","file_url":"https://example.com"}' Example response
{
"product_id": "Qx7B",
"name": "Notion Budget Template",
"type": "digital",
"price": "12.00",
"visibility": "invisible",
"url": "https://payhip.com/b/Qx7B"
} POST https://cotlet.dev/api/v1/payhip/update_product
Returns the product after the change. A price change applies to new orders at once, and products with variants are not covered by this tool. By default you confirm each call; you can switch that off for this tool.
Parameters
| Name | Type | Description |
|---|---|---|
| product_id required | string | Product ID from list_products. |
| fields required | object | Any of title, price, description, visibility (visible, invisible or unlisted). |
Request
curl -X POST https://cotlet.dev/api/v1/payhip/update_product \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"product_id":"product_8c41d2","fields":"fields"}' result = client.call("payhip", "update_product", {"product_id":"product_8c41d2","fields":"fields"}) const result = await cotlet.call('payhip', 'update_product', {"product_id":"product_8c41d2","fields":"fields"}); cotlet call payhip update_product --data '{"product_id":"product_8c41d2","fields":"fields"}' Example response
{
"product_id": "RGsF",
"name": "Notion Budget Template",
"type": "digital",
"price": "9.00",
"visibility": "visible",
"url": "https://payhip.com/b/RGsF"
} Add order note
writePOST https://cotlet.dev/api/v1/payhip/add_order_note
Order notes are only visible to you and appear in the Order Notes column of your orders export. The note reaches no customer, so this tool runs without asking.
Parameters
| Name | Type | Description |
|---|---|---|
| order_id required | string | Order ID from list_orders. |
| note required | string | Note text. |
Request
curl -X POST https://cotlet.dev/api/v1/payhip/add_order_note \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"order_id":"order_8c41d2","note":"note"}' result = client.call("payhip", "add_order_note", {"order_id":"order_8c41d2","note":"note"}) const result = await cotlet.call('payhip', 'add_order_note', {"order_id":"order_8c41d2","note":"note"}); cotlet call payhip add_order_note --data '{"order_id":"order_8c41d2","note":"note"}' Example response
{
"order_id": "ord_7K2mQx",
"notes": [
"Refunded in Stripe on request, emailed buyer"
]
} Reset download credits
writePOST https://cotlet.dev/api/v1/payhip/reset_download_credits
Sets the credits back to the Download Limit in your Advanced Settings, which is 5 unless you changed it. It changes only the count and does not email the buyer; call resend_receipt for that. The call reaches no one, so it runs without asking.
Parameters
| Name | Type | Description |
|---|---|---|
| order_id required | string | Order ID from list_orders. |
Request
curl -X POST https://cotlet.dev/api/v1/payhip/reset_download_credits \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"order_id":"ord_7K2mQx"}' result = client.call("payhip", "reset_download_credits", {"order_id":"ord_7K2mQx"}) const result = await cotlet.call('payhip', 'reset_download_credits', {"order_id":"ord_7K2mQx"}); cotlet call payhip reset_download_credits --data '{"order_id":"ord_7K2mQx"}' Example response
{
"order_id": "ord_7K2mQx",
"email": "client@example.com",
"download_limit": 5,
"download_credits": 5,
"status": "reset"
} POST https://cotlet.dev/api/v1/payhip/resend_receipt
Does the same as Resend Receipt in the Customers menu: the buyer gets the receipt again. If the buyer ran out of download attempts, call reset_download_credits first. By default you confirm each call; you can switch that off for this tool.
Parameters
| Name | Type | Description |
|---|---|---|
| order_id required | string | Order ID from list_orders. |
Request
curl -X POST https://cotlet.dev/api/v1/payhip/resend_receipt \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"order_id":"order_8c41d2"}' result = client.call("payhip", "resend_receipt", {"order_id":"order_8c41d2"}) const result = await cotlet.call('payhip', 'resend_receipt', {"order_id":"order_8c41d2"}); cotlet call payhip resend_receipt --data '{"order_id":"order_8c41d2"}' Example response
{
"order_id": "ord_7K2mQx",
"email": "client@example.com",
"status": "sent"
} POST https://cotlet.dev/api/v1/payhip/cancel_subscription
Does the same as Cancel Subscription on the Subscribers tab: it prevents future charges and unenrolls the customer, who immediately loses access to the product. It does not refund past payments. By default you confirm each call; you can switch that off for this tool.
Parameters
| Name | Type | Description |
|---|---|---|
| subscription_id required | string | Subscription ID from list_subscribers. |
Request
curl -X POST https://cotlet.dev/api/v1/payhip/cancel_subscription \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"subscription_id":"subscription_8c41d2"}' result = client.call("payhip", "cancel_subscription", {"subscription_id":"subscription_8c41d2"}) const result = await cotlet.call('payhip', 'cancel_subscription', {"subscription_id":"subscription_8c41d2"}); cotlet call payhip cancel_subscription --data '{"subscription_id":"subscription_8c41d2"}' Example response
{
"subscription_id": "sub_3Hf9aD",
"email": "client@example.com",
"product_name": "Design Club",
"status": "cancelled",
"access": "ended"
} POST https://cotlet.dev/api/v1/payhip/block_customer
Payhip stores the PayPal payer ID or card payer ID of the order on your Blocked List, and that buyer cannot make future purchases from your store. There is no unblock tool; remove a buyer on the Blocked List page. By default you confirm each call; you can switch that off for this tool.
Parameters
| Name | Type | Description |
|---|---|---|
| order_id required | string | Order ID from list_orders. |
Request
curl -X POST https://cotlet.dev/api/v1/payhip/block_customer \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"order_id":"order_8c41d2"}' result = client.call("payhip", "block_customer", {"order_id":"order_8c41d2"}) const result = await cotlet.call('payhip', 'block_customer', {"order_id":"order_8c41d2"}); cotlet call payhip block_customer --data '{"order_id":"order_8c41d2"}' Example response
{
"order_id": "ord_7K2mQx",
"email": "client@example.com",
"blocked": true,
"payer_type": "card"
}