Skip to content
Docs

Send your shop’s orders to credit revenue to emails and build purchase profiles.

Base URLhttps://api.emailit.com/v2AuthenticationErrorsRate limits

Create or update an order

Send an order from your shop’s backend. The order is keyed by its id in your shop: send the same id again and the stored order is updated instead. Requires an API key with the full or events scope. With an events key, the response holds only object, id and external_id.

When an order is stored for the first time, Emailit:

  • credits it to the campaign or automation email the buyer last clicked within the click window before placed_at, or, without a click, last opened within the open window. The windows are in the commerce settings. See How orders are credited to emails.
  • links it to the buyer’s contact, and creates the contact if needed (see create_contact).
  • marks the cart named in cart_id as converted, and also the buyer’s other open carts that were last updated before the order.
  • marks matching coupon codes as redeemed.
  • updates the contact’s purchase metrics.
  • emits order.placed, which webhooks and automations receive.

Sending an order that’s already stored updates it and emits order.updated, with previous_status when the status changed. The attribution doesn’t change. Only the fields you send change: status, placed_at, currency, the amounts, coupon_codes, cart_id and items keep their stored values when you leave them out, metadata is merged into the stored object, and total isn’t required. Sending items replaces all items. To change only the status or a refund, you can also use Update an order.

To import past orders without crediting emails or starting automations, use Import orders in bulk.

POST/orders

Request Body

idstring | numberRequired

The order ID in your shop, up to 255 characters. Numbers are stored as strings. Stored as external_id. You can also send it as external_id or order_id.

emailstring

The buyer’s email address. Stored in lowercase. Emailit uses it to find the contact and to credit the order to an email sent to that address. customer.email is also accepted.

contact_idstring

The buyer’s contact (con_...). If no contact has this ID, Emailit looks the contact up by email.

first_namestring

The buyer’s first name, up to 191 characters. Used when Emailit creates the contact. customer.first_name is also accepted.

last_namestring

The buyer’s last name, up to 191 characters. Used when Emailit creates the contact. customer.last_name is also accepted.

statusstring

placed (default), paid, fulfilled, canceled or refunded. The first time an order has paid, fulfilled, canceled or refunded, Emailit sets the matching paid_at, fulfilled_at, canceled_at or refunded_at to the current time. Canceled orders don’t count toward revenue.

currencystring

Three-letter ISO 4217 code. Defaults to the workspace currency in the commerce settings. Amounts are never converted: reports group revenue by currency.

totalnumber | string

Order total. Required for a new order without items. Without it, Emailit computes the sum of the item totals, minus discount, plus shipping and tax, and never below 0.

Amounts are numbers or numeric strings, can’t be negative, and are stored with up to 4 decimal places.

subtotalnumber | string

Amount before discount, shipping and tax. Defaults to the sum of the item totals when the order has items.

discountnumber | string

Discount amount, as a positive number.

shippingnumber | string

Shipping amount.

taxnumber | string

Tax amount.

refunded_amountnumber | string

Amount refunded. Defaults to 0, or to total when status is refunded. Revenue is total minus refunded_amount.

coupon_codesstring[]

Up to 20 coupon or discount codes used in the order. A code that matches a coupon code in the workspace, ignoring case, is marked redeemed by this order. coupon_code and discount_codes are also accepted.

cart_idstring

The cart or checkout ID in your shop that the order came from. The cart with this ID becomes converted.

placed_atstring | number

When the order was placed: an ISO 8601 date-time or a Unix timestamp in seconds (milliseconds also work). Defaults to the current time. Can’t be more than 24 hours in the future. created_at is also accepted.

itemsobject[]

Up to 250 line items. line_items is also accepted. Each item has:

  • product_id (string or number): the product ID in your shop. Items without a title, url, image_url or categories take them from the catalog. id is also accepted.

  • variant_id, sku (string): up to 255 characters.

  • title (string): up to 500 characters. Required when the item has no product_id or sku. name is also accepted.

  • quantity (integer): 1 or more. Defaults to 1.

  • price (number or string): the unit price. Defaults to 0. unit_price is also accepted.

  • total (number or string): the line total. Defaults to price times quantity.

  • categories (string[]): up to 50 category names.

  • url, image_url (string): http or https URLs.

