DoorDash API
Everything the Discord bot does — account generation, the 50%-off deal, preview, and ordering — exposed as a REST API you fully control. Build your own bot, website, dashboard, or automation on the same engine, and customize every detail of every order.
Overview
The DoorDash API lets you build your own tools on top of AutoMunch's DoorDash engine. You generate
accounts into named batches, the API automatically flags which ones have the
50%-off deal, and you place orders against them. Orders are session-based: order by
account_id
and the server uses the account's stored login — you never handle raw tokens.
https://automunch.site/dd
The DoorDash API requires an active DoorDash subscription (Tier I/II/III or Lifetime). Generate your key with /api_key in the AutoMunch Discord.
50% DashPass OR 40% promo (mutually exclusive — combining a DashPass deal with a promo code is no longer accepted by DoorDash), price-before-you-charge previews, Express & Scheduled delivery, an automatic public tracking link on every order, optional address-swap, and custom carts from the browser extension (automunch.site/cart/...). Failed orders never charge credits.
No /multiorder-equivalent and no /string endpoint — those are Discord-only. Use multiple /v1/order calls (cap: 2 active jobs).
The engine talks to DoorDash's Android mobile API (not the web site) with client id 1679956685075657170. Signup reCAPTCHA runs through CapMonster V3 Enterprise as a fallback (NextCaptcha broke for mobile reCAPTCHA on 2026-09-22, so acceptance under the fallback is lower than it used to be — expect retries on mode: "signup"). /v1/gen traffic goes out over a dedicated ET Mobile 4G pool; /v1/order and scrape traffic use the main ET Mobile pool. Every login-mode order submits a full Riskified fingerprint on each attempt — required since the 2026-09-23 fix to clear tap/3DS/dyscan declines.
Authentication
Every request needs a Bearer token in the Authorization header.
AutoMunch API keys are prefixed with am_live_ (unified across every AutoMunch bot — the same key works for DoorDash, Uber Eats, Instacart, etc.) and are generated with /api_key on Discord. One active key per user.
Legacy dd_live_ keys from before the unified-wallet migration are still accepted.
Authorization: Bearer am_live_your_key_here
Your SMS key, email domain, and List tier are read from your /settings on Discord (linked to your key). Run /settings once before using /v1/gen. Without a saved daisysms_api_key in /settings, POST /v1/gen returns 400 daisysms_api_key not configured. Default List tier is now DDPublic.
The 50% Deal
50% off is DashPass-only — not a combo. Every order lands in exactly one of two buckets: the 50% DashPass deal (no promo code) or a 40% promo code (no DashPass deal). The two are mutually exclusive. The old combo that layered a promo code on top of the DashPass deal is dead — DoorDash stopped allowing a promo to apply alongside the DashPass deal, so the bot picks whichever single path saves more on the cart.
What the deal actually is. The 50% deal is DoorDash's
UPSELL_OFFER_TYPE_DEALSPROMO
tied to a DashPass free-trial audience (CLASSIC_FREE_TRIAL /
RESURRECTED_FREE_TRIAL). It is not a code — it is an audience-targeted free-trial
offer DoorDash shows to some accounts. Subscribing the free trial commits a
PROMOTION_DISCOUNT line onto the cart. It is region/history/cart-sensitive, and DoorDash only
surfaces it on carts over a ~$15 subtotal floor.
Card-free trial. The bot subscribes the free DashPass trial with
stripe_id: "" — no payment method is attached, so the trial physically cannot
auto-charge the $9.99 when it would otherwise expire. Any pre-existing trial on the account is cancelled
before the card is added so DoorDash cannot auto-link the newly-tokenized card to a lingering
subscription, and a retry-cancel runs after the order lands (see
Confirm & Place).
How accounts get flagged. On POST /v1/gen the engine runs the
heavy probe: it builds a throwaway probe cart over the ~$15 floor, confirms the
UPSELL_OFFER_TYPE_DEALSPROMO upsell, subscribes the free DashPass trial card-free, verifies a
real committed PROMOTION_DISCOUNT line, then marks the account
is_50_eligible: true.
The /scrape command on Discord uses a light probe that sets the eligibility flag
from the upsell signal without subscribing the trial. The badge means "last probe saw
the deal on offer," not a permanent guarantee.
The free-trial deal can lapse as an account ages, so every eligible account carries a checked_at timestamp and a stale flag (default cutoff 24h). Stale accounts are re-verified for real at order time. The badge is also one-shot per account — the moment a 50% order confirms, is_50_eligible flips 1 → 0, because DashPass free trials can only be redeemed once per account.
If /scrape has recorded a promo code worth more than 50% on the account (stored in chain_data.promos_json, account-scope only), the bot picks that scraped code instead of the DashPass deal. Ties go to the 50% deal; a scraped code wins only if its percent is strictly greater than 50.
Async Jobs
Generating accounts and placing orders take time, so they run as background jobs. Those endpoints return
202 with a
job_id — poll
GET /v1/jobs/{id} until completed or failed. The preview endpoints are synchronous (they return pricing directly). Max 2 active jobs per user. Polling only — no webhooks or callbacks.
Quickstart
1 · Get a key
Run /api_key on Discord and configure /settings.
2 · Generate a batch
POST /v1/gen with a batch_name. Accounts are probed for the 50% deal.
3 · Find eligible
GET /v1/eligible returns the accounts that have the deal, with their account_id.
4 · Preview & confirm
POST /v1/order/preview to see the price, then POST /v1/order/confirm to place it.
Account Snapshot
Verify your API key and check your credit balance.
curl -H "Authorization: Bearer am_live_..." \ https://automunch.site/dd/v1/me
import requests
API_KEY = "am_live_..."
BASE = "https://automunch.site/dd"
headers = {"Authorization": f"Bearer {API_KEY}"}
r = requests.get(f"{BASE}/v1/me", headers=headers)
r.raise_for_status()
me = r.json()
print("Credits:", me["credits"])
print("Scopes:", me["scopes"])
{
"user_id": 1306300782123159674,
"credits": 42,
"scopes": ["gen", "order", "accounts", "otp"],
"key_prefix": "am_live_8Xk2aB9c..."
}
Generate a Batch
Creates accounts into the named batch and probes each for the 50% deal. SMS key, domain, and List tier come from your Discord /settings. Async — poll the job.
| Field | Type | Required | Notes |
|---|---|---|---|
batch_name | string | Yes | Batch (chain) to create/append to. Shows in /view on Discord too. |
amount | integer | No | 1–5. Default 1. |
account_name | string | No | Name for the accounts. Random if omitted. |
address | string | No | Optional address to attach. |
curl -X POST \
-H "Authorization: Bearer am_live_..." \
-H "Content-Type: application/json" \
-d '{"batch_name": "june-run", "amount": 2}' \
https://automunch.site/dd/v1/gen
import requests
API_KEY = "am_live_..."
BASE = "https://automunch.site/dd"
headers = {"Authorization": f"Bearer {API_KEY}"}
resp = requests.post(f"{BASE}/v1/gen", headers=headers,
json={"batch_name": "june-run", "amount": 2})
resp.raise_for_status()
print(resp.json()) # {"job_id": "...", "status": "queued", ...}
{
"job_id": "2f1c...e7",
"status": "queued",
"batch_name": "june-run",
"poll_url": "/v1/jobs/2f1c...e7"
}
{
"status": "completed",
"result": {
"batch": "june-run",
"successful": 2,
"accounts": [
{
"account_id": 8801,
"email": "johns4d2@outlook.com",
"password": "Pass123!",
"first_name": "John", "last_name": "Smith",
"phone_number": "+11234567890",
"is_50_eligible": true
},
{
"account_id": 8802,
"email": "maria9xk@outlook.com",
"password": "Pass456!",
"first_name": "Maria", "last_name": "K",
"phone_number": "+11234500000",
"is_50_eligible": false
}
]
}
}
List Batches
Your batches with totals and how many accounts are still eligible. Mirrors /view on Discord. The auto "Placed Orders" batch (used accounts) is flagged with is_placed_orders. Accounts generated through /v1/order or /order that fail to place land in a dedicated Order Gens batch so they never pollute your clean pools.
curl -H "Authorization: Bearer am_live_..." \ https://automunch.site/dd/v1/batches
import requests
API_KEY = "am_live_..."
BASE = "https://automunch.site/dd"
headers = {"Authorization": f"Bearer {API_KEY}"}
r = requests.get(f"{BASE}/v1/batches", headers=headers)
r.raise_for_status()
for b in r.json()["batches"]:
print(f'{b["name"]}: {b["total"]} total, {b["eligible_50"]} eligible')
{
"batches": [
{ "id": 12, "name": "june-run", "total": 10,
"eligible_50": 7, "is_placed_orders": false,
"created_at": "2026-06-06 04:22:11" },
{ "id": 19, "name": "Placed Orders", "total": 23,
"eligible_50": 0, "is_placed_orders": true,
"created_at": "2026-06-05 18:03:44" },
{ "id": 22, "name": "Order Gens", "total": 4,
"eligible_50": 2, "is_placed_orders": false,
"created_at": "2026-06-06 11:14:00" }
]
}
View a Batch
Accounts in a batch with their eligibility. No raw tokens are returned — has_jwt tells you a usable session exists.
curl -H "Authorization: Bearer am_live_..." \ https://automunch.site/dd/v1/batches/june-run
import requests
from urllib.parse import quote
API_KEY = "am_live_..."
BASE = "https://automunch.site/dd"
headers = {"Authorization": f"Bearer {API_KEY}"}
name = "june-run" # may contain spaces / special chars
r = requests.get(f"{BASE}/v1/batches/{quote(name, safe='')}", headers=headers)
r.raise_for_status()
batch = r.json()
for a in batch["accounts"]:
print(a["account_id"], a["email"], "50:", a["is_50_eligible"])
{
"batch": "june-run", "chain_id": 12, "total": 10,
"accounts": [
{ "account_id": 8801, "account_number": 1,
"email": "johns4d2@outlook.com", "phone": "+11234567890",
"is_50_eligible": true, "checked_at": "2026-06-07 06:40:12",
"stale": false, "has_jwt": true },
{ "account_id": 8803, "account_number": 3,
"email": "alex7p@outlook.com", "phone": "",
"is_50_eligible": null, "checked_at": null,
"stale": null, "has_jwt": true }
]
}
List Chains
Lower-level listing of every batch (chain) you own, keyed by numeric chain_id. Use this when you want to look batches up by id rather than by name. Returns the same batches as /v1/batches; the auto Placed Orders, Fraud-Retired, and Order Gens chains show up here with their flags.
curl -H "Authorization: Bearer am_live_..." \ https://automunch.site/dd/v1/chains
import requests
API_KEY = "am_live_..."
BASE = "https://automunch.site/dd"
headers = {"Authorization": f"Bearer {API_KEY}"}
r = requests.get(f"{BASE}/v1/chains", headers=headers)
r.raise_for_status()
for c in r.json()["chains"]:
print(c["chain_id"], c["name"], c["total"])
{
"chains": [
{ "chain_id": 12, "name": "june-run", "total": 10,
"eligible_50": 7, "is_placed_orders": false,
"is_fraud_retired": false, "is_order_gens": false },
{ "chain_id": 19, "name": "Placed Orders", "total": 23,
"eligible_50": 0, "is_placed_orders": true,
"is_fraud_retired": false, "is_order_gens": false },
{ "chain_id": 22, "name": "Order Gens", "total": 4,
"eligible_50": 2, "is_placed_orders": false,
"is_fraud_retired": false, "is_order_gens": true }
]
}
Accounts in a Chain
Same shape as /v1/batches/{name}, but keyed by numeric chain_id — handy if you cached chain ids from /v1/chains and don't want to deal with URL-encoding a name.
curl -H "Authorization: Bearer am_live_..." \ https://automunch.site/dd/v1/chains/12/accounts
import requests
API_KEY = "am_live_..."
BASE = "https://automunch.site/dd"
headers = {"Authorization": f"Bearer {API_KEY}"}
chain_id = 12
r = requests.get(f"{BASE}/v1/chains/{chain_id}/accounts", headers=headers)
r.raise_for_status()
for a in r.json()["accounts"]:
print(a["account_id"], a["email"], "50:", a["is_50_eligible"])
Eligible Accounts
Every account that currently has the 50% deal, across all batches. Use the account_id to place an order.
Placed Orders and Fraud-Retired chains.
| Query param | Notes |
|---|---|
batch | Only this batch. |
fresh_only | true drops accounts whose deal is stale (older than the cutoff). |
curl -H "Authorization: Bearer am_live_..." \ "https://automunch.site/dd/v1/eligible?fresh_only=true"
import requests
API_KEY = "am_live_..."
BASE = "https://automunch.site/dd"
headers = {"Authorization": f"Bearer {API_KEY}"}
r = requests.get(f"{BASE}/v1/eligible", headers=headers,
params={"batch": "june-run", "fresh_only": "true"})
r.raise_for_status()
elig = r.json()
print(f'{elig["count"]} fresh eligible accounts')
for a in elig["accounts"]:
print(a["account_id"], a["email"])
{
"count": 2,
"stale_cutoff_hours": 24,
"accounts": [
{ "account_id": 8801, "email": "johns4d2@outlook.com",
"batch": "june-run", "checked_at": "2026-06-07 06:40:12",
"stale": false },
{ "account_id": 8815, "email": "kayla2v@outlook.com",
"batch": "june-run", "checked_at": "2026-06-06 09:12:00",
"stale": true }
]
}
Preview a Checkout
Prepares and prices the order without placing it — nothing is charged. It loads the account, resolves the cart + address, and if the 50% deal is on offer it subscribes the free DashPass trial card-free (stripe_id empty — no payment method is attached, so the trial cannot auto-charge if left to expire). Returns the real discounted price plus an order_session_id you confirm later. Synchronous (no job).
| Field | Required | Notes |
|---|---|---|
account_id | Yes* | From /v1/eligible. (*or a raw jwt_token) |
jwt_token | Yes* | Raw DoorDash JWT — alternative to account_id, bypasses the stored session. |
cart_url | Yes | DoorDash group cart (https://drd.sh/cart/...) or a custom cart from the browser extension (automunch.site/cart/...) |
address | Yes | Delivery address, e.g. "123 Main St, 30301" — set as the account default automatically |
card | No | Optional at preview (card is needed at confirm). {number, exp_month, exp_year, cvv, zip} |
tip_cents | No | Tip in cents (e.g. 200 = $2.00) |
store_id | No | Pin the preview to a specific DoorDash store id (skips store resolution from the cart). |
subscribe_dashpass | No | Default true. Set false to skip the free-trial subscription step. |
wait_for_50_off | No | Default true. If the 50% deal hasn't settled yet, wait a few seconds for it to show before quoting. |
scheduled_time | No | ISO-8601 scheduled delivery time (requires delivery_option: "SCHEDULE"). |
promo_codes | No | Array of up to 5 promo codes to try. The server auto-rotates — your codes are unioned with every scraped ≥30% code in the dd_promos table, codes already used on this account are filtered out, and the survivors are shuffled. Designed to beat DoorDash's fraud_block_promo_abuse verdict. |
| + options | No | Any order option also prices here: delivery_option, track, address_swap, gift… |
curl -X POST \
-H "Authorization: Bearer am_live_..." \
-H "Content-Type: application/json" \
-d '{
"account_id": 8801,
"cart_url": "https://drd.sh/cart/abc",
"address": "123 Main St, 30301",
"tip_cents": 200
}' \
https://automunch.site/dd/v1/order/preview
import requests
API_KEY = "am_live_..."
BASE = "https://automunch.site/dd"
headers = {"Authorization": f"Bearer {API_KEY}"}
r = requests.post(f"{BASE}/v1/order/preview", headers=headers, json={
"account_id": 8801,
"cart_url": "https://drd.sh/cart/abc",
"address": "123 Main St, 30301",
"tip_cents": 200,
})
r.raise_for_status()
preview = r.json()
print(preview["pricing"]["total"], preview["order_session_id"])
{
"order_session_id": "os_7Fk2aB...",
"expires_at": "2026-06-07T07:51:00Z",
"store": { "store_id": "44321", "store_name": "Chipotle" },
"cart": { "items": [ { "name": "Burrito Bowl", "quantity": 1, "price_cents": 1095 } ],
"item_count": 1 },
"dashpass": { "has_50_off": true, "subscribed": true, "already_active": false },
"pricing": {
"subtotal": 1095,
"delivery_fee": 199,
"service_fee": 65,
"tax": 47,
"discount": 985,
"tip": 200,
"delivery_option": "STANDARD",
"express_fee": 0,
"promotions": [
{ "code": "DASHPASS50", "amount": 985, "type": "dashpass_50" }
],
"is_dashpass_applied": true,
"total_before_discount": 1606,
"total_after_discount": 621,
"total": 621,
"total_savings": 985,
"is_prediction": false,
"note": "Live price — DashPass active, 50% deal applied."
}
}
Edit a Preview
Change any field on an open preview session and get a new quote — just like the edit buttons on the Discord checkout. Send only the fields you want to change.
| Editable fields |
|---|
address, cart_url (swap the group link), tip_cents, promo_codes, gift, is_pickup, dasher_instructions, gate_code, unit, building_name, pin_coords, account_name, account_id, jwt_token, cancel_dashpass_after |
curl -X POST \
-H "Authorization: Bearer am_live_..." \
-H "Content-Type: application/json" \
-d '{"address": "55 Oak Ave, 30305", "tip_cents": 500}' \
https://automunch.site/dd/v1/order/preview/os_7Fk2aB.../edit
import requests
API_KEY = "am_live_..."
BASE = "https://automunch.site/dd"
headers = {"Authorization": f"Bearer {API_KEY}"}
sid = "os_7Fk2aB..."
r = requests.post(f"{BASE}/v1/order/preview/{sid}/edit", headers=headers, json={
"address": "55 Oak Ave, 30305",
"tip_cents": 500,
})
r.raise_for_status()
updated = r.json()
print("New total:", updated["pricing"]["total"])
The same shape as /v1/order/preview (updated pricing, cart, etc.) for the same order_session_id. Changing cart_url is the heavy edit — it's a new cart, so the deal is re-checked.
Cancel a Preview
Explicitly cancel an open preview session. Frees the account (so a next preview on the same account doesn't collide), rolls back the DashPass free-trial subscription that was taken for the quote, and marks the session cancelled. Idempotent — calling it on an already-cancelled or expired session returns 200 with already_cancelled: true.
curl -X POST \ -H "Authorization: Bearer am_live_..." \ https://automunch.site/dd/v1/order/preview/os_7Fk2aB.../cancel
import requests
API_KEY = "am_live_..."
BASE = "https://automunch.site/dd"
headers = {"Authorization": f"Bearer {API_KEY}"}
sid = "os_7Fk2aB..."
r = requests.post(f"{BASE}/v1/order/preview/{sid}/cancel", headers=headers)
r.raise_for_status()
print(r.json()) # {"cancelled": true, "dashpass_rolled_back": true}
{
"cancelled": true,
"already_cancelled": false,
"dashpass_rolled_back": true,
"order_session_id": "os_7Fk2aB..."
}
Confirm & Place
Async, returns 202 + job_id. DashPass handling: before placing we cancel any existing trial, fall back to a card-free subscribe if the card step fails, and retry a post-order cancel on completion to prevent the $9.99 trial charge. Re-verifies the deal is still good, charges the card, fetches tracking, and moves the account to "Placed Orders". You can pass last-second overrides (tip_cents, dasher_instructions, …).
curl -X POST \
-H "Authorization: Bearer am_live_..." \
-H "Content-Type: application/json" \
-d '{"order_session_id": "os_7Fk2aB..."}' \
https://automunch.site/dd/v1/order/confirm
import time, requests
API_KEY = "am_live_..."
BASE = "https://automunch.site/dd"
headers = {"Authorization": f"Bearer {API_KEY}"}
r = requests.post(f"{BASE}/v1/order/confirm", headers=headers,
json={"order_session_id": "os_7Fk2aB..."})
r.raise_for_status()
# 202 Accepted — place is now running in the background
job = r.json()
print("Queued:", job["job_id"])
# poll until completed
while True:
s = requests.get(f'{BASE}/v1/jobs/{job["job_id"]}', headers=headers).json()
if s["status"] in ("completed", "failed"):
print(s)
break
time.sleep(3)
{ "job_id": "9b7a...11", "status": "queued", "poll_url": "/v1/jobs/9b7a...11" }
{
"status": "completed",
"credits_charged": 3,
"result": {
"order": { "order_uuid": "a1b2c3d4-...",
"verified": { "confirmed": true, "status": "scheduled" } },
"account": { "account_id": 8801, "email": "johns4d2@outlook.com",
"consumer_id": "987654321" },
"store": { "store_id": "44321", "store_name": "Chipotle" },
"pricing": {
"subtotal": 1095,
"delivery_fee": 199,
"service_fee": 65,
"tax": 47,
"discount": 985,
"tip": 200,
"delivery_option": "STANDARD",
"express_fee": 0,
"promotions": [
{ "code": "DASHPASS50", "amount": 985, "type": "dashpass_50" }
],
"is_dashpass_applied": true,
"total_before_discount": 1606,
"total_after_discount": 621,
"total": 621,
"total_savings": 985
},
"dashpass": { "has_50_off": true, "verified_50_off": true,
"cancelled_after": true },
"gift": { "tracking_url": "https://www.doordash.com/orders/a1b2c3d4-.../gift",
"doomdash_tracking_url": "https://doomdash.online/track/X7K2" },
"consume": { "eligibility_used": true, "moved_to_batch": "Placed Orders",
"got_50": true },
"credits_charged": 3
}
}
One-Shot Order
Skips the preview step — prepares and places in one async job. Use this when you don't need a confirmation screen. Same body as preview, plus the full order options below; card is required. In mode: "signup" this is also a "gen & order" shortcut — it signs up a brand-new account inline, then orders. If the sign-up succeeds but the order itself fails, the fresh account lands in your Order Gens batch (not Placed Orders) so you can retry it later.
| Field | Notes |
|---|---|
mode | "login" (default) uses an existing account · "signup" creates a new account inline, then orders on it. |
cart_url, address, card | Required (any mode). |
Login mode (mode: "login") — identify the existing account | |
account_id | Preferred — looks up the stored session. |
jwt_token | Alternative to account_id: a raw DoorDash JWT. |
email / password | Alternative: log in on the fly (needs device_id). |
device_id, dd_session_id, dd_login_id | Device-identity fields for a fresh login (optional with jwt_token). |
Signup mode (mode: "signup") — create the account first | |
sms_api_key | Overrides the SMS key saved in /settings. |
signup_domain | Email domain for the new mailbox. Default "outlook.com". |
custom_email | Full email to use for sign-up instead of a generated one. |
account_name | First/last on the new account (random if omitted). |
list_sms_service | "DDPublic" (default) · "DDPremium" · "Mixed" (auto-pick, uses Premium when the 50% deal shows). Note: an order that uses DDPremium numbers is billed at the 50% rate; DDPublic and Mixed orders are billed at the lower 40% rate — see Credits. |
| Shared order options | |
tip_cents, is_pickup | Standard order options. |
promo_codes | Up to 5. Auto-rotated per account — pass a list and the server picks ones unused on that account. |
subscribe_dashpass | Default true. Set false to not take the free trial. |
wait_for_50_off | Default true. Give the 50% deal a few extra seconds to settle before placing. |
cancel_dashpass_after | Default true — cancels the DashPass trial after every order (success and hard failure) so the free trial never auto-charges. The card-free subscribe already removes the ability to charge, but this still ends the subscription cleanly. |
delivery_option | STANDARD (default) · PRIORITY (express) · SCHEDULE. With SCHEDULE, pass scheduled_time (ISO) or scheduled_min_time / scheduled_max_time. The express_fee is echoed back in pricing. |
scheduled_min_time / scheduled_max_time | Window (ISO) for a scheduled delivery; the engine books the first open slot inside the window. |
track | Default true — places as a gift so the order returns a public tracking link (no login). Set false for a plain order. |
address_swap | Deliver to a random nearby (~500m) address instead of the exact one — anti-ban. address_swap_radius tunes the distance. |
dasher_instructions, gate_code, unit, building_name, pin_coords | Delivery details (pin = "lat,lng") |
gift | Override the default self-gift with a custom recipient: {enabled, recipient_name, recipient_phone, card_message}. Shortcut: pass sender_name and card_id at the top level and the engine builds the gift block for you. |
sender_name | Top-level shortcut — becomes the "from" on the gift receipt. |
card_id | Top-level shortcut — DoorDash gift-card art id for the gift receipt. |
store_id | Pin to a specific DoorDash store id (skips store resolution from the cart). |
promo_codes is auto-rotated per account — pass a list and the server picks ones unused on that account. Codes that have already been consumed by this account are filtered out, so the same list can be reused on every call without burning codes.
curl -X POST \
-H "Authorization: Bearer am_live_..." \
-H "Content-Type: application/json" \
-d '{
"account_id": 8801,
"cart_url": "https://drd.sh/cart/abc",
"address": "123 Main St, 30301",
"card": { "number": "4242424242424242", "exp_month": "12",
"exp_year": "27", "cvv": "123", "zip": "30301" },
"tip_cents": 200,
"gift": { "enabled": true, "recipient_name": "Jane",
"recipient_phone": "+15551234567" }
}' \
https://automunch.site/dd/v1/order
import requests
API_KEY = "am_live_..."
BASE = "https://automunch.site/dd"
headers = {"Authorization": f"Bearer {API_KEY}"}
payload = {
"mode": "login",
"account_id": 8801,
"cart_url": "https://drd.sh/cart/abc",
"address": "123 Main St, 30301",
"card": {"number": "4242424242424242", "exp_month": "12",
"exp_year": "27", "cvv": "123", "zip": "30301"},
"tip_cents": 200,
"promo_codes": ["YOUGOT40", "SAVE40", "APP40"],
"subscribe_dashpass": True,
"wait_for_50_off": True,
"cancel_dashpass_after": True,
"gift": {"enabled": True, "recipient_name": "Jane",
"recipient_phone": "+15551234567"},
}
r = requests.post(f"{BASE}/v1/order", headers=headers, json=payload)
r.raise_for_status()
job = r.json()
print("Queued:", job["job_id"])
import requests
API_KEY = "am_live_..."
BASE = "https://automunch.site/dd"
headers = {"Authorization": f"Bearer {API_KEY}"}
payload = {
"mode": "signup",
"signup_domain": "outlook.com",
"list_sms_service": "DDPublic",
"account_name": "Jamie R",
"cart_url": "https://drd.sh/cart/abc",
"address": "123 Main St, 30301",
"card": {"number": "4242424242424242", "exp_month": "12",
"exp_year": "27", "cvv": "123", "zip": "30301"},
"tip_cents": 200,
"sender_name": "Jamie",
"card_id": "balloons-01",
}
r = requests.post(f"{BASE}/v1/order", headers=headers, json=payload)
r.raise_for_status()
job = r.json()
print("Queued signup+order:", job["job_id"])
# If signup succeeds but ordering fails, the fresh account
# lands in your "Order Gens" batch for a retry.
Returns 202 with a job_id; the completed job has the same full order result as Confirm above.
Check Eligibility
Probe a single account's 50%-off (50% DashPass) eligibility without ordering. Synchronous.
curl -X POST \
-H "Authorization: Bearer am_live_..." \
-H "Content-Type: application/json" \
-d '{"jwt_token": "eyJhbG..."}' \
https://automunch.site/dd/v1/check_50
import requests
API_KEY = "am_live_..."
BASE = "https://automunch.site/dd"
headers = {"Authorization": f"Bearer {API_KEY}"}
# Probe by account_id (uses the stored session)...
r = requests.post(f"{BASE}/v1/check_50", headers=headers,
json={"account_id": 8801})
r.raise_for_status()
print(r.json()) # {"checked": true, "eligible_50": true, ...}
# ...or by raw JWT:
r2 = requests.post(f"{BASE}/v1/check_50", headers=headers,
json={"jwt_token": "eyJhbG..."})
r2.raise_for_status()
print(r2.json())
{ "checked": true, "eligible_50": true, "savings": "$12.65",
"subtotal_cents": 2500, "reason": "ok" }
Poll a Job
Poll until completed or failed.
curl -H "Authorization: Bearer am_live_..." \ https://automunch.site/dd/v1/jobs/9b7a...11
import time, requests
API_KEY = "am_live_..."
BASE = "https://automunch.site/dd"
H = {"Authorization": f"Bearer {API_KEY}"}
def wait(job_id):
while True:
j = requests.get(f"{BASE}/v1/jobs/{job_id}", headers=H).json()
if j["status"] in ("completed", "failed"):
return j
time.sleep(3)
# 1) generate a batch
job = requests.post(f"{BASE}/v1/gen", headers=H,
json={"batch_name": "june-run", "amount": 2}).json()
wait(job["job_id"])
# 2) find an eligible account
elig = requests.get(f"{BASE}/v1/eligible?fresh_only=true", headers=H).json()
acct = elig["accounts"][0]["account_id"]
# 3) preview
prev = requests.post(f"{BASE}/v1/order/preview", headers=H, json={
"account_id": acct,
"cart_url": "https://drd.sh/cart/abc",
"address": "123 Main St, 30301",
"card": {"number": "4242424242424242", "exp_month": "12",
"exp_year": "27", "cvv": "123", "zip": "30301"},
}).json()
print("You pay:", prev["pricing"]["total"])
# 4) confirm
conf = requests.post(f"{BASE}/v1/order/confirm", headers=H,
json={"order_session_id": prev["order_session_id"]}).json()
result = wait(conf["job_id"])
print(result["result"]["order"]["order_uuid"])
Credits & pricing
A subscription unlocks the API; credits are then spent per checkout, scaled by your tier — Lifetime is free, higher tiers cost less. Failed orders never charge. Full tiers + credit packs are on the pricing page.
| Tier | Per 50% checkout | Per 40% checkout | Free checkouts / day |
|---|---|---|---|
| Lifetime | 0 | 0 | ∞ |
| Tier III | 0 | 0 | ∞ |
| Tier II | 6 credits | 4 credits | 15 |
| Tier I | 6 credits | 4 credits | 5 |
| No subscription | 9 credits | 6 credits | 0 |
40% and 50% orders are billed at flat separate brackets per tier (not a halving formula). An order using DDPremium SMS numbers bills at the 50% rate; DDPublic or Mixed bills at the 40% rate.
| Action | Cost |
|---|---|
Account gen (/v1/gen) | Lifetime & Tier III: free, unlimited · Tier II: 50 free / day, then 1 credit each · Tier I: 10 free / day, then 1 credit each · No-sub: 3 credits/account |
Preview, eligibility, batch reads, chains, /v1/me | Free |
| Beta (any server member) | 1 free 50% checkout + 1 free 40% checkout / day, then non-sub rates · 2 free gens / day, then 3 credits each |
Credits come from the same AutoMunch wallet as Discord. Check balance with /v1/me or /balance, top up with /buy on Discord.
Error Codes
| Status | Meaning |
|---|---|
202 | Async job accepted — a background job has been queued. The body carries job_id; poll GET /v1/jobs/{id}. |
400 | Missing/invalid field (e.g. batch_name required, no account_id/jwt_token, or daisysms_api_key not configured when /v1/gen is called before /settings is saved). |
401 | Missing, invalid, or revoked API key. |
404 | Account, batch, chain, job, or preview session not found (or not yours / expired). |
409 | The deal lapsed between preview and confirm — re-preview. |
429 | Too many active jobs (max 2). |
500 | Engine error during a synchronous probe/preview. |
