Adhoc Statement Summary Data

Overview

Spinwheel supports on-demand refreshes of statement data, enabling your app to retrieve the latest account information at any time in near real-time—ideal for scenarios such as when a user opens your app and wants to see the most up-to-date financial data.

This feature runs independently of any subscription and is entirely partner-triggered and asynchronous.

ℹ️

You will want to make sure to subscribe to the REFRESH_TRANSACTION_STATUS webhook

🔁 Step 1: Make the Refresh Request

You can request a real-time update for a user's statement data outside of the scheduled subscription logic. This is helpful for user-driven interactions, such as when someone opens your app and wants the most current data.

POST /v1/users/{userId}/liabilities/refresh

✔️ No active subscription is required for this endpoint to work.

🧾 Request Body

This request kicks off the asynchronous process to fetch the most up to date statement data on the user's liability.

The request must specify:

  • A unique extRequestId (for traceability across webhooks).
  • One or more creditCardIds.
  • The desired capabilities, such as "STATEMENT_SUMMARY".
{
    "extRequestId": "<UUID>",
    "creditCards": [						
        {
            "capabilities": [
                "STATEMENT_SUMMARY"
            ],
            "id": "<creditCardId>"
        },
    ]
}

🟢 Step 2: Interpret the Response

🧾 Response Body

Upon a successful request, Spinwheel will return an acknowledgment response with:

  • refreshTransactionStatus: "IN_PROGRESS"
  • refreshTransactionId: A unique reference for tracking the request.
  • nextEligibleRefreshOn: Timestamp indicating the next allowed refresh window.
{
  "status": {
    "code": 200,
    "desc": "success"
  },
  "data": [
    {
      "refreshTransactionStatus": "IN_PROGRESS",
      "refreshTransactionId": "<UUID>",
      "creditCardId": "<creditCardId>",			
      "nextEligibleRefreshOn": <epochTs>
    }
  ]
}

📡 Step 3: Listen for Webhook Completion

You will be notified of the status and results via the REFRESH_TRANSACTION_STATUS webhook once processing is complete.

✅ Make sure you subscribe to the REFRESH_TRANSACTION_STATUS webhook

Webhook Body - REFRESH_TRANSACTION_STATUS

{
  "eventType": "REFRESH_TRANSACTION_STATUS",
  "userId": "b790770b-33c7-49d4-b086-e6e18864ba34",
  "extRequestId": "28ddf73b-bd93-4c06-afa5-fd4e3994d23f",
  "refreshTransactionId": "b790770b-33c7-49d4-b086-e6e18864ba34",
  "creditCardId": "007035e0-7865-49f3-be50-c922b1c63dc6",
  "refreshTransactionStatus": "COMPLETED", 
  "webhookId": "1710361341615-0",
  "data": {    
    "statementSummary": {
          "statementBalance": 3194,
          "minimumPaymentAmount": 101,
          "dueDate": "2021-09-08T00:00:00.000Z",
          "lastPaymentAmount": 400,
          "lastPaymentDateWithFormat": {
            "value": "2021-08-21",
            "format": "YYYY-MM-DD"
          },
          "statementDateWithFormat": {
            "value": "2021-08-08",
            "format": "YYYY-MM-DD"
          },
          "overduePeriod": "NOT_OVERDUE",
          "amountPastDue": 700,
          "dueDateWithFormat": {
            "value": "2021-09-08",
            "format": "YYYY-MM-DD"
          },
          "updatedOn":1719584284061
        }
  }
}

📌 Developer Tips

✅ Always use a unique extRequestId for traceability and idempotency.

⏳ Use nextEligibleRefreshOn to throttle refreshes as per Spinwheel policy.

🔐 Webhook security headers are included for verification—refer to Webhook Auth Docs for validating payloads.