---
updatedAt: 2026-02-03T10:07:03.000Z
---

# Technical Implementation

[block:html]
{
  "html": "<script>/*\n=================\nINTERNAL COMMENTS\n=================\n\nContent Owner: Product, Risk & Underwriting team\n\nHow to contribute?: https://www.notion.so/pinwheelapi/Public-Docs-Philosophy-Guidance-bbd39c420e984ab9adf958394b6cef03\n\n*/</script>"
}
[/block]

This guide explains how to access Earnings Stream and handle updates. For an overview of concepts in the Pinwheel system that are referenced in this doc, review the [Platform Overview](https://docs.pinwheelapi.com/public/docs/implementation-guide).

## 1. Listen for Updates

Pinwheel sends the `earnings_stream.payouts.refreshed` webhook event to alert you when an up-to-date Earnings Stream is available for a user or [Monitoring](https://docs.pinwheelapi.com/public/docs/monitoring-implementation) has detected a change to a user's Earnings Stream.

Register a webhook endpoint using the [POST /v1/webhooks](https://docs.pinwheelapi.com/public/reference/post_v1_webhooks___post) with `earnings_stream.payouts.refreshed` specified in the `enabled_events`. See [Webhooks](https://docs.pinwheelapi.com/public/docs/webhooks-1) for additional configuration details and instructions on authenticating webhook events. For details on webhook event payloads, see [Earnings Stream Webhook Events](https://docs.pinwheelapi.com/public/reference/earnings-stream-webhook-events-1).

```json
POST /v1/webhooks
Host: api.getpinwheel.com
Content-Type: application/json
x-api-secret: YOUR-API-SECRET
{
  "url": "https://your-domain.com/webhook_endpoint",
  "status": "ACTIVE",
  "enabled_events": ["earnings_stream.payouts.refreshed"]
}
```

> ⚙️ Development Tip
>
> Use a tool like [Webhook.site](https://webhook.site/) to see webhook events in real-time without writing any code. Once you've developed a webhook endpoint, use a tool like [ngrok](https://ngrok.com/) to run it on your local machine and receive webhook events.

## 2. Connect an Account

[block:html]
{
  "html": "<script>\n/*\nInsert a diagram showing the UI for this step and the flow of requests made.\n\nhttps://www.figma.com/file/ZHqrIIqwzLVqpuH4rWgrxS/%5BDraft%5D-Docs%3A-Earnings-Stream-%3E-Technical-Implementation?node-id=0%3A1\n*/\n</script>"
}
[/block]

To initialize Link you will need to generate a short-lived [Link Token](https://docs.pinwheelapi.com/public/reference/post_v1_link_tokens___post). Your server side code will generate the Link token by sending a request to our [Create Link Token](https://docs.pinwheelapi.com/public/reference/post_v1_link_tokens___post) endpoint. Link tokens are single-use and expire after 15 minutes. Link tokens define your user experience and tell Pinwheel what jobs you need us to complete.

Launch Link so a user can connect a new account. To launch Link, your server side code will create a single-use, short-lived Link Token using the [POST /v1/link\_tokens](https://docs.pinwheelapi.com/public/reference/post_v1_link_tokens___post) endpoint.

You need to provide an `end_user_id` and set `paystubs` in `required_jobs` when creating the Link Token to enable Earnings Stream. Earnings Stream is built on your [User Model](https://docs.pinwheelapi.com/public/docs/user-model) since it may leverage cross-account data.

Visit the [Implementation Guide](https://docs.pinwheelapi.com/public/docs/implementation-guide) to see additional customization parameters for Link.

```json
POST /v1/link_tokens
Host: api.getpinwheel.com
Content-Type: application/json
x-api-secret: YOUR-API-SECRET
{
  "org_name": "YOUR APP NAME",
  "end_user_id": "my_user_12345",
  "required_jobs": ["paystubs"]
}
```

You'll pass the `token` from the response to one of the [Link SDKs](https://docs.pinwheelapi.com/public/docs/link-sdks) to launch a Link session inside your application.

> ⚙️ Development Tip
>
> Test this flow without writing any code using the *Test Console* to create a Link Token and launch a Link session in the [Developer Dashboard](https://developer.getpinwheel.com/).

## 3. Retrieve Data

If you've completed Step 1, you'll receive `earnings_stream.payouts.refreshed` webhook events at your webhook endpoint in these instances:

* After your user connects an account with [Link](https://docs.pinwheelapi.com/public/docs/implementation-guide#pinwheel-link) or performs an [On Demand Update](https://docs.pinwheelapi.com/public/docs/on-demand-updates-implementation)
* Whenever [Monitoring](https://docs.pinwheelapi.com/public/docs/monitoring-implementation) detects a change to the underlying information in Earnings Stream.

The webhook event will include metadata about the Earnings Stream, indicating which components are `available` or `unavailable`. If `unavailable` it will include an `unavailable_reason` summarizing why.

See [Earnings Stream Webhook Events](https://docs.pinwheelapi.com/public/reference/earnings-stream-webhook-events-1) for further details.

```json example &#x60;earnings_stream.payouts.refreshed&#x60; event
{
    "event": "earnings_stream.payouts.refreshed",
    "event_id": "e9d5660b-52cc-4b66-adba-67eed17447fe",
    "payload": {
        "end_user_id": "my_user_12345",
        "updated_at": "2022-01-01T00:00:00+0000",
        "refreshed_at": "2022-01-02T00:00:00+0000",
        "availability": {
            "payouts_estimated": {"earnings_accrued": {"status": "available", "unavailable_reason": null}},
            "payouts_processed": {
                "earnings_accrued": {"status": "available", "unavailable_reason": null},
                "earnings_unknown": {"status": "available", "unavailable_reason": null},
            },
        },
    }
}
```

Use `end_user_id` in the payload to query the [GET /v1/end\_users/{id}/earnings\_stream/payouts](https://docs.pinwheelapi.com/public/reference/get_earnings_stream_payouts_v1_end_users__end_user_id__earnings_stream_payouts_get) to fetch the most up-to-date payouts data; data from disconnected accounts will be excluded. See the [endpoint docs](https://docs.pinwheelapi.com/public/reference/get_earnings_stream_payouts_v1_end_users__end_user_id__earnings_stream_payouts_get) for a detailed breakdown of the schema and the [Earnings Stream overview](https://docs.pinwheelapi.com/public/docs/product-earnings-stream) for a walkthrough of the different components.

## 4. Use the Data

To estimate the size of someone’s next payout—for example, if you wanted to provide an Earned Wage Access cash advance to a user that you’d repay from their next direct deposit—you would select Payouts where `status = estimated` then sum up the `net_pay.amount` for all the `earnings` where `status = accrued`. You’d expect to see their account credited with this sum by the associated `pay_date`. The `status = accrued` earnings are based on real-time shifts information from the payroll system.

***

Please contact <sales@pinwheelapi.com> for access to our [Developer Dashboard](https://developer.getpinwheel.com/).