Early wage access

Manage on-demand and early worker payments efficiently with the Paystream and Worker Payment APIs.

Salsa allows you to pay workers outside of a payroll run as often as needed using our Worker Payment APIs. In this guide, you'll learn how to create a payment, pay a worker at the end of their shift (providing early access to wages), confirm that early wages were paid, and retrieve the worker's payment history.

This guide assumes that you've already set up an employer and workers. If you haven't, check out one of our tutorials:

Create a worker payment

First, create a worker payment for a specific worker, providing the pay period and regular pay date. Salsa will use the worker's pay schedule, in this case weekly, to calculate taxes.

curl --location 'https://api.sandbox.salsa.dev/api/rest/v1/employers/${employerId}/workers/${workerId}/worker-payments' \
--header 'accept: application/json' \
--header 'content-type: application/json'
--header 'Authorization: Bearer ${YOUR_API_TOKEN}'
--data '
{
  "payPeriod": {
    "startDate": "2023-05-01"
    "endDate": "2023-05-07",
    "payDate": "2023-05-07",
  }
}'

Example response

{
  "data": {
    "id": "wrrun_a5d448d9-60d5-403e-b9d0-b35a399ff6c4",
    "workerId": "wr_f1686628-b9d4-418d-857a-0e9fc3798b43",
    "payMethod": "DIRECT_DEPOSIT",
    "status": "PENDING",
    "grossPay": "0.00",
    "netPay": "0.00",
    "totals": {
      "payrollCost": "0.00",
      "grossPay": "0.00",
      "netPay": "0.00",
      "deduction": "0.00",
      "contribution": "0.00"
    },
    "paymentRecord": "ernrec_d6b18c12-966f-4466-af63-89e808966c97",
    "compensations": [],
    "deductions": [],
    "taxDeductions": [
      {
        "id": "payrunded_8b964f37-86f4-4909-98a0-09002f512343",
        "name": "Social Security",
        "policy": "key:tax:us:fica",
        "amount": "0.0"
      },
      {
        "id": "payrunded_1e55f609-423f-4897-a207-d9f72fa2fd74",
        "name": "Medicare",
        "policy": "key:tax:us:medi",
        "amount": "0.0"
      },
      {
        "id": "payrunded_99d5607a-5309-4d1b-a144-aaaed5f381f3",
        "name": "Federal Income Tax",
        "policy": "key:tax:us:fit",
        "amount": "0.0"
      },
      {
        "id": "payrunded_bb67f54e-9740-4c80-87b5-5d2bfe5cd02c",
        "name": "Additional Medicare",
        "policy": "key:tax:us:medi2",
        "amount": "0.0"
      },
      {
        "id": "payrunded_a9a99011-6556-4725-ad19-973fdc53de02",
        "name": "CA State Disability Insurance",
        "policy": "key:tax:us-ca:sdi",
        "amount": "0.0"
      },
      {
        "id": "payrunded_7ee2c2cc-ff91-42f6-97e8-fa19e90859ab",
        "name": "CA Personal Income Tax",
        "policy": "key:tax:us-ca:sit",
        "amount": "0.0"
      }
    ],
    "taxContributions": [
      {
        "id": "payruncontr_61f7c8de-71d3-4e9d-b08d-becbe167a8ef",
        "name": "Social Security",
        "policy": "key:tax:us:fica",
        "amount": "0.0"
      },
      {
        "id": "payruncontr_2b030fa1-08e7-4cc0-ab24-678313e25927",
        "name": "Federal Unemployment (FUTA)",
        "policy": "key:tax:us:futa",
        "amount": "0.0"
      },
      {
        "id": "payruncontr_f8d9fdba-b554-433f-99ff-65141a983ffc",
        "name": "Medicare",
        "policy": "key:tax:us:medi",
        "amount": "0.0"
      },
      {
        "id": "payruncontr_99109ead-6171-483f-86a6-0506311e2a06",
        "name": "CA Unemployment Insurance",
        "policy": "key:tax:us-ca:suta",
        "amount": "0.0"
      },
      {
        "id": "payruncontr_fb50df1d-36e2-48fa-819f-a78f28da6c5a",
        "name": "CA Employment Training Tax",
        "policy": "key:tax:us-ca:sutasc",
        "amount": "0.0"
      }
    ],
    "alerts": {
      "info": [],
      "warnings": [],
      "blockers": []
    }
  }
}

Add compensations

After a worker finishes their shift, send Salsa the worker's compensation for that day. Behind the scenes, Salsa automatically adjusts the worker payment created in the previous step, taking into consideration any compensation earner and calculating net pay accordingly.

