Web-Hooks (V2)

Web-Hooks (V2) is the cleaner customer-facing web-hook payload for Hybrid Experience journey lifecycle updates.

It keeps the same delivery model as existing Aarthik Labs web-hooks:

  • Aarthik Labs sends POST requests to your configured HTTPS web-hook URL.
  • The event type remains journey.snapshot.
  • Deliveries are signed with the existing Aarthik Labs web-hook signature headers.
  • Delivery is at least once, so your receiver should be idempotent.

The main difference is the body. V2 sends a cleaner, stage-aware payload that includes only the information that is useful for the lifecycle stage being delivered.

In this page, AA means Account Aggregator.

V2 is opt-in and enabled by Aarthik Labs at the application level. Applications that are not enabled continue receiving the existing web-hook payload.

Delivery Contract

ItemValue
MethodPOST
Content typeapplication/json
Event typejourney.snapshot
Delivery modelAt least once
ReceiverYour back-end-owned HTTPS web-hook URL
AuthenticationHMAC signature using the shared web-hook secret configured for your application
Idempotency keyX-AL-Event-ID

Delivery Headers

Every V2 delivery uses the same delivery headers as existing web-hooks.

HeaderMeaning
X-AL-Event-IDStable identifier for the delivered event. Store it and use it 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>.

For signature verification details, use the same process described in Web-Hooks.

Top-Level Envelope

Every V2 payload uses this top-level envelope.

1{
2 "request_id": "event-id",
3 "correlation_id": "event-id",
4 "timestamp": "2026-05-12T10:10:00.000Z",
5 "tenant_id": "tenant-id",
6 "application_id": "application-id",
7 "tenantID": "tenant-id",
8 "applicationID": "application-id",
9 "data": {
10 "status": "OFFERED"
11 },
12 "error": null
13}
FieldMeaning
request_idIdentifier for this delivery.
correlation_idIdentifier you can use to correlate related deliveries and logs.
timestampISO timestamp when the payload was created.
tenant_id, tenantIDTenant identifier. Both keys carry the same value.
application_id, applicationIDApplication identifier. Both keys carry the same value.
data.statusLifecycle stage represented by this snapshot.
errorAlways null for successful lifecycle snapshots.

Use whichever naming style fits your system. For example, JavaScript systems may prefer tenantID, while data warehouses may prefer tenant_id.

Lifecycle Stages

Hybrid Experience can send the following V2 lifecycle stages.

StatusMeaning
STARTEDThe borrower journey has been created and offer discovery has started.
PROFILEDBorrower profile details are available for offer discovery.
ACCOUNT_AGGREGATORAn Account Aggregator URL is available for the borrower.
OFFEREDOne or more offers are available. This can happen once for non-AA offers and again later for AA-backed offers.
NOT_OFFEREDOffer discovery completed without an eligible offer for the relevant path.
OFFER_ACCEPTEDThe borrower accepted an offer.
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.

Hybrid Offer Paths

A Hybrid journey can receive both non-AA and AA updates.

Common paths include:

  • non-AA offers arrive, then the borrower accepts a non-AA offer
  • non-AA offers arrive, then an Account Aggregator URL becomes available, then AA-backed offers arrive
  • no non-AA offers arrive, then an Account Aggregator URL becomes available, then AA-backed offers arrive
  • no eligible offers arrive after all relevant offer discovery paths complete

Because AA-backed offers can arrive after earlier non-AA offers, your receiver should treat OFFERED as additive. A later OFFERED payload can contain new offers for the same journey.

Stage Contents

V2 includes only the sections that make sense for the lifecycle stage being delivered.

StatusjourneyborrowerlendersoffersaccountAggregator / account_aggregatorinstallments
STARTEDMinimalNoNoNoNoNo
PROFILEDProfiledYesNoNoNoNo
ACCOUNT_AGGREGATORFullYesYesCurrent visible offers when presentYesNo
OFFEREDFullYesYesYesNoNo
NOT_OFFEREDFullYesLender metadata onlyNoNoNo
OFFER_ACCEPTEDFullYesYesYesNoNo
LENDER_REDIRECTEDFullYesYesYesNoNo
REJECTEDFullYesYesKnown offers when presentNoNo
DISBURSEDFullYesYesYesNoYes

Missing sections are intentionally absent for that stage. For example, if a PROFILED payload does not include lenders, it does not mean lender data was deleted. It means lender data is not part of the PROFILED snapshot.

