Skip to main content

Pushing point-of-sale events

eConnect ships collectors for the common till systems. Where it has no driver for yours — a bespoke system, a new vendor, a cloud POS — push the transactions yourself and the whole module works: events grid, receipts, statistics, behaviour reports, exception alerts, and the video beside each transaction.

POST /api/v2/pos/plugins/{pluginInstalledId}/events single
POST /api/v2/pos/plugins/{pluginInstalledId}/events/batch array

The payload​

{
"dataTimeStamp": "2026-10-02T21:14:05Z",
"eventTypeID": 12,
"terminalNumber": 4,
"revenueCenterNumber": 2,
"employeeNumber": 4471,
"checkNumber": 100382,
"dollarAmount": 24.50,
"quantity": 1,
"objectNumber": 55120,
"groupNumber": 3,
"tableNumber": 17,
"authorizationNumber": 0,
"authorizingPOSEmployeeNumber": 0,
"basicData": "VOID – Sirloin 10oz"
}

What each field is for​

FieldWhy it matters
dataTimeStampWhen the transaction happened, UTC. Drives every grid, report and the jump to video
eventTypeIDWhat kind of event this is — sale, void, discount, no-sale. The code set is configured per deployment; confirm yours before you map
terminalNumberThe till. Must match an eConnect entity, or the event cannot reach a camera
revenueCenterNumberThe outlet or area, as eConnect knows it
employeeNumberWho rang it. The behaviour report is built on this
checkNumberGroups line items into one check — the receipt view is assembled from it
dollarAmount, quantityThe figures statistics and exception rules work on
objectNumberThe item or PLU
authorizationNumber, authorizingPOSEmployeeNumberWho authorised an exception, where one was needed. This is what makes "who approved that void?" answerable
basicDataFree text shown on the row — the item description or the reason
Numbers, not names

The POS contract is numeric by design: terminals, revenue centres and employees are identified by the numbers your till system uses, and eConnect maps those to names through its entity setup. Send the numbers consistently and the names appear; invent them per batch and the data is unusable.

Map your entities first​

GET /api/v2/pos/plugins/{pluginInstalledId}/entities
GET /api/v2/pos/plugins/{pluginInstalledId}/entities/query
POST /api/v2/pos/plugins/{pluginInstalledId}/entities/by-familiar-id

Read them at start-up, map your till's numbering to eConnect's once, and fail loudly on anything unmapped rather than sending it into a void.

Sending it​

curl -X POST \
"https://your-server/api/v2/pos/plugins/$POS_ID/events/batch" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'Content-Type: application/json' \
-d '[
{
"dataTimeStamp": "2026-10-02T21:14:05Z",
"eventTypeID": 12,
"terminalNumber": 4,
"revenueCenterNumber": 2,
"employeeNumber": 4471,
"checkNumber": 100382,
"dollarAmount": 24.50,
"quantity": 1,
"basicData": "VOID - Sirloin 10oz"
}
]'
// A till drains its queue every few seconds; batch whatever accumulated.
var batch = queue.DrainUpTo(200).Select(e => new
{
dataTimeStamp = e.OccurredUtc,
eventTypeID = map.EventType(e.Kind),
terminalNumber = map.Terminal(e.TillId),
revenueCenterNumber = map.RevenueCentre(e.OutletId),
employeeNumber = e.OperatorNumber,
checkNumber = e.CheckNumber,
dollarAmount = e.Amount,
quantity = e.Quantity,
objectNumber = e.Plu,
basicData = e.Description,
}).ToArray();

if (batch.Length > 0)
{
var response = await http.PostAsJsonAsync($"pos/plugins/{posId}/events/batch", batch);
response.EnsureSuccessStatusCode();
queue.Commit(); // only once the server has acknowledged
}
# Catching up after an outage: send oldest first so the grid fills in order,
# and keep your own high-water mark rather than relying on the server.
for chunk in chunked(sorted(pending, key=lambda e: e.occurred_utc), 200):
resp = requests.post(
f"{BASE}/pos/plugins/{pos_id}/events/batch",
headers={"Authorization": f"Bearer {token}"},
json=[to_event(e) for e in chunk],
timeout=60,
)
resp.raise_for_status()
high_water = chunk[-1].occurred_utc
save(high_water)
MethodPathWhat it does
POSTpos/plugins/{id}/eventsOne event
POSTpos/plugins/{id}/events/batchMany
GETpos/plugins/{id}/eventsQuery events
GETpos/plugins/{id}/entitiesTerminals, revenue centres, employees
POSTpos/plugins/{id}/aggregate-reportTotals without pulling rows
POSTpos/plugins/{id}/events/cleanupRemove events you sent in error

The full list is on the Point of Sale reference page.

Permissions​

The service account needs the POSData* keys for the operations it performs — POSDataEventAdd to push events, the entity keys only if it also maintains terminals and employees — and the POS plugin instance must be within its logical group. See the Permission Keys reference.

What operators see​

Pushed events are ordinary POS data: they appear in Events, assemble into receipts by check number, feed statistics and the behaviour report, and — where the terminal is associated with a camera — open the footage of the transaction.