MadeThis API

Business primitives — products, checkout, orders — behind an HTTP API your own coding agent can drive. Bring your own editor, your own agent, and your own hosting; MadeThis handles the money.

Base URL https://api.madethis.com/v1

1. Get a key

Create a headless business at /api-keys and mint a key. Keys are business-scoped and shown exactly once. A headless business provisions nothing — no site, no inbox, no AI co-founder — because you are supplying all three.

2. First call

curl https://api.madethis.com/v1/business \
  -H "Authorization: Bearer $MADETHIS_API_KEY"

Every success returns { "data": … }, often alongside hint and next_action — one-line orientation written for agents, so a model can chain the next call without a human reading the docs.

3. Sell something

# Create a product. fileUrl is the deliverable buyers receive.
curl -X POST https://api.madethis.com/v1/products \
  -H "Authorization: Bearer $MADETHIS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"name":"My Guide","priceAmountCents":2900,"fileUrl":"https://…/guide.pdf"}'

# Turn it into a shareable checkout URL.
curl -X POST https://api.madethis.com/v1/checkout-links \
  -H "Authorization: Bearer $MADETHIS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"productId":"<id from above>"}'

# Watch for sales.
curl https://api.madethis.com/v1/orders \
  -H "Authorization: Bearer $MADETHIS_API_KEY"

Idempotency

Send Idempotency-Key on creates. Replaying the identical request returns the original response with Idempotency-Replayed: true instead of writing twice; reusing the key with a different body returns idempotency_conflict. Retry a timed-out create byte-identically and you cannot double-charge yourself a duplicate.

Routes

Ads

GET/adsAd budget and every campaign, newest first
PATCH/ads/{id}/budgetChange the daily ad budget (business-level; increases are spend-gated)
GET/ads/{id}/insightsPerformance for one campaign (checkpointed, lags Meta ~30m)
POST/ads/{id}/pausePause a campaign - never gated, always available
POST/ads/interestsResolve interest names against Meta's targeting catalog
POST/ads/publishCreate and launch a Meta campaign (async; spend-policy gated)

Business

GET/businessGet the authenticated business
PATCH/businessSet checkout return URLs and the unattended-spend policy

Money

POST/checkout-linksGet a shareable checkout URL for an active product
GET/ordersList orders, newest first
GET/orders/{id}Get one order
POST/orders/{id}/refundRefund an order, fully or partially (Idempotency-Key required)
GET/payoutsPayout status and onboarding eligibility (Stripe Connect)
POST/payouts/onboarding-linkStart Stripe Connect payout onboarding

Auth

POST/cli-auth/pollPoll a CLI login pairing for the minted key
POST/cli-auth/startBegin a CLI login pairing

Confirmations

GET/confirmationsList actions waiting on your confirmation
GET/confirmations/{id}Get one confirmation, including its stored result once it has executed
POST/confirmations/{id}/confirmConfirm a parked action — executes it exactly once
POST/confirmations/{id}/rejectReject a parked action — it will never execute

Domains

GET/domainsList registered domains and the DNS records still required
POST/domainsRegister a domain you host yourself; returns its verification record
DELETE/domains/{id}Unregister a domain (DNS is left untouched)
POST/domains/{id}/verifyCheck DNS now and verify ownership

Email

GET/email/inboxInbox address and provisioning status
POST/email/inboxProvision the business inbox (idempotent; still provisioning while DNS verifies)
POST/email/sendSend an email from the business inbox (per-inbox daily cap)
GET/email/threadsList email threads, newest first
GET/email/threads/{id}Get one thread with its messages, oldest first

Files

POST/filesGet a signed URL to upload a product deliverable
POST/files/completeRegister an uploaded file and get its permanent fileUrl

Leads

GET/leadsList leads, newest first
POST/leads/importImport your own lead list (per-row rejections, deduped)
POST/leads/searchSearch for leads matching an ICP (billed per Apollo enrichment)
GET/sequencesList sequences with send/reply/booked stats and outreach readiness
POST/sequencesCreate a cold-email sequence (draft - sends nothing until leads are enrolled)
POST/sequences/{id}/cancelCancel a sequence permanently (leads marked exhausted)
POST/sequences/{id}/leadsEnrol leads and start sending (held for confirmation)
POST/sequences/{id}/pausePause a sequence (mid-sequence leads keep their place)
POST/sequences/{id}/resumeResume a paused sequence (held for confirmation)

Orders

POST/orders/{id}/shipMark a physical order shipped, with optional tracking

Products

GET/productsList products
POST/productsCreate a product (syncs to Stripe when active)
GET/products/{id}Get one product
PATCH/products/{id}Update a product (status archived = retire)

Social

GET/social/accountsConnected social accounts with trust tier, liveness and postability
POST/social/connectGet a link the owner opens to connect an account (OAuth needs a browser)
GET/social/postsList social posts, newest first
POST/social/postsCompose and publish or schedule a social post
DELETE/social/posts/{id}Cancel a scheduled post before it publishes
POST/social/posts/{id}/retryRetry a failed or partially published post

Usage

GET/usageCredit balance and whether writes are currently allowed

Webhooks

GET/webhooksList webhook endpoints
POST/webhooksRegister a webhook endpoint (secret returned once)
DELETE/webhooks/{id}Delete a webhook endpoint

Errors

Stable machine-readable codes, each linking straight to its explanation. See the error reference.

CLI and MCP server

The MadeThis CLI includes a local stdio MCP server for approved developer accounts. It reuses the CLI's business-scoped credential, so a compatible coding agent can call this API without copying a key into its configuration. After authenticating the CLI, run madethis mcp to start the server.

For generated clients and validators, download the MadeThis OpenAPI 3.1 schema.