STARTED Shape

STARTED is intentionally small. It confirms that the journey exists.

1{
2 "request_id": "event-id",
3 "correlation_id": "event-id",
4 "timestamp": "2026-05-12T10:00:00.000Z",
5 "tenant_id": "tenant-id",
6 "application_id": "application-id",
7 "tenantID": "tenant-id",
8 "applicationID": "application-id",
9 "data": {
10 "status": "STARTED",
11 "journey": {
12 "id": "journey-id",
13 "status": "STARTED",
14 "type": "PERSONAL_LOAN",
15 "created": "2026-05-12T10:00:00.000Z",
16 "updated": "2026-05-12T10:00:00.000Z",
17 "decisionStatus": null,
18 "ondcTransactionIds": {}
19 }
20 },
21 "error": null
22}

PROFILED Shape

PROFILED adds borrower profile information.

1{
2 "request_id": "event-id",
3 "correlation_id": "event-id",
4 "timestamp": "2026-05-12T10:01:00.000Z",
5 "tenant_id": "tenant-id",
6 "application_id": "application-id",
7 "tenantID": "tenant-id",
8 "applicationID": "application-id",
9 "data": {
10 "status": "PROFILED",
11 "journey": {
12 "id": "journey-id",
13 "status": "PROFILED",
14 "type": "PERSONAL_LOAN",
15 "endUse": "education",
16 "bureauConsent": true,
17 "created": "2026-05-12T10:00:00.000Z",
18 "updated": "2026-05-12T10:01:00.000Z",
19 "decisionStatus": null,
20 "ondcTransactionIds": {}
21 },
22 "borrower": {
23 "id": "borrower-id",
24 "provider_id": "partner-borrower-id",
25 "providerID": "partner-borrower-id",
26 "profile": {
27 "personal": {
28 "pan": "ABCDE1234F",
29 "panName": "Jane Doe",
30 "dob": "1990-01-01",
31 "gender": "female",
32 "personalemail": "jane@example.com",
33 "contactNumber": "+919999999999"
34 },
35 "work": {
36 "employmentType": "salaried",
37 "officialemail": "jane@work.example",
38 "income": 550000,
39 "companyName": "Acme Corp",
40 "udyamNumber": null
41 },
42 "address": {
43 "addressL1": "Line 1",
44 "addressL2": null,
45 "city": "Mumbai",
46 "state": "MH",
47 "pincode": "400001"
48 }
49 }
50 }
51 },
52 "error": null
53}

ACCOUNT_AGGREGATOR Shape

ACCOUNT_AGGREGATOR is sent when an Account Aggregator URL is available for the borrower.

This stage includes both naming styles:

  • accountAggregator.expiresAt
  • account_aggregator.expires_at

Both objects carry the same values.