metadataobject

Your own key-value data, up to 16 KB as JSON. On updates, the keys you send are merged into the stored object.

create_contactboolean

Default true: when no contact matches contact_id or email, Emailit creates one from email, first_name and last_name and emits contact.created. The new contact isn’t subscribed to any audience, so campaigns don’t reach it. Set to false to never create a contact: the order is then linked only to a contact that already exists.

accepts_marketingboolean

Set to true together with audience_id when the buyer agreed to receive marketing. Emailit then subscribes the contact to that audience, unless the contact is already in it. Default false.

audience_idstring

The audience (aud_...) to subscribe the buyer to when accepts_marketing is true. If the audience doesn’t exist or your plan’s subscriber limit is reached, the order is still stored and the contact isn’t subscribed.

email_idstring

The campaign email (eml_...) the buyer came from, if your shop tracks it. Only used for new orders, and only IDs that start with eml_ are read. The order is credited to this email when it’s a campaign email of the workspace and either has a click within the click window before the order or was sent within that window. Otherwise Emailit credits the order as usual. attribution.email_id is also accepted.

Returns

201 Created with the order object when the order is new, or 200 OK when an existing order was updated. Returns 422 when a field is invalid.

POST/orders
Terminal
curl -X POST https://api.emailit.com/v2/orders \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "1042",
    "email": "ada@example.com",
    "first_name": "Ada",
    "last_name": "Lovelace",
    "status": "paid",
    "currency": "USD",
    "discount": 10.7,
    "shipping": 5,
    "tax": 0,
    "coupon_codes": ["WELCOME-7KQ2M9XA"],
    "cart_id": "c-58f1a2",
    "placed_at": "2026-10-08T14:32:10Z",
    "items": [
      { "product_id": "8123456789", "variant_id": "42-blue", "sku": "TRS-BLU-42", "title": "Trail running shoe", "quantity": 1, "price": 89 },
      { "product_id": "8123456790", "title": "Merino running socks", "quantity": 2, "price": 9 }
    ],
    "metadata": { "channel": "web" },
    "accepts_marketing": true,
    "audience_id": "aud_3Cz7WJ9GpvD7P0PQez50xOmkZSV"
  }'
JSON
{
  "object": "order",
  "id": "ord_3aMEK4No62Zw8S1fcHNznAnnbfp",
  "external_id": "1042",
  "contact_id": "con_3EwrXnu9OaQWlfI1AyPUUEoYjQs",
  "email": "ada@example.com",
  "status": "paid",
  "currency": "USD",
  "subtotal": 107,
  "discount": 10.7,
  "shipping": 5,
  "tax": 0,
  "total": 101.3,
  "refunded_amount": 0,
  "coupon_codes": [
    "WELCOME-7KQ2M9XA"
  ],
  "cart_id": "c-58f1a2",
  "source": "api",
  "placed_at": "2026-10-08T14:32:10.000Z",
  "paid_at": "2026-10-08T14:32:11.204Z",
  "fulfilled_at": null,
  "canceled_at": null,
  "refunded_at": null,
  "attribution": {
    "email_id": "eml_3TSvDAUQi7vqxvAQ1UEVN7k4igq",
    "campaign_id": "cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
    "campaign_name": "October newsletter",
    "variant_id": null,
    "automation_id": null,
    "automation_name": null,
    "type": "click",
    "touched_at": "2026-10-08T09:41:52.000Z"
  },
  "items": [
    {
      "product_id": "8123456789",
      "variant_id": "42-blue",
      "sku": "TRS-BLU-42",
      "title": "Trail running shoe",
      "quantity": 1,
      "unit_price": 89,
      "total": 89,
      "categories": [
        "Shoes",
        "Running"
      ],
      "url": "https://shop.example.com/products/trail-running-shoe",
      "image_url": "https://shop.example.com/images/trail-running-shoe.jpg"
    },
    {
      "product_id": "8123456790",
      "variant_id": null,
      "sku": null,
      "title": "Merino running socks",
      "quantity": 2,
      "unit_price": 9,
      "total": 18,
      "categories": [
        "Accessories"
      ],
      "url": "https://shop.example.com/products/merino-running-socks",
      "image_url": "https://shop.example.com/images/merino-running-socks.jpg"
    }
  ],
  "metadata": {
    "channel": "web"
  },
  "created_at": "2026-10-08T14:32:11.204Z",
  "updated_at": "2026-10-08T14:32:11.204Z"
}

