Agent skill
Smile API Webhooks Skill
Receive and verify Smile API (getsmileapi.com) webhooks. Use when setting up a Smile webhook endpoint, verifying the Smile-Signature header (HMAC-SHA512 hex over the raw body), debugging Smile signature verification failures, or handling employment/income data events like ACCOUNT_CONNECTED, TASK_FINISHED, INCOMES_ADDED, EMPLOYMENTS_ADDED, IDENTITY_ADDED, and RECORD_COMPLETED. This is Smile API for Southeast Asian employment/income data — NOT Smile.io loyalty and NOT Smile Identity KYC.
Install this skill
npx skills add hookdeck/webhook-skills --skill smile-webhooks
Smile API (getsmileapi.com) is an employment, income, and financial-data aggregator for Southeast Asia (Philippines-focused). It POSTs JSON webhooks to your HTTPS endpoint when a user connects an account, a task finishes, or new data is added. Each delivery carries a Smile-Signature header you verify with HMAC-SHA512 (hex) over the raw request body.
Not Smile.io (loyalty/rewards) and not Smile Identity (KYC). The signature header is
Smile-Signature(noX-prefix) and the algorithm is SHA-512, not SHA-256. Smile does not use the Standard Webhooks spec.
When to Use This Skill
- How do I receive Smile API (getsmileapi.com) webhooks?
- How do I verify the
Smile-Signatureheader? - Why is my Smile webhook signature verification failing?
- How do I handle
ACCOUNT_CONNECTED,TASK_FINISHED, orINCOMES_ADDEDevents? - How do I dedupe Smile webhook retries?
Verification (core)
Smile computes HMAC-SHA512(secret, rawBody) and hex-encodes it. The secret is the per-endpoint value you set when registering the webhook (1–64 chars). Digest the entire raw body with no leading/trailing whitespace — never the re-serialized parsed JSON. Compare in constant time.
const crypto = require('crypto');
// Verify the Smile-Signature header: HMAC-SHA512 hex over the RAW request body.
function verifySmileSignature(rawBody, signatureHeader, secret) {
const expected = crypto
.createHmac('sha512', secret)
.update(rawBody) // Buffer/raw string — NOT JSON.stringify(parsed)
.digest('hex');
const received = Buffer.from(String(signatureHeader || ''), 'utf8');
const computed = Buffer.from(expected, 'utf8');
// timingSafeEqual throws on length mismatch — guard first.
return (
received.length === computed.length &&
crypto.timingSafeEqual(received, computed)
);
}
Verify before parsing JSON, then dispatch on the type field. There is no official Smile SDK, so all three framework examples verify manually.
For complete handlers with signature verification, event dispatch, error responses, and tests, see:
Common Event Types
The event name is the type field inside the JSON body (UPPER_SNAKE_CASE):
type | Triggered when |
|---|---|
ACCOUNT_CONNECTED | A user successfully connects a data-source account |
ACCOUNT_DISCONNECTED | A connected account is disconnected |
TASK_FINISHED | A data-collection task completes (supports includePayload) |
IDENTITY_ADDED | Identity data is added for a user |
INCOMES_ADDED | Income records are added |
EMPLOYMENTS_ADDED | Employment records are added |
RECORD_COMPLETED | A record is fully collected and completed |
Smile emits ~35 event types (many with
_ADDED/_UPDATEDvariants — e.g.TRANSACTIONS_ADDED,DOCUMENTS_UPDATED,EINCOMES_ADDED,CONTRIBUTIONS_ADDED,LIABILITIES_ADDED). Subscribe toALL_EVENTSto receive everything. See references/overview.md for the full list.
Environment Variables
# Per-endpoint webhook secret (1-64 chars) set when you register the webhook.
# Used as the HMAC-SHA512 key.
SMILE_WEBHOOK_SECRET=your_webhook_secret
Delivery & Idempotency
- At-least-once delivery. A non-2xx response is retried up to 2 times, a few seconds apart. Dedupe on the event
idso retried deliveries are safe. includePayload(optional,TASK_FINISHED/ACCOUNT_SYNC_TASK_FINISHEDonly) inlines the full data — up to 300 list items — into thedataobject.- Deliveries originate from the static IP
18.142.61.230over HTTPS only — you may allowlist it as a defense-in-depth layer in addition to signature verification.
Local Development
# Start tunnel (no account needed)
npx hookdeck-cli listen 3000 smile --path /webhooks/smile
No account required — the CLI creates a guest account and provides a local tunnel plus a web UI for inspecting requests.
Reference Materials
- references/overview.md - What Smile webhooks are, the full event list, payload shape
- references/setup.md - Registering webhooks (portal + API), the secret, includePayload
- references/verification.md - HMAC-SHA512 verification details and gotchas