POST Customer Updated
POST /v1/integrations/{integrationId}/events/customer.updated
Inbound customer upsert
Authentication
HMAC-SHA256 over timestamp + "." + rawBody. Headers: X-ROS-Signature, X-ROS-Timestamp, X-ROS-Event-Id, X-ROS-Key-Id. Replay window 5 minutes.
Required scope
customer.write — Inbound customer.updated also accepts event.write.
Headers
| Header | Required |
|---|---|
X-ROS-Signature | Yes — sha256=<hex> |
X-ROS-Timestamp | Yes — unix seconds |
X-ROS-Event-Id | Yes |
X-ROS-Key-Id | Yes |
Content-Type | application/json |
Path parameters
| Name | Example |
|---|---|
integrationId | int_demo_0001 |
Query parameters
None on this path.
Request body
{
"eventId": "evt_01HDEMOCUSTOMER",
"eventType": "customer.updated",
"schemaVersion": "1.0",
"integrationId": "int_demo_0001",
"merchantId": "merchant_demo",
"outletId": "outlet_demo",
"occurredAt": "2026-08-17T12:00:00.000Z",
"idempotencyKey": "cust_demo_v1",
"data": {
"externalCustomerId": "cust_demo_1",
"mobile": "+910000000099",
"firstName": "Asha",
"lastName": "Khan",
"source": "mock_restaurant_pos"
}
}
Example request
TS=$(date +%s)
RAW='{
"eventId": "evt_01HDEMOCUSTOMER",
"eventType": "customer.updated",
"schemaVersion": "1.0",
"integrationId": "int_demo_0001",
"merchantId": "merchant_demo",
"outletId": "outlet_demo",
"occurredAt": "2026-08-17T12:00:00.000Z",
"idempotencyKey": "cust_demo_v1",
"data": {
"externalCustomerId": "cust_demo_1",
"mobile": "+910000000099",
"firstName": "Asha",
"lastName": "Khan",
"source": "mock_restaurant_pos"
}
}'
SIG=$(printf '%s' "${TS}.${RAW}" | openssl dgst -sha256 -hmac "$ROS_API_SECRET" | awk '{print $2}')
curl -sS -X POST "https://api.restrosync.com/v1/integrations/$INTEGRATION_ID/events/customer.updated" \
-H "Content-Type: application/json" \
-H "X-ROS-Timestamp: $TS" \
-H "X-ROS-Signature: sha256=$SIG" \
-H "X-ROS-Key-Id: $KEY_ID" \
-H "X-ROS-Event-Id: $EVENT_ID" \
--data-binary "$RAW"const crypto = require('crypto');
const raw = JSON.stringify(payload);
const ts = Math.floor(Date.now() / 1000).toString();
const sig = crypto.createHmac('sha256', process.env.ROS_API_SECRET).update(ts + '.' + raw).digest('hex');import hmac, hashlib, time raw = payload_bytes ts = str(int(time.time())) sig = hmac.new(secret, (ts + '.' + (raw.decode() if raw else '')).encode(), hashlib.sha256).hexdigest()
Response
{
"success": true,
"data": {
"accepted": true
}
}
Errors
Typical: SIGNATURE_INVALID (401), DUPLICATE_EVENT / IDEMPOTENCY_CONFLICT (409), RATE_LIMITED (429). Catalogue: errors.
{
"success": false,
"error": {
"code": "SIGNATURE_INVALID",
"message": "Invalid signature",
"requestId": "req_demo"
}
}
Idempotency
Send JSON idempotencyKey (partners often search for header Idempotency-Key). Same key + same body returns the stored result. Same key + different body → IDEMPOTENCY_CONFLICT.
Retry behavior
Retry 5xx / 429 with the same idempotency key. Do not retry 4xx signature, schema, or duplicate conflicts.
Webhook relationship
This is an inbound POS → ROS path, signed with the API secret. Outbound ROS → partner delivery is X11 and uses the webhook secret. See webhooks.