# Bandcamp API

> Every Bandcamp endpoint on Cotlet: inputs, JSON Schema, cURL, Python and Node.js examples and an example response for each call.

Source: https://cotlet.dev/docs/api/bandcamp

Docs sections: [Get started](https://cotlet.dev/docs.md) · [REST API](https://cotlet.dev/docs/api.md) · [MCP](https://cotlet.dev/docs/mcp.md) · [SDKs & CLI](https://cotlet.dev/docs/sdks.md) · [Integrations](https://cotlet.dev/docs/integrations.md)

13 endpoints for Bandcamp. Each one is a POST with a JSON body, called with your API key.

- Base URL: `https://cotlet.dev/api/v1/bandcamp`
- Connects with: Your own Bandcamp artist or label account
- Integration page: https://cotlet.dev/integrations/bandcamp-api-mcp-server

## Endpoints

| Endpoint | Access | Description |
|---|---|---|
| `list_releases` | read | Albums and tracks on your account with price, release date and visibility. |
| `list_sales` | read | Sales line items for a date range, with the net amount of each. |
| `export_sales_report` | read | One of the three reports from your Tools page for a date range. |
| `list_merch_orders` | read | Orders from your Merch Orders page with items, buyer and shipping address. |
| `list_merch_items` | read | Merch items with price, SKU, quantity sold and quantity available, per option. |
| `list_track_album_codes` | read | Your code batches with how many are redeemed; with batch_id, the codes of one batch. |
| `mark_order_shipped` | write | Mark a merch order shipped; Bandcamp emails the buyer with the tracking number and note. |
| `refund_merch_order` | write | Refund a physical order from the last 180 days and optionally return the item to stock. |
| `update_merch_quantity` | write | Set how many of a merch item or option are available. |
| `update_release` | write | Change the price, title or release date of an album or track. |
| `create_discount_code` | write | New discount code that fans enter in the Buy Now dialog. |
| `generate_track_album_codes` | write | New batch of one-use codes fans redeem for a download, counted against your code allowance. |
| `send_community_message` | write | Post a message to your Community page; followers get it by email and in the Bandcamp app. |

## List releases

`POST https://cotlet.dev/api/v1/bandcamp/list_releases`

Access: read.

Lists the releases on your account, the same items the Bulk Edit page shows. Filter by digital or physical and by public, private or draft. Use release_id from each item in the other tools.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `format` | enum | no | digital, physical or all. Default: all. |
| `visibility` | enum | no | public, private, draft or all. Default: all. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/bandcamp/list_releases \
  -H "Authorization: Bearer $COTLET_API_KEY"
```

**Python**

```python
result = client.call("bandcamp", "list_releases")
```

**Node.js**

```js
const result = await cotlet.call('bandcamp', 'list_releases');
```

**CLI**

```bash
cotlet call bandcamp list_releases
```

### Example response

```json
{
  "releases": [
    {
      "release_id": "r_1840221",
      "title": "Night Drive",
      "format": "digital",
      "visibility": "public",
      "price": 9,
      "currency": "USD",
      "release_date": "2025-11-14",
      "url": "https://yourname.bandcamp.com/album/night-drive"
    },
    {
      "release_id": "r_1902254",
      "title": "Tour EP",
      "format": "digital",
      "visibility": "draft",
      "price": 5,
      "currency": "USD",
      "release_date": "2026-11-01",
      "url": "https://yourname.bandcamp.com/album/tour-ep"
    }
  ]
}
```

## List sales

`POST https://cotlet.dev/api/v1/bandcamp/list_sales`

Access: read.

Returns the lines of your raw data sales report, oldest first: each line is the sale of an item, a payout or a sale reversal. Use export_sales_report for the revenue summary or the payout statement.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `since` | date | no | Start of the date range. Default: 30 days ago. |
| `until` | date | no | End of the date range. Default: today. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/bandcamp/list_sales \
  -H "Authorization: Bearer $COTLET_API_KEY"
```

**Python**

```python
result = client.call("bandcamp", "list_sales")
```

**Node.js**

```js
const result = await cotlet.call('bandcamp', 'list_sales');
```

**CLI**

```bash
cotlet call bandcamp list_sales
```

### Example response

```json
{
  "sales": [
    {
      "date": "2026-09-03T18:22:11Z",
      "type": "sale",
      "item_type": "album",
      "item_name": "Night Drive",
      "quantity": 1,
      "currency": "USD",
      "net_amount": 8.5
    },
    {
      "date": "2026-09-04T09:10:42Z",
      "type": "sale",
      "item_type": "package",
      "item_name": "Night Drive (12\" vinyl)",
      "quantity": 1,
      "currency": "USD",
      "net_amount": 24.1
    }
  ]
}
```

## Export sales report

`POST https://cotlet.dev/api/v1/bandcamp/export_sales_report`

Access: read.

Returns the report you pick: revenue_summary (gross and net revenue, shipping and tax for a release or the whole catalog), payout_statement (which sales are in each bulk payout) or raw_data. For revenue_summary you can narrow the report to one release.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `report` | enum | yes | revenue_summary, payout_statement or raw_data. |
| `since` | date | no | Start of the date range. Default: 30 days ago. |
| `until` | date | no | End of the date range. Default: today. |
| `release_id` | string | no | revenue_summary only: limit the report to this release. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/bandcamp/export_sales_report \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"report":"revenue_summary","since":"2026-09-01","until":"2026-09-30"}'
```

**Python**

```python
result = client.call("bandcamp", "export_sales_report", {"report":"revenue_summary","since":"2026-09-01","until":"2026-09-30"})
```

**Node.js**

```js
const result = await cotlet.call('bandcamp', 'export_sales_report', {"report":"revenue_summary","since":"2026-09-01","until":"2026-09-30"});
```

**CLI**

```bash
cotlet call bandcamp export_sales_report --data '{"report":"revenue_summary","since":"2026-09-01","until":"2026-09-30"}'
```

### Example response

```json
{
  "report": "revenue_summary",
  "since": "2026-09-01",
  "until": "2026-09-30",
  "currency": "USD",
  "gross_revenue": 1842.5,
  "net_revenue": 1713.1,
  "releases": [
    {
      "release_id": "r_1840221",
      "title": "Night Drive",
      "net_revenue": 1204.3
    },
    {
      "release_id": "r_1902254",
      "title": "Tour EP",
      "net_revenue": 508.8
    }
  ]
}
```

## List merch orders

`POST https://cotlet.dev/api/v1/bandcamp/list_merch_orders`

