GuidesAPI ReferenceChangelog
Log In

API Overview


The Pinwheel API is built on RESTful principles. All request and response payloads are encoded in JSON. For security purposes, all requests must be sent via HTTPS. To get access to the Developer Dashboard and interface with the API, please contact [email protected].

Pinwheel offers a Postman collection to explore Pinwheel's API endpoints with no code. The collection provides detailed instructions, and pre-formatted settings for a quick start. Click the button below to import the collection to your own workspace.

Run in Postman


The API is available in three modes that can be accessed by sending requests to different servers. Each API Key you are granted will be associated with a single mode.

sandboxhttps://sandbox.getpinwheel.comUse Sandbox mode to build and test your integration. In this mode, you must use test credentials to authenticate with payroll platforms. All API endpoints will return mock data and no actual updates are made to any payroll account.
developmenthttps://development.getpinwheel.comDevelopment mode can be used to test your integration before going live in Production. In this mode, you use real credentials to authenticate with payroll platforms. API endpoints return real data and updates are made to payroll accounts.
productionhttps://api.getpinwheel.comUse Production mode to go live with your integration. Your users will use their login credentials to authenticate with their payroll accounts. API endpoints return real data and updates are made to payroll accounts. Note that in this mode, all API calls are billable.



You can view, create, and revoke API Keys for each mode in the Developer Dashboard.

Your API Key is a unique identifier used by Pinwheel for logging and troubleshooting. Your API secret must be included in all requests to the API via a custom HTTP header. API keys are only valid for the mode they were created in.

x-api-secretYour API Secret

See API Key Rotation for details on how to create and revoke your keys using either the Developer Dashboard or our Admin API.


Our API accepts JSON-encoded requests. You must include a Content-Type header with the value application/json whenever you submit data in the request body, e.g., POST /v1/link_tokens.


The Pinwheel API supports different behavior depending on the API version requested. You must send a Pinwheel-Version header with each request to specify how the Pinwheel API should behave. You can find the latest API version on the Change Management page. If no header is specified the Pinwheel API will default to the deprecated version 2021-04-29. Once version 2021-04-29 is sunsetted, requests without a Pinwheel-Version header will return a 400 Bad Request error.

Responses from the Pinwheel API will include a Pinwheel-Version header specifying which API version was used to process the request.

POST /link_tokens
Content-Type: application/json
Pinwheel-Version: 2021-07-28

  "required_jobs": ["direct_deposit_switch"],
  "org_name": "",
  // ...
Content-Type: application/json
Pinwheel-Version: 2021-07-28

  "data": {
    "expires": "2021-01-09T02:52:26+00:00",
    "id": "bd2c09e7-1303-46d5-87c0-0ffa572d7ae4",
    "mode": "production",
    "token": "eyJhbGciOiJIUz....pZ-qZZPO-mA06Dzu-nfUdurwaTUA"

For more details, see Versioned Changes in the Change Management page.


There are a number of important objects in Pinwheel's systems. It is particularly useful to store the identifiers for Accounts, Link Token, and Jobs. These identifiers will help you optimize your Pinwheel integration, troubleshoot issues, and reconcile billing.

In addition to these Pinwheel identifiers, you can incorporate your existing user model into Pinwheel by providing your own internal user identifier, end_user_id, when you initiate an account connection. Please note this should be a unique identifier that does not contain any end-user PII. See User Model for more.

ObjectDescriptionWhere to find it
Account.idUUID of each payroll account. Store the account_id in correlation with your user and link_token_id. Used to query data endpoints like Income and Employment.It is returned in Link via the onLogin callback and in the account.added Webhook as account_id immediately after an end user authenticates. It can also be found by querying the List Accounts endpoint. This should be used as the primary account identifier.
LinkToken.idUUID of a given Link token. Store the link_token_id in correlation with your users. There can be many Link tokens per user. For example, if a customer abandons the Link flow, or comes back to change their direct deposit settings. If you use DDA Monitoring, there can be many Link tokens per payroll account, though only one is associated with account creation. For example, if a user goes through Link to reconnect a disconnected payroll account. Used to troubleshoot issues for users who were unable to connect.It is returned as id in the Create Link Token response and in all Link-initiated Webhooks.
Job.idUUID of a given job. Can be helpful for troubleshooting job specific issues.It is returned in Link-initiated Webhook payloads and can be found by querying the Jobs endpoint.
end_user_idThe end-user identifier provided to Pinwheel by the customer specified through a parameter in the Create Link Token endpoint. end_user_id is then associated with all account data returned by Pinwheel. See User Model for more info.end_user_id is included in all webhook events.



Every Pinwheel response will contain a unique request identifier. We recommend logging this request identifier to be used for troubleshooting.

x-pinwheel-request-ida3f19010-1bea-4527-8ef2-7e3b795a4056Request UUID


All responses are encoded in JSON and return an object with the key data. If the response is a single object, the value of the data key is that object. For example, the Get Employment endpoint will return a single Employment object:

  "data": {
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "employer_name": "Apple",
    "status": "active",
    "start_date": "2019-08-24",
    "account_id": "449e7a5c-69d3-4b8a-aaaf-5c9b713ebc65",
    "created_at": "2020-12-28T02:03:47+00:00"

If the response is a collection, the value of the data key is an array of objects. A meta key is also returned with metadata about the response. For example the List Platforms endpoint will return a collection of Platforms:

  "meta": {
    "count": 2
  "data": [
      "id": "d739ad63-7884-4f4c-a8f0-2c27cdce376d",
      "name": "Zenefits",
      "id": "2a551145-37b8-4fd8-9260-d595d0214514",
      "name": "ADP Workforce Now",

Status Codes

Pinwheel API responses use standard HTTP Status Codes.

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.
429Too Many RequestsPinwheel is receiving too many requests from you. Slow down your request rate. We recommend retrying with an exponential backoff strategy.
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.

Rate Limiting

Pinwheel uses rate limiting to safeguard our system against excessive traffic to maximize stability. If your application sends too many requests in quick succession, you may see error responses with a 429 status code. Unless specifically noted, Pinwheel allows 50 queries per second across all API endpoints for requests in production mode, and 10 queries per second for requests in sandbox or development mode. For more configuration options, please contact [email protected].

Please structure your application calls to avoid hitting these limits. If you do receive a 429 response, we recommend retrying with an exponential backoff strategy.


Some conventions used throughout our API are:

  • All dates and datetimes are returned as ISO-8601 strings in UTC Timezone, e.g., 2021-01-03T14:34:16.549923+00:00.
  • Object IDs are represented as UUIDs, e.g., 81575384-c55b-4a40-99af-6399910a2520.
  • To avoid any potential loss of precision when parsing response payloads, all financial values are represented in the smallest common currency unit along with the ISO 4217 currency code. For example, $292.23 is represented as 29223 with a currency code of USD.

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