GuidesAPI ReferenceChangelog
Log In

Test Console

Prior to diving in with development work, we recommend familiarizing yourself with Link in our Test Console. The Link Test Console lives in the developer dashboard and will allow you to create Link tokens and launch Pinwheel Link. The Test Console mimics Link token creation and allows you to see how different configurations affect the front-end UI. If you don't have access to the Developer Dashboard, please contact [email protected].

In Sandbox mode, you must use our Sandbox credentials. Live credentials will not work in Sandbox. In order to test with live payroll credentials, you can use our Development Environment.

Sandbox Credentials

In Sandbox mode, you can use the following credentials to test Link:

FieldValue
Company IDcompany_good
Usernameuser_good*
Email[email protected]
Passwordpass_good
SSN123456789
Last 4 of SSN1234
MFA codemfa_code
What street did you grow up on?pinwheel drive

*For USPS ONLY: Username value is "12345678"

For providers that support optional multifactor authentication (MFA), use the following credentials to test the MFA flow:

FieldValue
Usernameuser_mfa
Email[email protected]

To test Direct Deposit Forms use the following credentials:

FieldValue
Usernameuser_dd_form

To test jobs with an outcome of error, use the following credentials. Additional error cases are covered in the section below.

FieldValue
Usernameuser_error
Email[email protected]

To test jobs with an outcome of pending, use the following credentials:

FieldValue
Usernameuser_pending
Email[email protected]

In sandbox mode, jobs with a pending outcome will transition to an error outcome 60 seconds after the Link flow is completed. If you are subscribed to webhook events in Sandbox mode, you will first get an event with a pending outcome, followed by an event with an error outcome.

In Sandbox mode, the errors returned will be specific to the Sandbox mode. The full list of job errors can be viewed here.

*Note that in production mode, jobs may remain pending until they are resolved for up to 24 hours.

On Demand Updates

On Demand Updates may require user re-authentication before I&E data can be refreshed or a direct deposit switch is performed. The monitoring_status of an account will indicate whether a user re-authentication is needed or not. For the sandbox experience, we will focus on active and user_action_required states.

Getting started

An existing sandbox account initially connected with one of the following usernames is required before performing an On Demand Update. Each username corresponds to a re-authentication flow.

Re-authentication flow to simulateSandbox username
MFA requireduser_mfa
Credentials requireduser_good
Credentials and MFA requireduser_credentials_and_mfa

Updating monitoring_status of an Account

The PATCH /v1/sandbox/accounts/{account_id} sandbox-only endpoint can be used to simulate an account going into the user_action_required state by forcing an account with monitoring_status = active to monitoring_status = user_action_required

When the monitoring_status changes for an account, you will receive an account.monitoring_status.updated webhook event as you would in production. Once an account is in monitoring_status = user_action_required, re-authentication is required to get the account back to the monitoring_status = active state.

Simulating On Demand Update Re-authentication

Once the account is in the user_action_required state, you can launch Link with an On Demand Update and the experience will simulate what users will see when re-authentication is required for the account.

*Note that an account in the active state will not require re-authentication for On Demand Updates.

❗️

Limitation

Sandbox payroll accounts older than 7 days will default to requiring MFA and not follow the behavior associated with their username.

Earnings Stream

Earnings Stream can be tested in sandbox by leveraging user credentials to trigger specific scenarios.

Getting Started

The first step is to register a webhook with the earnings_stream.payouts.refreshed webhook event. For an introduction to webhooks, please read this.

Next, use the Developer Test Console to create a Link Token.

  • end_user_id must be provided to use Earnings Stream. Read the User Model documentation for details.

Select paystubs in required_jobs and provide a User Model end_user_id.

Create a Link Token, launch the Link Modal and select ADP as the payroll provider.

You will provide different User IDs to trigger different endpoint and webhook event scenarios. Use the password pass_good for all of the scenarios below.

Trigger an available state with:

User IDBehavior
earnings_stream_payouts_availableThis represents a hourly worker with shifts. The endpoint will be populated with valid estimated payout information and processed payout records going back to around one year. A webhook event will be sent with payload.availability set to available for all earnings_accrued subfields.
earnings_stream_payouts_available_salariedThis represents a salaried worker with no shifts. The endpoint will be populated with valid estimated payout information and processed payout records going back to around January 1st, 2022. A webhook event will be sent with payload.availability set to available for payouts_estimated.earnings_accrued and payouts_processed.earnings_unknown subfields.
earnings_stream_payouts_available_snpThis represents a new hourly worker with shifts and no paystubs. The endpoint will be populated with valid estimated payout information and processed payout records going back to around January 1st, 2022. A webhook event will be sent with payload.availability set to available for payouts_estimated.earnings_accrued and unavailable for payouts.processed subfields.

You can trigger different unavailable states, which will have empty responses in the endpoint and the following payload.unavailable_reasons in the webhook event:

User IDpayload.unavailable_reason
payouts_unavailable_temporary_outagetemporary_outage
payouts_unavailable_employer_not_supportedemployer_not_supported
payouts_unavailable_waiting_for_workuser_action_waiting_for_work
payouts_unavailable_new_employeeuser_action_new_employee
payouts_unavailable_undetermineduser_action_undetermined