Access: read.

Lists physical orders from your Merch Orders page, newest first, with the items bought, the buyer, the shipping address and whether the order shipped. By default only unshipped orders. Search by email, last name or Bandcamp payment ID. Pass order_id to mark_order_shipped or refund_merch_order.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `unshipped_only` | boolean | no | Only orders not marked shipped. Default: true. |
| `search` | string | no | Buyer email, last name or Bandcamp payment ID. |
| `since` | date | no | Start of the date range. Default: 30 days ago. |
| `until` | date | no | End of the date range. Default: today. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/bandcamp/list_merch_orders \
  -H "Authorization: Bearer $COTLET_API_KEY"
```

**Python**

```python
result = client.call("bandcamp", "list_merch_orders")
```

**Node.js**

```js
const result = await cotlet.call('bandcamp', 'list_merch_orders');
```

**CLI**

```bash
cotlet call bandcamp list_merch_orders
```

### Example response

```json
{
  "orders": [
    {
      "order_id": "4471025938",
      "ordered_at": "2026-10-08T14:03:00Z",
      "shipped": false,
      "buyer": {
        "name": "Maya Brandt",
        "email": "maya@example.com"
      },
      "ship_to": {
        "name": "Maya Brandt",
        "city": "Leeds",
        "country": "United Kingdom",
        "country_code": "GB"
      },
      "items": [
        {
          "title": "Night Drive (12\" vinyl)",
          "option": "Black",
          "quantity": 1
        }
      ]
    }
  ]
}
```

## List merch items

`POST https://cotlet.dev/api/v1/bandcamp/list_merch_items`

Access: read.

