POST Bill Created

POST /v1/integrations/{integrationId}/events/bill.created

Bill Created

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

bill.write (or event.write)

Headers

HeaderRequired
X-ROS-SignatureYes — sha256=<hex>
X-ROS-TimestampYes — unix seconds
X-ROS-Event-IdYes
X-ROS-Key-IdYes
Content-Typeapplication/json

Path parameters

NameExample
integrationIdint_demo_0001

Query parameters

None on this path.

Request body

{
  "eventId": "evt_01HDEMOBILL",
  "eventType": "bill.created",
  "schemaVersion": "1.0",
  "integrationId": "int_demo_0001",
  "occurredAt": "2026-08-17T12:00:00.000Z",
  "idempotencyKey": "bill_1480_created_v1",
  "data": {
    "externalBillId": "bill_1480",
    "billNumber": "MOCK-1480",
    "items": [
      {
        "name": "Chicken Tikka",
        "quantity": 2,
        "unitPriceMinor": 50000,
        "totalMinor": 100000
      },
      {
        "name": "Beer",
        "quantity": 2,
        "unitPriceMinor": 15000,
        "totalMinor": 30000
      },
      {
        "name": "Fries",
        "quantity": 1,
        "unitPriceMinor": 18000,
        "totalMinor": 18000
      }
    ],
    "totalMinor": 148000,
    "currency": "INR",
    "status": "COMPLETED",
    "vendorStatus": "closed",
    "rosStatus": "COMPLETED"
  }
}

Example request

TS=$(date +%s)
RAW='{
  "eventId": "evt_01HDEMOBILL",
  "eventType": "bill.created",
  "schemaVersion": "1.0",
  "integrationId": "int_demo_0001",
  "occurredAt": "2026-08-17T12:00:00.000Z",
  "idempotencyKey": "bill_1480_created_v1",
  "data": {
    "externalBillId": "bill_1480",
    "billNumber": "MOCK-1480",
    "items": [
      {
        "name": "Chicken Tikka",
        "quantity": 2,
        "unitPriceMinor": 50000,
        "totalMinor": 100000
      },
      {
        "name": "Beer",
        "quantity": 2,
        "unitPriceMinor": 15000,
        "totalMinor": 30000
      },
      {
        "name": "Fries",
        "quantity": 1,
        "unitPriceMinor": 18000,
        "totalMinor": 18000
      }
    ],
    "totalMinor": 148000,
    "currency": "INR",
    "status": "COMPLETED",
    "vendorStatus": "closed",
    "rosStatus": "COMPLETED"
  }
}'
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/bill.created" \
  -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.