Complete reference for programmatic order placement, tracking, and management.
https://api.orderatlas.netX-API-Key: oatl_live_... in every request. Generate API keys from your dashboard after signing in.credits_remaining field showing your current balance after the request. Use it to monitor your quota without an extra API call. Example: {"success": true, "order_id": "...", "credits_remaining": 998}.Pass the platform identifier in the platform field of your API requests. The Convert badge marks marketplaces where Aquiline tracking conversion is available via POST /v1/order/:id/convert.
AmazonUSAmazon US (amazon.com)LiveConvertAmazonUKAmazon UK (amazon.co.uk)LiveConvertAmazonCAAmazon Canada (amazon.ca)LiveConvertAmazonMXAmazon Mexico (amazon.com.mx)LiveAmazonDEAmazon Germany (amazon.de)LiveConvertAmazonFRAmazon France (amazon.fr)LiveConvertAmazonITAmazon Italy (amazon.it)LiveConvertAmazonESAmazon Spain (amazon.es)LiveConvertAmazonNLAmazon Netherlands (amazon.nl)LiveAmazonBEAmazon Belgium (amazon.com.be)LiveAmazonPLAmazon Poland (amazon.pl)LiveAmazonSEAmazon Sweden (amazon.se)LiveAmazonIEAmazon Ireland (amazon.ie)LiveAmazonAUAmazon Australia (amazon.com.au)LiveAmazonINAmazon India (amazon.in)LiveConvertAmazonSGAmazon Singapore (amazon.sg)LiveAmazonJPAmazon Japan (amazon.co.jp)LiveAmazonBRAmazon Brazil (amazon.com.br)LiveAmazonTRAmazon Turkey (amazon.com.tr)LiveAmazonEGAmazon Egypt (amazon.eg)LiveAmazonZAAmazon South Africa (amazon.co.za)LiveAmazonSAAmazon Saudi Arabia (amazon.sa)LiveAmazonAEAmazon UAE (amazon.ae)LiveAll possible values for the status field returned in order responses and webhook payloads.
confirmedOrder placed successfully, awaiting shipment from the retailer.purchasedPayment processed and order confirmed on the platform. Equivalent to confirmed for most workflows.shippedOrder has shipped. Tracking number and carrier are available.out_for_deliveryPackage is out for delivery and should arrive today.deliveredPackage has been delivered to the shipping address.cancelledOrder was cancelled by the buyer, seller, or platform.lostPackage was lost in transit or could not be located by the carrier.failedOrder placement failed due to a platform error, payment issue, or invalid credentials.PRICE_EXCEEDEDSubtotal exceeded the price_max limit. Order was not placed.refundedOrder has been refunded by the retailer.payment_revisionPlatform requires a payment method update. The order is on hold until resolved.awaiting_approvalOrder requires manual approval on the platform (e.g., high-value items or identity verification).warningOrder was placed but the platform order ID could not be retrieved. May require manual verification.Strings you'll see in the error field of a failed order — and how to resolve each. The full reason is also stored on the order's notes column and surfaced in GET /v1/order/:id.
For programmatic branching, every failed order also carries a machine-readable failure_reason_code on GET /v1/order/:id — values match the bolded codes below (e.g. SHIPPING_RESTRICTED, PRICE_EXCEEDED, ACCOUNT_SOFTBLOCK, DIGITAL_PRODUCT_UNSUPPORTED, ASIN_SWAPPED, LOGIN_FAILED, CHECKOUT_RPC_ERROR, STALE_PLATFORM_ORDER_ID, GATEWAY_RESTART_INTERRUPTED). Branch on the code instead of substring-matching the notes — the codes are stable, the human strings may rewrite as we improve diagnostics.
Amazon requires CVV / security code re-entry on this accountThe Amazon account has "require security code on every order" enabled. Amazon's CVV widget RSA-encrypts client-side via secureFields, so the API can't supply the code at checkout time. Two fixes: (1) disable the setting at amazon.com → Account → Login & security → Payment options → Security code preferences; or (2) include the payment_method block on POST /v1/order — we'll add a fresh card to the wallet as default and place the order against it before the CVV check fires.amazon required additional verification (CVF / one-time-passcode verification)Amazon's risk engine flagged this login attempt and demanded an OTP verification we can't pass. Usually transient — retry in a few minutes; the same account often succeeds on the next try. Persistent CVF on a single account suggests Amazon flagged the proxy or the account itself.amazon required additional verification (captcha challenge)The login redirected to opfcaptcha.amazon.com. Most flavors are auto-solved on the next checkout retry; persistent captcha means the proxy or session is heavily flagged. Rotate the proxy.amazon required additional verification (account-fixup prompt)Amazon wants the account holder to add a phone number or verify an email. Log in to amazon.com manually, complete the prompt, then retry.place-order step did not create a new orderAmazon de-duplicated this submission against a recent purchase, OR the place-order POST silently failed. Credits are auto-refunded. Either Amazon already placed the order (check the account's order history) or the placement failed and you can retry — they're distinguishable by whether a new order ID appears on Amazon.BOT_CHALLENGE_RX_SHELLAmazon served the JS-fingerprint shell page. Gateway auto-relogs and retries once. If it persists, the proxy / session is flagged at the IP layer — rotate to a fresher proxy.SESSION_FLAGGED_AT_PLACEAmazon's risk filter bounced the place-order step to a captcha page, sign-in form, or account-locked banner. Gateway auto-retries once on a forced-fresh login (drops the cached session, runs full password + 2FA). If the fresh-session attempt also flags, the result is rewritten to ACCOUNT_SOFTBLOCK (see below). Detection is shape-specific now — looks for real captcha endpoints (/errors/validateCaptcha) and real sign-in forms, not just substring matches on the persistent nav widget.SESSION_FLAGGED_NO_CSRFThe SPC checkout page rendered without a CSRF token, which means Amazon's risk engine stripped the form rather than serving an explicit captcha. Same auto-retry path as SESSION_FLAGGED_AT_PLACE: fresh login + one retry, then escalates to ACCOUNT_SOFTBLOCK if the fresh session also gets stripped.OOS_AFTER_RETRIESThe place-order POST returned Amazon's 1187-byte turbo "out of stock" micro-page 15 times in a row on the same session. Often a session softblock rather than a real stockout — Amazon serves the OOS template to flagged sessions while the item is still buyable on a fresh login. Gateway auto-retries on a forced-fresh session before terminalizing. If the fresh-session attempt also returns the OOS shell, it's escalated to ACCOUNT_SOFTBLOCK.ADDRESS_RATE_LIMITEDTerminal for ~2 hours on the affected account. Amazon's address-change widget responded with "You have exceeded the maximum attempts allowed, please retry after 2 hours." — a per-account throttle that fires after too many shipping-address changes in a short window. Typical trigger: rapid back-to-back orders on the same Amazon account where each placement re-changes the buyer's ship-to. The throttle is persistent per Amazon's message; fresh-login retry doesn't help (it's account-scoped, not session-scoped). Retry on a different Amazon account, or wait the full window. Before this status existed (pre-2026-06-05), the same condition cascaded silently into ADDRESS_VALIDATION_FAILED because Amazon's response was a 200 with the rate-limit message in the inline error_messages array — we now detect and surface it precisely.ATC_OOS_AFTER_RETRIESSame softblock pattern as OOS_AFTER_RETRIES but caught at the add-to-cart step rather than place-order. Amazon's ATC endpoint returned "out of stock" across 15 attempts with up to 5 distinct refreshed offer IDs from fresh product-page fetches — while the product page itself consistently shows the buybox in stock. Strong signal that Amazon's risk engine is rejecting the SESSION (not the offer). Gateway auto-retries on a forced-fresh login; if the fresh-session attempt also returns ATC OOS, escalated to ACCOUNT_SOFTBLOCK. Genuine OOS would have shown up earlier (the product page wouldn't have yielded a working offer ID in the first place).ACCOUNT_SOFTBLOCKTerminal — auto-retry won't fire. The fresh-session retry triggered by SESSION_FLAGGED_AT_PLACE / OOS_AFTER_RETRIES / BOT_CHALLENGE_RX_SHELL / SESSION_FLAGGED_NO_CSRF ALSO came back flagged. That means the block is at the account level, not the session — a new login won't clear it. Manually log in to amazon.com in a browser and place one order to clear the flag, then resubmit. The flag usually self-clears within a few hours; if it persists beyond 24h, the account may need a full Amazon-side recovery.SHIPPING_RESTRICTEDTerminal — only fires after offer rotation also failed. Amazon refused to ship this ASIN from the buybox seller to the customer's address (HAZMAT to PR/AK/HI, marketplace policy, jurisdiction restriction, AMZL-only seller to non-AMZL ZIP). When the order has price_max > 0 set, the gateway auto-rotates: pulls every seller's offer via Amazon's AOD endpoint, filters to those with price ≤ price_max (excluding the failed buybox offer), sorts cheapest-first, and retries checkout against the top 3 alternatives. If any succeeds, the order ends as confirmed with a note in notes[] identifying which alternative offer placed (seller name, price, fulfillment type). SHIPPING_RESTRICTED as the final status means EITHER no alternatives qualified under price_max, OR all rotated alternatives also failed. Submit a different shipping address, raise price_max, or try a different ASIN. Orders without price_max skip rotation entirely (deterministic behaviour — we won't pick an offer at an arbitrary higher price without your ceiling).DIGITAL_PRODUCT_UNSUPPORTEDTerminal — auto-retry won't fire. The submitted ASIN is a digital-only item (Kindle, Audible, MP3, software download, game code, Streaming/Prime Video, magazine subscription, etc.). Amazon's digital checkout pipeline doesn't bind a ship-to address, so the order has no physical destination and OrderAtlas can't place it. Detected during the product-page fetch from a title-token match (e.g. Kindle Edition, [PC Download], 1 Year Download) or a page-shell class match (digital-purchase-checkout, kindleProductPage). Resolve by submitting the ASIN of the physical edition instead — or removing the SKU from the eBay listing.ASIN_SWAPPEDTerminal — auto-retry won't fire. Amazon's product page is rendering a different variant than the ASIN you submitted (server-side redirect from OOS to a substitute, or the SKU was merged into a sibling). Placing the order would charge for the wrong item. Resubmit with the canonical ASIN Amazon now serves — see the order's log for the swap target.Amazon account has no credit or debit card on fileThe wallet has no usable CC/DC — only Loan, Points, or other instruments Amazon won't auto-submit. Add a card via amazon.com → Account → Payment options, OR use the payment_method request field to add one inline at order time.Set a webhook_url on your API key (or per-order via the webhook_url field in POST /v1/order) to receive real-time notifications. All webhooks are sent as POST requests with Content-Type: application/json and a User-Agent: OrderAtlas-Webhook/1.0 header. Delivery is retried up to 3 times with exponential backoff (5s, 10s, 15s) on failure. Your endpoint should respond with a 2xx status code to acknowledge receipt.
order.createdFires when an order is first created (status: pending). Sent immediately after POST /v1/order succeeds.order.status_changedFires whenever the order status transitions (e.g. pending → confirmed, confirmed → shipped, shipped → delivered).tracking.convertedFires when Aquiline tracking conversion succeeds and an AQ tracking number is assigned to the order.aqualine.skippedFires when the auto-conversion poller bails for a reason the customer can act on (e.g. low credit balance, missing ship-from). Includes skip_reason (machine code), skip_message (human description), and where relevant credits_have/credits_need. Deduped per order — only fires when the reason changes, so a stuck order doesn't spam every 3-hour poll cycle. Cleared on successful conversion so a later regression re-notifies. The same message is also appended to notes on the order so it shows up in GET /v1/order/:id. The poller will keep auto-retrying every ~3 hours; nothing else needs to happen on your side once the blocker (e.g. balance) is resolved.Every webhook event uses the same JSON shape. Optional fields are only included when populated.
{
"event": "order.status_changed",
"order_id": "b7e4a8c2-1234-5678-9abc-def012345678",
"platform": "AmazonUS",
"platform_order_id": "112-4567890-1234567",
"status": "shipped",
"previous_status": "confirmed",
"tracking_number": "1Z999AA10123456784",
"carrier": "UPS",
"aqualine_tracking": "AQ9281736450",
"timestamp": "2026-03-31T14:30:00Z"
}On order.status_changed events that transition into status: "failed", the payload also carries failure_reason_code (machine-readable taxonomy, same values as GET /v1/order/:id) and failure_reason(human-readable explanation, the most-recent entry from the order's notes). Example failure payload:
{
"event": "order.status_changed",
"order_id": "50e98f9c-9f18-4185-b967-879b86a16630",
"platform": "AmazonUS",
"platform_order_id": "",
"status": "failed",
"previous_status": "processing",
"logged_in": true,
"asin": "B0CWNJ75X1",
"failure_reason_code": "SHIPPING_RESTRICTED",
"failure_reason": "Sorry, MONDAY HAIRCARE ORIGINAL Dry Shampoo with Keratin, oil-absorbing for All Hair Types 200 mL can't be shipped to the address you selected. Please remove the item or select another address.",
"timestamp": "2026-06-04T14:43:11Z"
}eventEvent type: order.created, order.status_changed, tracking.converted, or aqualine.skipped.order_idOrderAtlas internal UUID for the order.platformPlatform identifier (e.g., AmazonUS).platform_order_idRetailer order ID (e.g., 112-4567890-1234567). Empty until the order is confirmed.statusCurrent order status. See Order Statuses above.previous_statusPrevious status (omitted on order.created).tracking_numberCarrier tracking number (omitted until available).carrierShipping carrier name (omitted until available).aqualine_trackingAquiline-converted tracking number (only included after tracking.converted).skip_reasonMachine-readable code on aqualine.skipped events. Current values: insufficient_credits. Branch on this — the human skip_message wording can change.skip_messageHuman-readable explanation, also appended to the order's notes array.credits_haveAccount's current credit balance at the moment of the skip. Only included on insufficient_credits.credits_needHow many credits the operation required. Only included on insufficient_credits.retry_eligibletrue when the poller will auto-retry once the blocker clears (e.g. balance topped up). Use to differentiate from terminal failures.failure_reason_codeMachine-readable failure taxonomy. Only present when status=failed. Same values as the failure_reason_code field on GET /v1/order/:id — see the field reference there for the full code list. Branch on this to drive retry / refund / manual-fulfillment logic.failure_reasonHuman-readable explanation. Only present when status=failed. The most-recent entry from the order's notes column — same string you'd see in the dashboard. Use this for display to operators; use failure_reason_code for programmatic decisions.timestampISO 8601 UTC timestamp of the event.Set discord_webhook_url on your API key to receive events as rich Discord embeds. The same events fire to Discord as to your regular webhook, with color-coded embeds (green for delivered, gold for shipped/out_for_delivery, red for cancelled/failed, blue for others). Discord webhook URLs must match https://discord.com/api/webhooks/... or https://discordapp.com/api/webhooks/....
/v1/orderPlace a new order on the specified platform. Returns immediately with status=pending while checkout runs asynchronously. Fetch final details (pricing, tracking, status) via GET /v1/order/:order_id or subscribe to order.status_change webhooks. Deducts 2 credits on success, refunded on failure.
Two request shapes are accepted:
1) Legacy single-item — pass product_id, quantity, and price_max at the top level. Routes through Amazon's turbo Buy Now flow.
2) Multi-item — pass items as an array; each entry has its own asin, quantity, and price_max. Routes through the regular cart + Chewbacca pipeline (single Amazon order with N line items, one shipping fee). Per-item price guard reads each line's actual cart price from /gp/cart/view.html and aborts the whole order if any line exceeds its cap (no partial-charge surprises). Per-item outcomes (placed / no_offer / asin_swapped / price_exceeded / dropped_post_atc) are persisted to order_items and surfaced in GET /v1/order/:order_id.
# Legacy single-item shape (still supported):
curl -X POST https://api.orderatlas.net/v1/order \
-H "X-API-Key: oatl_live_abc123def456..." \
-H "Content-Type: application/json" \
-d '{
"platform": "AmazonUS",
"product_id": "B09V3KXJPB",
"quantity": 1,
"price_max": 50.00,
"account_email": "[email protected]",
"account_password": "...",
"shipping_address": {"name":"John Doe","phone":"5125551234","line1":"123 Main St","city":"Austin","state":"TX","zip":"78701"}
}'
# Multi-item shape (preferred, rolling out):
curl -X POST https://api.orderatlas.net/v1/order \
-H "X-API-Key: oatl_live_abc123def456..." \
-H "Content-Type: application/json" \
-d '{
"platform": "AmazonUS",
"items": [
{"asin": "B09V3KXJPB", "quantity": 1, "price_max": 50.00},
{"asin": "B0CLWJ1423", "quantity": 2, "price_max": 80.00}
],
"account_email": "[email protected]",
"account_password": "...",
"shipping_address": {"name":"John Doe","phone":"5125551234","line1":"123 Main St","city":"Austin","state":"TX","zip":"78701"}
}'
# Full single-item example with all optional fields:
curl -X POST https://api.orderatlas.net/v1/order \
-H "X-API-Key: oatl_live_abc123def456..." \
-H "Content-Type: application/json" \
-d '{
"platform": "AmazonUS",
"product_id": "B09V3KXJPB",
"quantity": 1,
"account_email": "[email protected]",
"account_password": "...",
"account_2fa_secret": "...",
"proxy": "ip:port:user:pass",
"shipping_address": {
"name": "John Doe",
"phone": "5125551234",
"line1": "123 Main St",
"line2": "Apt 4B",
"city": "Austin",
"state": "TX",
"zip": "78701"
},
"ship_from": {
"name": "Your Store",
"phone": "9735551234",
"line1": "1500 Industrial Pkwy",
"city": "Edison",
"state": "NJ",
"zip": "08817"
},
"payment_method": {
"credit_card_number": "4111111111111111",
"holder_name": "John Doe",
"exp_month": "01",
"exp_year": "2029",
"cvv": "123",
"billing_address": {
"name": "John Doe",
"phone": "5125551234",
"line1": "123 Main St",
"line2": "Apt 4B",
"city": "Austin",
"state": "TX",
"zip": "78701"
}
},
"price_max": 50.00,
"webhook_url": "https://yourapp.com/webhooks",
"convert_tracking": true,
"gift": true,
"gifter_name": "Your Store",
"gift_message": "Enjoy!",
"payment_method": {
"credit_card_number": "4111111111111111",
"holder_name": "John Doe",
"exp_month": "08",
"exp_year": "2027",
"cvv": "123"
}
}'{
"success": true,
"order_id": "550e8400-e29b-41d4-a716-446655440000",
"platform": "AmazonUS",
"status": "pending",
"message": "Order submitted for processing",
"credits_remaining": 998
}platform*Platform identifier. See supported platforms above.product_idLegacy single-item shape. Product identifier (ASIN for Amazon, SKU for Best Buy). Either product_id or items must be present. When both are sent, items wins and product_id is ignored.quantityLegacy single-item shape, paired with product_id. Number of units to order. Defaults to 1 if omitted or ≤ 0. Ignored when items is set (use items[].quantity per line instead).price_maxLegacy single-item shape, paired with product_id. Maximum allowed subtotal. If the item subtotal exceeds this amount, checkout is aborted before placing the order. Ignored when items is set (use items[].price_max per line instead). Omit or set to 0 to disable.itemsMulti-item shape. Array of products, each with its own asin, quantity, and price_max. Either items or product_id must be present; sending both makes items win and the legacy fields are ignored.items[].asin*ASIN of this line item.items[].quantityQuantity for this line item. Defaults to 1 if omitted or ≤ 0.items[].price_maxMaximum allowed cart price (per unit) for this specific line item. The order's /gp/cart/view.html is read after add-to-cart and each line's actual price is checked against its cap. If any line exceeds its cap the entire order is aborted before place-order — no partial purchases. Omit or set to 0 to disable for this line.account_email*Account email/username for the platform.account_password*Account password.account_2fa_secretTOTP 2FA secret (base32 format). Required if the account has 2FA enabled.proxy*Proxy in format ip:port:user:pass or ip:port. Use residential IPs matching the shipping address region.shipping_address*Delivery address object. See fields below.shipping_address.name*Recipient full name.shipping_address.phone*Recipient phone number.shipping_address.line1*Street address line 1.shipping_address.line2Street address line 2 (apartment, suite, etc).shipping_address.city*City name.shipping_address.state*State/province code (e.g., TX, CA, ON).shipping_address.zip*Postal/ZIP code.ship_fromPer-order ship-from override for the Aquiline tracking label. When omitted, falls back to the account-level ship_from_* from PUT /v1/settings, then a platform default. When provided, applies to this order only (other orders unaffected). Useful for multi-store dropshippers using different return addresses per store.ship_from.nameStore / sender name.ship_from.phoneStore phone number.ship_from.line1Street address line 1.ship_from.cityCity.ship_from.stateState / province.ship_from.zipPostal / ZIP.payment_methodOptional card to add to the Amazon account before checkout. Use this when Amazon requires CVV re-entry or you need to force a fresh card for this order. Card details are used only for this request and are not persisted.payment_method.credit_card_numberCard number. Required when payment_method is provided.payment_method.holder_nameName on card. Required when payment_method is provided.payment_method.exp_monthTwo-digit expiration month, e.g. 01. Required when payment_method is provided.payment_method.exp_yearFour-digit expiration year, e.g. 2029. Required when payment_method is provided.payment_method.cvvCard security code. Optional, but include it when the account/card flow requires CVV.payment_method.billing_addressBilling address for the submitted card. If omitted or incomplete, OrderAtlas uses the order/account ship_from address as the billing address and returns a warning in the order response.payment_method.billing_address.nameBilling full name. If omitted, falls back to ship_from.name.payment_method.billing_address.phoneBilling phone number. If omitted, falls back to ship_from.phone.payment_method.billing_address.line1Billing street address line 1. If omitted, falls back to ship_from.line1.payment_method.billing_address.line2Billing street address line 2.payment_method.billing_address.cityBilling city. If omitted, falls back to ship_from.city.payment_method.billing_address.stateBilling state/province code. If omitted, falls back to ship_from.state.payment_method.billing_address.zipBilling postal/ZIP code. If omitted, falls back to ship_from.zip.webhook_urlPer-order webhook URL override. If omitted, uses the webhook URL configured on your API key.convert_trackingPer-order Aquiline conversion override (true/false). If omitted, uses the setting configured on your API key.auto_subscribe_saveOpt into Amazon's Subscribe & Save flow on this order to capture the (typically 5%) subscription discount. When set to true and the product exposes an S&S option with a non-zero discount, the order is placed at the subscription price and the resulting subscription is auto-cancelled in the same request — no future shipments are scheduled, the first-order discount stays applied. Read back via auto_subscribe_save + subscription_canceled on the order detail. Products without S&S, or S&S with 0% discount, are placed normally. Defaults to false.giftMark the order as an Amazon gift. After payment selection the checkout sets Amazon's gift options on the order: hidePrices=1 and includeReceipt=1 are always applied so the recipient gets a proper gift receipt with no prices shown. Requires gifter_name. Defaults to false. Best-effort: if Amazon rejects the gift-options form the order still places (without the gift flag) rather than failing the whole checkout.gifter_nameSender name shown on the gift receipt. Required when gift=true — requests with gift=true and an empty gifter_name are rejected with HTTP 400 before checkout starts.gift_messageOptional message printed on the gift receipt alongside the sender name. Plain text; Amazon enforces its own length cap.payment_methodOptional credit card to add to the Amazon account before placing the order. Use this for accounts with "require security code on every order" enabled — Amazon would otherwise force CVV re-entry that the API can't supply (CVV is RSA-encrypted client-side by Amazon's secureFields widget). When provided, the bot adds this card to the wallet, sets it as default, then places the order against it. Sensitive fields are held in memory only — never persisted, never logged, never echoed in webhooks.payment_method.credit_card_numberCard number, no spaces.payment_method.holder_nameCardholder name as printed on the card.payment_method.exp_monthExpiration month, two digits (e.g., "08").payment_method.exp_yearExpiration year, four digits (e.g., "2027").payment_method.cvvCVV / security code. Only required when Amazon's add-card flow asks for it; safe to include preemptively./v1/order/importImport an order you already placed on the platform into OrderAtlas for tracking and conversion. Costs 1 credit. shipping_address is required — Aquiline tracking needs a ship-to to generate a label.
curl -X POST https://api.orderatlas.net/v1/order/import \
-H "X-API-Key: oatl_live_abc123def456..." \
-H "Content-Type: application/json" \
-d '{
"platform": "AmazonUS",
"platform_order_id": "112-4567890-1234567",
"account_email": "[email protected]",
"account_password": "...",
"account_2fa_secret": "...",
"proxy": "ip:port:user:pass",
"shipping_address": {
"name": "Jane Buyer",
"phone": "5551234567",
"line1": "123 Main St",
"line2": "Apt 4B",
"city": "Austin",
"state": "TX",
"zip": "78701"
}
}'{
"success": true,
"order_id": "112-4567890-1234567",
"status": "confirmed",
"platform": "AmazonUS",
"message": "Order imported successfully"
}/v1/order/:order_id/statusRetrieve the current status, tracking info, and delivery timeline for an order. Requires account credentials for the platform session.
curl -X POST https://api.orderatlas.net/v1/order/112-4567890-1234567/status \
-H "X-API-Key: oatl_live_abc123def456..." \
-H "Content-Type: application/json" \
-d '{
"account_email": "[email protected]",
"account_password": "...",
"account_2fa_secret": "...",
"proxy": "ip:port:user:pass"
}'{
"order_id": "112-4567890-1234567",
"status": "shipped",
"platform": "AmazonUS",
"tracking_number": "1Z999AA10123456784",
"carrier": "UPS",
"est_delivery_min": "2026-03-28T14:00:00Z",
"est_delivery_max": "2026-03-30T20:00:00Z"
}/v1/order/:order_id/trackingPush tracking information for an order. Used to provide carrier, tracking number, and delivery events.
curl -X PUT https://api.orderatlas.net/v1/order/112-4567890-1234567/tracking \
-H "X-API-Key: oatl_live_abc123def456..." \
-H "Content-Type: application/json" \
-d '{
"tracking_number": "1Z999AA10123456784",
"carrier": "UPS",
"status": "shipped"
}'{
"order_id": "112-4567890-1234567",
"status": "shipped",
"tracking_number": "1Z999AA10123456784",
"carrier": "UPS",
"message": "shipped"
}/v1/order/:order_id/convertConvert a carrier tracking number into a universal tracking number valid for eBay uploads. Costs 1 credit. Only available on the marketplaces Aquiline supports: AmazonUS, AmazonCA, AmazonUK, AmazonDE, AmazonFR, AmazonIT, AmazonES, AmazonIN. Other marketplaces return platform X is not supported by Aquiline. Works as soon as the order is confirmed — Aquiline can be assigned from the order details page even before Amazon publishes a tracking number.
curl -X POST https://api.orderatlas.net/v1/order/112-4567890-1234567/convert \ -H "X-API-Key: oatl_live_abc123def456..."
{
"order_id": "112-4567890-1234567",
"tracking_number": "1Z999AA10123456784",
"aqualine_tracking": "AQUAA4223090426YQ",
"carrier": "UPS",
"message": "tracking converted successfully"
}/v1/order/:order_id/drop-conversionDetach the current Aquiline tracking from an order so you can re-convert it with corrected data — typically used when an order was imported with a wrong ship-to address and the resulting Aquiline label is shipping the wrong route. The order row stays intact (no change to status, no refund of credits). The previous Aquiline label is moved to dropped_aqualine_tracking on the order; we continue refreshing its tracking HTML in the background until the underlying Amazon package reaches a terminal state (Aquiline TOS requires updates on assigned labels until delivered/cancelled). After dropping, call POST /v1/order/:order_id/convert again to mint a fresh AQUAA against the corrected data.
Credits are NOT refunded. The original conversion ran, the label was issued, the carrier may already be scanning against it. If a customer needs a billing adjustment on top of the drop, contact support — the operation is a tracking reset, not a billing rewind.
Accepts either the OA order_id (UUID) or the Amazon platform_order_id in the URL path.
curl -X POST https://api.orderatlas.net/v1/order/9677d1cf-03ac-4bb6-acba-d5b933f3099e/drop-conversion \ -H "X-API-Key: oatl_live_abc123def456..."
{
"success": true,
"order_id": "9677d1cf-03ac-4bb6-acba-d5b933f3099e",
"dropped_aqualine": "AQUAA6610400526YQ",
"message": "Aquiline conversion dropped — order is ready to be re-converted. The dropped label will keep refreshing until it reaches delivered/cancelled (per Aquiline TOS)."
}(no body)No request body. The order is identified entirely by the URL path; the active Aquiline tracking is moved off the row and the order becomes eligible for a fresh convert call./v1/order/:order_id/deliveredManually mark an order as delivered. Optionally include a delivery photo URL.
curl -X POST https://api.orderatlas.net/v1/order/112-4567890-1234567/delivered \
-H "X-API-Key: oatl_live_abc123def456..." \
-H "Content-Type: application/json" \
-d '{ "delivery_photo_url": "https://..." }'{
"success": true,
"order_id": "112-4567890-1234567",
"status": "delivered",
"message": "Order marked as delivered"
}/v1/order/:order_id/cancelledManually mark an order as cancelled or lost.
curl -X POST https://api.orderatlas.net/v1/order/112-4567890-1234567/cancelled \
-H "X-API-Key: oatl_live_abc123def456..." \
-H "Content-Type: application/json" \
-d '{ "reason": "cancelled" }'{
"success": true,
"order_id": "112-4567890-1234567",
"status": "cancelled",
"message": "Order marked as cancelled"
}/v1/order/:order_idRetrieve full details for a single order including the pricing breakdown, tracking info, and Aquiline conversion.
curl https://api.orderatlas.net/v1/order/550e8400-e29b-41d4-a716-446655440000 \ -H "X-API-Key: oatl_live_abc123def456..."
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"platform": "AmazonUS",
"status": "confirmed",
"platform_order_id": "112-4567890-1234567",
"asin": "B08125WZHR",
"product_title": "Example Product Name",
"price": "$14.85",
"shipping": "$0.00",
"credit": "$14.85",
"tax": "$0.00",
"total": "$0.00",
"price_amount": 14.85,
"shipping_amount": 0,
"credit_amount": 14.85,
"tax_amount": 0,
"total_amount": 0,
"invoice_link": "https://cdn.orderatlas.net/invoices/112-4567890-1234567-3f8a9c1b2d4e5f60.html",
"invoice_fetched_at": "2026-04-18T21:14:02Z",
"logged_in": true,
"auto_subscribe_save": true,
"subscription_canceled": true,
"tracking_number": "TBA123456789",
"carrier": "AMZN",
"aqualine_tracking": "AQUAA4223090426YQ",
"order_html_url": "https://cdn.orderatlas.net/tracking/112-4567890-1234567.html",
"order_html_updated_at": "2026-04-18T21:13:41Z",
"failure_reason_code": "",
"created_at": "2026-04-17T18:42:57Z",
"updated_at": "2026-04-17T18:43:22Z",
"credits_remaining": 998
}priceItem(s) subtotal as the locale-formatted string Amazon rendered it (e.g. "$14.85") — product price × quantity, before shipping/tax/credits. For arithmetic use price_amount below.shippingShipping & handling charges as the locale-formatted string. For arithmetic use shipping_amount.creditAmazon courtesy credit, promotional credit, or gift card applied, as the locale-formatted string. Reduces the grand total. If non-zero and total=$0.00, the order was free to the buyer. For arithmetic use credit_amount.taxSales tax collected as the locale-formatted string. For arithmetic use tax_amount.totalGrand total — what the buyer actually paid after all credits and taxes — as the locale-formatted string. This is the amount charged to the payment method. For arithmetic use total_amount.price_amountNumeric mirror of price with the currency symbol stripped. JSON number, not a string. 0 when the underlying string is empty or unparseable. Use this when you need to sum, compare, or format prices yourself — no parseFloat("$14.85") dance.shipping_amountNumeric mirror of shipping.credit_amountNumeric mirror of credit.tax_amountNumeric mirror of tax.total_amountNumeric mirror of total.invoice_linkHosted copy of Amazon's order print summary (HTML), uploaded to our CDN once the order is confirmed. Empty until OrderAtlas successfully fetches the invoice from Amazon. Files expire after 14 days; the parsed amounts above (price/shipping/credit/tax/total) persist forever.invoice_fetched_atUTC timestamp when the invoice HTML was scraped from Amazon and uploaded. Empty if the invoice hasn't been captured yet.logged_inWhether the seller account session was successfully validated for this order. Use to split status=failed rows into login problems (logged_in=false) vs checkout-side problems (logged_in=true: price guard rejected, item out of stock, place-order blocked, etc.). Once true, never reverts to false on this row.auto_subscribe_saveMirrors the auto_subscribe_save opt-in passed at order placement. When true, the order was placed via Amazon's Subscribe & Save flow to capture the (typically 5%) subscription discount.subscription_canceledOnly meaningful when auto_subscribe_save=true. true = the post-place subscription cancel succeeded and no future shipments are scheduled. false = the cancel call did not confirm; the customer may still receive a follow-up delivery and should manually cancel via Amazon's "Your Subscribe & Save items" page. The first delivery (the actual order) is unaffected either way.order_html_urlLive link to the raw order tracking-page HTML on our CDN. Stable per order — refreshes overwrite the same key. Refreshed every ~8h while the order is in flight; deleted 7 days after the order is marked delivered.order_html_updated_atUTC timestamp of the most recent refresh of order_html_url. Use this to decide whether to re-poll for fresher data.failure_reason_codeMachine-readable taxonomy code for why the order failed — empty for successful orders. Branch on this in your connector to drive retry / refund / manual-fulfillment logic. Stable across releases (the human-readable notes may rewrite as we improve diagnostics, the codes won't). Values include SHIPPING_RESTRICTED (destination won't accept this item — terminal), PRICE_EXCEEDED (Amazon price > your price_max), ACCOUNT_SOFTBLOCK (Amazon flagged the account at place-order even after a fresh login retry — manual amazon.com login required), DIGITAL_PRODUCT_UNSUPPORTED (Kindle/Audible/etc. — terminal), ASIN_SWAPPED (Amazon redirected the ASIN to a variant — terminal), SESSION_FLAGGED_AT_PLACE / SESSION_FLAGGED_NO_CSRF / OOS_AFTER_RETRIES / BOT_CHALLENGE_RX_SHELL (the gateway already retries these on a fresh login internally; if you see one of these as the final code, the retry also failed — usually a transient Amazon-side flag, retry the whole order later), CHECKOUT_BLOCKED (Amazon refused at SPC with no specific reason — usually transient), ADDRESS_VALIDATION_FAILED (address change didn't bind), PAYMENT_METHOD_BINDING_FAILED (added card didn't bind to the cart), ORDER_NOT_PLACED (placement appeared to succeed but couldn't verify via /your-orders), LOGIN_FAILED, CHECKOUT_RPC_ERROR, STALE_PLATFORM_ORDER_ID, GATEWAY_RESTART_INTERRUPTED./v1/order/:order_idPermanently delete an order from your account. This cannot be undone.
curl -X DELETE https://api.orderatlas.net/v1/order/550e8400-e29b-41d4-a716-446655440000 \ -H "X-API-Key: oatl_live_abc123def456..."
{
"status": "deleted"
}/v1/sessions/validateCheck if stored session cookies for a platform account are still valid.
curl -X POST https://api.orderatlas.net/v1/sessions/validate \
-H "X-API-Key: oatl_live_abc123def456..." \
-H "Content-Type: application/json" \
-d '{
"cookie_string": "session-id=...",
"proxy": "ip:port:user:pass"
}'{
"valid": true,
"status": "LOGGED_IN",
"cookie_string": "session-id=...",
"message": "Session is active"
}/v1/settingsGet your account-level settings including webhook URLs, Discord webhook, tracking-conversion preferences, ship-from address, current credit balance, and your webhook signing secret.
curl https://api.orderatlas.net/v1/settings \ -H "X-API-Key: oatl_live_abc123def456..."
{
"convert_tracking": true,
"webhook_url": "https://mysite.com/webhook",
"discord_webhook_url": "https://discord.com/api/webhooks/...",
"webhook_secret": "a1b2c3...64-char-hex",
"rate_limit": 60,
"credit_balance": 4500,
"email": "[email protected]",
"ship_from_name": "Your Store",
"ship_from_line1": "123 Main St",
"ship_from_city": "Austin",
"ship_from_state": "TX",
"ship_from_zip": "78701",
"ship_from_phone": "5125551234",
"ship_from_required": false
}webhook_secret is the HMAC-SHA256 key for verifying outbound webhook deliveries. Every webhook we send carries X-OrderAtlas-Signature: sha256=<hex> — your handler should compute HMAC-SHA256(raw_body, webhook_secret) and reject mismatches. Auto-generated 64-char hex by default; user-set values may differ in length and charset.ship_from_required is true when convert_tracking is on but no ship-from address is configured. While true, instant-tracking labels fall back to a platform-provided default — set your own values to override.PATCH /v1/api-keys/:key_id./v1/settingsUpdate account-level settings. Webhook URLs set here apply to all API keys on the account. To override the webhook for a specific key, use PATCH /v1/api-keys/:key_id. Supports partial updates — only send the fields you want to change. Discord webhook URL must be a valid discord.com/api/webhooks/ URL.
curl -X PUT https://api.orderatlas.net/v1/settings \
-H "X-API-Key: oatl_live_abc123def456..." \
-H "Content-Type: application/json" \
-d '{
"convert_tracking": true,
"webhook_url": "https://mysite.com/webhook",
"discord_webhook_url": "https://discord.com/api/webhooks/123/abc"
}'{
"convert_tracking": true,
"webhook_url": "https://mysite.com/webhook",
"discord_webhook_url": "https://discord.com/api/webhooks/123/abc",
"rate_limit": 60
}/v1/settings/rotate-webhook-secretEither generate a new HMAC-SHA256 signing secret for outbound webhook deliveries, OR set a custom value (e.g. one you already use in another system). The previous secret stops being valid immediately — update your webhook handler with the new secret first.
# Auto-generate (no body):
curl -X POST https://api.orderatlas.net/v1/settings/rotate-webhook-secret \
-H "X-API-Key: oatl_live_abc123def456..."
# Set a custom value:
curl -X POST https://api.orderatlas.net/v1/settings/rotate-webhook-secret \
-H "X-API-Key: oatl_live_abc123def456..." \
-H "Content-Type: application/json" \
-d '{"webhook_secret": "my-custom-32-char-or-longer-secret"}'{
"webhook_secret": "a1b2c3...64hex"
}X-OrderAtlas-Signature: sha256=<hex> header. The hex is HMAC-SHA256(raw_body_bytes, webhook_secret).crypto.createHmac("sha256", secret).update(body).digest("hex"). Python: hmac.new(secret.encode(), body, hashlib.sha256).hexdigest(). Compare against the hex part of the header (after sha256=).GET /v1/settings (field webhook_secret) or copy from the dashboard./v1/api-keys/:key_idSet per-key webhook overrides. The values you set here only apply to orders placed with this specific API key, and take precedence over the account-level webhook from PUT /v1/settings. Pass an empty string ("") to clear an override and fall back to the account default. Supports partial updates — only send the fields you want to change.
curl -X PATCH https://api.orderatlas.net/v1/api-keys/123e4567-e89b-12d3-a456-426614174000 \
-H "X-API-Key: oatl_live_abc123def456..." \
-H "Content-Type: application/json" \
-d '{
"webhook_url": "https://prod.mysite.com/webhook",
"discord_webhook_url": "https://discord.com/api/webhooks/123/abc",
"name": "production"
}'{
"id": "123e4567-e89b-12d3-a456-426614174000",
"key_prefix": "oatl_live_a",
"name": "production",
"email": "[email protected]",
"active": true,
"created_at": "2026-04-01T00:00:00Z",
"webhook_url": "https://prod.mysite.com/webhook",
"discord_webhook_url": "https://discord.com/api/webhooks/123/abc"
}/v1/billing/topupCreate a Stripe Checkout session to purchase credits. Redirect the user to the returned URL to complete payment.
curl -X POST https://api.orderatlas.net/v1/billing/topup \
-H "X-API-Key: oatl_live_abc123def456..." \
-H "Content-Type: application/json" \
-d '{
"credits": 100,
"success_url": "https://orderatlas.net/dashboard",
"cancel_url": "https://orderatlas.net/dashboard"
}'{
"checkout_url": "https://checkout.stripe.com/c/pay/cs_live_...",
"credits": 100
}/v1/billing/balanceReturns the current credit balance and the cost of each action.
curl https://api.orderatlas.net/v1/billing/balance \ -H "X-API-Key: oatl_live_abc123def456..."
{
"credit_balance": 4500,
"costs": {
"order_placement": 2,
"tracking_conversion": 2,
"order_import": 1
}
}/v1/billing/transactionsGet the credit transaction history for your account.
curl https://api.orderatlas.net/v1/billing/transactions \ -H "X-API-Key: oatl_live_abc123def456..."
{
"transactions": [
{
"id": "uuid",
"amount": 100,
"type": "deposit",
"description": "Purchased 100 credits",
"created_at": "2026-03-20T10:00:00Z"
},
{
"id": "uuid",
"amount": -1,
"type": "order_debit",
"description": "Order placement: 112-456...",
"created_at": "2026-03-25T14:30:00Z"
}
]
}/v1/dashboard/overviewSummary stats: order counts, credit balance, API usage, and recent orders.
curl https://api.orderatlas.net/v1/dashboard/overview \ -H "X-API-Key: oatl_live_abc123def456..."
{
"orders_today": 12,
"active_tracking": 5,
"total_orders": 347,
"credit_balance": 4500,
"api_calls_month": 2841
}/v1/dashboard/ordersPaginated list of all orders. Supports limit + offset (max limit 200) and optional search + status filters. search is a case-insensitive substring match against amazon_order_id, external_order_id, product_title, asin, and account_email. status is an exact match against the order status column (one of pending, processing, confirmed, shipped, delivered, failed, etc.). When either filter is set, total in the response reflects the count under that filter — not the global total — so you can drive pagination directly off it.
curl "https://api.orderatlas.net/v1/dashboard/orders?limit=20&offset=0&search=B0CWNJ&status=failed" \ -H "X-API-Key: oatl_live_abc123def456..."
{
"orders": [
{
"id": "uuid",
"platform_order_id": "112-4567890-1234567",
"platform": "AmazonUS",
"status": "delivered",
"total": "$29.99",
"tracking_number": "1Z999AA10123456784",
"created_at": "2026-03-25T14:30:00Z"
}
],
"total": 347
}/v1/dashboard/tracking-conversionsList orders with converted tracking numbers.
curl https://api.orderatlas.net/v1/dashboard/tracking-conversions \ -H "X-API-Key: oatl_live_abc123def456..."
{
"orders": [
{
"id": "uuid",
"platform_order_id": "112-4567890-1234567",
"status": "shipped",
"tracking_number": "1Z999AA10123456784",
"converted_tracking": "AQ9281736450",
"created_at": "2026-03-25T14:30:00Z"
}
],
"total": 42
}All errors return JSON with an error field:
{
"error": "insufficient credits: have 0, need 1"
}400 Bad request / validation error401 Invalid or missing API key / JWT402 Insufficient credits404 Resource not found429 Rate limit exceeded (60 req/min default)500 Internal server error503 Service unavailable — see code field for the specific reasonSome errors include a stable machine-readable code alongside the human-readable error. Branch on code, not on the error string — error wording can change without notice.
{
"error": "proxy 154.7.143.184:5804 unreachable: dial tcp 154.7.143.184:5804: connect: connection refused",
"code": "proxy_unreachable"
}Returned from POST /v1/order and POST /v1/order/import when the per-account proxy refuses or times out a TCP connection (3-second probe before checkout starts). Nothing is written to the database and no credits are charged — fix the proxy and retry. Common causes: provider outage on that IP, rotated/revoked proxy credentials, or the IP being removed from your pool. Probe runs against the host:port in the proxy field of your request.