Earnings Stream
Pinwheel Earnings Stream shows you how much someone has earned but not yet been paid. It updates when there are newly completed shifts and triggers webhooks to alert you of any updates.
Use Cases
- Earned Wage Access: Reduce time-to-money by letting users access their paychecks ahead of standard bi-weekly pay dates.
- Spend Management / PFM & Engagement Tools: Support users’ healthy spending habits by showing them how much they’ve earned and when their next pay date is.
- Overdraft Protection: Extend short term credit lines confident that end users will be able to repay on their next pay date.
- Credit Limits: Dynamically size credit lines based on your users’ changing income situation.
- Default Prevention: Proactively defer loan repayments to avoid NSF (non-sufficient funds) errors that send your borrowers into default and increase loss rates.
Overview
Earnings Stream combines information from our Shifts, Paystubs, Income, and Employment endpoints to derive actionable values for you. Earning Stream is built around earnings which role up into top-level payout entities.
Entities
{
"data": [ /* A collection of payouts */
{ "earnings": [ /* A collection of earnings */ ] },
{ "earnings": [ /* ... */ ] },
/* ... */
]
}
Payouts are discrete cash flow event. An estimated payout represents income that has been earned but not finalized in the payroll system. A processed payout represents income that has a finalized paystub issued in the payroll system. Payouts are the top-level entities in the Earnings Stream, meaning everything rolls up into a payout.
Earnings are synthetic cash flows that materialize as payouts. They are a summary of income that was earned on a given day. Earnings are broken out per day to support visualizing earnings in a calendar format for end users. All earnings roll up into specific payouts.
Earnings Stream is focused on net pay, which is gross pay minus any deductions (taxes, healthcare contributions, etc.).
Estimated Payouts
Estimated payouts, status = estimated
, represent income that is expected to have been earned but not finalized in the payroll system, i.e., no corresponding paystub has been issued yet.
{
"data": [ /* A collection of payouts */
{
"status": "estimated",
"pay_date": "...",
"earnings": [ /* A collection of earnings */
{
"status": "accrued",
"date": "...",
"net_pay": { /* ... */ }
}
]
},
/* ... */
]
}
Estimated payouts include projected pay dates, pay_date
, which is when the user's pay is expected to be disbursed to them. We project these from historical pay dates. For consistency, this matches the pay date reported in paystubs, which, by convention, is intended to be when the user will see funds in their account and therefore buffers for ACH settlement time (e.g., 2 days). This projected value may be within +/- 2 days of actual settlement, so it is best used for UI instead of pre-scheduling repayment via account debits. We will improve the accuracy in future iterations.
Estimated payouts include accrued earnings, earnings
with status = accrued
, which specify net pay. Accrued earnings use real-time shifts data, i.e., hours worked, pulled from payroll or T&A platforms and leverage historical paystubs to estimate deduction rates (at least 1 historical paystub is required). Earnings are aggregated on a daily basis, specified by date
.
Processed Payouts
Processed payouts, status = processed
, represent guaranteed income, i.e., a paystub has been issued finalizing the net pay and other details.
{
"data": [ /* A collection of payouts */
{
"status": "processed",
"pay_date": "...",
"net_pay": { /* ... */ },
"earnings": [ /* A collection of earnings */
{
"status": "accrued",
"date": "...",
"net_pay": { /* ... */ }
}
]
},
/* ... */
{
"status": "processed",
/* ... */
"earnings": [
{
"status": "unknown",
"date": "...",
"net_pay": null
}
]
}
]
}
Processed payouts include pay date, pay_date
, which is when the user's pay will be disbursed to them. This date is retrieved from the paystub, and, by convention, is when the user will see funds in their account at a standard financial institution and therefore buffers for ACH settlement time (e.g., 2 days).
- For most processed payouts, the pay date is in the past. However, for recent processed payouts the pay date may be in the future, since the median time between paystub issuance and pay date is 6 days.
- To know if you have received the funds from a processed payout, e.g., via direct deposit, you'll need to reconcile incoming ACH credit transactions with processed payout records. Leverage the
pay_date
andnet_pay
amount to find matches.
Processed payouts include a top-level net pay attribute, net_pay
, which is the final amount of funds that will disbursed to the user.
Each processed payout has a collection of earnings, earnings
, which can be one of two statuses, accrued
or unknown
. All earnings in a payout are the same status. Each day in the earnings period contributing to the payout will have an earnings record. The two statuses have distinct meanings:
- Accrued earnings,
earnings
withstatus = accrued
, are based on historical shifts information and specify the net pay that was accrued on each day. For some users, these daily net pay value may vary moderately from reality since we may not have enough information to attribute overtime to the correct days. The sum of net pay values in accrued earnings will always equal the top-level net pay on the processed payout. - Unknown earnings,
earnings
withstatus = unknown
, have date values but specify anull
net pay. For these users, we have paystub data indicating the start and end of the date range that the earnings occurred in, but we do not have shifts data indicating which days the user actually worked, and therefore can't attribute net pay on a daily basis. Unknown earnings can be used to show the user the date range over which earnings occurred.
FAQ
-
What happens when an estimated payout transitions to processed?
The estimated payout entry will be removed and a new processed payout entry will be added. The new processed payout entry may have a different pay date and earnings values, based on new information from the finalized paystub. -
Can there be multiple payouts for a given pay date?
Yes. There are several reasons: some employers run concurrent pay periods, some users work multiple jobs, some pay periods open and close the same day, some employers issue bonuses or other earnings as one-off payouts. -
Can there be multiple estimated payouts at once?
Yes. The primary instance is you've connected multiple payroll accounts for one end user because they work multiple jobs (e.g., Uber and McDonald’s). We will surface estimated Payouts for each of the user’s jobs. In rare instances we may surface multiple estimated Payouts because a new pay period has started, even though the previous pay period has not been processed (i.e., finalized). -
Does Earnings Stream support all users?
Earnings Stream only estimated payouts for users when we have enough information to make sufficiently accurate projections about. To determine accuracy, we backtested our underlying model against real paystubs from all employers in our system. Our model is designed to let you advance 30-50% of accrued earnings with minimal risk-of-loss due to overestimated net pay. Earnings Stream includes processed payouts for all users which we can retrieve paystubs for. -
How quickly will Earnings Stream include newly completed shifts?
Most employers approve completed shifts in less than 24 hours. Therefore, expect to see updated Earnings within 1 day of a user completing their shift. -
On what schedule are most users paid?
Most users we see are paid bi-weekly in arrears, i.e., every two weeks they are paid for the work they completed in the preceding two week period. The median time between a payout being processed and the pay date when a user receives their funds is 6 days (or 4 days, if they use an early pay bank), though this ranges from 0-days to 12-days and is controlled on a per-employer basis. -
What is the difference between
missing_*
andinvalid_*
unavailable reasons?
We require data from the Income, Paystubs, and Shifts jobs data in order to create an Earnings Stream.missing
means that there is no data for the current pay period that we’re trying to create the Earnings Stream for.invalid
means that there is data for the current pay period, however it doesn’t meet our criteria of what valid data means. Here are some example criteria (not an exhaustive list):- Paystub net_pay_amount and gross_pay_amount > 0
- Paystub gross_pay_amount ≥ net_pay_amount
- Shift earning amount > 0 or hours & rate are > 0
- Income compensation unit is hourly
Please contact [email protected] for access to our Developer Dashboard.
Updated over 1 year ago