Skip to content

Connect any other store

AguMail works with any online store. WooCommerce has a ready-made plugin (Connect your store); every other store, Shopify included, whether a hosted platform without a plugin or a store you built yourself, sends the same data to the same API that plugin uses. Once it arrives, abandoned-cart emails, purchase-triggered automations, product blocks and revenue per campaign all work.

You need a developer, or a platform that can call a webhook URL with JSON. Store connections and the API are part of the Commerce plans.

In AguMail, go to Settings → API keys → Create key and choose Other store or your own code. Copy the key; it is shown once. Every request below sends it as a header:

Authorization: Bearer agm_…
Content-Type: application/json
POST /api/v1/connect
{ "platform": "custom", "storeUrl": "yourstore.com", "currency": "EUR" }

Your store now shows under Settings → Integrations with the time it last sent data, and can be disconnected there. currency is the 3-letter ISO 4217 code your store prices in; products and carts you send without a currency of their own are priced in it. If your plan already has its stores connected, this returns 402 with the reason.

Orders and carts are matched to contacts by email, and only to contacts AguMail already has. Send the customer before their first order or cart.

POST /api/v1/contacts
{ "contacts": [
{ "email": "sam@example.com", "firstName": "Sam",
"consent": { "optedIn": true, "source": "checkout" } }
] }

Only send optedIn: true for people who agreed to marketing email. A contact without consent is stored but never mailed.

POST /api/v1/products
{ "products": [
{ "externalId": "sku-101", "sku": "TOTE-LIN-01", "title": "Linen tote bag",
"price": 38, "currency": "USD",
"categories": ["Bags", "Gifts"],
"imageUrl": "https://yourstore.com/img/tote.jpg",
"productUrl": "https://yourstore.com/p/tote" }
] }

Products fill the product picker in the email editor, and give cart lines their picture when a cart arrives without one.

sku and categories are what make “bought this” and “ordered from Gifts” segments possible: AguMail copies them onto every order that contains the product, so you can build an audience from what someone actually put in their basket. Both are optional, and leaving categories out of a later update keeps whatever the product already has.

5. Send orders, with the campaign they came from

Section titled “5. Send orders, with the campaign they came from”
POST /api/v1/orders
{ "orders": [
{ "externalId": "1042", "email": "sam@example.com", "total": 68, "currency": "USD",
"occurredAt": "2026-09-12T10:15:00Z",
"items": [{ "externalId": "sku-101", "sku": "TOTE-LIN-01",
"title": "Linen tote bag", "qty": 1, "price": 38 }],
"campaignRef": "c_7f3a…" }
] }

A line’s externalId is the product it names, which is how an order picks up that product’s categories. sku is optional on the line — leave it out and AguMail takes it from the product you sent.

Every link in an AguMail email carries an agm_cid query parameter. Keep it when a shopper lands on your store (a cookie or the session is enough), and send it back as campaignRef on their order. That is how each campaign and flow report shows the revenue it earned. A flow is credited when the shopper was sent one of its emails in the 7 days before the order.

POST /api/v1/carts
{ "carts": [
{ "externalId": "cart-88", "email": "sam@example.com", "total": 68, "currency": "USD",
"items": [{ "title": "Linen tote bag", "qty": 1, "price": 38, "productExternalId": "sku-101",
"sku": "TOTE-LIN-01", "url": "https://yourstore.com/p/tote" }],
"checkoutUrl": "https://yourstore.com/cart/recover?token=…",
"lastActivityAt": "2026-09-12T09:40:00Z" }
] }

Send the cart again whenever it changes. A cart that sits idle for an hour counts as abandoned and starts your abandoned-cart flow for that shopper. The recovery email shows the cart’s lines and a button to checkoutUrl, so make it a link that brings this cart back, not your generic checkout page. When the shopper buys, send the cart with "status": "completed", or send the order.

In Automations, start Abandoned Cart Recovery from the gallery. Its emails already show the cart and a button back to it. Review them, then turn the flow on.

Anything else your business records can be sent as an event, and is then something a segment can count, a flow can start from, and an email can print.

POST /api/v1/events
{ "events": [
{ "email": "sam@example.com", "metric": "Booked appointment",
"occurredAt": "2026-09-19T10:15:00Z", "uniqueId": "appt_991", "value": 49,
"properties": { "service": "Cut & finish", "staff": "Ana" } }
] }
  • metric is your own name for what happened. Spelling and capitals do not matter: “Booked appointment”, “booked_appointment” and “Booked Appointment” are one event.
  • uniqueId is your name for this particular occurrence — an appointment id, an invoice number. Send it and you can safely retry: the same id is never recorded twice, and nobody is enrolled in a flow twice for it.
  • occurredAt is when it happened, not when you sent it. Leave it out and AguMail uses now.
  • properties is anything you want the email to be able to say. Up to 30 keys.
  • value is money, if the event is worth some.

Then, in AguMail:

  • Segment on it. In the segment builder pick Did something…, choose your event, and set a count and a window — “at least 1 time in the last 30 days”. Add narrow by property to ask about one of your own properties, for example service is Cut & finish.
  • Trigger a flow with it. In the flow editor choose the Any recorded event trigger and pick your event. It appears in that list once the first one has arrived.
  • Print it in the email. {{event.service}} and {{event.staff}} render what that contact’s event carried. A missing property renders as nothing rather than breaking the email.

The response counts what happened: { "ok": true, "created": 1, "duplicates": 0, "unknownContacts": 0 }. unknownContacts is the important one — an event for an address AguMail does not hold is skipped rather than creating a contact, because an event is not permission to email someone. Send the person to /api/v1/contacts first.

Unlike products, orders and carts, events are not part of the store half of the API: any plan with API access can send them.

  • 120 requests a minute per key, and up to 500 records per request.
  • 400 means a field is missing or malformed; the message names it.
  • 401 means the key is missing, wrong or revoked.
  • 402 means your plan does not include the API or has no room for another store.
  • 429 means you are over the rate limit; retry after a minute.

AguMail does not watch your store’s own pages. There is no on-site script, so it cannot see product views, and a flow cannot start from someone browsing. Carts, orders and events are what your store’s backend sends.