curl --request POST \ 
--url 'https://api.sandbox.salsa.dev/api/rest/v1/paystream' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'X-Salsa-Organization-Id: :partnerId	' \
--header 'Authorization: Bearer ${YOUR_API_TOKEN}' \
--data-raw '{
  "data": [
    {
      "compensationReferenceId": "ref:comp:partnername:hourly",
      "endDate": "2023-07-07",
      "startDate": "2023-07-07",
      "type": "PaystreamCompensationItemInput",
      "workerId": ":workerId",
      "hours": "20",
      "rate": "50",
      "unit": "HOURS"
    }
  ]
}'

Example response

{
    "data": [
        {
            "paystreamItemId": "paystream_86f0d3db-1393-460f-9f25-069628a351db",
            "partnerId": "prtnr_608bef46-ad22-455a-8eec-20eca48810aa",
            "createdAt": "2023-07-07T16:14:13.020047557",
            "updatedAt": "2023-07-07T16:14:13.035124876",
            "status": "IN_PROGRESS",
            "itemInput": {
                "type": "PaystreamCompensationItemInput",
                "compensationReferenceId": "ref:comp:verticalfintech:hourly",
                "workerId": "wr_f1686628-b9d4-418d-857a-0e9fc3798b43",
                "startDate": "2023-07-07",
                "endDate": "2023-07-07",
                "amount": null,
                "rate": "50",
                "hours": "20",
                "frequency": null
            }
        }
    ]
}

You can also retriever worker payment information, including the net pay calculated for the shift.

curl --location 'https://api.sandbox.salsa.dev/api/rest/v1/employers/${employerId}/worker-payments/${workerPaymentId}' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer ${YOUR_API_TOKEN}

Example response

{
  "data": {
    "id": "wrrun_a5d448d9-60d5-403e-b9d0-b35a399ff6c4",
    "workerId": "wr_f1686628-b9d4-418d-857a-0e9fc3798b43",
    "payMethod": "DIRECT_DEPOSIT",
    "status": "PENDING",
    "grossPay": "1000.00",
    "netPay": "914.50",
    "totals": {
      "payrollCost": "1123.50",
      "grossPay": "1000.00",
      "netPay": "914.50",
      "deduction": "85.50",
      "contribution": "123.50"
    },
    "paymentRecord": "ernrec_f3019ed0-8e71-4b60-9c84-ba50975e4214",
    "compensations": [
      {
        "id": "payruncomp_86be98e0-dbe6-419a-b893-e09a8caa51ef",
        "name": "Hourly",
        "policy": "prtnrcomppol_2758f64e-b1f7-4fd5-b629-dc91cd4930cf",
        "amount": {
          "type": "RATE",
          "rate": "50.00",
          "unit": "HOURS",
          "unitAmount": "20",
          "multiplier": "1"
        }
      }
    ],
    "deductions": [],
    "taxDeductions": [
      {
        "id": "payrunded_8b964f37-86f4-4909-98a0-09002f512343",
        "name": "Social Security",
        "policy": "key:tax:us:fica",
        "amount": "62.0"
      },
      {
        "id": "payrunded_1e55f609-423f-4897-a207-d9f72fa2fd74",
        "name": "Medicare",
        "policy": "key:tax:us:medi",
        "amount": "14.5"
      },
      {
        "id": "payrunded_99d5607a-5309-4d1b-a144-aaaed5f381f3",
        "name": "Federal Income Tax",
        "policy": "key:tax:us:fit",
        "amount": "0.0"
      },
      {
        "id": "payrunded_bb67f54e-9740-4c80-87b5-5d2bfe5cd02c",
        "name": "Additional Medicare",
        "policy": "key:tax:us:medi2",
        "amount": "0.0"
      },
      {
        "id": "payrunded_a9a99011-6556-4725-ad19-973fdc53de02",
        "name": "CA State Disability Insurance",
        "policy": "key:tax:us-ca:sdi",
        "amount": "9.0"
      },
      {
        "id": "payrunded_7ee2c2cc-ff91-42f6-97e8-fa19e90859ab",
        "name": "CA Personal Income Tax",
        "policy": "key:tax:us-ca:sit",
        "amount": "0.0"
      }
    ],
    "taxContributions": [
      {
        "id": "payruncontr_9dce9497-7e70-483a-b868-7864a27bf30b",
        "name": "Social Security",
        "policy": "key:tax:us:fica",
        "amount": "62.0"
      },
      {
        "id": "payruncontr_1905e861-254a-4b7d-8529-1df3801d8be9",
        "name": "Federal Unemployment (FUTA)",
        "policy": "key:tax:us:futa",
        "amount": "6.0"
      },
      {
        "id": "payruncontr_fe3f2728-bdbe-4bc8-a3b4-b05b1c2fd0db",
        "name": "Medicare",
        "policy": "key:tax:us:medi",
        "amount": "14.5"
      },
      {
        "id": "payruncontr_cdbab172-f7e5-47f6-8404-9ef4b34c3abe",
        "name": "CA Unemployment Insurance",
        "policy": "key:tax:us-ca:suta",
        "amount": "40.0"
      },
      {
        "id": "payruncontr_85028844-b25d-4b12-91a1-5aaef504eb24",
        "name": "CA Employment Training Tax",
        "policy": "key:tax:us-ca:sutasc",
        "amount": "1.0"
      }
    ],
    "alerts": {
      "info": [],
      "warnings": [],
      "blockers": []
    }
  }
}

