> ## Documentation Index
> Fetch the complete documentation index at: https://developer.moneyone.in/llms.txt
> Use this file to discover all available pages before exploring further.

# Track Status

> Track the journey across AA and PDF via webhook, status polling, or in-iframe UI events.

There are three ways to know when a journey reaches a terminal state. Pick whichever
fits your integration — they can also be combined.

* **Webhook** (recommended) — MoneyOne pushes a terminal notification to your endpoint.
* **Status Polling** — you pull the journey status with the `transactionId`.
* **UI Events** — if you embed the orchestration UI in an iframe, listen for `postMessage` events.

All three surface whether AA or the PDF fallback ultimately delivered the data.

<Tabs>
  <Tab title="Webhook (Recommended)">
    When the journey reaches a terminal state, a webhook is pushed to your registered endpoint. For the
    AA + PDF flow, the `eventData` array always contains **both** an `AA` block and a `PDF` block, so you
    can see exactly which path delivered the data.

    <Note>
      To configure your webhook URL, contact `support@moneyone.in`.
    </Note>

    ### Payload examples

    <Tabs>
      <Tab title="A — AA success (PDF skipped)">
        AA delivered successfully, so the PDF fallback was never triggered (`status: "SKIPPED"`).

        ```json theme={null}
        {
          "timestamp": "2026-03-31T08:02:45.111480334Z",
          "transactionID": "ad277c38-ca13-49b0-befd-38343e221e6b",
          "eventType": "JOURNEY_COMPLETE",
          "eventStatus": "SUCCESS",
          "accountID": "ACC-78291",
          "eventData": [
            {
              "type": "AA",
              "status": "SUCCESS",
              "consents": [
                {
                  "consentID": "6934dcbb-ee3f-4ea0-85dc-b564c9e5e1d2",
                  "consentHandle": "7af9f26a-097c-4974-9e63-164a2b4c598e",
                  "consentStatus": "CONSENT_APPROVED",
                  "productID": "HOME2001",
                  "fetchType": "PERIODIC",
                  "fiFetch": "MANUAL",
                  "dataFetchStatus": "SUCCESS",
                  "accounts": [
                    { "linkRefNumber": "9bd5e87a-7916-49ff-8ee1-969375f4f5e3", "fiStatus": "DELIVERED", "fipID": "finsharebank", "maskedAccountNumber": "XXXXXXXX1100" }
                  ]
                }
              ]
            },
            { "type": "PDF", "status": "SKIPPED", "accounts": [] }
          ]
        }
        ```
      </Tab>

      <Tab title="B — AA failed, PDF fallback">
        AA failed (`CONSENT_REJECTED`), and the smart router fell back to PDF, which succeeded. The overall
        `eventStatus` is still `SUCCESS` because data was delivered.

        ```json theme={null}
        {
          "timestamp": "2026-03-31T06:59:46.465644026Z",
          "transactionID": "c664bcaa-c0bf-4101-b9ac-31e6d78cdb48",
          "eventType": "JOURNEY_COMPLETE",
          "eventStatus": "SUCCESS",
          "accountID": "ACC-90342",
          "eventData": [
            {
              "type": "AA",
              "status": "FAILED",
              "consents": [
                { "consentID": null, "consentHandle": "974e2b5d-196e-4965-bea2-eb5bcce88e01", "consentStatus": "CONSENT_REJECTED", "productID": null, "fetchType": null, "fiFetch": null, "dataFetchStatus": "NOT_ATTEMPTED", "accounts": [] }
              ]
            },
            {
              "type": "PDF",
              "status": "SUCCESS",
              "accounts": [
                { "maskedAccountNumber": "10021535948", "bankName": "idfc", "accountType": "saving", "startDate": "02-09-2025", "endDate": "28-02-2026" }
              ]
            }
          ]
        }
        ```
      </Tab>

      <Tab title="C — both skipped (failure)">
        Neither AA nor PDF delivered data. The overall `eventStatus` is `FAILED`.

        ```json theme={null}
        {
          "timestamp": "2026-04-20T09:23:28.838168037Z",
          "transactionID": "d4e9259c-0ddb-437e-9955-6738f8a4caf1",
          "eventType": "JOURNEY_COMPLETE",
          "eventStatus": "FAILED",
          "accountID": "D2C20260420070500007248",
          "eventData": [
            { "type": "AA", "status": "SKIPPED", "consents": [] },
            { "type": "PDF", "status": "SKIPPED", "accounts": [] }
          ]
        }
        ```
      </Tab>
    </Tabs>

    ### Top-level fields

    | Field           | Description                                          |
    | --------------- | ---------------------------------------------------- |
    | `timestamp`     | ISO-8601 time the event was emitted.                 |
    | `transactionID` | Unified transaction identifier for the journey.      |
    | `eventType`     | Always `JOURNEY_COMPLETE` for the terminal push.     |
    | `eventStatus`   | `SUCCESS` or `FAILED` for the journey overall.       |
    | `accountID`     | The account identifier associated with the journey.  |
    | `eventData`     | Array containing one `AA` block and one `PDF` block. |

    ### AA block fields

    The `AA` entry carries `type` (`AA`), `status` (`SUCCESS` / `FAILED` / `SKIPPED`), and a `consents`
    array.

    | Field                                       | Description                                         |
    | ------------------------------------------- | --------------------------------------------------- |
    | `consents[].consentID`                      | Consent identifier (may be `null` if not approved). |
    | `consents[].consentHandle`                  | Consent handle.                                     |
    | `consents[].consentStatus`                  | `CONSENT_APPROVED` or `CONSENT_REJECTED`.           |
    | `consents[].productID`                      | Product the consent belongs to.                     |
    | `consents[].fetchType`                      | `PERIODIC` or `ONETIME`.                            |
    | `consents[].fiFetch`                        | `MANUAL` or `AUTOMATIC`.                            |
    | `consents[].dataFetchStatus`                | `SUCCESS`, `FAILED`, `NO_DATA`, or `NOT_ATTEMPTED`. |
    | `consents[].accounts[].linkRefNumber`       | Link reference number for the account.              |
    | `consents[].accounts[].fiStatus`            | `DELIVERED` when data was delivered.                |
    | `consents[].accounts[].fipID`               | FIP identifier.                                     |
    | `consents[].accounts[].maskedAccountNumber` | Masked account number.                              |

    ### PDF block fields

    The `PDF` entry carries `type` (`PDF`), `status` (`SUCCESS` / `SKIPPED` / `FAILED`), and an `accounts`
    array.

    | Field                            | Description                                        |
    | -------------------------------- | -------------------------------------------------- |
    | `accounts[].maskedAccountNumber` | Masked account number from the uploaded statement. |
    | `accounts[].bankName`            | Bank the statement belongs to (e.g. `idfc`).       |
    | `accounts[].accountType`         | Account type (e.g. `saving`).                      |
    | `accounts[].startDate`           | Statement period start (`DD-MM-YYYY`).             |
    | `accounts[].endDate`             | Statement period end (`DD-MM-YYYY`).               |

    <Info>
      When `status` is `SKIPPED`, the `accounts` array is empty — that path was not used for this journey.
    </Info>
  </Tab>

  <Tab title="Status Polling">
    If you prefer to pull the journey status instead of receiving a webhook push, poll this
    endpoint. For the AA + PDF flow, the response includes a `pdf` step and a `smart_routing_decision` step
    in addition to `health_check`, `aa`, and `analytics`.

    ### Endpoint

    ```
    POST /transaction/status
    ```

    <Info>
      Base URL (UAT / Production): **Contact [support@moneyone.in](mailto:support@moneyone.in)**
    </Info>

    ### Headers

    | Header           | Description          |
    | ---------------- | -------------------- |
    | `Content-Type`   | `application/json`   |
    | `client_id`      | Your client ID       |
    | `client_secret`  | Your client secret   |
    | `organisationId` | Your organisation ID |
    | `appIdentifier`  | Your app identifier  |

    ### Request body

    ```json theme={null}
    { "transactionId": "<transaction_id>" }
    ```

    ### Sample request

    <CodeGroup>
      ```bash cURL theme={null}
      curl --location 'https://<base_url>/transaction/status' \
        --header 'Content-Type: application/json' \
        --header 'client_id: <your_client_id>' \
        --header 'client_secret: <your_client_secret>' \
        --header 'organisationId: <your_org_id>' \
        --header 'appIdentifier: <your_app_identifier>' \
        --data '{ "transactionId": "<transaction_id>" }'
      ```
    </CodeGroup>

    ### Response

    This example shows AA failing and the smart router falling back to PDF, which succeeds.

    ```json theme={null}
    {
      "status": "SUCCESSFUL",
      "transaction_id": "<transaction_id>",
      "data": [
        {
          "type": "health_check",
          "status": "SUCCESSFUL",
          "data": {
            "healthy_fips": ["<fip_id_1>"],
            "unhealthy_fips": ["<fip_id_2>"],
            "fip_decisions": [
              { "fip": "<fip_id_1>", "decision": "FIP_HEALTHY" },
              { "fip": "<fip_id_2>", "decision": "FIP_UNHEALTHY" }
            ]
          }
        },
        {
          "type": "aa",
          "status": "FAILED",
          "data": {
            "fips": [ { "fip": "<fip_id_1>", "status": "FAILED" } ],
            "consents": [
              { "consentHandle": "<consent_handle>", "consentId": "<consent_id>", "consentStatus": "CONSENT_APPROVED", "productId": "<product_id>", "dataFetchStatus": "FAILED", "accounts": [] }
            ]
          }
        },
        {
          "type": "pdf",
          "status": "SUCCESSFUL",
          "data": {
            "expected_fips": ["<fip_id_2>", "<fip_id_1>"],
            "total_expected": 2,
            "uploaded": 1,
            "processed": 1,
            "fetched": 1,
            "accounts": [
              { "maskedAccountNumber": "10021535948", "bankName": "idfc", "accountType": "saving", "startDate": "02-09-2025", "endDate": "28-02-2026" }
            ]
          }
        },
        { "type": "analytics", "status": "SUCCESSFUL" },
        { "type": "smart_routing_decision", "status": "SUCCESSFUL", "data": { "route": "PDF" } }
      ],
      "message": null
    }
    ```

    ### Step types

    The `data` array contains one entry per step. For the AA + PDF flow there are five step types:

    | Step type                | Description                                                                                                                            |
    | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- |
    | `health_check`           | FIP health evaluation; lists `healthy_fips`, `unhealthy_fips`, and per-FIP `fip_decisions`.                                            |
    | `aa`                     | Account Aggregator fetch; carries `fips` and `consents` (with per-account detail).                                                     |
    | `pdf`                    | PDF statement-upload fallback; reports `expected_fips`, counts (`total_expected`, `uploaded`, `processed`, `fetched`), and `accounts`. |
    | `analytics`              | Analytics computation over the delivered data.                                                                                         |
    | `smart_routing_decision` | The router's chosen path; `data.route` is `AA` or `PDF`.                                                                               |

    ### Step statuses

    Each step's `status` is one of:

    | Status         | Meaning                                                       |
    | -------------- | ------------------------------------------------------------- |
    | `SUCCESSFUL`   | The step completed successfully.                              |
    | `UNSUCCESSFUL` | The step completed without success.                           |
    | `FAILED`       | The step failed.                                              |
    | `SKIPPED`      | The step was not needed (e.g. PDF skipped when AA succeeded). |
    | `IN_PROGRESS`  | The step is currently running.                                |
    | `PENDING`      | The step has not started yet.                                 |
    | `PARTIAL`      | The step completed for some accounts only.                    |

    ### Overall statuses

    The top-level `status` reflects the journey overall:

    | Status         | Meaning                             |
    | -------------- | ----------------------------------- |
    | `SUCCESSFUL`   | The journey completed successfully. |
    | `UNSUCCESSFUL` | The journey did not deliver data.   |
    | `IN_PROGRESS`  | The journey is still running.       |
    | `SKIPPED`      | The journey was skipped.            |
    | `PENDING`      | The journey has not started yet.    |

    <Note>
      Poll until the overall `status` reaches a terminal value (`SUCCESSFUL` / `UNSUCCESSFUL`). Inspect the
      `smart_routing_decision` step to learn whether AA or PDF delivered the data for this transaction.
    </Note>

    ### Error Codes

    | HTTP Status                 | Condition                                                         |
    | --------------------------- | ----------------------------------------------------------------- |
    | `400 Bad Request`           | `transactionId` is missing or invalid in the request body.        |
    | `401 Unauthorized`          | Credentials are missing or invalid in the `Authorization` header. |
    | `500 Internal Server Error` | An unexpected server-side error occurred.                         |
  </Tab>

  <Tab title="UI Events">
    When the orchestration UI is embedded in an iframe, it communicates with the parent
    window using the browser [`postMessage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage)
    API. Your parent window can listen for these events to react the moment a journey
    reaches a terminal state. These events fire the same way whether the journey completed
    through AA or through the PDF fallback — the `statusData` payload reflects whichever
    path was taken.

    ### Event structure

    ```json theme={null}
    {
      "type": "REDIRECT",
      "eventCode": "JOURNEY-SUCCESS",
      "message": "Workflow completed successfully for transaction <transaction_id>",
      "statusData": { ... }
    }
    ```

    | Field        | Type   | Description                                   |
    | ------------ | ------ | --------------------------------------------- |
    | `type`       | string | Event type (e.g. `REDIRECT`).                 |
    | `eventCode`  | string | The event code (see below).                   |
    | `message`    | string | Human-readable message.                       |
    | `statusData` | object | The full status response for the transaction. |

    ### Event codes

    | Event Code                    | Trigger Condition                                          | Description                                 |
    | ----------------------------- | ---------------------------------------------------------- | ------------------------------------------- |
    | `JOURNEY-SUCCESS`             | `status === 'SUCCESSFUL'`                                  | Workflow completed successfully.            |
    | `JOURNEY-FAILURE`             | `status === 'UNSUCCESSFUL'`, `'EXPIRED'`, or `'CANCELLED'` | Workflow failed.                            |
    | `JOURNEY-SKIPPED`             | `status === 'SKIPPED'`                                     | Workflow was skipped.                       |
    | `JOURNEY-NETBANKING-REDIRECT` | Netbanking redirect required                               | User needs to be redirected for netbanking. |

    ### Listening for events

    ```javascript theme={null}
    window.addEventListener('message', (event) => {
      const { type, eventCode, message, statusData } = event.data;

      if (eventCode === 'JOURNEY-SUCCESS') {
        // Handle successful completion (AA or PDF)
        console.log('Workflow success:', statusData);
      } else if (eventCode === 'JOURNEY-FAILURE') {
        // Handle failure
        console.log('Workflow failed:', message);
      } else if (eventCode === 'JOURNEY-SKIPPED') {
        // Handle skipped journey
        console.log('Workflow skipped:', message);
      }
    });
    ```

    <Tip>
      For production integrations, verify `event.origin` against the orchestration UI's
      origin before trusting the payload.
    </Tip>
  </Tab>
</Tabs>

## Next step

Once the journey is `SUCCESSFUL`, fetch the raw FI data or analytics on the
[Fetch Data](./fetch-data) page using the same `transaction_id`.
