Latest transaction
curl --request GET \
--url https://clientapi.retailgrid.io/v1/transactions/latestimport requests
url = "https://clientapi.retailgrid.io/v1/transactions/latest"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://clientapi.retailgrid.io/v1/transactions/latest', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://clientapi.retailgrid.io/v1/transactions/latest",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://clientapi.retailgrid.io/v1/transactions/latest"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://clientapi.retailgrid.io/v1/transactions/latest")
.asString();require 'uri'
require 'net/http'
url = URI("https://clientapi.retailgrid.io/v1/transactions/latest")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_bodyTransactions
Latest transaction
Retrieve the latest stored transaction by business timestamp, optionally within one store.
GET
/
v1
/
transactions
/
latest
Latest transaction
curl --request GET \
--url https://clientapi.retailgrid.io/v1/transactions/latestimport requests
url = "https://clientapi.retailgrid.io/v1/transactions/latest"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://clientapi.retailgrid.io/v1/transactions/latest', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://clientapi.retailgrid.io/v1/transactions/latest",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://clientapi.retailgrid.io/v1/transactions/latest"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://clientapi.retailgrid.io/v1/transactions/latest")
.asString();require 'uri'
require 'net/http'
url = URI("https://clientapi.retailgrid.io/v1/transactions/latest")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_bodyGET https://clientapi.retailgrid.io/v1/transactions/latest returns one transaction
with the greatest non-null stored transaction_timestamp across your organization’s
data namespace. It requires no pagination or export. Existing list ordering and cursors are unchanged.
Authenticate with the same Bearer API key as other public endpoints:
curl --fail-with-body \
'https://clientapi.retailgrid.io/v1/transactions/latest' \
-H "Authorization: Bearer $RETAILGRID_API_KEY"
store_id, a canonical organization store UUID:
curl --fail-with-body \
'https://clientapi.retailgrid.io/v1/transactions/latest?store_id=00000000-0000-0000-0000-00000000000b' \
-H "Authorization: Bearer $RETAILGRID_API_KEY"
{"item": null}
{
"item": {
"sku": null,
"region": null,
"sales_value": null,
"gross_profit": null,
"stock_after_sale": null,
"regular_price": null,
"promo_type": null,
"zone_price": null,
"external_transaction_id": null,
"unit_cost": null,
"discount_rate": null,
"currency": null,
"tax_rate": null,
"transaction_type": null,
"id": "00000000-0000-0000-0000-000000000003",
"item_id": "item-3",
"store_id": "00000000-0000-0000-0000-00000000000b",
"transaction_timestamp": "2026-01-01T22:30:00",
"quantity": "1.25",
"selling_price": "9.90"
}
}
Ordering and timezones
Selection orders bytransaction_timestamp DESC, id DESC, ignoring null dates.
For equal dates, the greatest canonical UUID string wins. updated_at, arrival
order and the requesting actor do not affect selection within the namespace.
BigQuery stores this field as DATETIME without an offset. Aware API inputs are
normalized to UTC before storage: 2026-01-02T00:30:00+02:00 and
2026-01-01T22:30:00Z both become 2026-01-01T22:30:00. Naive inputs retain their
supplied wall-clock value. Historical naive values have no recoverable original
timezone; the response does not invent a Z suffix or a client-local date.
Synchronization and cost
This maximum is not a lossless synchronization checkpoint. Resuming strictly after it can miss late arrivals, backdated records, corrections and equal timestamps. The deterministic ID tie-break does not solve those cases. Reconcile with supported transaction lists or exports; where usingupdated_since, overlap time windows and
apply records idempotently by transaction ID. Follow returned cursors with the same
selection and limit. The latest endpoint itself has no date-window filter.
The database filters, sorts and limits the result to one row; the application decodes
only that row. Each call can still scan historical partitions, and repeated calls
can each incur source-scan cost. LIMIT 1 is not a partition-pruning or low-cost
guarantee. Existing usage accounting and query ceilings apply; no uncapped fallback
or retained full export is created. Use asynchronous exports
for large extractions.