Record the advanced payment

After you've disbursed money to the worker, you can record early payment, so it's deducted from the worker's net pay at the end of the pay period.

📘

Outstanding pay

Salsa will assume outstanding net pay was paid to the worker, and create a post-tax deduction to represent the total amount disbursed.

curl --request POST \
    --url 'https://api.sandbox.salsa.dev/api/rest/v1/employers/${employerId}/worker-payments/${workerPaymentId}/advance-payment' \
    --header 'Accept: application/json' \
    --header 'Authorization: Bearer ${YOUR_API_TOKEN}'

Example response

{
  "data": [
    {
      "id": "wrrun_a5d448d9-60d5-403e-b9d0-b35a399ff6c4",
      "workerId": "wr_f1686628-b9d4-418d-857a-0e9fc3798b43",
      "payMethod": "DIRECT_DEPOSIT",
      "status": "PENDING",
      "grossPay": "1000.00",
      "netPay": "0.00",
      "totals": {
        "payrollCost": "1123.50",
        "grossPay": "1000.00",
        "netPay": "0.00",
        "deduction": "1000.00",
        "contribution": "123.50"
      },
      "paymentRecord": "ernrec_7b34d973-98c7-4f00-91b5-69b371a7bae0",
      "compensations": [
        {
          "id": "payruncomp_86be98e0-dbe6-419a-b893-e09a8caa51ef",
          "name": "Hourly",
          "policy": "prtnrcomppol_2758f64e-b1f7-4fd5-b629-dc91cd4930cf",
          "amount": {
            "type": "RATE",
            "rate": "50.00",
            "unit": "HOURS",
            "unitAmount": "20",
            "multiplier": "1"
          }
        }
      ],
      "deductions": [
        {
          "id": "payrunded_0e9bb115-5ee3-4542-abcf-129287b62bf2",
          "name": "Pay Advancement",
          "policy": "prtnrdedpol_190db0a1-7fcc-4c9f-ae31-4956dd6c929f",
          "amount": {
            "type": "FIXED",
            "amount": "914.50"
          }
        }
      ],
      "taxDeductions": [
        {
          "id": "payrunded_8b964f37-86f4-4909-98a0-09002f512343",
          "name": "Social Security",
          "policy": "key:tax:us:fica",
          "amount": "62.0"
        },
        {
          "id": "payrunded_1e55f609-423f-4897-a207-d9f72fa2fd74",
          "name": "Medicare",
          "policy": "key:tax:us:medi",
          "amount": "14.5"
        },
        {
          "id": "payrunded_99d5607a-5309-4d1b-a144-aaaed5f381f3",
          "name": "Federal Income Tax",
          "policy": "key:tax:us:fit",
          "amount": "0.0"
        },
        {
          "id": "payrunded_bb67f54e-9740-4c80-87b5-5d2bfe5cd02c",
          "name": "Additional Medicare",
          "policy": "key:tax:us:medi2",
          "amount": "0.0"
        },
        {
          "id": "payrunded_a9a99011-6556-4725-ad19-973fdc53de02",
          "name": "CA State Disability Insurance",
          "policy": "key:tax:us-ca:sdi",
          "amount": "9.0"
        },
        {
          "id": "payrunded_7ee2c2cc-ff91-42f6-97e8-fa19e90859ab",
          "name": "CA Personal Income Tax",
          "policy": "key:tax:us-ca:sit",
          "amount": "0.0"
        }
      ],
      "taxContributions": [
        {
          "id": "payruncontr_ece26052-fd2a-44b4-8b3e-9fb594104468",
          "name": "Social Security",
          "policy": "key:tax:us:fica",
          "amount": "62.0"
        },
        {
          "id": "payruncontr_6fd759af-d266-4f17-b507-85de7228d872",
          "name": "Federal Unemployment (FUTA)",
          "policy": "key:tax:us:futa",
          "amount": "6.0"
        },
        {
          "id": "payruncontr_5a3dcefd-cd88-471f-bea0-2b5047d571f0",
          "name": "Medicare",
          "policy": "key:tax:us:medi",
          "amount": "14.5"
        },
        {
          "id": "payruncontr_d584bab6-72ab-443e-a574-ca8fde88d677",
          "name": "CA Unemployment Insurance",
          "policy": "key:tax:us-ca:suta",
          "amount": "40.0"
        },
        {
          "id": "payruncontr_32358ef6-2ae4-4cfe-b5f2-daab51937e46",
          "name": "CA Employment Training Tax",
          "policy": "key:tax:us-ca:sutasc",
          "amount": "1.0"
        }
      ],
      "alerts": {
        "info": [],
        "warnings": [],
        "blockers": []
      }
    }
  ]
}