1{
2 "request_id": "event-id",
3 "correlation_id": "event-id",
4 "timestamp": "2026-05-12T10:10:00.000Z",
5 "tenant_id": "tenant-id",
6 "application_id": "application-id",
7 "tenantID": "tenant-id",
8 "applicationID": "application-id",
9 "data": {
10 "status": "ACCOUNT_AGGREGATOR",
11 "accountAggregator": {
12 "url": "https://credit.aarthiklabs.com/lab/account-aggregator?token=...",
13 "expiresAt": "2026-05-12T10:40:00.000Z",
14 "lenders": ["AA Bank"]
15 },
16 "account_aggregator": {
17 "url": "https://credit.aarthiklabs.com/lab/account-aggregator?token=...",
18 "expires_at": "2026-05-12T10:40:00.000Z",
19 "lenders": ["AA Bank"]
20 },
21 "journey": {
22 "id": "journey-id",
23 "status": "ACCOUNT_AGGREGATOR",
24 "type": "PERSONAL_LOAN",
25 "endUse": "education",
26 "bureauConsent": true,
27 "created": "2026-05-12T10:00:00.000Z",
28 "updated": "2026-05-12T10:10:00.000Z",
29 "decisionStatus": null,
30 "kycStatus": "PENDING",
31 "kycAttempts": 1,
32 "emandateStatus": null,
33 "emandateAttempts": null,
34 "esignStatus": null,
35 "esignAttempts": null,
36 "changeInOffer": false,
37 "borrowerPreferredAmount": 200000,
38 "borrowerPreferredTenure": 12,
39 "ondcTransactionIds": {
40 "bpp.id.of.lender": "ondc-tx-id"
41 }
42 },
43 "borrower": {
44 "id": "borrower-id",
45 "provider_id": "partner-borrower-id",
46 "providerID": "partner-borrower-id",
47 "profile": {
48 "personal": {
49 "pan": "ABCDE1234F",
50 "panName": "Jane Doe",
51 "dob": "1990-01-01",
52 "gender": "female",
53 "personalemail": "jane@example.com",
54 "contactNumber": "+919999999999"
55 },
56 "work": {
57 "employmentType": "salaried",
58 "officialemail": "jane@work.example",
59 "income": 550000,
60 "companyName": "Acme Corp",
61 "udyamNumber": null
62 },
63 "address": {
64 "addressL1": "Line 1",
65 "addressL2": null,
66 "city": "Mumbai",
67 "state": "MH",
68 "pincode": "400001"
69 }
70 }
71 },
72 "lenders": {
73 "AA Bank": {
74 "id": "bpp.id.of.lender",
75 "minimumLoanAmount": "50000.00",
76 "maximumLoanAmount": "5000000.00",
77 "configuration": {
78 "mode": "ONLINE",
79 "redirectionType": "SINGLE",
80 "loanAmountAdjustmentAllowed": true
81 },
82 "gro": {
83 "name": null,
84 "email": null,
85 "contactNumber": null,
86 "designation": null,
87 "address": null
88 },
89 "customerSupport": {
90 "link": null,
91 "contactNumber": null,
92 "email": null
93 },
94 "offers": []
95 }
96 }
97 },
98 "error": null
99}

Only ACCOUNT_AGGREGATOR includes accountAggregator and account_aggregator.

OFFERED Shape

OFFERED includes lenders and offers that are available for the borrower.

1{
2 "request_id": "event-id",
3 "correlation_id": "event-id",
4 "timestamp": "2026-05-12T10:20:00.000Z",
5 "tenant_id": "tenant-id",
6 "application_id": "application-id",
7 "tenantID": "tenant-id",
8 "applicationID": "application-id",
9 "data": {
10 "status": "OFFERED",
11 "lenders": {
12 "Non-AA Bank": {
13 "id": "bpp.id.of.lender",
14 "minimumLoanAmount": "50000.00",
15 "maximumLoanAmount": "5000000.00",
16 "configuration": {
17 "mode": "ONLINE",
18 "redirectionType": "SINGLE",
19 "loanAmountAdjustmentAllowed": true
20 },
21 "gro": {
22 "name": "Name",
23 "email": "gro@example.com",
24 "contactNumber": "+919999999999",
25 "designation": "Manager",
26 "address": "Address"
27 },
28 "customerSupport": {
29 "link": "https://example.com/support",
30 "contactNumber": "+919999999999",
31 "email": "support@example.com"
32 },
33 "offers": [
34 {
35 "offerID": "offer-id",
36 "consentHandleAvailable": false,
37 "installmentAmount": null,
38 "ltvRatio": null,
39 "status": "OFFER_RECEIVED",
40 "periods": {
41 "offerTerm": "12 Months",
42 "coolOffPeriod": "3 Days"
43 },
44 "interest": {
45 "rate": "12.50",
46 "type": "Fixed"
47 },
48 "amounts": {
49 "principal": "460000",
50 "totalInterestPayable": "15000",
51 "netDisbursedAmount": "480000"
52 },
53 "annualPercentageRate": "14.10",
54 "ondcTransactionID": "ondc-tx-id",
55 "accepted": false,
56 "expired": false,
57 "documents": {
58 "termsAndConditionsLink": "https://example.com/terms",
59 "keyFactsStatementLink": "https://example.com/kfs"
60 },
61 "chargesAndFees": {
62 "applicationFees": "0",
63 "foreclosureFees": "0",
64 "interestRateConversionCharges": "0",
65 "delayPenaltyFees": "0",
66 "otherPenaltyFees": "0",
67 "processingFees": "999",
68 "otherUpfrontCharges": "0",
69 "insuranceCharges": "0",
70 "otherCharges": "0"
71 },
72 "numberOfInstallments": 12
73 }
74 ]
75 }
76 },
77 "journey": {
78 "id": "journey-id",
79 "status": "OFFERED",
80 "type": "PERSONAL_LOAN",
81 "endUse": "education",
82 "bureauConsent": true,
83 "created": "2026-05-12T10:00:00.000Z",
84 "updated": "2026-05-12T10:20:00.000Z",
85 "decisionStatus": null,
86 "kycStatus": "PENDING",
87 "kycAttempts": 1,
88 "emandateStatus": null,
89 "emandateAttempts": null,
90 "esignStatus": null,
91 "esignAttempts": null,
92 "changeInOffer": false,
93 "borrowerPreferredAmount": 200000,
94 "borrowerPreferredTenure": 12,
95 "ondcTransactionIds": {
96 "bpp.id.of.lender": "ondc-tx-id"
97 }
98 },
99 "borrower": {
100 "id": "borrower-id",
101 "provider_id": "partner-borrower-id",
102 "providerID": "partner-borrower-id",
103 "profile": {
104 "personal": {
105 "pan": "ABCDE1234F",
106 "panName": "Jane Doe",
107 "dob": "1990-01-01",
108 "gender": "female",
109 "personalemail": "jane@example.com",
110 "contactNumber": "+919999999999"
111 },
112 "work": {
113 "employmentType": "salaried",
114 "officialemail": "jane@work.example",
115 "income": 550000,
116 "companyName": "Acme Corp",
117 "udyamNumber": null
118 },
119 "address": {
120 "addressL1": "Line 1",
121 "addressL2": null,
122 "city": "Mumbai",
123 "state": "MH",
124 "pincode": "400001"
125 }
126 }
127 }
128 },
129 "error": null
130}