Lists the merch on your account with price, SKU, how many were sold and how many are available. Items with sizes or colors list each option. Quantities are kept per shipping origin. An item with no limit shows quantity_available as null.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `low_stock_below` | integer | no | Only items with fewer available than this. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/bandcamp/list_merch_items \
  -H "Authorization: Bearer $COTLET_API_KEY"
```

**Python**

```python
result = client.call("bandcamp", "list_merch_items")
```

**Node.js**

```js
const result = await cotlet.call('bandcamp', 'list_merch_items');
```

**CLI**

```bash
cotlet call bandcamp list_merch_items
```

### Example response

```json
{
  "items": [
    {
      "item_id": "p_1154611570",
      "title": "Band Tote",
      "sku": "GGRA3-1",
      "price": 12,
      "currency": "USD",
      "quantity_sold": 4,
      "quantity_available": 6,
      "options": []
    },
    {
      "item_id": "p_175167691",
      "title": "Night Drive (12\" vinyl)",
      "sku": "ND-LP",
      "price": 25.5,
      "currency": "USD",
      "quantity_sold": 12,
      "quantity_available": 8,
      "options": [
        {
          "item_id": "o_1842702675",
          "title": "Black",
          "sku": "ND-LP-B",
          "quantity_sold": 9,
          "quantity_available": 3
        },
        {
          "item_id": "o_1842702676",
          "title": "Red",
          "sku": "ND-LP-R",
          "quantity_sold": 3,
          "quantity_available": 5
        }
      ]
    }
  ]
}
```

## List track/album codes

`POST https://cotlet.dev/api/v1/bandcamp/list_track_album_codes`

Access: read.

Without batch_id, returns each batch with its release, size and redeemed count, as the Track/album codes section of your Tools page does. With batch_id, returns every code of that batch and whether it was redeemed.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `batch_id` | string | no | Batch ID from a previous call. Returns the codes of this batch. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/bandcamp/list_track_album_codes \
  -H "Authorization: Bearer $COTLET_API_KEY"
```

**Python**

```python
result = client.call("bandcamp", "list_track_album_codes")
```

**Node.js**

```js
const result = await cotlet.call('bandcamp', 'list_track_album_codes');
```

**CLI**

```bash
cotlet call bandcamp list_track_album_codes
```

### Example response

```json
{
  "batches": [
    {
      "batch_id": "b_0042",
      "batch_name": "tour-2026",
      "release_title": "Tour EP",
      "codes": 100,
      "redeemed": 37
    }
  ]
}
```

## Mark order shipped

`POST https://cotlet.dev/api/v1/bandcamp/mark_order_shipped`

Access: write. Confirm: waits for the user's OK before it runs.

Marks one order shipped. Bandcamp then emails the buyer with the tracking number and note you pass. One order per call. By default you confirm each call; you can switch that off for this tool.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `order_id` | string | yes | Order ID from list_merch_orders. |
| `tracking_number` | string | no | Tracking number shown to the buyer. |
| `note` | string | no | Note for the buyer in the shipping email. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/bandcamp/mark_order_shipped \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"order_id":"4471025938","tracking_number":"9400111899223344556677","note":"Thanks for the support! Your LP is on its way."}'
```

**Python**

```python
result = client.call("bandcamp", "mark_order_shipped", {"order_id":"4471025938","tracking_number":"9400111899223344556677","note":"Thanks for the support! Your LP is on its way."})
```

**Node.js**

```js
const result = await cotlet.call('bandcamp', 'mark_order_shipped', {"order_id":"4471025938","tracking_number":"9400111899223344556677","note":"Thanks for the support! Your LP is on its way."});
```

**CLI**

```bash
cotlet call bandcamp mark_order_shipped --data '{"order_id":"4471025938","tracking_number":"9400111899223344556677","note":"Thanks for the support! Your LP is on its way."}'
```

### Example response

```json
{
  "order_id": "4471025938",
  "status": "shipped",
  "tracking_number": "9400111899223344556677",
  "note": "Thanks for the support! Your LP is on its way.",
  "buyer_notified": true,
  "items": [
    {
      "title": "Night Drive (12\" vinyl)",
      "option": "Black",
      "quantity": 1
    }
  ]
}
```

## Refund merch order

`POST https://cotlet.dev/api/v1/bandcamp/refund_merch_order`

