# Pirate Ship API and MCP server

> Pirate Ship has no API (checked 11 Oct 2026). Its help center says so and points to store integrations and spreadsheet uploads instead.

Free web app for small US shippers to compare and buy discounted USPS and UPS labels, one at a time or in batches, from a spreadsheet or a connected store.

## What is the Pirate Ship API?

Cotlet's Pirate Ship API exposes 14 endpoints for your own Pirate Ship account: get rates, get batch rates, list import orders, list shipments, get shipment, get account balance, list saved packages, export shipments, create batch, buy label, buy batch, refund label, create SCAN Form and schedule pickup. The get_rates endpoint returns USPS and UPS services with price for one package, cheapest first. Each endpoint takes simple JSON inputs like batch_id, service or ship_date and works both as an MCP tool for agents and as a REST call for scripts.

- **Category:** [Local services & SaaS](https://cotlet.dev/integrations/category/local-services-saas)
- **Endpoints:** 14 (8 read, 6 write)
- **Updated:** 2026-10-11

Pirate Ship has no API (checked 11 Oct 2026). Cotlet is a hosted MCP server and REST API for Pirate Ship with 14 endpoints (8 read, 6 write): your AI agent signs in as you and does the work.

## Does Pirate Ship have an official API?

Pirate Ship has no API (checked 11 Oct 2026). Its help center says so and points to store integrations and spreadsheet uploads instead.

| Task | Pirate Ship official | Cotlet |
|---|---|---|
| Compare USPS and UPS rates | No | Yes |
| Buy a label | No | Yes |
| Buy a batch of labels from a spreadsheet | No: Spreadsheet upload exists in the web app, not as an API | Yes |
| Pull orders from Shopify, eBay and other stores | Partly: Built-in integrations in the web app, not reachable from your code | Yes |
| Find shipments and their tracking numbers | No: The Export button in the web app is manual | Yes |
| Refund an unused label | No | Yes |
| Create a SCAN Form | No | Yes |
| Schedule a pickup | No | Yes |

Sources: [Does Pirate Ship have an API? (help center)](https://support.pirateship.com/en/articles/2309246-does-pirate-ship-have-an-api), [How to import from integrations (help center)](https://support.pirateship.com/en/articles/10624292-how-to-import-from-integrations), [Spreadsheet shipping software (Pirate Ship)](https://www.pirateship.com/integrations/spreadsheets), [Can I get a refund if I make a mistake? (help center)](https://support.pirateship.com/en/articles/1068139-can-i-get-a-refund-if-i-make-a-mistake-or-don-t-need-a-label-anymore), [How do auto-refunds work? (help center)](https://support.pirateship.com/en/articles/3535545-how-do-auto-refunds-work), [How do I schedule a UPS pickup? (help center)](https://support.pirateship.com/en/articles/5611367-how-do-i-schedule-a-ups-pickup)

## For AI agents

```text
Pirate Ship has no API (checked 11 Oct 2026). Its help center says so and points to store integrations and spreadsheet uploads instead.
Cotlet provides a hosted MCP server and REST API for Pirate Ship: 14 tools (8 read, 6 write).
Access       Request access at https://cotlet.dev/app/signup?app=pirate-ship; we email the API key.

MCP server   https://cotlet.dev/mcp/v1
REST base    https://cotlet.dev/api/v1/pirate-ship
Auth         Authorization: Bearer <COTLET_API_KEY>. Listing endpoints and schemas needs no key; calling an endpoint needs one.
Tools        get_rates, get_batch_rates, list_import_orders, list_shipments, get_shipment, get_account_balance, list_saved_packages, export_shipments, create_batch, buy_label, buy_batch, refund_label, create_scan_form, schedule_pickup
Confirm      buy_label, buy_batch, refund_label, schedule_pickup (by default the user approves each call; the user can switch this off per tool, e.g. for scheduled automations)
Markdown     https://cotlet.dev/integrations/pirate-ship-api-mcp-server.md

How access works:
1. The user requests access at https://cotlet.dev/app/signup?app=pirate-ship (Pirate Ship is pre-selected). Each request is reviewed and the API key is sent by email.
2. The user signs in to Pirate Ship once in a browser. An agent cannot do this step.
3. The API key goes into the MCP client or the REST call as a bearer token.

Fits: people who want a hosted Pirate Ship server that someone else maintains, including non-developers.

Policy: Cotlet never stores passwords, never solves CAPTCHAs, never bypasses MFA.
Company: legal details in the Terms of service at https://cotlet.dev/terms. Contact contact@cotlet.dev.
Session: the user signs in to Pirate Ship in a browser; Cotlet keeps only the session, AES-256 encrypted, revocable in the dashboard at any time.
Terms: the user stays responsible for following Pirate Ship's terms; Cotlet is not affiliated with Pirate Ship.
```

## What can an AI agent do in Pirate Ship?

Cotlet is best for small online sellers who ship in batches and want an agent to buy labels, refund unused ones and book pickups without running or fixing a server.

- **[Buy shipping labels in bulk](https://cotlet.dev/integrations/pirate-ship-api-mcp-server/buy-shipping-labels-in-bulk)** (runs: daily): "Take the wholesale orders in wholesale.csv plus my unshipped Shopify orders, split them by box, show me the USPS Ground Advantage totals and buy the labels once I say OK." → `list_import_orders`, `list_saved_packages`, `create_batch`, `get_batch_rates`, `get_account_balance`, `buy_batch`
- **Ship store orders at the cheapest rate** (runs: daily): "Pull my unshipped Shopify and eBay orders, put them in my small box and buy the cheapest USPS label for each." → `list_import_orders`, `create_batch`, `get_batch_rates`, `buy_batch`
- **[Refund unused shipping labels](https://cotlet.dev/integrations/pirate-ship-api-mcp-server/refund-unused-labels)** (runs: weekly): "Find labels I bought twice for the same order and labels for the orders I cancelled this week, check none of them has been scanned, and refund them." → `list_shipments`, `get_shipment`, `refund_label`, `get_account_balance`
- **[Create a SCAN Form and book a pickup](https://cotlet.dev/integrations/pirate-ship-api-mcp-server/scan-form-and-pickup)** (runs: daily): "When today's labels are done, make the SCAN Form for the USPS ones and book a free USPS pickup at the front porch for tomorrow. For UPS, tell me the count and ask before booking." → `list_shipments`, `create_scan_form`, `schedule_pickup`
- **Check tracking on recent shipments** (runs: daily): "Show me this week's shipments that are not delivered yet, with their tracking numbers." → `list_shipments`, `get_shipment`

## Can Pirate Ship automations run on a schedule in n8n, Make or Zapier?

Yes. Cotlet does not replace your automation platform: it gives it a Pirate Ship connection it does not have, with the same API key as your agent. Write actions ask for your OK by default; switch that off in your dashboard for the tools you choose, for example to buy shipping labels in bulk, and the schedule runs on its own. Cotlet runs in the cloud, so it keeps going while your computer is off.

| Where | How to connect | How to schedule |
|---|---|---|
| Your AI agent | Add https://cotlet.dev/mcp/v1 with your API key. | A scheduled agent run, for example a Claude Code routine. |
| n8n | MCP Client node with https://cotlet.dev/mcp/v1, or an HTTP Request node to https://cotlet.dev/api/v1/pirate-ship/{tool}. | Schedule Trigger node. |
| Make | HTTP module: POST https://cotlet.dev/api/v1/pirate-ship/{tool} with an Authorization: Bearer header and a JSON body. | Scenario schedule. |
| Zapier | Webhooks by Zapier: POST https://cotlet.dev/api/v1/pirate-ship/{tool} with the same header and body. | Schedule by Zapier trigger. |
| Your own script | POST https://cotlet.dev/api/v1/pirate-ship/{tool} with your API key. | cron or GitHub Actions. |

## Tools

**For AI agents:** Every endpoint and its schema is public. The 14 endpoints on this page, with parameters and example responses, can be listed without an account. Calling one returns 403 until the account has an API key with access to Pirate Ship.

### get_rates

USPS and UPS services with price for one package, cheapest first. Access: read. REST: `POST /api/v1/pirate-ship/get_rates`.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `to_address` | object | yes | name, street1, street2, city, state, zip, country. |
| `from_address_id` | string | no | Ship From Address ID. Default: your default Ship From Address. |
| `package` | object | no | weight_oz, and length, width, height in inches. Use this or saved_package_id. |
| `saved_package_id` | string | no | ID of one of your Saved Packages from list_saved_packages. Its size, weight and extra services such as insurance apply. |
| `packaging` | string | no | Type of Packaging as the app lists it, e.g. a box or a poly mailer. Priority Mail packaging works only with Priority Mail. |

Returns each service Pirate Ship offers for this package with its price. Rates change with weight, size, ZIP and packaging, so call it again if any of them changes. Nothing is bought.

Example response:

```json
{
  "rates": [
    {
      "rate_id": "r_01UG",
      "carrier": "USPS",
      "service": "Ground Advantage",
      "price_usd": 7.12
    },
    {
      "rate_id": "r_02PM",
      "carrier": "USPS",
      "service": "Priority Mail",
      "price_usd": 9.86
    },
    {
      "rate_id": "r_03UP",
      "carrier": "UPS",
      "service": "Ground",
      "price_usd": 11.4
    }
  ]
}
```

### get_batch_rates

Rates for every shipment in a batch, like Get Rates with all rows ticked. Access: read. REST: `POST /api/v1/pirate-ship/get_batch_rates`.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `batch_id` | string | yes | Batch ID from create_batch. |

Returns each service with its total for the batch and the price per shipment, so the agent can pick one service for all labels. Shipments with an address problem are listed separately and are skipped until fixed. Nothing is bought.

Example response:

```json
{
  "batch_id": "b_7Q4K2M",
  "shipments": 4,
  "services": [
    {
      "carrier": "USPS",
      "service": "USPS Ground Advantage",
      "total_usd": 32
    },
    {
      "carrier": "UPS",
      "service": "UPS Ground",
      "total_usd": 41.6
    }
  ],
  "address_problems": []
}
```

### list_import_orders

Unshipped orders from your connected store integrations, as in the Import grid. Access: read. REST: `POST /api/v1/pirate-ship/list_import_orders`.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `source` | string | no | Only orders from this connected store, like the Source filter. Default: all. |
| `refresh` | boolean | no | Press Refresh Data first. Default: false. |
| `limit` | integer | no | Maximum orders to return. |

Returns orders the Import grid shows, which by default are the unfulfilled or unshipped ones. Orders sync on their own; refresh asks for new ones right away. Each order has the ID that create_batch accepts.

Example response:

```json
{
  "orders": [
    {
      "order_id": "o_4412",
      "source": "Shopify",
      "order_number": "#1042",
      "ship_to": "J. Rivera, Austin, TX 78701"
    },
    {
      "order_id": "o_4413",
      "source": "Shopify",
      "order_number": "#1043",
      "ship_to": "M. Chen, Portland, OR 97205"
    },
    {
      "order_id": "o_4415",
      "source": "eBay",
      "order_number": "22-11044-31",
      "ship_to": "S. Okafor, Atlanta, GA 30303"
    }
  ]
}
```

### list_shipments

Your label purchases from the Ship page grid: recipient, carrier, service, cost, tracking number and status. Access: read. REST: `POST /api/v1/pirate-ship/list_shipments`.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `search` | string | no | Recipient, Order ID or tracking number, as in the grid search. |
| `status` | string | no | Tracking status as the grid filter names it. |
| `service` | string | no | Shipping service as the grid filter names it. |
| `since` | date | no | Only labels with a Ship Date on or after this date. |
| `cursor` | string | no | Next page cursor from the previous call. |

Returns the grid rows that match, newest first. Batches appear as their labels. Use the shipment_id with get_shipment or refund_label.

Example response:

```json
{
  "shipments": [
    {
      "shipment_id": "s_83F2A1",
      "ship_date": "2026-10-08",
      "recipient": "J. Rivera",
      "carrier": "USPS",
      "service": "Ground Advantage",
      "cost_usd": 7.12,
      "tracking": "9400 1112 0000 0000 0001 23",
      "status": "In Transit"
    },
    {
      "shipment_id": "s_83F2A2",
      "ship_date": "2026-10-08",
      "recipient": "M. Chen",
      "carrier": "USPS",
      "service": "Ground Advantage",
      "cost_usd": 8.45,
      "tracking": "9400 1112 0000 0000 0001 30",
      "status": "Delivered"
    }
  ],
  "next_cursor": null
}
```

### get_shipment

One shipment with its service, cost, insurance, tracking number and status. Access: read. REST: `POST /api/v1/pirate-ship/get_shipment`.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `shipment_id` | string | yes | Shipment ID from list_shipments, buy_label or buy_batch. |

Returns what the label page shows, including the Email Recipients line that says whether a tracking email was sent. It sends nothing to the customer.

Example response:

```json
{
  "shipment_id": "s_83F2A1",
  "ship_date": "2026-10-08",
  "recipient": "J. Rivera",
  "carrier": "USPS",
  "service": "Ground Advantage",
  "cost_usd": 7.12,
  "insurance": "none",
  "tracking": "9400 1112 0000 0000 0001 23",
  "status": "In Transit",
  "tracking_email_sent": false
}
```

### get_account_balance

Account Balance, Pending Refunds and Pending Returns from the Reports page. Access: read. REST: `POST /api/v1/pirate-ship/get_account_balance`.

No parameters.

Returns the funds available for labels and the refunds the carrier has not approved yet. Funds come from added credit, approved refunds and adjustments. Call it before buy_batch to see that the balance covers the batch.

Example response:

```json
{
  "account_balance_usd": 84.5,
  "pending_refunds_usd": 7.12,
  "pending_returns_usd": 0
}
```

### list_saved_packages

Your Saved Packages from Settings: size, weight and the extra services stored with each. Access: read. REST: `POST /api/v1/pirate-ship/list_saved_packages`.

No parameters.

Returns the presets you can pass to get_rates, create_batch and buy_label. A Saved Package holds size and weight, and can also hold extras such as Signature Confirmation or insurance.

Example response:

```json
{
  "saved_packages": [
    {
      "saved_package_id": "pkg_small_box",
      "name": "Small box",
      "weight_oz": 12,
      "length_in": 9,
      "width_in": 6,
      "height_in": 3,
      "extras": []
    },
    {
      "saved_package_id": "pkg_insured_mailer",
      "name": "Insured mailer",
      "weight_oz": 6,
      "length_in": 12,
      "width_in": 9,
      "height_in": 1,
      "extras": [
        "insurance"
      ]
    }
  ]
}
```

### export_shipments

Your shipments grid for the current filter as a spreadsheet download link. Access: read. REST: `POST /api/v1/pirate-ship/export_shipments`.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `search` | string | no | Same search as list_shipments. |
| `status` | string | no | Tracking status as the grid filter names it. |
| `service` | string | no | Shipping service as the grid filter names it. |

Does what the Export button does: all rows of the current filter or search, with the columns you set in the grid. A blank search exports every label purchase to date.

Example response:

```json
{
  "rows": 2,
  "download_url": "https://cotlet.dev/api/v1/files/exports/pirate-ship-shipments-2026-10-11.xlsx"
}
```

### create_batch

A batch from spreadsheet-style rows or import orders. Nothing is bought yet. Access: write. REST: `POST /api/v1/pirate-ship/create_batch`.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `rows` | object[] | no | Recipients: name, address, address2, city, state, zip, country, company, email, order_id, weight, length, width, height. Name, address, city, state and zip are required. |
| `order_ids` | string[] | no | Order IDs from list_import_orders, instead of rows. |
| `package` | object | no | weight_oz, and length, width, height in inches. Use this or saved_package_id. |
| `saved_package_id` | string | no | ID of one of your Saved Packages from list_saved_packages. Its size, weight and extra services such as insurance apply. |
| `rubber_stamp` | string[] | no | Up to 3 row fields to print in the corner of each label, e.g. order_id. |

Does the work of a spreadsheet upload or an import from a store. Rows without their own weight and size use the package or saved package you pass. Insurance and Extra Services come only from a saved package, and one batch holds one package type. The call reaches no one and spends no money, so it does not ask for your OK.

Example response:

```json
{
  "batch_id": "b_9X2LQ1",
  "shipments": 3,
  "rows_with_address_errors": 0,
  "bought": false
}
```

### buy_label

Buy one label from a rate, paid from your Account Balance or payment method. Access: write, asks the user first. REST: `POST /api/v1/pirate-ship/buy_label`.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `rate_id` | string | yes | Rate ID from get_rates. |
| `ship_date` | date | no | Default: today. |
| `extras` | string[] | no | Extra Services such as Signature Confirmation, as the app names them. |
| `insured_value_usd` | number | no | Declared value for added insurance. |

Spends money: the balance is used first and a payment method must be on file. Returns the shipment ID, the tracking number and the label to print. A bought label can be refunded with refund_label within 28 days. By default you confirm each call; you can switch that off for this tool.

Example response:

```json
{
  "shipment_id": "s_91AB02",
  "carrier": "USPS",
  "service": "Ground Advantage",
  "cost_usd": 7.12,
  "tracking": "9400 1112 0000 0000 0002 09",
  "labels_url": "https://cotlet.dev/api/v1/files/labels/s_91AB02.pdf"
}
```

### buy_batch

Buy labels for every shipment in a batch with one service, like Buy Labels. Access: write, asks the user first. REST: `POST /api/v1/pirate-ship/buy_batch`.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `batch_id` | string | yes | Batch ID from create_batch. |
| `service` | string | yes | Service from get_batch_rates, e.g. USPS Ground Advantage. |
| `ship_date` | date | no | Default: today. |

Spends money for every label in the batch at once. Returns each shipment with its cost and tracking number, the total, and one link to print all labels. For store orders, Pirate Ship then sends the tracking numbers back to the store. By default you confirm each call; you can switch that off for this tool.

Example response:

```json
{
  "batch_id": "b_7Q4K2M",
  "status": "purchased",
  "service": "USPS Ground Advantage",
  "ship_date": "2026-10-12",
  "labels": [
    {
      "shipment_id": "s_91B001",
      "order_id": "#1042",
      "cost_usd": 7.12,
      "tracking": "9400 1112 0000 0000 0003 11"
    },
    {
      "shipment_id": "s_91B002",
      "order_id": "#1043",
      "cost_usd": 7.12,
      "tracking": "9400 1112 0000 0000 0003 28"
    },
    {
      "shipment_id": "s_91B003",
      "order_id": "#1044",
      "cost_usd": 8.45,
      "tracking": "9400 1112 0000 0000 0003 35"
    },
    {
      "shipment_id": "s_91B004",
      "order_id": "#1045",
      "cost_usd": 9.31,
      "tracking": "9400 1112 0000 0000 0003 42"
    }
  ],
  "total_usd": 32,
  "labels_url": "https://cotlet.dev/api/v1/files/labels/b_7Q4K2M.pdf"
}
```

### refund_label

Request a refund for an unused label, like Refund Label. Access: write, asks the user first. REST: `POST /api/v1/pirate-ship/refund_label`.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `shipment_id` | string | yes | Shipment ID from list_shipments, buy_label or buy_batch. |

Works within 28 days of buying the label. USPS labels you have not printed refund instantly, printed ones wait for USPS to confirm they were never scanned, and UPS refunds are usually approved within about an hour. Approved money goes to your Account Balance. A refunded label can no longer be used. By default you confirm each call; you can switch that off for this tool.

Example response:

```json
{
  "shipment_id": "s_83F2A1",
  "carrier": "USPS",
  "status": "refunded",
  "amount_usd": 7.12,
  "credited_to": "Account Balance"
}
```

### create_scan_form

USPS End of Day SCAN Form for the labels of one Ship Date, as a PDF link. Access: write. REST: `POST /api/v1/pirate-ship/create_scan_form`.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `ship_date` | date | no | Ship Date group on the End of Day page. Default: today. |
| `batch_id` | string | no | Only the labels of this batch. |
| `from_address_id` | string | no | Ship From Address, when you ship from more than one. |

Covers USPS labels only. Labels bought after 8:00 PM local time belong to the next day. A created form cannot be edited, so a later label needs a second form. It reaches no one and costs nothing, so it does not ask for your OK.

Example response:

```json
{
  "ship_date": "2026-10-12",
  "usps_labels": 24,
  "scan_form_url": "https://cotlet.dev/api/v1/files/scan-forms/2026-10-12.pdf"
}
```

### schedule_pickup

Ask USPS or UPS to collect your packages, like Schedule a Pickup. Access: write, asks the user first. REST: `POST /api/v1/pirate-ship/schedule_pickup`.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `carrier` | enum | yes | usps or ups. |
| `date` | date | yes | Pickup date. |
| `package_count` | integer | yes | Number of packages. |
| `total_weight_oz` | number | no | Total weight of the packages, required for USPS. |
| `location` | string | no | Where the carrier finds the packages, e.g. front door. |

USPS pickups are free and run every day except Sunday. UPS pickups are always requested by hand, and the help center lists a fee for them, so check get_account_balance first. The call books a driver visit at your address. By default you confirm each call; you can switch that off for this tool.

Example response:

```json
{
  "carrier": "USPS",
  "date": "2026-10-13",
  "package_count": 12,
  "total_weight_oz": 264,
  "fee_usd": 0,
  "status": "scheduled"
}
```

## How do I connect Pirate Ship to Claude Code, Codex or Cursor?

Connecting Pirate Ship takes three steps: request access, sign in to Pirate Ship once, then add one MCP server or call the REST API with the same key.

### Connect Pirate Ship to your agent.

1. **Create an account** Sign up and add Pirate Ship in the console. Your API key is there too.

2. **Sign in to Pirate Ship once** Open the connect page from the console and sign in to Pirate Ship the way you always do. We keep the session, never your password, and you can revoke it anytime.

3. **Add Cotlet to your agent** Paste the snippet for your client. The same server and key serve every app you connect, so you do this once.

   Claude Code:

```
claude mcp add --transport http cotlet \
  https://cotlet.dev/mcp/v1 \
  --header "Authorization: Bearer $COTLET_API_KEY"
```

   Cursor:

```
{
  "mcpServers": {
    "cotlet": {
      "url": "https://cotlet.dev/mcp/v1",
      "headers": {
        "Authorization": "Bearer ${COTLET_API_KEY}"
      }
    }
  }
}
```

   Codex:

```
# ~/.codex/config.toml
[mcp_servers.cotlet]
url = "https://cotlet.dev/mcp/v1"
bearer_token_env_var = "COTLET_API_KEY"
```

4. **Ask your agent** Ask in plain words. Your agent finds the Pirate Ship tools on the server and calls them for you; anything that reaches other people waits for your OK unless you switch that off for a tool.

```
Take the wholesale orders in wholesale.csv plus my unshipped Shopify orders, split them by box, show me the USPS Ground Advantage totals and buy the labels once I say OK.
```

### Call Pirate Ship from your scripts.

1. **Export your API key** Your scripts use the same API key as your agent. Keep it in an environment variable, never in your code.

```
export COTLET_API_KEY="cotlet_..."
```

2. **Call a tool** Every tool is a POST endpoint at /api/v1/pirate-ship/{tool}. Send its parameters as JSON, exactly as listed in the endpoints above.

```
curl https://cotlet.dev/api/v1/pirate-ship/buy_batch \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"batch_id":"b_7Q4K2M","service":"USPS Ground Advantage","ship_date":"2026-10-12"}'
```

3. **Read the result** You get plain JSON back, ready for your script. A failed call costs nothing.

```
{
  "batch_id": "b_7Q4K2M",
  "status": "purchased",
  "labels": 4,
  "total_usd": 32,
  "labels_url": "https://cotlet.dev/api/v1/files/labels/b_7Q4K2M.pdf"
}
```

## Why use Cotlet for Pirate Ship?

**Built for agents**

- One MCP server for every app you connect.
- The same tools as a REST API for scripts and cron jobs.
- Works with Claude Code, Codex and Cursor.

**Your login stays yours**

- You sign in to Pirate Ship yourself. We keep only the session, encrypted with AES-256.
- The model never sees a login.
- No stored passwords, no CAPTCHA solving, no MFA bypass.

**You stay in control**

- Pick read only, or read and write.
- Anything that reaches other people waits for your OK, unless you switch it off per tool.
- Revoke access in one click.

**Kept working for you**

- We test every integration daily.
- When Pirate Ship changes, the tool pauses until we fix it.
- Failed calls cost nothing.

## Is there a Pirate Ship MCP server on GitHub?

We found no Pirate Ship app on Zapier and no community MCP server (checked 11 Oct 2026). The usual workaround is exporting orders to a spreadsheet and uploading it in the web app, or connecting a store.

|  | Spreadsheet upload | Cotlet |
|---|---|---|
| Setup | Export orders to CSV or XLSX, map the columns the first time you upload a new format | Request access, sign in to Pirate Ship once in your browser, add one MCP server or API key |
| When the app changes | Nothing to maintain | Our team tests it daily and fixes it for you; failed calls are free |
| Orders from other sources | You export and upload each time | Your agent turns any list, email or sheet into a batch |
| Your Pirate Ship session | Your own browser login | Encrypted in an EU vault, limited to the actions you allow, revoked in one click |
| When the session expires | You sign in again | If Pirate Ship logs you out, your agent gets a link to sign in again |
| Where it runs | In your browser, when you are there | Hosted: Claude Code, Codex, Cursor, n8n and scripts, also on a schedule |
| Price | Pirate Ship is free, you pay only postage | Free 7-day trial with 5,000 credits, then credits per call; postage is still paid in Pirate Ship |

### Which one fits you

**Pick Cotlet if**

- you are not a developer, or you do not want to maintain a server
- you need it to keep working when Pirate Ship changes, without checking it yourself
- your agent or a script should run it on a schedule, also while your computer is off

**Pick an open-source server if**

- you are comfortable installing, updating and fixing it yourself
- you want the session to stay on your own computer
- you only need it now and then, from one MCP client

## How much does the Pirate Ship API cost?

Free 7-day trial with 5,000 credits, no card needed. After that, the Pirate Ship API comes with the Cotlet plan, from $29 a month for 3,000 credits, with no limit on apps. Each month's credits stay valid for 3 months, so unused credits add up.

| Size | Price | Credits / month | Per credit |
|---|---|---|---|
| Solo | $29/mo | 3,000 | about $0.0097 |
| Pro | $99/mo | 12,000 | about $0.0083 |
| Agency | $299/mo | 40,000 | $0.0075 |

Each successful call uses credits for the work it takes; failed calls and timeouts cost nothing. A hard spend cap is on by default. Authenticate with the `Authorization: Bearer` header. [See full pricing](https://cotlet.dev/pricing)

## How Cotlet holds your access

Cotlet hosts MCP servers and REST APIs for apps with no usable API. Your agent works in your own Pirate Ship account.

- **Company details:** The legal name, address and registration numbers of the company behind Cotlet are in the Terms of service. [Terms](https://cotlet.dev/terms)
- **Your session:** You sign in to Pirate Ship yourself, in your browser. We keep only the session, never your password: encrypted with AES-256 in an EU vault, isolated to your account and used only when your agent calls a Pirate Ship tool you allowed. When it expires, your agent gives you a link to sign in again. [Security](https://cotlet.dev/security)
- **Revoking access:** Disconnect Pirate Ship in your dashboard: the session is deleted and access ends at once. Actions that reach other people wait for your OK unless you switch that off per tool.
- **What we never do:** Store passwords, solve CAPTCHAs or bypass MFA.
- **Pirate Ship's terms:** You use your own Pirate Ship account and stay responsible for following Pirate Ship's terms. Cotlet is independent and not affiliated with Pirate Ship. [Terms](https://cotlet.dev/terms)
- **Contact:** Questions about the company, security or an app: [contact@cotlet.dev](mailto:contact@cotlet.dev)

## Frequently asked questions

**How do I get access?**

Request access and pick Pirate Ship. Cotlet reviews each request and emails you your API key.

**Do I need to be technical?**

No. You sign in to Pirate Ship once in your browser and paste one command into your agent, or one URL into n8n. Your agent can walk you through it. There is no server to install, update or fix.

**Is a hosted server safe? My Pirate Ship session would leave my computer.**

Cotlet keeps your Pirate Ship session encrypted with AES-256 in an EU vault, isolated to your account and used only for the tools you allow: read only, or read and write. The AI model never sees it, and you revoke it in one click. A local server keeps the same session in a file on your computer, readable by any program you run, and needs a fresh sign-in whenever it expires.

**Do I need money in my Account Balance?**

No. Pirate Ship uses your Account Balance first and charges your payment method on file for the rest. You can add credit at any time.

**Can the agent add insurance to a whole batch?**

Yes, through a Saved Package. A spreadsheet cannot carry insurance, so Pirate Ship asks you to save a package with insurance and apply it to the upload.

**Can my agent post or send messages in Pirate Ship without asking me?**

No. Every call to buy_label, buy_batch, refund_label or schedule_pickup waits for your OK by default. For scheduled automations you can switch confirmation off per tool in your dashboard, for example only for approvals. create_batch, create_scan_form runs without asking, because it sends nothing to anyone and one call undoes it.

**Can I use the Pirate Ship API in n8n?**

Yes. Add https://cotlet.dev/mcp/v1 with your API key in n8n's MCP Client node, or call https://cotlet.dev/api/v1/pirate-ship/{tool} from the HTTP Request node.