Refreshing Data

Once a user is connected, you can refresh their data by triggering an On Demand Update. Once the user is re-authenticated, we will send another earnings_stream.payouts.refreshed webhook event to let you know how the user's payouts have changed. The refreshed_at field in the payload will show when we last refreshed the payouts data, while the updated_at field will show when the payouts last changed.

Verification Reports

Verification Reports can be tested in sandbox by leveraging user credentials to trigger specific scenarios.

Getting Started

The first step is to register a webhook with the verification_reports.refreshed webhook event. For an introduction to webhooks, please read this.

Next, use the Developer Test Console to create a Link Token.

  • end_user_id must be provided to use Verification Reports. Read the User Model documentation for details.

Select income and employment in required_jobs and provide an end_user_id.

Create a Link Token, launch the Link Modal and select ADP as the payroll provider.

You will provide different User IDs to trigger different endpoint and webhook event scenarios. Use the password pass_good for all of the scenarios below.

Trigger an available state with:

User IDBehavior
voe_and_voie_availableBoth the Verification of Employment and Verification of Income & Employment reports are available.
Both the VOE and VOIE endpoints will return the full set of data including paystubs for VOIE.
A webhook event will be sent with voe and voie availability set to available.
voe_and_voie_available_no_paystubsThis represents a user with identity, employment, and income details but no paystubs. The user could have recently started work with this employer and hasn't received a paystub yet. Both the Verification of Employment and Verification of Income & Employment reports are available. The VOIE report will be missing paystubs data.
Both the VOE and VOIE endpoints will return data.
A webhook event will be sent with voe and voie availability set to available.
voe_available_voie_unavailableThis represents a user with identity and employment data but no income or paystubs data. Only the Verification of Employment report is available.
The VOE endpoint will return data while the VOIE endpoint will return a 404 error.
A webhook event will be sent with voe availability set to available and voie availability set to unavailable.
voe_and_voie_unavailableThis represents a user with required data missing to generate both reports (at minimum, identity and employment data is required to generate a report).
Both the VOE and VOIE endpoints will return a 404 error.
A webhook event will be sent with voe and voie availability set to unavailable.

Additional Error Cases

If you would like to test specific Job Errors, use the credentials below. Errors that are job-specific will have a note called out in the description.

Login errors

📘

Note

A few errors here (marked with *) can only be raised within platforms that have native support. We recommend testing with ADP as your platform.

changePasswordRequired

This error indicates that the user must update their password before logging in.

FieldValue
Usernameuser_change_password_required
Email[email protected]
Passwordpass_good

accountNotActive

