Web-Hooks

Aarthik Labs uses one shared web-hook system across borrower experiences.

Hosted Experience and Hybrid Experience use the same web-hook contract. Your back-end can build one receiver and handle events consistently across both Aarthik-powered credit journeys.

Web-hooks are back-end-to-back-end notifications. Use them as the durable signal for journey state, reconciliation, support workflows, notifications, analytics, and post-disbursal servicing.

Where This Applies

ExperienceHow web-hooks apply
Hosted ExperienceAarthik Labs owns the borrower-facing journey after your app opens the embedded URL. Web-hooks keep your back-end updated.
Hybrid ExperienceYour product owns the borrower UI until offer selection, then the borrower may move into Hosted Experience. Web-hooks continue across both surfaces.

Your receiver does not need to be split by experience. Use origin_experience, current_experience_surface, tenant_id, application_id, and borrower.journey.type to route events inside your own systems.

Delivery Contract

ItemValue
MethodPOST
Content typeapplication/json
Event typejourney.snapshot
ReceiverYour back-end-owned HTTPS web-hook URL
AuthenticationHMAC signature using the shared web-hook secret configured for your application
BodyCanonical Aarthik Labs OutBound journey snapshot
Delivery modelAt-least-once delivery; your receiver should be idempotent

Subscription APIs

Use the web-hook subscription APIs from your back-end to manage the callback URL for an application. Authenticate with the platform API key for the same tenant/application scope.

ActionEndpoint
Read ConfigurationGET /api/tenants/{tenantID}/applications/{applicationID}/webhooks/configuration
SubscribePOST /api/tenants/{tenantID}/applications/{applicationID}/webhooks/subscribe
Un-SubscribePOST /api/tenants/{tenantID}/applications/{applicationID}/webhooks/unsubscribe

Read Configuration returns the currently active web-hook status and callback URL for the application.

Subscribe accepts an HTTPS url and enables delivery for journey.snapshot events.

1{
2 "url": "https://partner.example.com/webhooks/aarthik-labs"
3}

Un-Subscribe does not require a request body. It disables delivery for the application, clears the callback URL, and disables the stored signing secret. After this call succeeds, Aarthik Labs stops sending web-hooks for that tenant/application until Subscribe is called again.

Delivery Headers

HeaderPurpose
X-AL-Event-IDStable identifier for the journey snapshot event. Store this for deduplication.
X-AL-Tenant-IDTenant that owns the journey.
X-AL-Application-IDApplication that owns the web-hook configuration.
X-AL-Webhook-TimestampTimestamp used while computing the signature.
X-AL-Webhook-SignatureSignature value in the format t=<timestamp>,v1=<hmac_sha256_hex>.

Payload Shape

The request body is the latest OutBound snapshot for the borrower journey. It includes experience metadata, tenant/application identifiers, borrower profile data, journey status, lender state, offer state, and repayment schedule data when available.

A shortened example:

1{
2 "origin_experience": "HYBRID",
3 "current_experience_surface": "HOSTED",
4 "handoff": {
5 "state": "CONSUMED",
6 "target_offer_id": "offer_123",
7 "target_journey_id": "journey_123",
8 "target_hosted_path": "/lab/loan-details",
9 "issued_at": "2026-05-04T10:00:00.000Z",
10 "consumed_at": "2026-05-04T10:02:00.000Z",
11 "expired_at": null
12 },
13 "tenant_id": "tenant_123",
14 "application_id": "application_123",
15 "borrower": {
16 "id": "borrower_123",
17 "provider_id": "customer_001",
18 "profile": {
19 "personal": {
20 "pan": "ABCDE1234F",
21 "panName": "Example Customer",
22 "dob": "1992-01-31",
23 "gender": "male",
24 "personalemail": "customer@example.com",
25 "contactNumber": "+919999999999"
26 },
27 "work": {
28 "employmentType": "salaried",
29 "officialemail": null,
30 "income": 750000,
31 "companyName": "Example Pvt Ltd",
32 "udyamNumber": null
33 },
34 "address": {
35 "addressL1": "Address line 1",
36 "addressL2": null,
37 "city": "Mumbai",
38 "state": "Maharashtra",
39 "pincode": "400001"
40 }
41 },
42 "journey": {
43 "id": "journey_123",
44 "type": "PERSONAL_LOAN",
45 "status": "OFFER_ACCEPTED",
46 "selection_state": "LOCKED",
47 "activity_status": "ACTIVE",
48 "decision_status": "APPROVED",
49 "lender_mode": "ONLINE",
50 "kyc_status": "SUCCESS",
51 "emandate_status": "PENDING",
52 "esign_status": "PENDING",
53 "change_in_offer": false,
54 "borrower_preferred_amount": 300000,
55 "borrower_preferred_tenure": 12,
56 "lenders": [],
57 "offers": []
58 }
59 }
60}