Access: write. Confirm: waits for the user's OK before it runs.

Refunds a physical order the way the "refund this order" link on the Merch Orders page does, and your revenue share adjusts. It works for orders placed in the last 180 days and not under a dispute; for older orders the call fails and you refund the fan yourself, for example through PayPal. Digital purchases are refunded through Bandcamp Support. By default you confirm each call; you can switch that off for this tool.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `order_id` | string | yes | Order ID from list_merch_orders. |
| `return_to_stock` | boolean | no | Put the item back into your inventory. Default: false. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/bandcamp/refund_merch_order \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"order_id":"order_8c41d2"}'
```

**Python**

```python
result = client.call("bandcamp", "refund_merch_order", {"order_id":"order_8c41d2"})
```

**Node.js**

```js
const result = await cotlet.call('bandcamp', 'refund_merch_order', {"order_id":"order_8c41d2"});
```

**CLI**

```bash
cotlet call bandcamp refund_merch_order --data '{"order_id":"order_8c41d2"}'
```

### Example response

```json
{
  "order_id": "4471025938",
  "status": "refunded",
  "restocked": true
}
```

## Update merch quantity

`POST https://cotlet.dev/api/v1/bandcamp/update_merch_quantity`

Access: write.

Sets the available quantity of an item or one of its options at a shipping origin. Bandcamp lowers it by itself when an item sells, so use this when you also sell elsewhere. 0 marks the item Sold Out. It runs without asking first: it reaches no one and one more call sets the old number back.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `item_id` | string | yes | Item or option ID from list_merch_items. |
| `quantity_available` | integer | yes | New stock level. 0 marks the item Sold Out. |
| `shipping_origin` | string | no | Shipping origin to change. Default: your main origin. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/bandcamp/update_merch_quantity \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"item_id":"o_1842702675","quantity_available":6,"shipping_origin":"Tour van"}'
```

**Python**

```python
result = client.call("bandcamp", "update_merch_quantity", {"item_id":"o_1842702675","quantity_available":6,"shipping_origin":"Tour van"})
```

**Node.js**

```js
const result = await cotlet.call('bandcamp', 'update_merch_quantity', {"item_id":"o_1842702675","quantity_available":6,"shipping_origin":"Tour van"});
```

**CLI**

```bash
cotlet call bandcamp update_merch_quantity --data '{"item_id":"o_1842702675","quantity_available":6,"shipping_origin":"Tour van"}'
```

### Example response

```json
{
  "item_id": "p_1154611570",
  "title": "Band Tote",
  "quantity_available": 40,
  "previous_quantity_available": 6
}
```

## Update release

`POST https://cotlet.dev/api/v1/bandcamp/update_release`

Access: write. Confirm: waits for the user's OK before it runs.

Changes the price, title or release date of one album or track, like the edit button on its page or the Bulk Edit page. Pass only the fields you want to change. By default you confirm each call; you can switch that off for this tool.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `release_id` | string | yes | Album or track ID from list_releases. |
| `price` | number | no | New price. |
| `title` | string | no | New title. |
| `release_date` | date | no | New release date. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/bandcamp/update_release \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"release_id":"release_8c41d2"}'
```

**Python**

```python
result = client.call("bandcamp", "update_release", {"release_id":"release_8c41d2"})
```

**Node.js**

```js
const result = await cotlet.call('bandcamp', 'update_release', {"release_id":"release_8c41d2"});
```

**CLI**

```bash
cotlet call bandcamp update_release --data '{"release_id":"release_8c41d2"}'
```

### Example response

```json
{
  "release_id": "r_1840221",
  "title": "Night Drive",
  "price": 7,
  "currency": "USD",
  "release_date": "2025-11-14",
  "updated": [
    "price"
  ]
}
```

## Create discount code

`POST https://cotlet.dev/api/v1/bandcamp/create_discount_code`

Access: write. Confirm: waits for the user's OK before it runs.