This error is thrown when a user attempts to login to an inactive account (e.g. if they've been terminated and have lost access).

FieldValue
Usernameuser_account_not_active
Email[email protected]
Passwordpass_good

accountLoggedIn

This error is thrown when the platform detects that the user is logged in via another mechanism.

FieldValue
Usernameuser_account_logged_in
Email[email protected]
Passwordpass_good

mfaSetupRequired

This error is thrown when MFA needs to be set up (e.g. on first time login).

FieldValue
Usernameuser_mfa_setup_required
Email[email protected]
Passwordpass_good

locationRestricted

This error is thrown when the platform cannot be accessed at the user's current location (e.g. some employers restrict access to corporate networks, or from specific IPs or locations).

FieldValue
Usernameuser_location_restricted
Email[email protected]
Passwordpass_good

invalidCredentials

The user has entered invalid credentials. Sandbox will always raise this error when an unknown / invalid username, email or password were used (e.g. if some_password was used instead of pass_good).

FieldValue
Usernameuser_invalid_credentials
Email[email protected]
Passwordpass_good

emailNotRegistered

This error is thrown when the email address provided by the user has not been registered with the payroll platform. This error can relate to both Username or Email being invalid. Unlike the invalidCredentials error, where a platform could recognize the user but their credentials could be invalid for login, this error represents instances when a user cannot be recognized by the platform at all.

FieldValue
Usernameuser_email_not_registered
Email[email protected]
Passwordpass_good

maxFailedAttempts *

This error is thrown when a user reaches the maximum number of login attempts (e.g. when entering MFA code). Prior to seeing this error in Sandbox, you will be prompted to enter an MFA code 3 times (invalidMfaCode failure will be returned each time).

FieldValue
Usernameuser_max_failed_attempts
Email[email protected]
Passwordpass_good
MFA codemfa_code or any valid string

challengeAnswerIncorrect *

This error is thrown when the answer provided for the challenge question was invalid (e.g. during an MFA step). Sandbox will raise this error 3 times while prompting you to enter an answer to the security question. Note that after 3 failed attempts (they are all set to fail no matter what), maxFailedAttempts error is returned.

FieldValue
Usernameuser_challenge_answer_incorrect
Email[email protected]
Passwordpass_good
Security question answersecurity_answer_good or pinwheel drive

passwordsNotEqual *

This error is thrown in the password reset flow, when a password and its confirmation do not match. To mimic the behavior we see natively in platforms, changePasswordRequired error will be raised first, then you will be prompted to reset the password 3 times, each time passwordsNotEqual error will be raised. Note that after 3 failed attempts (they are all set to fail as long as passwords don't match), maxFailedAttempts error is returned.

FieldValue
Usernameuser_passwords_not_equal
Email[email protected]
Passwordpass_good
Confirm passwordany valid string, but cannot match Password

Direct Deposit Switch errors

📘

Note

A few errors here (marked with *) can appear in both Login and Direct Deposit Switch flows. In Sandbox mode, these will be raised during the Direct Deposit Switch job.

systemError*

An unhandled error when a payroll integration behaves in an unexpected manner. We have internal processes to triage and fix these errors such that subsequent users do not trigger them.

FieldValue
Usernameuser_system_error
Email[email protected]
Passwordpass_good

accountLocked*

This error is thrown when the user's account has been locked. Generally, users will need to reach out to their HR Admin to proceed.

FieldValue
Usernameuser_account_locked
Email[email protected]
Passwordpass_good

contactHelpDesk*

This error is thrown when the user needs to contact their payroll admin in order to continue.

FieldValue
Usernameuser_contact_help_desk
Email[email protected]
Passwordpass_good

directDepositDisabled

This error is thrown when the account does not support any updates to direct deposit settings (e.g. the employer has disabled the ability to update settings within the online portal).

FieldValue
Usernameuser_direct_deposit_disabled
Email[email protected]
Passwordpass_good

directDepositAllocationsDisabled

This error is thrown when the account does not support the ability to read its allocations settings. Accounts that exhibit this behavior are also unable to support allocations updates.

FieldValue
Usernameuser_direct_deposit_allocations_disabled
Email[email protected]
Passwordpass_good

sessionTimeout*

This error occurs when the session closes after a period of inactivity (e.g. due to lack of user action).

FieldValue
Usernameuser_session_timeout
Email[email protected]
Passwordpass_good

platformError*

This error is thrown when there is an issue with the underlying payroll platform. Although our connection is behaving as expected, the platform itself is not working as expected.

FieldValue
Usernameuser_platform_error
Email[email protected]
Passwordpass_good

platformUnavailable*

This error is thrown when the platform is unavailable (e.g. some platforms will go offline during routine maintenance).

FieldValue
Usernameuser_platform_unavailable
Email[email protected]
Passwordpass_good

routingNumberRejected

This error is thrown when the routing number provided in the Link token is rejected by the platform's validation logic.

FieldValue
Usernameuser_routing_number_rejected
Email[email protected]
Passwordpass_good

invalidExistingSplit

This error is thrown when the user's account does not support the requested change (e.g. a user attempts to add a fixed amount allocation to an account that has an existing percentage allocation). Validation rules vary from platform to platform.

FieldValue
Usernameuser_invalid_existing_split
Email[email protected]
Passwordpass_good

changesTemporarilyDisabled

This error is thrown when a change is rejected due to existing changes that are still pending on the account (e.g. a direct deposit switch has been submitted and is pending processing).

FieldValue
Usernameuser_changes_temporarily_disabled
Email[email protected]
Passwordpass_good

maxAccounts

This error is thrown when a user has reached the maximum number of permitted direct deposit allocations, such that a new one cannot be added.

FieldValue
Usernameuser_max_accounts
Email[email protected]
Passwordpass_good

mfaTimeExceeded*

This error is thrown when the MFA token expires.

FieldValue
Usernameuser_mfa_time_exceeded
Email[email protected]
Passwordpass_good

invalidMfaCode*

The MFA code that was entered was invalid.

FieldValue
Usernameuser_invalid_mfa_code
Email[email protected]
Passwordpass_good

validationFailed

This is a catch-all error that is thrown to capture account data validation issues.

FieldValue
Usernameuser_validation_failed
Email[email protected]
Passwordpass_good

invalidInput*

This is a catch-all error that is thrown to capture generic input errors.

FieldValue
Usernameuser_invalid_input
Email[email protected]
Passwordpass_good

Income and Employment job errors

dataNotAvailable

This error occurs only for Income and Employment jobs. It occurs when the user's payroll platform does not surface the data requested. The availability of data varies within platform, employer, and employee combinations.

FieldValue
Usernameuser_data_not_available
Email[email protected]
Passwordpass_good

dataNotRefreshable

This error occurs only for Income and Employment jobs. It is raised when the user's payroll platform is able to surface the data requested when the user starts a new link session, but not when the job is run via refresh. The availability of data sometimes requires user action, such as an MFA code input, in order retrieve the requested data.

FieldValue
Usernameuser_data_not_refreshable
Email[email protected]
Passwordpass_good

directDepositAllocationsDisabled

This error is raised when the account does not support direct deposit switches through the online portal. For this set of credentials, this error will be thrown for the Direct Deposit Allocations job, along with directDepositDisabled for the Direct Deposit Switch job.

FieldValue
Usernameuser_direct_deposit_allocations_disabled
Email[email protected]
Passwordpass_good

Please contact [email protected] for access to our Developer Dashboard.