NOT_OFFERED Shape

NOT_OFFERED includes journey, borrower, and lender metadata. It does not include an offers array.

1{
2 "request_id": "event-id",
3 "correlation_id": "event-id",
4 "timestamp": "2026-05-12T10:20:00.000Z",
5 "tenant_id": "tenant-id",
6 "application_id": "application-id",
7 "tenantID": "tenant-id",
8 "applicationID": "application-id",
9 "data": {
10 "status": "NOT_OFFERED",
11 "lenders": {
12 "Non-AA Bank": {
13 "id": "bpp.id.of.lender",
14 "minimumLoanAmount": "50000.00",
15 "maximumLoanAmount": "5000000.00",
16 "configuration": {
17 "mode": "ONLINE",
18 "redirectionType": "SINGLE",
19 "loanAmountAdjustmentAllowed": true
20 },
21 "gro": {
22 "name": "Name",
23 "email": "gro@example.com",
24 "contactNumber": "+919999999999",
25 "designation": "Manager",
26 "address": "Address"
27 },
28 "customerSupport": {
29 "link": "https://example.com/support",
30 "contactNumber": "+919999999999",
31 "email": "support@example.com"
32 }
33 }
34 },
35 "journey": {
36 "id": "journey-id",
37 "status": "NOT_OFFERED",
38 "type": "PERSONAL_LOAN",
39 "endUse": "education",
40 "bureauConsent": true,
41 "created": "2026-05-12T10:00:00.000Z",
42 "updated": "2026-05-12T10:20:00.000Z",
43 "decisionStatus": null,
44 "kycStatus": "PENDING",
45 "kycAttempts": 1,
46 "emandateStatus": null,
47 "emandateAttempts": null,
48 "esignStatus": null,
49 "esignAttempts": null,
50 "changeInOffer": false,
51 "borrowerPreferredAmount": 200000,
52 "borrowerPreferredTenure": 12,
53 "ondcTransactionIds": {
54 "bpp.id.of.lender": "ondc-tx-id"
55 }
56 },
57 "borrower": {
58 "id": "borrower-id",
59 "provider_id": "partner-borrower-id",
60 "providerID": "partner-borrower-id",
61 "profile": {
62 "personal": {
63 "pan": "ABCDE1234F",
64 "panName": "Jane Doe",
65 "dob": "1990-01-01",
66 "gender": "female",
67 "personalemail": "jane@example.com",
68 "contactNumber": "+919999999999"
69 },
70 "work": {
71 "employmentType": "salaried",
72 "officialemail": "jane@work.example",
73 "income": 550000,
74 "companyName": "Acme Corp",
75 "udyamNumber": null
76 },
77 "address": {
78 "addressL1": "Line 1",
79 "addressL2": null,
80 "city": "Mumbai",
81 "state": "MH",
82 "pincode": "400001"
83 }
84 }
85 }
86 },
87 "error": null
88}