Confirm the payment

At the end of the pay period, confirm the worker's been paid.

curl --request POST \
     --url 'https://api.sandbox.salsa.dev/api/rest/v1/employers/${employerId}/worker-payments/${workerPaymentId}/confirm' \
     --header 'Accept: application/json' \
     --header 'Authorization: Bearer ${YOUR_API_TOKEN}'

Example response

{
    "data": {
        "id": "wrrun_d199eb6e-244d-4efb-b13d-97aa3da5a6e6",
        "workerId": "wr_f1686628-b9d4-418d-857a-0e9fc3798b43",
        "payMethod": "DIRECT_DEPOSIT",
        "status": "CONFIRMED",
        "grossPay": "1000.00",
        "netPay": "0.00",
        "totals": {
            "payrollCost": "1123.50",
            "grossPay": "1000.00",
            "netPay": "0.00",
            "deduction": "1000.00",
            "contribution": "123.50"
        },
        "paymentRecord": "ernrec_33c35651-41fb-4fa3-b61a-b0ccb4f6880c",
        "compensations": [
            {
                "id": "payruncomp_f8c65cc9-6140-479a-b44f-e6abff6c2f64",
                "name": "Hourly",
                "policy": "prtnrcomppol_2758f64e-b1f7-4fd5-b629-dc91cd4930cf",
                "amount": {
                    "type": "RATE",
                    "rate": "50.00",
                    "unit": "HOURS",
                    "unitAmount": "20",
                    "multiplier": "1"
                }
            }
        ],
        "deductions": [
            {
                "id": "payrunded_0965f88b-3e40-463e-9358-c1eab2fb61f3",
                "name": "Pay Advancement",
                "policy": "prtnrdedpol_190db0a1-7fcc-4c9f-ae31-4956dd6c929f",
                "amount": {
                    "type": "FIXED",
                    "amount": "787.44"
                }
            }
        ],
        "taxDeductions": [
            {
                "id": "payrunded_6a5231a6-1d14-4e91-b05c-60bd3e7bcb7f",
                "name": "Social Security",
                "policy": "key:tax:us:fica",
                "amount": "62.0"
            },
            {
                "id": "payrunded_6597e984-1cdf-4dab-8d78-1bcc3b62ff9c",
                "name": "Medicare",
                "policy": "key:tax:us:medi",
                "amount": "14.5"
            },
            {
                "id": "payrunded_80d262e1-5328-47d5-ae56-2efb5bb9f0a6",
                "name": "Federal Income Tax",
                "policy": "key:tax:us:fit",
                "amount": "127.06"
            },
            {
                "id": "payrunded_440b12da-bd2f-464f-964b-a2f0b2344856",
                "name": "Additional Medicare",
                "policy": "key:tax:us:medi2",
                "amount": "0.0"
            },
            {
                "id": "payrunded_5f77f1dc-0cac-4c5d-a804-1a7f804dc2c5",
                "name": "CA State Disability Insurance",
                "policy": "key:tax:us-ca:sdi",
                "amount": "9.0"
            },
            {
                "id": "payrunded_3a9b3a11-7691-48e0-8471-59bd81d6851c",
                "name": "CA Personal Income Tax",
                "policy": "key:tax:us-ca:sit",
                "amount": "0.0"
            }
        ],
        "taxContributions": [
            {
                "id": "payruncontr_9d14c095-da52-44ae-a8e7-4440bb1231d0",
                "name": "Social Security",
                "policy": "key:tax:us:fica",
                "amount": "62.0"
            },
            {
                "id": "payruncontr_5d239119-6d4f-422c-8627-149816879a4a",
                "name": "Federal Unemployment (FUTA)",
                "policy": "key:tax:us:futa",
                "amount": "6.0"
            },
            {
                "id": "payruncontr_13b337bb-f986-4969-99aa-a995c12bf6b8",
                "name": "Medicare",
                "policy": "key:tax:us:medi",
                "amount": "14.5"
            },
            {
                "id": "payruncontr_dcf5717f-18cf-40ef-94ce-b5b140e993ed",
                "name": "CA Unemployment Insurance",
                "policy": "key:tax:us-ca:suta",
                "amount": "40.0"
            },
            {
                "id": "payruncontr_6b805188-c413-4288-8131-993cff5fc3bf",
                "name": "CA Employment Training Tax",
                "policy": "key:tax:us-ca:sutasc",
                "amount": "1.0"
            }
        ],
        "alerts": {
            "info": [],
            "warnings": [],
            "blockers": []
        }
    }
}

