RCS Events
When a partner customer applies for RCS via
POST /partner/customers/{customer_id}/rcs/apply,
the submission queues for admin review. The moment admin approves or
rejects it, we POST an event to the account-level webhook URL you
configured under Settings → Webhook URL on the partner panel.
These events do not flow through the per-config-set destinations —
that surface is email-only. RCS events use the same channel as
production_access.approved and account.deletion.requested.
Event types
| Event | When |
|---|---|
rcs_kyc.approved | Admin approved the customer’s RCS KYC. RCS sender registration follows. |
rcs_kyc.rejected | Admin rejected the submission. data.rejection_reason explains why. Re-call apply with a corrected payload to resubmit. |
Envelope
Account-level webhooks share this envelope (different from the email events’ SES-shaped envelope — same headers, different body):
{
"event_type": "rcs_kyc.approved",
"partner_id": "11111111-2222-3333-4444-555555555555",
"occurred_at": "2026-05-21T07:04:11.482Z",
"data": { /* event-specific, see below */ }
}rcs_kyc.approved payload
{
"event_type": "rcs_kyc.approved",
"partner_id": "11111111-2222-3333-4444-555555555555",
"occurred_at": "2026-05-21T07:04:11.482Z",
"data": {
"customer_id": "8f3b2a1e-49d8-4c2d-9e1a-b7e6d5f8a3c2",
"customer_name": "Acme Corporation",
"customer_email": "[email protected]",
"customer_phone": "+919876543210",
"status": "approved",
"rejection_reason": "",
"reviewed_by": "[email protected]",
"reviewed_at": "2026-05-21T07:04:11.482Z",
"submitted_at": "2026-05-20T10:18:42.000Z"
}
}rcs_kyc.rejected payload
{
"event_type": "rcs_kyc.rejected",
"partner_id": "11111111-2222-3333-4444-555555555555",
"occurred_at": "2026-05-21T07:04:11.482Z",
"data": {
"customer_id": "8f3b2a1e-49d8-4c2d-9e1a-b7e6d5f8a3c2",
"customer_name": "Acme Corporation",
"customer_email": "[email protected]",
"customer_phone": "+919876543210",
"status": "rejected",
"rejection_reason": "Bot logo is 512×512; we need 224×224 JPEG ≤ 50 KB.",
"reviewed_by": "[email protected]",
"reviewed_at": "2026-05-21T07:04:11.482Z",
"submitted_at": "2026-05-20T10:18:42.000Z"
}
}Headers
Same headers as all account-level webhooks:
| Header | Value / purpose |
|---|---|
Content-Type | application/json |
User-Agent | Splashify-Pro-Webhook/1.0 |
X-Splashify-Event | rcs_kyc.approved or rcs_kyc.rejected |
X-Splashify-Delivery-ID | UUID per delivery attempt — use for idempotency |
X-Splashify-Timestamp | Unix seconds — replay protection |
Signature verification (
X-Splashify-Signature) is only emitted by the email-events surface today. RCS events arrive unsigned over HTTPS; whitelist the source by domain if you need stricter authentication.
Handler example (Node)
app.post("/webhooks/splashify", express.json(), (req, res) => {
const event = req.headers["x-splashify-event"];
const { partner_id, occurred_at, data } = req.body;
switch (event) {
case "rcs_kyc.approved":
await db.customers.update(data.customer_id, {
rcs_status: "approved",
rcs_approved_at: data.reviewed_at,
});
break;
case "rcs_kyc.rejected":
await db.customers.update(data.customer_id, {
rcs_status: "rejected",
rcs_rejection_reason: data.rejection_reason,
});
await notifyTeam(`RCS rejected for ${data.customer_email}: ${data.rejection_reason}`);
break;
}
res.status(200).end();
});Delivery semantics
- Fire-and-forget. Admin’s approve/reject action commits regardless of whether your webhook returns 2xx. A failed delivery doesn’t block the status flip.
- No retries on this surface. Account-level webhooks log 4xx/5xx
responses but do not retry. Keep your endpoint healthy, or poll
GET /partner/customers/{customer_id}/rcs/statusas a fallback. - 10 s timeout. If your endpoint takes longer to respond, the request is cancelled and logged as a delivery failure.
- Order is not guaranteed. Don’t assume
rcs_kyc.approvedarrives beforercs_kyc.rejectedfor the same customer in a re-review scenario. Always trustdata.statusandoccurred_at.
Idempotency
Same delivery ID retried (e.g. by a manual replay tool — coming) will
carry the same X-Splashify-Delivery-ID. De-dupe on it.
For the underlying event itself, the tuple
(partner_id, data.customer_id, data.status, occurred_at) is unique —
two reviews of the same submission produce two events with different
occurred_at.