OFFER_ACCEPTED, LENDER_REDIRECTED, And REJECTED Shapes

These stages use the same broad structure as OFFERED:

  • journey
  • borrower
  • lenders
  • offers, when offers are known for the journey

The main changes are the stage in data.status and journey.status, plus the latest offer flags and verification fields.

For example, an accepted-offer snapshot marks the accepted offer with accepted: true.

1{
2 "data": {
3 "status": "OFFER_ACCEPTED",
4 "lenders": {
5 "Selected Bank": {
6 "id": "bpp.id.of.lender",
7 "minimumLoanAmount": "50000.00",
8 "maximumLoanAmount": "5000000.00",
9 "configuration": {
10 "mode": "ONLINE",
11 "redirectionType": "SINGLE",
12 "loanAmountAdjustmentAllowed": true
13 },
14 "gro": {
15 "name": "Name",
16 "email": "gro@example.com",
17 "contactNumber": "+919999999999",
18 "designation": "Manager",
19 "address": "Address"
20 },
21 "customerSupport": {
22 "link": "https://example.com/support",
23 "contactNumber": "+919999999999",
24 "email": "support@example.com"
25 },
26 "offers": [
27 {
28 "offerID": "offer-id",
29 "consentHandleAvailable": false,
30 "installmentAmount": null,
31 "ltvRatio": null,
32 "status": "OFFER_RECEIVED",
33 "periods": {
34 "offerTerm": "12 Months",
35 "coolOffPeriod": "3 Days"
36 },
37 "interest": {
38 "rate": "12.50",
39 "type": "Fixed"
40 },
41 "amounts": {
42 "principal": "460000",
43 "totalInterestPayable": "15000",
44 "netDisbursedAmount": "480000"
45 },
46 "annualPercentageRate": "14.10",
47 "ondcTransactionID": "ondc-tx-id",
48 "accepted": true,
49 "expired": false,
50 "documents": {
51 "termsAndConditionsLink": "https://example.com/terms",
52 "keyFactsStatementLink": "https://example.com/kfs"
53 },
54 "chargesAndFees": {
55 "applicationFees": "0",
56 "foreclosureFees": "0",
57 "interestRateConversionCharges": "0",
58 "delayPenaltyFees": "0",
59 "otherPenaltyFees": "0",
60 "processingFees": "999",
61 "otherUpfrontCharges": "0",
62 "insuranceCharges": "0",
63 "otherCharges": "0"
64 },
65 "numberOfInstallments": 12
66 }
67 ]
68 }
69 },
70 "journey": {
71 "id": "journey-id",
72 "status": "OFFER_ACCEPTED",
73 "type": "PERSONAL_LOAN",
74 "endUse": "education",
75 "bureauConsent": true,
76 "created": "2026-05-12T10:00:00.000Z",
77 "updated": "2026-05-12T10:25:00.000Z",
78 "decisionStatus": null,
79 "kycStatus": "PENDING",
80 "kycAttempts": 1,
81 "emandateStatus": null,
82 "emandateAttempts": null,
83 "esignStatus": null,
84 "esignAttempts": null,
85 "changeInOffer": false,
86 "borrowerPreferredAmount": 200000,
87 "borrowerPreferredTenure": 12,
88 "ondcTransactionIds": {
89 "bpp.id.of.lender": "ondc-tx-id"
90 }
91 },
92 "borrower": {
93 "id": "borrower-id",
94 "provider_id": "partner-borrower-id",
95 "providerID": "partner-borrower-id",
96 "profile": {}
97 }
98 },
99 "error": null
100}

For LENDER_REDIRECTED, use the same shape with data.status: "LENDER_REDIRECTED" and journey.status: "LENDER_REDIRECTED".

For REJECTED, use the same shape with data.status: "REJECTED" and journey.status: "REJECTED". Known lenders and offers may still be present to help reconciliation and support workflows.

DISBURSED Shape

DISBURSED is the only V2 stage that includes installments.

