Documentation

Getting StartedLinkSitesAPI ReferenceHeadersResponsesCreate Link TokenFetch Job ResultsDEPRECATED - Fetch Job Results by Link TokenFetch EmployersFetch PlatformsSearch Platforms + EmployersCreate SitesCreate WebhooksList WebhooksDelete WebhookWebhooksAPI Change ManagementChangelog

API Reference

Headers

All requests to Pinwheel’s API are required to include a custom HTTP header with the correct API secret for your application and environment.

X-API-SECRET: <INSERT_API_SECRET>

Responses

All Pinwheel API responses come in a consistent structure. They return in JSON format and use standard HTTP Status Codes.

CodeTextDescription
200OKSuccess!
204No ContentThe request was successfully processed and no content was returned.
307Temporary RedirectRedirection to another URI.
400Bad RequestThe request was invalid or cannot be served. The accompanying error type, code, and message will explain further.
401UnauthorizedMissing or incorrect authentication credentials.
403ForbiddenThe request is understood, but it has been refused or access is not allowed. An accompanying error message and code will explain why.
404Not FoundThe requested resource could not be found.
500Internal Server ErrorAn unexpected error occurred. Try again later.
502Bad GatewayPinwheel is down, or being upgraded.
503Service UnavailableThe Pinwheel servers are up, but overloaded with requests. Try again later.
504Gateway TimeoutThe Pinwheel servers are up, but the request could not be completed. Try again later.

Errors

Pinwheel API error messages are also returned in JSON format inside an error object. An error may look like:

{
"error": {
"type": "INVALID_REQUEST_PARAMETERS",
"code": "MISSING_FIELDS",
"message": "Request is missing required fields: [enabled, name].",
"status_code": 400
}
}

The type field contains a higher level category of the error, and the code field will contain are more specific error. The message field contains a human-readable description of the error. Per Pinwheel's API Change Management policy, messages are subject to change.

Error TypeDescription
RECORD_NOT_FOUNDA requested record could not be found.
INVALID_REQUEST_PARAMETERSA request was invalid.
UNAUTHORIZED_REQUESTA request was unauthorized.
UNKNOWN_ERRORAn unknown error occurred.

Request

POST /v1/link_tokens
Host: api.getpinwheel.com
Content-Type: application/json
X-API-SECRET: INSERT_API_SECRET
KeyTypeDescription
jobstringdirect_deposit_switch or direct_deposit_payment
org_namestringOrganization name
account_numberstringUnique account number
routing_numberstringRouting number of bank
account_typestringAccount type, checking or savings
account_name (optional)stringName of the bank account
amount (optional)numberAmount for each direct deposit payment. Must be at exactly two decimal places and required if job is direct_deposit_payment.
employer_id (optional)stringIf set, user will not be able to select their employer
platform_id (optional)stringIf set, user will not be able to select their platform. For example, ADP Portal.
disable_direct_deposit_splitting (optional)booleanIf set to true, user will not be given the option to choose between a full or partial direct deposit switch. Only relevant with job direct_deposit_switch. Defaults to false.
skip_exit_survey (optional)booleanIf set to true, exit survey is not shown to user. Defaults to false.
{
"org_name": "XYZ Bank",
"job": "direct_deposit_switch",
"routing_number": "401355953",
"account_number": "491190534152",
"account_type": "checking",
"employer_id": "ae0047bf-cd48-4f41-9fa2-2e578ca82969",
"skip_exit_survey": false
}

Response

KeyTypeDescription
modestringsandbox, development, or production
tokenstringShort-lived token that is used to initialize Pinwheel Link.
expiresnumberUnix timestamp of when token expires.
token_idstringUnique identifier for the object.
{
"mode": "production",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzaWQiOiJjZTkzNDQ3OS0wYTE2LTRiNzMtYWM2NC0yNDIxMTk2MTA2MGIiLCJkYXRhIjp7ImJhbmtfbmFtZSI6IkJhbmsgb2YgQW1lcmljYSIsInJvdXRpbmdfbnVtYmVyIjoiMDAwMDAwMDAwMSIsImFjY291bnRfbnVtYmVyIjoiMDAwMDAwMDAwMSIsImFjY291bnRfdHlwZSI6ImNoZWNraW5nIiwiZW52aXJvbm1lbnQiOiJzdGFnaW5nIn0sImlhdCI6MTU4MzQyODA4MSwiZXhwIjoxNTgzNDI4OTgxfQ.6HHcrMxkakXaaDNpZ-qZZPO-mA06Dzu-nfUdurwaTUA",
"expires": 1583428981,
"token_id": "bd2c09e7-1303-46d5-87c0-0ffa572d7ae4"
}

Fetch Job Results

Request

