Send an event batch
# The Grona SDK makes this call. Your code does not.# The body is gzip-compressed JSON, so compress it before you send it.gzip -c batch.json | curl https://api.grona.ai/v1/mobile/events \ -H 'Content-Type: application/json' \ -H 'Content-Encoding: gzip' \ --data-binary @-Called by the Grona SDK, not by your code.
The body is gzip-compressed JSON (Content-Encoding: gzip) with at most 50 events and
at most 64 KB before compression. The workspace key travels in the body. Grona
deduplicates events on event_id and corrects device clock skew using the time it
receives the batch minus sent_at.
How the SDK handles the response:
- Any
2xx: removes the batch from its queue. The response body is ignored. 429and503: honoursRetry-After.- Any other
4xx: drops the batch. - Other failures: retries at most 3 times with exponential backoff and jitter.
Parameters
Section titled “Parameters”Header Parameters
Section titled “Header Parameters”Request Bodyrequired
Section titled “Request Bodyrequired”object
Unix milliseconds, device clock.
On Android, the API level, such as 34.
object
Random UUID. Grona deduplicates on it.
Per-install counter, so gaps reveal lost events.
Unix milliseconds, device clock.
SDK-owned install id.
Opaque customer id, only when the shopper is identified. Never an email or a phone number.
The config the decision came from.
true while a preview pin is active. Excluded from analysis.
true only in demo mode. Excluded from analysis.
Type-specific fields, for example delivery and grant_jti on offer events, or
order_id, total_minor, currency, campaign_product_ids and treatments on
purchase.
object
Example
{ "schema": 1, "workspace": "acme-market", "sent_at": 1761681600123, "sdk_version": "0.1.0", "app_version": "4.2.0 (420)", "platform": "android", "os_version": 34, "events": [ { "event_id": "0f6b1c5e-2d8a-4b7e-9a51-3c2e7d9f4a10", "seq": 41, "type": "eligible", "trigger": "decision", "ts": 1761681598410, "session_id": "8c1d2e3f-4a5b-4c6d-8e7f-90a1b2c3d4e5", "install_id": "5e4d3c2b-1a09-4f8e-8d7c-6b5a49382716", "customer_id": "cus_7Hq2Lm9x", "config_version": 12, "campaign_id": "free-delivery-bar", "variant_id": "progress-bar", "arm": "treatment", "unit": "install", "placement": "home_top" } ]}Responses
Section titled “Responses”Too many requests. Retry with exponential backoff and jitter, and wait at least as long
as Retry-After when it is present. Branch on the status code; the body is not
guaranteed to use the error envelope.
Headers
Section titled “Headers”How long to wait before retrying, in seconds or as an HTTP date.
Temporarily unavailable. Retry with exponential backoff and jitter, and wait at least as
long as Retry-After when it is present. Branch on the status code; the body is not
guaranteed to use the error envelope.
Headers
Section titled “Headers”How long to wait before retrying, in seconds or as an HTTP date.
Accepted. The SDK removes the batch and ignores the body.
The SDK drops the batch.
The SDK retries at most 3 times with backoff.