Fetching records

POST /v1/query answers questions about your data — totals, trends, breakdowns. Sometimes you want the records themselves: the orders, with their fields, so you can load them into another system.

That is what these endpoints are for, and they need no query language:

curl -H "Authorization: Bearer $ECOMSOLO_API_KEY" \
  "https://api.ecomsolo.com/v1/orders?financial_status=paid&page_size=50"

Available datasets

PathContents
/v1/ordersOrders across every connected store
/v1/customersCustomers
/v1/productsProducts
/v1/draft_ordersDraft orders

Each returns the same fields you can query with SoloQL. GET /v1/datasets lists every field of every dataset, and is the authoritative reference — if a field is listed there, you can request it, filter on it, and receive it here.

The response

{
  "data": [
    {
      "order_name": "#1001",
      "created_at": "2026-03-14T09:22:11Z",
      "financial_status": "paid",
      "total_price": 129.5,
      "customer_name": "Ada Lovelace",
      "store_id": "6f2c…"
    }
  ],
  "page": 1,
  "page_size": 50,
  "has_more": true
}

has_more tells you whether another page exists. There is no total count — see Paging for why.

Filtering

Any field of the dataset is a filter. Use the field name as the query parameter:

# one value
/v1/orders?financial_status=paid

# several values (OR)
/v1/orders?financial_status=paid,partially_refunded

# combined (AND)
/v1/orders?financial_status=paid&fulfillment_status=fulfilled

Dates use created_at_min and created_at_max (ISO 8601, UTC):

/v1/orders?created_at_min=2026-03-01&created_at_max=2026-04-01

Restrict to particular stores with store_ids (comma-separated). Omit it and you get every store your key can read:

/v1/orders?store_ids=6f2c…,9a1b…

info

An unknown filter returns 400 naming the offending parameter, rather than silently ignoring it and returning the wrong rows. If a filter is rejected, check GET /v1/datasets for the exact field name.

Choosing fields

Ask for only what you need with fields:

/v1/orders?fields=order_name,total_price,created_at

Worth doing for two reasons: responses get smaller and faster, and you stop receiving personal data you have no use for. If you are syncing revenue figures, requesting only the money fields means customer names never leave our systems at all.

Paging

/v1/orders?page=1&page_size=100
/v1/orders?page=2&page_size=100

page_size defaults to 50 and maxes at 250. Keep requesting pages while has_more is true.

There is no total_count. Producing one costs a second query on every request, and for the common case — loop until has_more is false — it is not needed. We would rather keep the endpoint fast than return a number most callers discard.

warning

Paging is for reading, not for bulk extraction. If you are pulling tens of thousands of records — a full history load, a warehouse sync — use an export instead. Exports run in the background, handle any volume, and deliver a file to email, FTP, Google Drive or Sheets — and you can trigger one from code. Deep paging through a large dataset is slow for you and expensive for us, and results can shift underneath you if a store syncs midway.

A single record

curl -H "Authorization: Bearer $ECOMSOLO_API_KEY" \
  "https://api.ecomsolo.com/v1/orders/6f2c8a1e…"

Returns the record directly, without the data wrapper. An id that does not exist — or belongs to a store your key cannot read — returns 404. Those two cases are deliberately indistinguishable, so the API never confirms the existence of data you are not entitled to.

Which endpoint should I use?

You wantUse
Revenue by month, top products, trendsPOST /v1/query (SoloQL)
The orders themselves, to load elsewhereGET /v1/orders
A specific record you have the id forGET /v1/orders/{id}
Everything, in bulk, on a scheduleAn export

The two are complements, not alternatives. SoloQL answers questions — it aggregates and returns a flat table, and cannot hand you a record. These endpoints return records and never aggregate. Most integrations use both: a query for the summary, records for the detail behind it.

info

Not every field works on both. Aggregate-only fields like order_count exist so COUNT has something to count and have no meaning on one record, so records never return them — ask SoloQL for that number instead. GET /v1/datasets is the authoritative field list for both surfaces.

Stability

The fields these endpoints return are a published contract. We may add new fields over time — your integration should ignore ones it does not recognise — but we will not remove a field or change its type without a new API version.

Fields are never added by accident: the published list is explicit, so internal changes on our side cannot quietly alter what you receive.