Retrieve an order

Retrieve an order by its Emailit ID or by the order ID in your shop, with its items and its attribution. Requires an API key with the full scope.

GET/orders/{id}

Path Parameters

idstringRequired

The order ID (ord_...) or the order ID in your shop (external_id). URL-encode shop IDs that contain special characters.

The order object

objectstring

Always order.

idstring

Emailit order ID (ord_...).

external_idstring

The order ID in your shop: the id you sent.

contact_idstring | null

The buyer’s contact (con_...), or null when the order isn’t linked to a contact.

emailstring | null

The buyer’s email address, in lowercase.

statusstring

placed, paid, fulfilled, canceled or refunded.

currencystring

Three-letter ISO 4217 code of the amounts.

subtotalnumber | null

Sum of the items before discount, shipping and tax.

discountnumber | null

Discount amount.

shippingnumber | null

Shipping amount.

taxnumber | null

Tax amount.

totalnumber

Order total. Revenue in reports is total minus refunded_amount, and canceled orders don’t count.

refunded_amountnumber

Amount refunded so far. 0 when nothing was refunded.

coupon_codesstring[]

Coupon or discount codes used in the order.

cart_idstring | null

The cart or checkout ID in your shop that the order came from.

sourcestring

How the order reached Emailit: api, js (the tracking script) or import (bulk import).

placed_atstring

When the order was placed, in ISO 8601 UTC.

paid_at, fulfilled_at, canceled_at, refunded_atstring | null

When Emailit first stored the order with that status. Set once and not cleared when the status changes again.

attributionobject | null

The email the order is credited to, or null. Set once, when the order is first stored. See How orders are credited to emails.

  • email_id (string): the credited email.

  • campaign_id, campaign_name (string or null): its campaign.

  • variant_id (string or null): the A/B test variant (cvr_...) the buyer received.

  • automation_id, automation_name (string or null): its automation.

  • type (string): click or open.

  • touched_at (string or null): when the click or open happened.

itemsobject[]

Line items. Each has product_id (the product ID in your shop), variant_id, sku, title, quantity, unit_price, total, categories, url and image_url.

metadataobject

Your own key-value data.

created_at, updated_atstring

When Emailit stored the order and when it last changed, in ISO 8601 UTC.

GET/orders/{id}
Terminal
curl https://api.emailit.com/v2/orders/ord_3aMEK4No62Zw8S1fcHNznAnnbfp \
  -H "Authorization: Bearer your_api_key"
JSON
{
  "object": "order",
  "id": "ord_3aMEK4No62Zw8S1fcHNznAnnbfp",
  "external_id": "1042",
  "contact_id": "con_3EwrXnu9OaQWlfI1AyPUUEoYjQs",
  "email": "ada@example.com",
  "status": "paid",
  "currency": "USD",
  "subtotal": 107,
  "discount": 10.7,
  "shipping": 5,
  "tax": 0,
  "total": 101.3,
  "refunded_amount": 0,
  "coupon_codes": [
    "WELCOME-7KQ2M9XA"
  ],
  "cart_id": "c-58f1a2",
  "source": "api",
  "placed_at": "2026-10-08T14:32:10.000Z",
  "paid_at": "2026-10-08T14:32:11.204Z",
  "fulfilled_at": null,
  "canceled_at": null,
  "refunded_at": null,
  "attribution": {
    "email_id": "eml_3TSvDAUQi7vqxvAQ1UEVN7k4igq",
    "campaign_id": "cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
    "campaign_name": "October newsletter",
    "variant_id": null,
    "automation_id": null,
    "automation_name": null,
    "type": "click",
    "touched_at": "2026-10-08T09:41:52.000Z"
  },
  "items": [
    {
      "product_id": "8123456789",
      "variant_id": "42-blue",
      "sku": "TRS-BLU-42",
      "title": "Trail running shoe",
      "quantity": 1,
      "unit_price": 89,
      "total": 89,
      "categories": [
        "Shoes",
        "Running"
      ],
      "url": "https://shop.example.com/products/trail-running-shoe",
      "image_url": "https://shop.example.com/images/trail-running-shoe.jpg"
    },
    {
      "product_id": "8123456790",
      "variant_id": null,
      "sku": null,
      "title": "Merino running socks",
      "quantity": 2,
      "unit_price": 9,
      "total": 18,
      "categories": [
        "Accessories"
      ],
      "url": "https://shop.example.com/products/merino-running-socks",
      "image_url": "https://shop.example.com/images/merino-running-socks.jpg"
    }
  ],
  "metadata": {
    "channel": "web"
  },
  "created_at": "2026-10-08T14:32:11.204Z",
  "updated_at": "2026-10-08T14:32:11.204Z"
}

