{"openapi":"3.1.0","info":{"title":"CurlShip API","version":"1.0.0","summary":"Bot-friendly SaaS directory. Submit and manage listings with a single curl command.","description":"CurlShip is a SaaS directory that welcomes automated submissions — **bots, agents, and AI are explicitly welcome**. No CAPTCHA, no login, no approval queue. Submit a product, verify your dofollow badge on demand, or upgrade to a paid tier, all over plain JSON.\n\nSee also [`/llms.txt`](/llms.txt) for a plain-text agent brief.","contact":{"name":"CurlShip Support","email":"support@curlship.com","url":"https://curlship.com"},"license":{"name":"Proprietary"}},"servers":[{"url":"https://curlship.com","description":"Production"}],"externalDocs":{"description":"Badge guide & instant verify","url":"https://curlship.com/badge"},"tags":[{"name":"Listings","description":"Create and read directory listings."},{"name":"Badge","description":"Dofollow badge verification."},{"name":"Billing","description":"Paid-tier upgrades."}],"paths":{"/api/submit":{"post":{"tags":["Listings"],"summary":"Submit a product listing","description":"Add a product to the directory. Goes live instantly — no review queue. One listing per root domain. Rate limit: 10 submissions/hour per IP.\n\nFree tier gets a `nofollow` link; add the [badge](/badge) for `dofollow`. Pass `tier` to start a paid checkout instead.","operationId":"submitListing","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url","email"],"properties":{"url":{"type":"string","format":"uri","example":"https://yourapp.com"},"email":{"type":"string","format":"email","example":"you@email.com"},"tier":{"type":"string","enum":["bronze","silver","gold","platinum"],"description":"Optional. Omit for the free tier."}}},"example":{"url":"https://yourapp.com","email":"you@email.com"}}}},"responses":{"201":{"description":"Listing created","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"message":{"type":"string"},"listing":{"type":"object","properties":{"id":{"type":"integer","example":2076},"url":{"type":"string","format":"uri","example":"https://yourapp.com/"},"tier":{"type":"string","enum":["free","bronze","silver","gold","platinum"]},"title":{"type":["string","null"],"example":"YourApp — ship faster"},"description":{"type":["string","null"]},"image":{"type":["string","null"],"format":"uri"},"has_badge":{"type":"boolean","description":"True if a dofollow link back to curlship.com was found on the site."}}},"badge_html":{"type":"string","description":"Ready-to-paste badge snippet."},"badge_guide":{"type":"string","format":"uri"}}}}}},"200":{"description":"Already listed (idempotent)","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"URL on a blocklist (adult/phishing/malware)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A listing for this domain already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/verify-badge":{"post":{"tags":["Badge"],"summary":"Verify your badge on demand","description":"Immediately re-fetch your listed site and check for a link back to `curlship.com`. This is the manual trigger for the otherwise-hourly badge cron — use it right after adding the badge. A qualifying link (not `rel=nofollow/ugc/sponsored`) upgrades a free listing to `dofollow`. Paid tiers are always `dofollow`. Rate limit: 30/hour per IP.","operationId":"verifyBadge","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri","example":"https://yourapp.com"}}},"example":{"url":"https://yourapp.com"}}}},"responses":{"200":{"description":"Check completed","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"has_badge":{"type":"boolean"},"dofollow":{"type":"boolean"},"tier":{"type":"string"},"listing":{"type":"object","properties":{"id":{"type":"integer","example":2076},"url":{"type":"string","format":"uri","example":"https://yourapp.com/"},"tier":{"type":"string","enum":["free","bronze","silver","gold","platinum"]},"title":{"type":["string","null"],"example":"YourApp — ship faster"},"description":{"type":["string","null"]},"image":{"type":["string","null"],"format":"uri"},"has_badge":{"type":"boolean","description":"True if a dofollow link back to curlship.com was found on the site."}}},"message":{"type":"string"}}},"example":{"ok":true,"has_badge":true,"dofollow":true,"tier":"free","message":"Badge verified — your link is now dofollow. 🎉"}}}},"400":{"description":"Missing or malformed url","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No listing found for that URL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/upgrade":{"post":{"tags":["Billing"],"summary":"Upgrade a listing to a paid tier","description":"Returns a hosted checkout URL for the chosen tier. The listing must already exist.","operationId":"upgradeListing","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url","tier"],"properties":{"url":{"type":"string","format":"uri","example":"https://yourapp.com"},"tier":{"type":"string","enum":["bronze","silver","gold","platinum"]}}},"example":{"url":"https://yourapp.com","tier":"gold"}}}},"responses":{"200":{"description":"Checkout URL created","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"checkout_url":{"type":"string","format":"uri"}}}}}},"400":{"description":"Invalid tier","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Listing not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Payments not configured for this tier","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/listings":{"get":{"tags":["Listings"],"summary":"List all active listings","description":"Returns every active listing as JSON. Good for agents building a directory mirror or picking a tier.","operationId":"listListings","responses":{"200":{"description":"All active listings","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"listings":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer","example":2076},"url":{"type":"string","format":"uri","example":"https://yourapp.com/"},"tier":{"type":"string","enum":["free","bronze","silver","gold","platinum"]},"title":{"type":["string","null"],"example":"YourApp — ship faster"},"description":{"type":["string","null"]},"image":{"type":["string","null"],"format":"uri"},"has_badge":{"type":"boolean","description":"True if a dofollow link back to curlship.com was found on the site."}}}}}}}}}}}}},"components":{"schemas":{"Listing":{"type":"object","properties":{"id":{"type":"integer","example":2076},"url":{"type":"string","format":"uri","example":"https://yourapp.com/"},"tier":{"type":"string","enum":["free","bronze","silver","gold","platinum"]},"title":{"type":["string","null"],"example":"YourApp — ship faster"},"description":{"type":["string","null"]},"image":{"type":["string","null"],"format":"uri"},"has_badge":{"type":"boolean","description":"True if a dofollow link back to curlship.com was found on the site."}}},"Error":{"type":"object","properties":{"ok":{"type":"boolean","example":false},"error":{"type":"string","example":"url is required and must start with http"}},"required":["ok","error"]}}}}