Introduction
The MIUMIU API exposes everything you can do in the dashboard, placing orders, checking status, listing services and reading your wallet balance, as a clean REST API. All requests and responses are JSON over HTTPS. Base URL: https://api.miumiu.market
Authentication
Authenticate with your API key as a Bearer token in the Authorization header. Generate, label and rotate keys from the dashboard. Each request also increments a per-key rate-limit counter (see Rate limits).
Three accepted ways to pass the key
Authorization: Bearer fb_live_… (recommended), X-Api-Key: fb_live_… (alternative header), or key=fb_live_… as a form/query field for Perfect-Panel-compatible clients. Pick whichever fits your stack, the server treats all three identically.
curl https://api.miumiu.market/v1/reseller/balance \
-H "Authorization: Bearer fb_live_a1b2c3..."List services
GET/v1/reseller/servicesReturns the full service catalog the caller can order from, with live per-1000 rates, min/max quantities, refill flag and platform identifier. Cache responses for up to five minutes, rates can shift when provider routing changes.
curl https://api.miumiu.market/v1/reseller/services \
-H "Authorization: Bearer fb_live_•••••"Get balance
GET/v1/reseller/balanceReturns your current wallet balance, currency, and any pending holds. Useful as a guard before placing a batch of orders so you fail fast client-side instead of after the first INSUFFICIENT_BALANCE.
curl https://api.miumiu.market/v1/reseller/balance \
-H "Authorization: Bearer fb_live_•••••"Place an order
POST/v1/reseller/ordersCreates a new order. Charge is taken from your wallet at request time as a HOLD; once dispatched to the provider it becomes a DEBIT. Pass an Idempotency-Key header so retries are safe.
curl -X POST https://api.miumiu.market/v1/reseller/orders \
-H "Authorization: Bearer fb_live_•••••" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"serviceId": "svc_01ABCDE...",
"link": "https://instagram.com/yourbrand",
"quantity": 1000
}'Get an order
GET/v1/reseller/orders/{id}Returns the current state of one order: status, start count, remains, charge, provider order id, and timestamps. Poll this endpoint OR subscribe to webhooks, webhooks scale better.
| Status | Meaning |
|---|---|
| PENDING | Charged and queued for dispatch. |
| WAITING_PROVIDER | No eligible provider mapping right now, retrying. |
| IN_PROGRESS | Accepted upstream and currently fulfilling. |
| PARTIAL | Provider delivered some but not all; refund queued for the gap. |
| COMPLETED | Fully delivered. Terminal. |
| CANCELED | Canceled before dispatch; HOLD released. Terminal. |
| REFUNDED | Refund issued after the fact (manual or auto). Terminal. |
| FAILED | Could not be fulfilled (provider error, invalid link). Terminal. |
curl https://api.miumiu.market/v1/reseller/orders/ord_01ABC... \
-H "Authorization: Bearer fb_live_•••••"Get many orders
GET/v1/reseller/orders?ids=...Bulk status lookup for up to 50 orders at once. Useful to refresh a screen of in-flight orders in a single round-trip. Pass a comma-separated list of order IDs in the `ids` query parameter.
curl 'https://api.miumiu.market/v1/reseller/orders?ids=ord_01A,ord_01B,ord_01C' \
-H "Authorization: Bearer fb_live_•••••"Cancel an order
POST/v1/reseller/orders/{id}/cancelCancels an order that hasn't started yet. Only valid while the order is in PENDING or WAITING_PROVIDER, once the provider accepts it, cancellation is provider-dependent and may be refused.
curl -X POST https://api.miumiu.market/v1/reseller/orders/ord_01ABC.../cancel \
-H "Authorization: Bearer fb_live_•••••"Webhooks
MIUMIU POSTs each event to your configured webhook URL once. Every body carries an HMAC-SHA256 signature derived from your per-key webhook secret in the X-MIUMIU-Signature header. Verify the signature before acting on the payload, anyone can POST to your endpoint, only we can sign it.
| Event | Fired when |
|---|---|
| order.placed | An order is created (either via API or the dashboard). |
| order.status_changed | An order transitions between non-terminal statuses. |
| order.completed | An order reaches COMPLETED, full delivery confirmed. |
| order.refunded | A refund is issued back to your wallet. |
| wallet.credited | A top-up confirms; balance is now available. |
import { createHmac, timingSafeEqual } from 'node:crypto';
/** Verifies an inbound MIUMIU webhook. Reject anything that fails. */
function verifySignature(rawBody, signatureHeader, secret) {
const expected = createHmac('sha256', secret).update(rawBody).digest('hex');
const got = Buffer.from(signatureHeader, 'hex');
const exp = Buffer.from(expected, 'hex');
return got.length === exp.length && timingSafeEqual(got, exp);
}
// Express-style handler - read raw body (not parsed JSON) for the HMAC.
app.post('/webhooks/MIUMIU', (req, res) => {
const sig = req.header('x-miumiu-signature');
if (!verifySignature(req.rawBody, sig, process.env.FB_WEBHOOK_SECRET)) {
return res.status(401).end();
}
const evt = JSON.parse(req.rawBody.toString('utf8'));
// ... handle evt.event, evt.data ...
res.status(204).end();
});Errors
All errors return a JSON envelope: { error: { code, message, details? } }. HTTP status follows REST conventions, 4xx for client errors, 429 for rate-limited, 5xx for our side. The `code` is stable; the `message` is human copy and can change.
| Code | HTTP | Meaning |
|---|---|---|
| BAD_REQUEST | 400 | Payload failed schema validation. `details.fields` lists which fields. |
| UNAUTHORIZED | 401 | API key missing, malformed, or revoked. |
| FORBIDDEN | 403 | Key is valid but doesn't have the scope this endpoint requires. |
| NOT_FOUND | 404 | The order, service or resource doesn't exist for this caller. |
| CONFLICT | 409 | The action isn't valid in the current state (e.g. cancel an IN_PROGRESS order). |
| INSUFFICIENT_BALANCE | 409 | Wallet balance is below the order charge. Top up and retry. |
| RATE_LIMITED | 429 | Too many requests on this key. Back off, `details.retryAfterSec` says how long. |
| UPSTREAM | 502 | A downstream provider failed; the request itself was valid. Safe to retry. |
# Example: insufficient funds at order placement
{
"error": {
"code": "INSUFFICIENT_BALANCE",
"message": "موجودی کیف پول کافی نیست"
}
}Idempotency
Send an Idempotency-Key header (any opaque string up to 128 chars) on any POST that creates state. We cache the first response for 24 hours, repeat requests with the same key return the original body, status code, and headers. Generate a fresh UUID per logical operation.
curl -X POST https://api.miumiu.market/v1/reseller/orders \
-H "Authorization: Bearer fb_live_•••••" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 7c9a1f-2026-05-31" \
-d '{"serviceId":"svc_01ABC...","link":"https://x.com/y","quantity":500}'
# Re-running the same command returns the original order, not a new one.Rate limits
Each API key has a per-minute request budget (default 600/min, configurable per key on Pro and above). Exceeding it returns 429 RATE_LIMITED with a retryAfterSec in `details`. The window is sliding, once a request is outside the 60-second window it stops counting.
Burst-safe retries
On 429, sleep `retryAfterSec` seconds before the next call to the same endpoint. The X-RateLimit-Remaining response header (when present) reflects the current bucket, use it to throttle preemptively rather than reactively.
Need help integrating?
Stuck on the HMAC verification or a 409 you don't recognize? Open a ticket from your dashboard with a delivery ID, we triage API tickets first.