Update an order

Change the status of a stored order, record a refund, or add metadata. Everything else stays as it is, including the items and the attribution. The buyer’s purchase metrics are recalculated, and Emailit emits order.updated, with the order’s previous_status when the status changed. Requires an API key with the full or events scope. With an events key, the response holds only object, id and external_id.

POST/orders/{id}

Path Parameters

idstringRequired

The order ID (ord_...) or the order ID in your shop.

Request Body

Send at least one of these fields.

statusstring

placed, paid, fulfilled, canceled or refunded. The first time the order gets paid, fulfilled, canceled or refunded, the matching paid_at, fulfilled_at, canceled_at or refunded_at is set to the current time. Canceled orders don’t count toward revenue.

refunded_amountnumber | string

Total amount refunded so far, not the amount of this refund. Can’t be negative. Revenue is total minus refunded_amount. If you set status to refunded without refunded_amount and nothing was refunded before, the whole total counts as refunded.

metadataobject

Keys to merge into the order’s metadata. Up to 16 KB as JSON.

Returns

200 OK with the updated order object. Returns 404 if no order matches id and 422 when the body is empty or a field is invalid.

POST/orders/{id}
Terminal
curl -X POST https://api.emailit.com/v2/orders/1042 \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "refunded_amount": 18 }'
JSON
{
  "object": "order",
  "id": "ord_3aMEK4No62Zw8S1fcHNznAnnbfp",
  "external_id": "1042",
  "contact_id": "con_3EwrXnu9OaQWlfI1AyPUUEoYjQs",
  "email": "ada@example.com",
  "status": "paid",
  "currency": "USD",
  "subtotal": 107,
  "discount": 10.7,
  "shipping": 5,
  "tax": 0,
  "total": 101.3,
  "refunded_amount": 18,
  "coupon_codes": [
    "WELCOME-7KQ2M9XA"
  ],
  "cart_id": "c-58f1a2",
  "source": "api",
  "placed_at": "2026-10-08T14:32:10.000Z",
  "paid_at": "2026-10-08T14:32:11.204Z",
  "fulfilled_at": null,
  "canceled_at": null,
  "refunded_at": null,
  "attribution": {
    "email_id": "eml_3TSvDAUQi7vqxvAQ1UEVN7k4igq",
    "campaign_id": "cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
    "campaign_name": "October newsletter",
    "variant_id": null,
    "automation_id": null,
    "automation_name": null,
    "type": "click",
    "touched_at": "2026-10-08T09:41:52.000Z"
  },
  "items": [
    {
      "product_id": "8123456789",
      "variant_id": "42-blue",
      "sku": "TRS-BLU-42",
      "title": "Trail running shoe",
      "quantity": 1,
      "unit_price": 89,
      "total": 89,
      "categories": [
        "Shoes",
        "Running"
      ],
      "url": "https://shop.example.com/products/trail-running-shoe",
      "image_url": "https://shop.example.com/images/trail-running-shoe.jpg"
    },
    {
      "product_id": "8123456790",
      "variant_id": null,
      "sku": null,
      "title": "Merino running socks",
      "quantity": 2,
      "unit_price": 9,
      "total": 18,
      "categories": [
        "Accessories"
      ],
      "url": "https://shop.example.com/products/merino-running-socks",
      "image_url": "https://shop.example.com/images/merino-running-socks.jpg"
    }
  ],
  "metadata": {
    "channel": "web"
  },
  "created_at": "2026-10-08T14:32:11.204Z",
  "updated_at": "2026-10-10T08:05:39.871Z"
}

