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
Payhip Endpoints
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.

POST 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

Parameters: list_orders
NameTypeDescription
email 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
curl -X POST https://cotlet.dev/api/v1/payhip/list_orders \
  -H "Authorization: Bearer $COTLET_API_KEY"
Python
result = client.call("payhip", "list_orders")
Node.js
const result = await cotlet.call('payhip', 'list_orders');
CLI
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

read

POST 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

Parameters: get_order
NameTypeDescription
order_id required string Order ID from list_orders.

Request

cURL
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"}'
Python
result = client.call("payhip", "get_order", {"order_id":"order_8c41d2"})
Node.js
const result = await cotlet.call('payhip', 'get_order', {"order_id":"order_8c41d2"});
CLI
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"
}

POST 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

Parameters: list_products
NameTypeDescription
type enum digital, course, coaching, membership or physical. Default: all.
visibility enum visible, invisible or unlisted. Default: all.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/payhip/list_products \
  -H "Authorization: Bearer $COTLET_API_KEY"
Python
result = client.call("payhip", "list_products")
Node.js
const result = await cotlet.call('payhip', 'list_products');
CLI
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"
    }
  ]
}

POST 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

Parameters: get_sales_stats
NameTypeDescription
from required date Start date (UTC).
to required date End date (UTC).

Request

cURL
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"}'
Python
result = client.call("payhip", "get_sales_stats", {"from":"2026-10-05","to":"2026-10-11"})
Node.js
const result = await cotlet.call('payhip', 'get_sales_stats', {"from":"2026-10-05","to":"2026-10-11"});
CLI
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

Parameters: get_sales_report
NameTypeDescription
month required string Month as YYYY-MM.

Request

cURL
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"}'
Python
result = client.call("payhip", "get_sales_report", {"month":"month"})
Node.js
const result = await cotlet.call('payhip', 'get_sales_report', {"month":"month"});
CLI
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
}

POST 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

Parameters: list_subscribers
NameTypeDescription
status enum active, trialing, cancelled, paused, unpaid, past_due, incomplete or incomplete_expired.
email string Find one subscriber by email.
limit integer 1 to 100. Default: 25.
cursor string Next page cursor from the previous call.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/payhip/list_subscribers \
  -H "Authorization: Bearer $COTLET_API_KEY"
Python
result = client.call("payhip", "list_subscribers")
Node.js
const result = await cotlet.call('payhip', 'list_subscribers');
CLI
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
}

POST 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

Parameters: list_coupons
NameTypeDescription
limit integer 1 to 100. Default: 25.
cursor string Next page cursor from the previous call.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/payhip/list_coupons \
  -H "Authorization: Bearer $COTLET_API_KEY"
Python
result = client.call("payhip", "list_coupons")
Node.js
const result = await cotlet.call('payhip', 'list_coupons');
CLI
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
}

Create coupon

write Confirm

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

Parameters: create_coupon
NameTypeDescription
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
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"}'
Python
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"})
Node.js
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"});
CLI
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"
}

Create product

write Confirm

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

Parameters: create_product
NameTypeDescription
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
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"}'
Python
result = client.call("payhip", "create_product", {"title":"title","price":"price","file_url":"https://example.com"})
Node.js
const result = await cotlet.call('payhip', 'create_product', {"title":"title","price":"price","file_url":"https://example.com"});
CLI
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"
}

Update product

write Confirm

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

Parameters: update_product
NameTypeDescription
product_id required string Product ID from list_products.
fields required object Any of title, price, description, visibility (visible, invisible or unlisted).

Request

cURL
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"}'
Python
result = client.call("payhip", "update_product", {"product_id":"product_8c41d2","fields":"fields"})
Node.js
const result = await cotlet.call('payhip', 'update_product', {"product_id":"product_8c41d2","fields":"fields"});
CLI
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"
}

POST 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

Parameters: add_order_note
NameTypeDescription
order_id required string Order ID from list_orders.
note required string Note text.

Request

cURL
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"}'
Python
result = client.call("payhip", "add_order_note", {"order_id":"order_8c41d2","note":"note"})
Node.js
const result = await cotlet.call('payhip', 'add_order_note', {"order_id":"order_8c41d2","note":"note"});
CLI
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"
  ]
}

POST 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

Parameters: reset_download_credits
NameTypeDescription
order_id required string Order ID from list_orders.

Request

cURL
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"}'
Python
result = client.call("payhip", "reset_download_credits", {"order_id":"ord_7K2mQx"})
Node.js
const result = await cotlet.call('payhip', 'reset_download_credits', {"order_id":"ord_7K2mQx"});
CLI
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"
}

Resend receipt

write Confirm

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

Parameters: resend_receipt
NameTypeDescription
order_id required string Order ID from list_orders.

Request

cURL
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"}'
Python
result = client.call("payhip", "resend_receipt", {"order_id":"order_8c41d2"})
Node.js
const result = await cotlet.call('payhip', 'resend_receipt', {"order_id":"order_8c41d2"});
CLI
cotlet call payhip resend_receipt --data '{"order_id":"order_8c41d2"}'

Example response

{
  "order_id": "ord_7K2mQx",
  "email": "client@example.com",
  "status": "sent"
}

Cancel subscription

write Confirm

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

Parameters: cancel_subscription
NameTypeDescription
subscription_id required string Subscription ID from list_subscribers.

Request

cURL
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"}'
Python
result = client.call("payhip", "cancel_subscription", {"subscription_id":"subscription_8c41d2"})
Node.js
const result = await cotlet.call('payhip', 'cancel_subscription', {"subscription_id":"subscription_8c41d2"});
CLI
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"
}

Block customer

write Confirm

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

Parameters: block_customer
NameTypeDescription
order_id required string Order ID from list_orders.

Request

cURL
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"}'
Python
result = client.call("payhip", "block_customer", {"order_id":"order_8c41d2"})
Node.js
const result = await cotlet.call('payhip', 'block_customer', {"order_id":"order_8c41d2"});
CLI
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"
}