API Reference
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>
All Pinwheel API responses come in a consistent structure. They return in JSON format and use standard HTTP Status Codes
.
Code | Text | Description |
---|
200 | OK | Success! |
204 | No Content | The request was successfully processed and no content was returned. |
307 | Temporary Redirect | Redirection to another URI. |
400 | Bad Request | The request was invalid or cannot be served. The accompanying error type, code, and message will explain further. |
401 | Unauthorized | Missing or incorrect authentication credentials. |
403 | Forbidden | The request is understood, but it has been refused or access is not allowed. An accompanying error message and code will explain why. |
404 | Not Found | The requested resource could not be found. |
500 | Internal Server Error | An unexpected error occurred. Try again later. |
502 | Bad Gateway | Pinwheel is down, or being upgraded. |
503 | Service Unavailable | The Pinwheel servers are up, but overloaded with requests. Try again later. |
504 | Gateway Timeout | The Pinwheel servers are up, but the request could not be completed. Try again later. |
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 Type | Description |
---|
RECORD_NOT_FOUND | A requested record could not be found. |
INVALID_REQUEST_PARAMETERS | A request was invalid. |
UNAUTHORIZED_REQUEST | A request was unauthorized. |
UNKNOWN_ERROR | An unknown error occurred. |
POST /v1/link_tokens
Host: api.getpinwheel.com
Content-Type: application/json
X-API-SECRET: INSERT_API_SECRET
Key | Type | Description |
---|
job | string | direct_deposit_switch or direct_deposit_payment |
org_name | string | Organization name |
account_number | string | Unique account number |
routing_number | string | Routing number of bank |
account_type | string | Account type, checking or savings |
account_name (optional) | string | Name of the bank account |
amount (optional) | number | Amount for each direct deposit payment. Must be at exactly two decimal places and required if job is direct_deposit_payment. |
employer_id (optional) | string | If set, user will not be able to select their employer |
platform_id (optional) | string | If set, user will not be able to select their platform. For example, ADP Portal. |
disable_direct_deposit_splitting (optional) | boolean | If 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) | boolean | If 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
}
Key | Type | Description |
---|
mode | string | sandbox, development, or production |
token | string | Short-lived token that is used to initialize Pinwheel Link. |
expires | number | Unix timestamp of when token expires. |
token_id | string | Unique identifier for the object. |
{
"mode": "production",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzaWQiOiJjZTkzNDQ3OS0wYTE2LTRiNzMtYWM2NC0yNDIxMTk2MTA2MGIiLCJkYXRhIjp7ImJhbmtfbmFtZSI6IkJhbmsgb2YgQW1lcmljYSIsInJvdXRpbmdfbnVtYmVyIjoiMDAwMDAwMDAwMSIsImFjY291bnRfbnVtYmVyIjoiMDAwMDAwMDAwMSIsImFjY291bnRfdHlwZSI6ImNoZWNraW5nIiwiZW52aXJvbm1lbnQiOiJzdGFnaW5nIn0sImlhdCI6MTU4MzQyODA4MSwiZXhwIjoxNTgzNDI4OTgxfQ.6HHcrMxkakXaaDNpZ-qZZPO-mA06Dzu-nfUdurwaTUA",
"expires": 1583428981,
"token_id": "bd2c09e7-1303-46d5-87c0-0ffa572d7ae4"
}
GET /v1/jobs
Host: api.getpinwheel.com
Content-Type: application/json
X-API-SECRET: INSERT_API_SECRET
Optional query parameters:
Key | Type | Description |
---|
job_types | direct_deposit_payment , direct_deposit_switch | Filter on supported jobs. Multiple keys are allowed. |
link_token_id | string | UUID of the link token. |
from_timestamp | string | ISO-8601 format time. |
to_timestamp | string | ISO-8601 format time. |
limit | number | The maximum number of objects to return. |
Returns an array of objects with attributes:
Key | Type | Description |
---|
id | string | Unique identifier for the object. |
name | string | Name of the job, either direct_deposit_switch or direct_deposit_payment . |
timestamp | string | ISO 8601 timestamp of job completion. |
outcome | string | The outcome of the job, either success or error . |
error_code (optional) | string | On error, a string describing the error. |
link_token_id | string | Unique identifier for the object. |
params | object | Input parameters to job (defined in table below ). |
Key | Type | Description |
---|
amount | number | The 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.
GET /v1/link_tokens/:token_id/jobs
Host: api.getpinwheel.com
Content-Type: application/json
X-API-SECRET: INSERT_API_SECRET
Returns an array of objects with attributes:
Key | Type | Description |
---|
id | string | Unique identifier for the object. |
name | string | Name of the job, either direct_deposit_switch or direct_deposit_payment . |
timestamp | string | ISO 8601 timestamp of job completion. |
outcome | string | The outcome of the job, either success or error . |
error_code (optional) | string | On error, a string describing the error. |
link_token_id | string | Unique identifier for the object. |
params | object | Input parameters to job (defined in table below ). |
Key | Type | Description |
---|
amount | number | The 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
}
}
]
GET /v1/employers
Host: api.getpinwheel.com
Content-Type: application/json
X-API-SECRET: INSERT_API_SECRET
Optional query parameters:
Key | Type | Description |
---|
last_updated | string | ISO-8601 format time. |
Returns an array of objects with attributes:
Key | Type | Description |
---|
id | string | Unique identifier for the object. |
name | string | Name of employer, e.g., Apple, Disney, Walmart. |
fractional_amount_supported | boolean | Whether or not the employer accepts decimal values for direct_deposit_switch or direct_deposit_payment . |
supported_jobs | string[] | Array of supported jobs. |
last_updated | string | ISO-8601 format time when employer was last updated. |
min_amount (optional) | number | Minimum amount, if any, employer accepts for direct_deposit_switch or direct_deposit_payment . |
max_amount (optional) | number | Maximum amount, if any, employer accepts for direct_deposit_switch or direct_deposit_payment . |
logo_url (optional) | string | Resource 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",
}
]
GET /v1/platforms
Host: api.getpinwheel.com
Content-Type: application/json
X-API-SECRET: INSERT_API_SECRET
Optional query parameters:
Key | Type | Description |
---|
last_updated | string | ISO-8601 format time. |
include_esps | boolean | ESP (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. |
Returns an array of objects with attributes:
Key | Type | Description |
---|
id | string | UUID of the platform. |
name | string | Name of platform, e.g., ADP Portal, Gusto, Paylocity. |
fractional_amount_supported | boolean | Whether or not the platform accepts decimal values for direct_deposit_switch or direct_deposit_payment . |
supported_jobs | string[] | Array of supported jobs. |
last_updated | string | ISO-8601 format time when platform was last updated. |
min_amount (optional) | number | Minimum amount, if any, platform accepts for direct_deposit_switch or direct_deposit_payment . |
max_amount (optional) | number | Maximum amount, if any, platform accepts for direct_deposit_switch or direct_deposit_payment . |
logo_url (optional) | string | Resource 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",
}
]
GET /v1/search
Host: api.getpinwheel.com
Content-Type: application/json
X-API-SECRET: INSERT_API_SECRET
Optional query parameters:
Key | Type | Description |
---|
q | string | Search query on employer/platform name. |
supported_jobs | string[] | Filter on supported jobs. Multiple keys are allowed ie: ?supported_jobs=direct_deposit_switch&supported_jobs=direct_deposit_payment . |
response_types | string[] | Filter on response object. Multiple keys are allowed ie: ?response_types=employer&response_types=platform . |
Returns an array of objects with attributes:
Key | Type | Description |
---|
id | string | UUID of the employer/platform. |
name | string | Name of employer/platform, e.g., ADP Portal, Apple. |
fractional_amount_supported | boolean | Whether or not the employer/platform accepts decimal values for direct_deposit_switch or direct_deposit_payment . |
supported_jobs | string[] | Array of supported jobs. |
last_updated | string | ISO-8601 format time when employer/platform was last updated. |
response_type | string | employer , platform |
min_amount (optional) | number | Minimum amount, if any, employer/platform accepts for direct_deposit_switch or direct_deposit_payment . |
max_amount (optional) | number | Maximum amount, if any, employer/platform accepts for direct_deposit_switch or direct_deposit_payment . |
logo_url (optional) | string | Resource 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",
}
]
POST /v1/sites
Host: api.getpinwheel.com
Content-Type: application/json
X-API-SECRET: INSERT_API_SECRET
Key | Type | Description |
---|
org_name | string | Organization name |
job | string | direct_deposit_switch direct_deposit_payment |
account_number | string | Unique account number |
routing_number | string | Routing number of bank |
account_type | string | Account type, checking or savings |
redirect_url | string | A URL to redirect after the job has been executed. |
amount (optional) | number | Amount for each direct deposit payment. Must be at exactly two decimal places and required if job is direct_deposit_payment. |
employer_id (optional) | string | If set, user will not be able to select their employer |
platform_id (optional) | string | If set, user will not be able to select their platform. For example, ADP Portal. |
skip_exit_survey (optional) | boolean | If set to true, exit survey is not shown to user. Defaults to false. |
ttl (optional) | number | TTL 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
}
Key | Type | Description |
---|
url | string | URL of the generated site you can send your users. |
expires | number | Timestamp in seconds when the URL expires. |
token_id | string | Unique identifier for the object. |
{
"url": "https://site.getpinwheel.com/?token=eyJhbGciOiJIUzI1NiIsInR...",
"expires": 1593952965,
"token_id": "bd2c09e7-1303-46d5-87c0-0ffa572d7ae4"
}
POST /v1/webhooks
Host: api.getpinwheel.com
Content-Type: application/json
X-API-SECRET: INSERT_API_SECRET
Key | Type | Description |
---|
url | string | URL to post job results to |
status | string | active , paused |
enabled_events | string[] | Reference list of events here |
{
"url": "https://your-domain.com/webhook_endpoint",
"status": "active"
"enabled_events": [direct_deposit_payment.added, direct_deposit_payment.added]
}
Key | Type | Description |
---|
url | string | URL Pinwheel will post events to. |
status | string | active , paused |
id | string | Unique identifier for the object. |
{
"url": "https://your-domain.com/webhook_endpoint",
"status": "active"
"id": "ae0047bf-cd48-4f41-9fa2-2e578ca82969",
}
GET /v1/webhooks
Host: api.getpinwheel.com
Content-Type: application/json
X-API-SECRET: INSERT_API_SECRET
Key | Type | Description |
---|
url | string | URL Pinwheel will post events to. |
status | string | active , paused |
id | string | Unique identifier for the object. |
created_at | string | ISO 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 /v1/webhooks/:webhook_id
Host: api.getpinwheel.com
Content-Type: application/json
X-API-SECRET: INSERT_API_SECRET