GET /v1/jobs
Host: api.getpinwheel.com
Content-Type: application/json
X-API-SECRET: INSERT_API_SECRET

Optional query parameters:

KeyTypeDescription
job_typesdirect_deposit_payment, direct_deposit_switchFilter on supported jobs. Multiple keys are allowed.
link_token_idstringUUID of the link token.
from_timestampstringISO-8601 format time.
to_timestampstringISO-8601 format time.
limitnumberThe maximum number of objects to return.

Response

Returns an array of objects with attributes:

KeyTypeDescription
idstringUnique identifier for the object.
namestringName of the job, either direct_deposit_switch or direct_deposit_payment.
timestampstringISO 8601 timestamp of job completion.
outcomestringThe outcome of the job, either success or error.
error_code (optional)stringOn error, a string describing the error.
link_token_idstringUnique identifier for the object.
paramsobjectInput parameters to job (defined in table below ).

Params

KeyTypeDescription
amountnumberThe amount used in a direct_deposit_switch or direct_deposit_payment job, in cents.
[
{
"id": "ae0047bf-cd48-4f41-9fa2-2e578ca82969",
"name": "direct_deposit_payment",
"timestamp": "2020-06-26T19:06:16.993000",
"outcome": "success",
"error_code": null,
"link_token_id": "bd2c09e7-1303-46d5-87c0-0ffa572d7ae4",
"params": {
"amount": 10000
}
},
{
"id": "d9db3ea0-08f0-4c3f-a3e9-b99ec07b3746",
"name": "direct_deposit_switch",
"timestamp": "2020-06-26T19:06:20.993000",
"outcome": "success",
"error_code": null,
"link_token_id": "bd2c09e7-1303-46d5-87c0-0ffa572d7ae4",
"params": {
"amount": 10000
}
},
{
"id": "1ec611f2-c876-4a0a-8de6-c6b12b36cf22",
"name": "direct_deposit_payment",
"timestamp": "2020-06-26T19:06:16.993000",
"outcome": "error",
"error_code": "invalidConfiguration",
"link_token_id": "bd2c09e7-1303-46d5-87c0-0ffa572d7ae4",
"params": {
"amount": null
}
}
]

This method has been deprecated in favor of /v1/jobs

Fetch all jobs run with a given link token.

Request

GET /v1/link_tokens/:token_id/jobs
Host: api.getpinwheel.com
Content-Type: application/json
X-API-SECRET: INSERT_API_SECRET

Response

Returns an array of objects with attributes:

KeyTypeDescription
idstringUnique identifier for the object.
namestringName of the job, either direct_deposit_switch or direct_deposit_payment.
timestampstringISO 8601 timestamp of job completion.
outcomestringThe outcome of the job, either success or error.
error_code (optional)stringOn error, a string describing the error.
link_token_idstringUnique identifier for the object.
paramsobjectInput parameters to job (defined in table below ).

Params

KeyTypeDescription
amountnumberThe amount used in a direct_deposit_switch or direct_deposit_payment job, in cents.
[
{
"id": "ae0047bf-cd48-4f41-9fa2-2e578ca82969",
"name": "direct_deposit_payment",
"timestamp": "2020-06-26T19:06:16.993000",
"outcome": "success",
"error_code": null,
"link_token_id": "bd2c09e7-1303-46d5-87c0-0ffa572d7ae4",
"params": {
"amount": 10000
}
},
{
"id": "d9db3ea0-08f0-4c3f-a3e9-b99ec07b3746",
"name": "direct_deposit_switch",
"timestamp": "2020-06-26T19:06:20.993000",
"outcome": "success",
"error_code": null,
"link_token_id": "bd2c09e7-1303-46d5-87c0-0ffa572d7ae4",
"params": {
"amount": 10000
}
},
{
"id": "1ec611f2-c876-4a0a-8de6-c6b12b36cf22",
"name": "direct_deposit_payment",
"timestamp": "2020-06-26T19:06:16.993000",
"outcome": "error",
"error_code": "invalidConfiguration",
"link_token_id": "bd2c09e7-1303-46d5-87c0-0ffa572d7ae4",
"params": {
"amount": null
}
}
]

Fetch Employers

Request

GET /v1/employers
Host: api.getpinwheel.com
Content-Type: application/json
X-API-SECRET: INSERT_API_SECRET

Optional query parameters:

KeyTypeDescription
last_updatedstringISO-8601 format time.

Response

Returns an array of objects with attributes:

KeyTypeDescription
idstringUnique identifier for the object.
namestringName of employer, e.g., Apple, Disney, Walmart.
fractional_amount_supportedbooleanWhether or not the employer accepts decimal values for direct_deposit_switch or direct_deposit_payment.
supported_jobsstring[]Array of supported jobs.
last_updatedstringISO-8601 format time when employer was last updated.
min_amount (optional)numberMinimum amount, if any, employer accepts for direct_deposit_switch or direct_deposit_payment.
max_amount (optional)numberMaximum amount, if any, employer accepts for direct_deposit_switch or direct_deposit_payment.
logo_url (optional)stringResource path for employer logo.
[
{
"id": "ae0047bf-cd48-4f41-9fa2-2e578ca82969",
"name": "Apple",
"fractional_amount_supported": false,
"supported_jobs": [
"direct_deposit_switch",
"direct_deposit_payment"
],
"last_updated": "2020-09-02 23:18:08.757698+00",
},
{
"id": "d9db3ea0-08f0-4c3f-a3e9-b99ec07b3746",
"name": "Disney",
"fractional_amount_supported": true,
"min_amount": 1,
"supported_jobs": [
"direct_deposit_switch",
"direct_deposit_payment"
],
"last_updated": "2020-10-14 17:33:01.753768+00",
},
{
"id": "1ec611f2-c876-4a0a-8de6-c6b12b36cf22",
"name": "Walmart",
"fractional_amount_supported": true,
"supported_jobs": [
"direct_deposit_switch",
"direct_deposit_payment"
],
"last_updated": "2020-10-22 12:14:55.187104+00",
}
]

Fetch Platforms

Request

GET /v1/platforms
Host: api.getpinwheel.com
Content-Type: application/json
X-API-SECRET: INSERT_API_SECRET

Optional query parameters:

KeyTypeDescription
last_updatedstringISO-8601 format time.
include_espsbooleanESP (employer-specific platform) is a term that is used to describe an Employer that uses a unique, dedicated payroll portal to serve their employees. Eg. - Walmart employees will authenticate via a Walmart payroll portal, whereas employees at Hilton will authenticate via ADP. ESPs can be thought of as both employers and platforms, so you can use this flag to include ESPs in the set of supported payroll platforms if desired.

Response

Returns an array of objects with attributes:

KeyTypeDescription
idstringUUID of the platform.
namestringName of platform, e.g., ADP Portal, Gusto, Paylocity.
fractional_amount_supportedbooleanWhether or not the platform accepts decimal values for direct_deposit_switch or direct_deposit_payment.
supported_jobsstring[]Array of supported jobs.
last_updatedstringISO-8601 format time when platform was last updated.
min_amount (optional)numberMinimum amount, if any, platform accepts for direct_deposit_switch or direct_deposit_payment.
max_amount (optional)numberMaximum amount, if any, platform accepts for direct_deposit_switch or direct_deposit_payment.
logo_url (optional)stringResource path for platform logo.
[
{
"id": "ae0047bf-cd48-4f41-9fa2-2e578ca82969",
"name": "ADP Portal",
"fractional_amount_supported": false,
"supported_jobs": [
"direct_deposit_switch",
"direct_deposit_payment"
],
"last_updated": "2020-09-02 23:18:08.757698+00",
},
{
"id": "d9db3ea0-08f0-4c3f-a3e9-b99ec07b3746",
"name": "Gusto",
"fractional_amount_supported": true,
"min_amount": 1,
"supported_jobs": [
"direct_deposit_switch",
"direct_deposit_payment"
],
"last_updated": "2020-10-14 17:33:01.753768+00",
},
{
"id": "1ec611f2-c876-4a0a-8de6-c6b12b36cf22",
"name": "Paylocity",
"fractional_amount_supported": true,
"supported_jobs": [
"direct_deposit_switch",
"direct_deposit_payment"
],
"last_updated": "2020-10-22 12:14:55.187104+00",
}
]

Search Platforms + Employers

Request

GET /v1/search
Host: api.getpinwheel.com
Content-Type: application/json
X-API-SECRET: INSERT_API_SECRET

Optional query parameters:

KeyTypeDescription
qstringSearch query on employer/platform name.
supported_jobsstring[]Filter on supported jobs. Multiple keys are allowed ie: ?supported_jobs=direct_deposit_switch&supported_jobs=direct_deposit_payment.
response_typesstring[]Filter on response object. Multiple keys are allowed ie: ?response_types=employer&response_types=platform.

Response

Returns an array of objects with attributes:

