# CurlShip

Action list for agents. Do not parse the homepage HTML.
Tool catalog: https://curlship.com/agents.json
MCP: https://curlship.com/mcp
Agent card: https://curlship.com/.well-known/agent-card.json
Paid actions return checkout_url. Opening that URL is the payment.
Long rules: https://curlship.com/llms.txt

## Featured — read this first

One listing above every tier, including Platinum. Always dofollow. One-time payment. No refund when outbid. Not a tier.
MakiRoll: Become someone who makes video (https://www.makiroll.app/) holds it for $50. Next bid $51.
The product must already be listed. The checkout bills the address stored on the listing.
Omit amount_usd to bid the minimum.

GET https://curlship.com/api/featured
POST https://curlship.com/api/feature
{"url": "<listed product URL>", "amount_usd": 51}

## Tools

### bid_featured

Take the Featured spot. It sits above every listing. The minimum right now is $51. Always dofollow. One-time payment, no refund when someone outbids you. The product must already be listed. Omit amount_usd to bid $51.

POST https://curlship.com/api/feature
{"url": {"type": "string", "description": "URL of a listing that is already on the directory."}, "amount_usd": {"type": "number", "description": "Bid in USD. Omit to bid the minimum (51)."}}

### read_featured

Who holds the Featured spot, and the current minimum bid.

GET https://curlship.com/api/featured

### submit_listing

List a product. It goes live immediately. One listing per root domain. https://yourapp.com is the documentation placeholder and is refused.

POST https://curlship.com/api/submit
{"url": {"type": "string"}, "email": {"type": "string"}, "tier": {"type": "string", "enum": ["bronze", "bronze_lifetime", "silver", "gold", "platinum"], "description": "Omit for the free tier. For the spot above every tier use bid_featured."}}

### upgrade_listing

Checkout URL for a paid tier on a listing that already exists. Featured is bid_featured, not this.

POST https://curlship.com/api/upgrade
{"url": {"type": "string"}, "tier": {"type": "string", "enum": ["bronze", "bronze_lifetime", "silver", "gold", "platinum"]}}

### refresh_listing

Re-read title, description, and image from the listed page. Send listing_id and proof only. The first confirm previews; send apply back to save.

POST https://curlship.com/api/edit-request
{"listing_id": {"type": "integer"}, "proof": {"type": "string", "enum": ["email", "domain"]}}

### change_listing_url

Point an existing listing at a new URL. One listing per root domain, so this is how a second page replaces the first.

POST https://curlship.com/api/edit-request
{"listing_id": {"type": "integer"}, "url": {"type": "string"}, "proof": {"type": "string", "enum": ["email", "domain"]}}

### remove_free_listing

Take a free listing off the directory. Send remove true and no url or email. A paid listing or the Featured holder is refused.

POST https://curlship.com/api/edit-request
{"listing_id": {"type": "integer"}, "remove": {"type": "boolean", "const": true}, "proof": {"type": "string", "enum": ["email", "domain"]}}

### confirm_edit

Apply an edit request. A refresh needs a second call with the apply digest from the preview.

POST https://curlship.com/api/edit-confirm
{"request_id": {"type": "integer"}, "token": {"type": "string"}, "apply": {"type": "string", "description": "Digest from the refresh preview. Omit for a URL change or a removal."}}

### verify_badge

Re-check the listed site for a link to curlship.com. A free listing with the badge becomes dofollow.

POST https://curlship.com/api/verify-badge
{"url": {"type": "string"}}

### list_listings

Active listings as JSON. No query returns every listing, in the same order as before. Optional query parameters: limit, offset, q, and since. q matches the title, description, or URL. since is an ISO timestamp; listings created at or after it are kept. Each listing includes created_at. There is no category or tag field.

GET https://curlship.com/api/listings
{"limit": {"type": "integer", "minimum": 0, "description": "Max listings. 50 with offset, 100 with q, when omitted."}, "offset": {"type": "integer", "minimum": 0, "description": "How many matching listings to skip."}, "q": {"type": "string", "description": "Substring of the title, description, or URL."}, "since": {"type": "string", "description": "ISO timestamp. Keep listings created at or after this moment."}}

### get_stats

Listing counts and the Ahrefs Domain Rating.

GET https://curlship.com/api/stats

### get_daily_stats

Active listings added per UTC day — the zero-filled series behind the public /stats page. One entry per calendar day from the first listing to today, each with added and the cumulative running total.

GET https://curlship.com/api/stats/daily
{"range": {"type": ["string", "integer"], "description": "\"all\" (default) for the whole series, or a day count 1-3650 for the last N days."}}

### get_dr_history

The site's Ahrefs Domain Rating over time — the series behind /stats#dr. Every recorded reading, one per UTC day, plus the current value, the last step (change vs the most recent different reading) and the growth since the first reading.

GET https://curlship.com/api/stats/dr

https://yourapp.com is a placeholder. The API refuses that host.