1{
2 "request_id": "event-id",
3 "correlation_id": "event-id",
4 "timestamp": "2026-05-12T10:45:00.000Z",
5 "tenant_id": "tenant-id",
6 "application_id": "application-id",
7 "tenantID": "tenant-id",
8 "applicationID": "application-id",
9 "data": {
10 "status": "DISBURSED",
11 "lenders": {
12 "Selected Bank": {
13 "id": "bpp.id.of.lender",
14 "minimumLoanAmount": "50000.00",
15 "maximumLoanAmount": "5000000.00",
16 "configuration": {
17 "mode": "ONLINE",
18 "redirectionType": "SINGLE",
19 "loanAmountAdjustmentAllowed": true
20 },
21 "gro": {
22 "name": "Name",
23 "email": "gro@example.com",
24 "contactNumber": "+919999999999",
25 "designation": "Manager",
26 "address": "Address"
27 },
28 "customerSupport": {
29 "link": "https://example.com/support",
30 "contactNumber": "+919999999999",
31 "email": "support@example.com"
32 },
33 "offers": [
34 {
35 "offerID": "offer-id",
36 "consentHandleAvailable": false,
37 "installmentAmount": null,
38 "ltvRatio": null,
39 "status": "OFFER_RECEIVED",
40 "periods": {
41 "offerTerm": "12 Months",
42 "coolOffPeriod": "3 Days"
43 },
44 "interest": {
45 "rate": "12.50",
46 "type": "Fixed"
47 },
48 "amounts": {
49 "principal": "460000",
50 "totalInterestPayable": "15000",
51 "netDisbursedAmount": "480000"
52 },
53 "annualPercentageRate": "14.10",
54 "ondcTransactionID": "ondc-tx-id",
55 "accepted": true,
56 "expired": false,
57 "documents": {
58 "termsAndConditionsLink": "https://example.com/terms",
59 "keyFactsStatementLink": "https://example.com/kfs"
60 },
61 "chargesAndFees": {
62 "applicationFees": "0",
63 "foreclosureFees": "0",
64 "interestRateConversionCharges": "0",
65 "delayPenaltyFees": "0",
66 "otherPenaltyFees": "0",
67 "processingFees": "999",
68 "otherUpfrontCharges": "0",
69 "insuranceCharges": "0",
70 "otherCharges": "0"
71 },
72 "numberOfInstallments": 12,
73 "installments": [
74 {
75 "serial_number": 1,
76 "type": "INSTALLMENT",
77 "amount": "11917",
78 "status": "NOT-DUE",
79 "installment_due_date": "2026-06-09T00:00:00.000Z"
80 }
81 ]
82 }
83 ]
84 }
85 },
86 "journey": {
87 "id": "journey-id",
88 "status": "DISBURSED",
89 "type": "PERSONAL_LOAN",
90 "endUse": "education",
91 "bureauConsent": true,
92 "created": "2026-05-12T10:00:00.000Z",
93 "updated": "2026-05-12T10:45:00.000Z",
94 "decisionStatus": null,
95 "kycStatus": "SUCCESS",
96 "kycAttempts": 1,
97 "emandateStatus": "SUCCESS",
98 "emandateAttempts": 1,
99 "esignStatus": "SUCCESS",
100 "esignAttempts": 1,
101 "changeInOffer": false,
102 "borrowerPreferredAmount": 200000,
103 "borrowerPreferredTenure": 12,
104 "ondcTransactionIds": {
105 "bpp.id.of.lender": "ondc-tx-id"
106 }
107 },
108 "borrower": {
109 "id": "borrower-id",
110 "provider_id": "partner-borrower-id",
111 "providerID": "partner-borrower-id",
112 "profile": {}
113 }
114 },
115 "error": null
116}

Object Reference

journey

journey identifies the borrower journey and the latest lifecycle state. journey.id is present in every lifecycle stage and matches data.journey.id in Hybrid Start/Hosted API responses and data.journeyID in Hybrid Offers API responses.

FieldTypeNotes
idstringAarthik Labs journey ID.
statusstringSame lifecycle stage as data.status.
typestringProduct type, for example PERSONAL_LOAN.
endUsestringPresent after STARTED when available.
bureauConsentbooleanPresent after STARTED when available.
createdstringISO timestamp.
updatedstringISO timestamp.
decisionStatusstring or nullLatest decision status, if available.
kycStatus, emandateStatus, esignStatusstring or nullVerification statuses, present in full journey snapshots.
kycAttempts, emandateAttempts, esignAttemptsnumber or nullAttempt counts, present in full journey snapshots.
changeInOfferbooleanWhether the selected offer changed after borrower action.
borrowerPreferredAmountnumber or nullBorrower’s preferred amount when available.
borrowerPreferredTenurenumber or nullBorrower’s preferred tenure when available.
ondcTransactionIdsobjectNetwork transaction IDs used for reconciliation.