KeyTypeDescription
idstringUUID of the employer/platform.
namestringName of employer/platform, e.g., ADP Portal, Apple.
fractional_amount_supportedbooleanWhether or not the employer/platform accepts decimal values for direct_deposit_switch or direct_deposit_payment.
supported_jobsstring[]Array of supported jobs.
last_updatedstringISO-8601 format time when employer/platform was last updated.
response_typestringemployer, platform
min_amount (optional)numberMinimum amount, if any, employer/platform accepts for direct_deposit_switch or direct_deposit_payment.
max_amount (optional)numberMaximum amount, if any, employer/platform accepts for direct_deposit_switch or direct_deposit_payment.
logo_url (optional)stringResource path for logo.
[
{
"id": "ae0047bf-cd48-4f41-9fa2-2e578ca82969",
"name": "ADP Portal",
"fractional_amount_supported": false,
"supported_jobs": [
"direct_deposit_switch",
"direct_deposit_payment"
],
"last_updated": "2020-09-02 23:18:08.757698+00",
"response_type": "platform",
"logo_url": "https://cdn.getpinwheel.com/assets/platforms/some-example-logo.jpeg",
},
{
"id": "1ec611f2-c876-4a0a-8de6-c6b12b36cf22",
"name": "Apple",
"fractional_amount_supported": true,
"supported_jobs": [
"direct_deposit_switch",
"direct_deposit_payment"
],
"last_updated": "2020-10-22 12:14:55.187104+00",
"response_type": "employer",
"logo_url": "https://cdn.getpinwheel.com/assets/employers/another-example-logo.jpeg",
}
]

Create Sites

Request

POST /v1/sites
Host: api.getpinwheel.com
Content-Type: application/json
X-API-SECRET: INSERT_API_SECRET

Body

KeyTypeDescription
org_namestringOrganization name
jobstringdirect_deposit_switch direct_deposit_payment
account_numberstringUnique account number
routing_numberstringRouting number of bank
account_typestringAccount type, checking or savings
redirect_urlstringA URL to redirect after the job has been executed.
amount (optional)numberAmount for each direct deposit payment. Must be at exactly two decimal places and required if job is direct_deposit_payment.
employer_id (optional)stringIf set, user will not be able to select their employer
platform_id (optional)stringIf set, user will not be able to select their platform. For example, ADP Portal.
skip_exit_survey (optional)booleanIf set to true, exit survey is not shown to user. Defaults to false.
ttl (optional)numberTTL in seconds before site URL expires. Defaults to minimum of 900 (15 minutes). Max is 1209600 (14 days).
{
"org_name": "XYZ Bank",
"job": "direct_deposit_switch",
"routing_number": "401355953",
"account_number": "491190534152",
"account_type": "checking",
"employer_id": "ae0047bf-cd48-4f41-9fa2-2e578ca82969",
"skip_exit_survey": false,
"redirect_url": "https://your-domain.com/landing-page",
"ttl": 86400
}

Response

KeyTypeDescription
urlstringURL of the generated site you can send your users.
expiresnumberTimestamp in seconds when the URL expires.
token_idstringUnique identifier for the object.
{
"url": "https://site.getpinwheel.com/?token=eyJhbGciOiJIUzI1NiIsInR...",
"expires": 1593952965,
"token_id": "bd2c09e7-1303-46d5-87c0-0ffa572d7ae4"
}

Create Webhooks

Request

POST /v1/webhooks
Host: api.getpinwheel.com
Content-Type: application/json
X-API-SECRET: INSERT_API_SECRET

Body

KeyTypeDescription
urlstringURL to post job results to
statusstringactive, paused
enabled_eventsstring[]Reference list of events here
{
"url": "https://your-domain.com/webhook_endpoint",
"status": "active"
"enabled_events": [direct_deposit_payment.added, direct_deposit_payment.added]
}

Response

KeyTypeDescription
urlstringURL Pinwheel will post events to.
statusstringactive, paused
idstringUnique identifier for the object.
{
"url": "https://your-domain.com/webhook_endpoint",
"status": "active"
"id": "ae0047bf-cd48-4f41-9fa2-2e578ca82969",
}

List Webhooks

Request

GET /v1/webhooks
Host: api.getpinwheel.com
Content-Type: application/json
X-API-SECRET: INSERT_API_SECRET

Response

KeyTypeDescription
urlstringURL Pinwheel will post events to.
statusstringactive, paused
idstringUnique identifier for the object.
created_atstringISO 8601 timestamp of webhook creation time.
[
{
"url": "https://your-domain.com/webhook_endpoint",
"status": "active"
"id": "ae0047bf-cd48-4f41-9fa2-2e578ca82969",
"created_at": "2020-06-26T19:06:16.993000"
},
{
"url": "https://your-domain.com/webhook_endpoint",
"status": "active"
"id": "ae0047bf-cd48-4f41-9fa2-2e578ca82969",
"created_at": "2020-06-26T19:06:16.993000"
}
]

Delete Webhook

Request

DELETE /v1/webhooks/:webhook_id
Host: api.getpinwheel.com
Content-Type: application/json
X-API-SECRET: INSERT_API_SECRET