Creates a discount code. The percentage applies to the base price of the item, never to shipping or taxes. Codes cannot take a release priced at zero, and 100% off is not offered. If you set expires_on, Bandcamp disables the code on that day. By default you confirm each call; you can switch that off for this tool.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `name` | string | yes | The code fans type, e.g. summersale. |
| `percent_off` | integer | yes | Percent off the base price. 100 is not offered. |
| `applies_to` | enum | no | anything, anything_except_preorders, digital_only, physical_only or single_item. Default: anything. |
| `item_id` | string | no | Release or package ID when applies_to is single_item. |
| `expires_on` | date | no | Bandcamp disables the code on this day. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/bandcamp/create_discount_code \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"NIGHTDRIVE20","percent_off":20,"applies_to":"single_item","item_id":"r_1840221","expires_on":"2026-10-31"}'
```

**Python**

```python
result = client.call("bandcamp", "create_discount_code", {"name":"NIGHTDRIVE20","percent_off":20,"applies_to":"single_item","item_id":"r_1840221","expires_on":"2026-10-31"})
```

**Node.js**

```js
const result = await cotlet.call('bandcamp', 'create_discount_code', {"name":"NIGHTDRIVE20","percent_off":20,"applies_to":"single_item","item_id":"r_1840221","expires_on":"2026-10-31"});
```

**CLI**

```bash
cotlet call bandcamp create_discount_code --data '{"name":"NIGHTDRIVE20","percent_off":20,"applies_to":"single_item","item_id":"r_1840221","expires_on":"2026-10-31"}'
```

### Example response

```json
{
  "code": "summersale",
  "percent_off": 20,
  "applies_to": "single_item",
  "item_id": "r_1840221",
  "expires_on": "2026-08-31",
  "status": "active"
}
```

## Generate track/album codes

`POST https://cotlet.dev/api/v1/bandcamp/generate_track_album_codes`

Access: write. Confirm: waits for the user's OK before it runs.

Creates a batch of track/album codes for a release you choose. Codes come in multiples of 100 with a minimum of 100 per batch, never expire, and count against the code allowance shown on your Tools page. The batch name is private to you. By default you confirm each call; you can switch that off for this tool.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `release_id` | string | yes | Album or track ID from list_releases. |
| `batch_name` | string | yes | Private label for the batch, e.g. tour-2026. |
| `count` | integer | yes | Multiples of 100, at least 100. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/bandcamp/generate_track_album_codes \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"release_id":"release_8c41d2","batch_name":"batch name","count":20}'
```

**Python**

```python
result = client.call("bandcamp", "generate_track_album_codes", {"release_id":"release_8c41d2","batch_name":"batch name","count":20})
```

**Node.js**

```js
const result = await cotlet.call('bandcamp', 'generate_track_album_codes', {"release_id":"release_8c41d2","batch_name":"batch name","count":20});
```

**CLI**

```bash
cotlet call bandcamp generate_track_album_codes --data '{"release_id":"release_8c41d2","batch_name":"batch name","count":20}'
```

### Example response

```json
{
  "batch_id": "b_0042",
  "batch_name": "tour-2026",
  "release_id": "r_1902254",
  "codes_created": 100
}
```

## Send Community message

`POST https://cotlet.dev/api/v1/bandcamp/send_community_message`

Access: write. Confirm: waits for the user's OK before it runs.

Posts a message under your artist name. Fans who follow you receive it by email and in the Bandcamp app, and it appears on your Community page. Fans need to follow you to receive messages and to buy a release before they can comment. By default you confirm each call; you can switch that off for this tool.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `body` | string | yes | Message text. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/bandcamp/send_community_message \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"body":"body"}'
```

**Python**

```python
result = client.call("bandcamp", "send_community_message", {"body":"body"})
```

**Node.js**

```js
const result = await cotlet.call('bandcamp', 'send_community_message', {"body":"body"});
```

**CLI**

```bash
cotlet call bandcamp send_community_message --data '{"body":"body"}'
```

### Example response

```json
{
  "message_id": "cm_2207",
  "status": "published",
  "published_at": "2026-10-11T10:00:00+02:00"
}
```
