iAdvizeDocs

Send orders from another platform

Report completed orders to AISA with one HTTP request per order. The contract of the public orders endpoint, what it ignores and what it never tells you.

If your store is not on Shopify, or you do not want to use the Shopify order webhooks, you can send AISA each completed order yourself. One POST per order, from your server or from your storefront.

On Shopify, the AISA pixel already sends here

The Shopify pixel posts each completed order to this endpoint. On a Shopify store you do not need a sender of your own: install the pixel, the webhooks, or both.

Send an order

curl -X POST "https://iadvize.ai/api/public/sites/pk_site_YOUR_PUBLIC_KEY/orders" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "purchase",
    "orderRef": "order-10432",
    "amount": "129.90",
    "currency": "EUR",
    "occurredAt": "2026-10-23T09:15:00Z",
    "attributionId": "atr_01kvnwmagvf27rc9cze5rm9e1r"
  }'

The answer is 204 No Content with an empty body. That says nothing about whether the order was recorded, see What you get back.

Authentication

The URL is the only credential. pk_site_… is the site's public key, the same one as in your install snippet. It is not secret and ships in page source, so anyone who reads it can post an order for your site. A forged order only changes your own organization's figures. Do not treat a recorded order as proof that a sale happened.

There is no API key, no session and no origin check.

The body

JSON, at most 4096 bytes.

FieldRequiredWhat it is
typeyesAlways "purchase". Any other value writes nothing.
orderRefyesYour own order id, 1 to 200 characters after trimming. AISA treats it as opaque and deduplicates on it.
amountyesThe order total in the currency's major units, as a number or a string ("129.90", 129.9). Not negative. A string is digits with an optional decimal part, 32 characters at most.
currencyyesA three-letter ISO 4217 code, case does not matter (eur is stored as EUR). A code the platform's currency data does not know writes nothing.
occurredAtnoWhen the order was placed, as a date string. If it is missing, does not parse, is in the future or is more than 24 hours old, AISA uses the time it received the request.
sessionIdnoThe AISA tag session key, 1 to 200 characters, if your sender can read it. It authorizes nothing.
attributionIdnoThe conversation key (atr_…) the shopper's cart carried. See Link an order to a conversation.
objectednoA boolean. true writes nothing. See Shoppers who objected.

A body that does not match this table (a missing field, a wrong type, a string where objected expects a boolean, an unknown type) writes nothing. Extra fields are ignored.

Amounts

You send major units. AISA converts to minor units with the currency's own number of decimals: 129.90 in EUR is stored as 12990, 1500 in JPY as 1500. A converted amount that does not fit in a 32-bit signed integer is refused.

Content type and CORS

AISA reads the body as text and parses it as JSON whatever Content-Type says. Send text/plain from a browser and no CORS preflight happens. The endpoint answers every origin (Access-Control-Allow-Origin: *) and also answers an OPTIONS preflight with 204, so a sender that sets application/json works too.

What you get back

Always 204 with an empty body, for every POST. A recorded order, a malformed body, an unknown key, a refused amount and a rate-limited request look the same. This is deliberate: the response never reveals whether a key exists, whether a site has counting switched off, or whether a shopper objected.

The work happens after the response is sent. To check that orders arrive, look at your reports, not at the status code. Or read lastStorefrontOrderAt from Get a site's storefront activity (or the MCP tool get_storefront_activity): the time AISA received the latest order through this endpoint, null before the first. A request that stored nothing, a repeated orderRef included, leaves it unchanged.

What writes nothing

The request still gets its 204, and AISA stores no order, when:

  • the body is empty, over 4096 bytes (a Content-Length over the cap is refused without reading the body), not JSON, or does not match the table above;
  • objected is true;
  • the key in the URL matches no site;
  • the site's counting is switched off: Site settings > Site access > Count add-to-carts on your pages controls the add-to-cart pixel and this endpoint together, and it is on by default;
  • amount is negative, malformed or too large once converted, or currency is not a known code;
  • the request is over a rate limit.

Idempotence

An order sent here is unique by orderRef within your organization. Sending the same orderRef again changes nothing, so a retry is safe. The first one received wins: a later request with the same reference is dropped, including when its amount or key differs. The Shopify pixel posts to this same endpoint, so a reference it already sent counts as received.

The Shopify order webhooks are a separate source. If they report an order with the same reference, AISA keeps both reports and counts the order once, with the webhook's figures. Yours are used only when no webhook reported the order. See If the Shopify pixel also reports orders.

Send attributionId when you have it. An order with no attributionId, or one that does not have the shape of a conversation key (atr_ followed by 26 lowercase letters or digits), is stored with no key. It is read as not assisted, never inferred. AISA does not check that the key exists when it receives the order. The order read joins only on an exact match with a conversation key of the same organization, so a key from another organization credits nothing.

How the key gets onto a cart is described in The conversation join key. It is only put on a cart on Shopify stores, so on another platform you have no key to send unless you obtained it by other means. ⚠ AISA documents no way for a non-Shopify storefront to read a conversation key.

Shoppers who objected

If the shopper objected to measurement, your sender must not send anything for that order. Sending it with objected: true is not the way to comply: the endpoint drops that request, but the order should never leave your system in the first place.

AISA checks the flag too, and drops a request that says objected: true before it even looks up the site. It is a second safety net, not a replacement for your sender's own check. There is no way to say a shopper consented: the flag can only lower what AISA writes.

Rate limits

Two limits apply, shared with the add-to-cart endpoint, so both draw from the same budget:

LimitWindowRequests
Per IP address10 seconds20
Per organization60 seconds1200

The IP limit is checked first. A request over a limit is dropped, still with a 204. If the limiter itself fails, the request goes through. Counters are per region, so the effective ceiling can be higher.

⚠ These two values were copied from another endpoint and have not been calibrated on real traffic of this one. They can change. Send one request per order and do not batch retries in a tight loop.

Limits to know

  • Source and lines. An order recorded here has the source pixel, no order lines, no test flag and no sales channel. It cannot tell a test order from a real one, so do not send test orders.
  • Device. AISA derives it from the request's User-Agent, so a server-side sender's device type is whatever that header says.
  • No refunds or cancellations. purchase is the only type. A refund or cancellation made on another platform cannot be sent.
  • Your store's key is public. See Authentication.

On this page