Retrieve payment records

You can retrieve worker payment records for the pay period, which includes compensations, deductions, tax contributions, and totals.

curl --location 'https://api.sandbox.salsa.dev/api/rest/v1/employers/${employerId}/worker-payments/${workerPaymentId}/worker-payment-record' \ \
     --header 'Accept: application/json' \
     --header 'Authorization: Bearer ${YOUR_API_TOKEN}'

Example response

{
  "data": {
    "id": "ernrec_0919bbb2-d4d5-4c7c-bcdb-e0ebbe852cfe",
    "status": "CONFIRMED",
    "category": "EMPLOYEE",
    "document": "doc_ab219643-3b85-4b7d-b8b6-facceeea1cd1",
    "employerDetails": {
      "employer": "er_9c43d4a2-018c-44e0-b19d-9ed3adb42449",
      "businessName": "Early Wage Access Demo",
      "address": {
        "addressLine1": "Address Line 1",
        "addressLine2": "Address Line 2",
        "locality": "Mountain View",
        "administrativeArea": "CA",
        "postalCode": "92300",
        "country": "USA"
      }
    },
    "workerDetails": {
      "worker": "wr_f1686628-b9d4-418d-857a-0e9fc3798b43",
      "displayName": "Joe Doen",
      "firstName": "Joe",
      "lastName": "Doe",
      "address": {
        "addressLine1": "Address Line 1",
        "addressLine2": "Address Line 2",
        "locality": "San Francisco",
        "administrativeArea": "ca",
        "postalCode": "92300",
        "country": "USA"
      }
    },
    "payPeriod": {
      "start": "2023-07-07",
      "end": "2023-07-15"
    },
    "payDate": "2023-07-14",
    "payrollCost": "1123.50",
    "grossPay": "1000.00",
    "netPay": "0.00",
    "payMethod": "DIRECT_DEPOSIT",
    "workTime": {
      "hours": "0"
    },
    "totals": {
      "totalCompensations": {
        "amount": "1000.00",
        "ytdAmount": "1000.00"
      },
      "totalDeductions": {
        "amount": "914.50",
        "ytdAmount": "914.50"
      },
      "totalTaxDeductions": {
        "amount": "85.5",
        "ytdAmount": "85.50"
      },
      "totalTaxContributions": {
        "amount": "123.5",
        "ytdAmount": "123.50"
      }
    },
    "compensations": [
      {
        "description": "Hourly",
        "amount": "1000.00",
        "ytdAmount": "1000.00"
      }
    ],
    "deductions": [
      {
        "description": "Pay Advancement",
        "amount": "914.50",
        "ytdAmount": "914.50"
      }
    ],
    "taxDeductions": [
      {
        "description": "Social Security",
        "amount": "62.0",
        "ytdAmount": "62.00"
      },
      {
        "description": "Medicare",
        "amount": "14.5",
        "ytdAmount": "14.50"
      },
      {
        "description": "CA State Disability Insurance",
        "amount": "9.0",
        "ytdAmount": "9.00"
      }
    ],
    "taxContributions": [
      {
        "description": "Social Security",
        "amount": "62.0",
        "ytdAmount": "62.00"
      },
      {
        "description": "Medicare",
        "amount": "14.5",
        "ytdAmount": "14.50"
      },
      {
        "description": "Federal Unemployment (FUTA)",
        "amount": "6.0",
        "ytdAmount": "6.00"
      },
      {
        "description": "CA Unemployment Insurance",
        "amount": "40.0",
        "ytdAmount": "40.00"
      },
      {
        "description": "CA Employment Training Tax",
        "amount": "1.0",
        "ytdAmount": "1.00"
      }
    ]
  }
}