borrower

borrower is present from PROFILED onward.

FieldTypeNotes
idstringAarthik Labs borrower ID.
provider_idstringBorrower ID from your system.
providerIDstringSame value as provider_id, provided for naming-style convenience.
profileobjectBorrower profile submitted for the journey.

accountAggregator And account_aggregator

These objects appear only in ACCOUNT_AGGREGATOR snapshots.

FieldTypeNotes
urlstring or nullURL that the borrower should open for the Account Aggregator consent flow.
expiresAt / expires_atstring or nullISO expiry timestamp for the URL.
lendersstring[]Lenders associated with the Account Aggregator flow.

lenders

lenders is an object keyed by borrower-visible lender name.

If two lenders have the same visible name, both entries are included with unique keys.

FieldTypeNotes
idstringLender identifier.
minimumLoanAmountstring or nullMinimum loan amount supported by the lender for this journey.
maximumLoanAmountstring or nullMaximum loan amount supported by the lender for this journey.
configuration.modestring or nullLender mode, for example ONLINE.
configuration.redirectionTypestring or nullRedirection type when applicable.
configuration.loanAmountAdjustmentAllowedbooleanWhether borrower amount adjustment is allowed.
groobjectGrievance redressal contact information when available.
customerSupportobjectCustomer support contact information when available.
offersarrayPresent only for stages that include offers.

offers

offers is present for stages where offer details are available.

FieldTypeNotes
offerIDstring or nullAarthik Labs offer ID.
consentHandleAvailableboolean or nullWhether the offer is associated with an Account Aggregator consent handle.
installmentAmountstring or nullInstallment amount when available.
ltvRatiostring or nullLoan-to-value ratio when available.
statusstringOffer status.
periods.offerTermstring or nullOffer term.
periods.coolOffPeriodstring or nullCool-off period.
interest.ratestring or nullInterest rate.
interest.typestringInterest type.
amounts.principalstring or nullPrincipal amount.
amounts.totalInterestPayablestring or nullTotal interest payable.
amounts.netDisbursedAmountstring or nullNet disbursed amount.
annualPercentageRatestring or nullAnnual percentage rate.
ondcTransactionIDstring or nullNetwork transaction ID for reconciliation.
acceptedbooleanWhether this offer has been accepted.
expiredbooleanWhether this offer has expired.
documents.termsAndConditionsLinkstring or nullTerms and conditions document link.
documents.keyFactsStatementLinkstring or nullKey Facts Statement document link.
chargesAndFeesobjectFee and charge fields, each as string or null.
numberOfInstallmentsnumber or nullNumber of installments.
installmentsarrayPresent only in DISBURSED snapshots.

installments

installments appears only in DISBURSED snapshots.

FieldTypeNotes
serial_numbernumber or nullInstallment sequence number.
typestringUsually INSTALLMENT.
amountstringInstallment amount.
statusstringInstallment status.
installment_due_datestringISO due date.
  1. Verify the signature before trusting the payload.
  2. Deduplicate using X-AL-Event-ID.
  3. Read data.status.
  4. Upsert the latest journey, borrower, lenders, and offers details into your system when those sections are present.
  5. Treat ACCOUNT_AGGREGATOR as an action signal to make the AA URL available to the borrower.
  6. Treat OFFERED as additive. A journey can receive a later OFFERED snapshot when AA-backed offers arrive.
  7. Treat missing optional sections as intentionally absent for that stage.
  8. Ignore unknown fields so your receiver remains forward-compatible.

Polling And Web-Hooks

Hybrid offer polling and web-hooks complement each other.

  • Polling keeps your borrower-facing UI responsive while the borrower is active.
  • Web-hooks give your back-end durable lifecycle updates even if the borrower closes the screen, completes Account Aggregator later, or moves into lender-managed steps.
  • When an Account Aggregator URL becomes available, V2 can send an ACCOUNT_AGGREGATOR web-hook so your back-end can reconcile the same milestone.

Enabling V2

Web-Hooks (V2) is enabled by Aarthik Labs for a specific application. Contact Aarthik Labs to enable it for your integration.

Until V2 is enabled, your application continues receiving the existing web-hook payload.