List orders

List orders with their items, the most recently placed first. Requires an API key with the full scope.

GET/orders

Query Parameters

pageinteger

Page number for pagination (minimum: 1, default: 1).

limitinteger

Number of orders to return (minimum: 1, maximum: 100, default: 25).

searchstring

Case-insensitive match on the order ID in your shop or the buyer’s email address.

contact_idstring

Only orders of this contact (con_...).

emailstring

Only orders with this buyer email address, ignoring case.

statusstring

Only orders with this status: placed, paid, fulfilled, canceled or refunded.

campaign_idstring

Only orders credited to this campaign (cmp_...).

automation_idstring

Only orders credited to this automation (aut_...).

attributedboolean

true for orders credited to an email, false for orders that aren’t.

fromstring

Only orders placed at or after this time. An ISO 8601 date or date-time; anything else returns 422.

tostring

Only orders placed at or before this time. An ISO 8601 date or date-time; anything else returns 422.

matchstring

all (default) requires every key.condition filter to match. or matches any of them. See Filtering.

sortstring

Sort key: placed_at (default), total or created_at.

orderstring

Sort direction: asc or desc (default).

Filters

List filters are one layer of key.condition=value query parameters. See Filtering for match, order, direction and the condition list per type.

Filter keys

KeyTypeConditionsNotes
external_idstringexact, not_exact, contains, not_contains, starts_with, ends_with, empty, not_empty
emailstringexact, not_exact, contains, not_contains, starts_with, ends_with, empty, not_empty
statusenumexact, not_exactValues: placed, paid, fulfilled, canceled, refunded
currencystringexact, not_exact, contains, not_contains, starts_with, ends_with, empty, not_empty
totalnumberexact, not_exact, gt, gte, lt, lte, empty, not_empty
sourceenumexact, not_exactValues: api, js, import, dashboard
attribution_typeenumexact, not_exactValues: click, open
placed_atdateexact, before, after, empty, not_empty
created_atdateexact, before, after, empty, not_empty

Sort keys

This endpoint sorts with sort set to one of these keys and order set to asc or desc (order=<key> returns 400 here): placed_at, total, created_at

On this endpoint, order only accepts asc or desc. Pass the sort key in sort, for example sort=total&order=desc.

Returns

A page of order objects in data, with total_records, next_page_url and previous_page_url. The page URLs carry only page and limit, so add your search and filters again when you follow them.

GET/orders
Terminal
curl "https://api.emailit.com/v2/orders?campaign_id=cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN&from=2026-10-01&limit=25" \
  -H "Authorization: Bearer your_api_key"