The exact fields that are populated depend on the credit product, journey stage, lender mode, borrower progress, and whether the borrower has crossed from one experience surface to another.

Experience Fields

FieldMeaning
origin_experienceThe experience where the journey originally started. For the experiences documented here, this is HOSTED or HYBRID.
current_experience_surfaceThe surface that currently owns borrower progression. For Hybrid journeys, this can move from API to HOSTED after handoff.
handoffMetadata for a cross-surface handoff. It is null when no handoff has happened yet.

Lifecycle Statuses

The snapshot includes the latest public journey status. Do not assume every journey will emit every status; the path depends on product, lender, eligibility, redirect behavior, and post-disbursal actions.

StatusMeaning
STARTEDThe borrower journey was created or resumed.
PROFILEDBorrower profile information has been captured for offer discovery.
OFFEREDOne or more offers or actionable offer states are available.
NOT_OFFEREDOffer discovery completed without an eligible offer.
OFFER_SELECTEDThe borrower selected an offer.
OFFER_ACCEPTEDThe selected offer moved into downstream acceptance.
LENDER_REDIRECTEDThe borrower entered a lender-managed redirect step.
REJECTEDThe selected-offer journey ended without disbursal.
DISBURSEDThe loan journey completed successfully and disbursal was reached.

Delivery Flow

Signature Verification

Every delivery includes X-AL-Webhook-Timestamp and X-AL-Webhook-Signature.

To verify the signature:

  1. Read the timestamp from X-AL-Webhook-Timestamp.
  2. Parse the v1 value from X-AL-Webhook-Signature.
  3. Canonicalize the parsed JSON body by sorting object keys recursively and removing undefined values.
  4. Compute HMAC-SHA256 over <timestamp>.<canonical-json-body> using your shared web-hook secret.
  5. Compare the computed digest with the v1 digest using a timing-safe comparison.

Reject the event if the signature is missing, invalid, or outside the timestamp tolerance you enforce.

Receiver Checklist

Your web-hook endpoint should:

  • accept POST requests over HTTPS
  • verify the Aarthik Labs signature before trusting the payload
  • deduplicate using X-AL-Event-ID
  • persist the snapshot against your borrower, lead, application, or loan record
  • process events idempotently
  • return 2xx only after the event has been accepted for processing
  • keep long-running downstream work outside the request-response path

Polling And Web-Hooks

Frontend polling, bridge events, or browser callbacks can help your UI react while the borrower is actively on screen. Web-hooks are the back-end source of truth for events that may happen after the borrower closes the screen, completes an external lender step, returns later, or moves into post-disbursal servicing.

Operational Notes

  • Web-hook configuration is application-scoped.
  • The receiver URL must use HTTPS.
  • Failed deliveries can be retried. Treat delivery as at-least-once, not exactly-once.
  • Network failures, timeouts, rate limits, and temporary server errors should be handled idempotently by your receiver.
  • Keep borrower notifications separate from delivery acknowledgement so a retry does not accidentally notify a borrower twice.
  • Monitor delivery failures and reconciliation gaps so your internal state does not silently drift from the Aarthik Labs journey state.