JSON
{
  "data": [
    {
      "object": "order",
      "id": "ord_3aMEK4No62Zw8S1fcHNznAnnbfp",
      "external_id": "1042",
      "contact_id": "con_3EwrXnu9OaQWlfI1AyPUUEoYjQs",
      "email": "ada@example.com",
      "status": "paid",
      "currency": "USD",
      "subtotal": 89,
      "discount": null,
      "shipping": 5,
      "tax": 0,
      "total": 94,
      "refunded_amount": 0,
      "coupon_codes": [],
      "cart_id": null,
      "source": "api",
      "placed_at": "2026-10-08T14:32:10.000Z",
      "paid_at": "2026-10-08T14:32:11.204Z",
      "fulfilled_at": null,
      "canceled_at": null,
      "refunded_at": null,
      "attribution": {
        "email_id": "eml_3TSvDAUQi7vqxvAQ1UEVN7k4igq",
        "campaign_id": "cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
        "campaign_name": "October newsletter",
        "variant_id": null,
        "automation_id": null,
        "automation_name": null,
        "type": "click",
        "touched_at": "2026-10-08T09:41:52.000Z"
      },
      "items": [
        {
          "product_id": "8123456789",
          "variant_id": null,
          "sku": "TRS-BLU-42",
          "title": "Trail running shoe",
          "quantity": 1,
          "unit_price": 89,
          "total": 89,
          "categories": [
            "Shoes",
            "Running"
          ],
          "url": "https://shop.example.com/products/trail-running-shoe",
          "image_url": "https://shop.example.com/images/trail-running-shoe.jpg"
        }
      ],
      "metadata": {},
      "created_at": "2026-10-08T14:32:11.204Z",
      "updated_at": "2026-10-08T14:32:11.204Z"
    }
  ],
  "total_records": 1,
  "next_page_url": null,
  "previous_page_url": null
}

Import orders in bulk

Send up to 1,000 orders in one request. Use it to import your order history, so purchase metrics, segments and product recommendations have data from day one. Each order follows the rules of Create or update an order: it’s created or updated by its id, contacts are created unless create_contact is false, carts are converted, coupon codes are redeemed and purchase metrics are updated. Requires an API key with the full or events scope. With an events key, the response holds only object, id and external_id.

By default the orders are historical: they aren’t credited to any email, and Emailit doesn’t emit order.placed or order.updated, so they don’t start automations or reach webhooks. New contacts still emit contact.created. Orders sent with this endpoint have source set to import, with or without historical.

Invalid orders are skipped and listed in rejected; the others are stored. The request still returns 200.

POST/orders/batch

Request Body

ordersobject[]Required

1 to 1,000 orders, each with the fields of Create or update an order.

historicalboolean

Default true: no attribution and no order events. Set to false to treat the orders like orders sent one by one: new orders are credited to emails and emit order.placed, updated orders emit order.updated.

Returns

createdinteger

Number of new orders.

updatedinteger

Number of orders that were already stored and were updated.

rejectedobject[]

Orders that weren’t stored. Each item has the index of the order in your orders array and errors, keyed by field path such as orders.4.currency. An order that passed validation but couldn’t be saved has the error could not be stored under orders.<index>.

Returns 422 if orders is empty or has more than 1,000 items.

POST/orders/batch
Terminal
curl -X POST https://api.emailit.com/v2/orders/batch \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "orders": [
      {
        "id": "981",
        "email": "ada@example.com",
        "status": "fulfilled",
        "currency": "USD",
        "placed_at": "2026-03-14T10:12:00Z",
        "items": [{ "product_id": "8123456789", "quantity": 1, "price": 89 }]
      },
      {
        "id": "982",
        "email": "grace@example.com",
        "status": "fulfilled",
        "currency": "usd dollars",
        "total": 18,
        "placed_at": "2026-03-15T16:40:00Z"
      }
    ]
  }'
JSON
{
  "created": 1,
  "updated": 0,
  "rejected": [
    {
      "index": 1,
      "errors": {
        "orders.1.currency": [
          "must be a three-letter ISO 4217 code, e.g. USD"
        ]
      }
    }
  ]
}

Delete an order

Delete an order and its items. The buyer’s purchase metrics are recalculated without it, and its revenue no longer counts in reports. Coupon codes it redeemed stay redeemed and converted carts stay converted. No event is emitted. To keep the order but stop counting its revenue, set its status to canceled with Update an order instead. Requires an API key with the full scope.

DELETE/orders/{id}

Path Parameters

idstringRequired

The order ID (ord_...) or the order ID in your shop.

DELETE/orders/{id}
Terminal
curl -X DELETE https://api.emailit.com/v2/orders/ord_3aMEK4No62Zw8S1fcHNznAnnbfp \
  -H "Authorization: Bearer your_api_key"
JSON
{
  "object": "order",
  "id": "ord_3aMEK4No62Zw8S1fcHNznAnnbfp",
  "deleted": true
}

Was this page helpful?

Thanks for the feedback.

Thanks, we read every message.