curl --request POST \
--url https://api.cadanapay.com/v1/payrolls/{payrollId}/save \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"payrollDate": "2026-03-01",
"payPeriod": {
"fromDate": "2026-02-01",
"toDate": "2026-02-28"
},
"entries": [
{
"personId": "8ab2ba37-3c37-485d-9af9-122d11c96bf9",
"salary": {
"amount": 500000,
"currency": "USD"
}
},
{
"personId": "ca49c55b-12c7-4085-8a0d-ebd006ed8002",
"salary": {
"amount": 375000,
"currency": "USD"
}
}
]
}
'import requests
url = "https://api.cadanapay.com/v1/payrolls/{payrollId}/save"
payload = {
"payrollDate": "2026-03-01",
"payPeriod": {
"fromDate": "2026-02-01",
"toDate": "2026-02-28"
},
"entries": [
{
"personId": "8ab2ba37-3c37-485d-9af9-122d11c96bf9",
"salary": {
"amount": 500000,
"currency": "USD"
}
},
{
"personId": "ca49c55b-12c7-4085-8a0d-ebd006ed8002",
"salary": {
"amount": 375000,
"currency": "USD"
}
}
]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
payrollDate: '2026-03-01',
payPeriod: {fromDate: '2026-02-01', toDate: '2026-02-28'},
entries: [
{
personId: '8ab2ba37-3c37-485d-9af9-122d11c96bf9',
salary: {amount: 500000, currency: 'USD'}
},
{
personId: 'ca49c55b-12c7-4085-8a0d-ebd006ed8002',
salary: {amount: 375000, currency: 'USD'}
}
]
})
};
fetch('https://api.cadanapay.com/v1/payrolls/{payrollId}/save', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.cadanapay.com/v1/payrolls/{payrollId}/save",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'payrollDate' => '2026-03-01',
'payPeriod' => [
'fromDate' => '2026-02-01',
'toDate' => '2026-02-28'
],
'entries' => [
[
'personId' => '8ab2ba37-3c37-485d-9af9-122d11c96bf9',
'salary' => [
'amount' => 500000,
'currency' => 'USD'
]
],
[
'personId' => 'ca49c55b-12c7-4085-8a0d-ebd006ed8002',
'salary' => [
'amount' => 375000,
'currency' => 'USD'
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.cadanapay.com/v1/payrolls/{payrollId}/save"
payload := strings.NewReader("{\n \"payrollDate\": \"2026-03-01\",\n \"payPeriod\": {\n \"fromDate\": \"2026-02-01\",\n \"toDate\": \"2026-02-28\"\n },\n \"entries\": [\n {\n \"personId\": \"8ab2ba37-3c37-485d-9af9-122d11c96bf9\",\n \"salary\": {\n \"amount\": 500000,\n \"currency\": \"USD\"\n }\n },\n {\n \"personId\": \"ca49c55b-12c7-4085-8a0d-ebd006ed8002\",\n \"salary\": {\n \"amount\": 375000,\n \"currency\": \"USD\"\n }\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.cadanapay.com/v1/payrolls/{payrollId}/save")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"payrollDate\": \"2026-03-01\",\n \"payPeriod\": {\n \"fromDate\": \"2026-02-01\",\n \"toDate\": \"2026-02-28\"\n },\n \"entries\": [\n {\n \"personId\": \"8ab2ba37-3c37-485d-9af9-122d11c96bf9\",\n \"salary\": {\n \"amount\": 500000,\n \"currency\": \"USD\"\n }\n },\n {\n \"personId\": \"ca49c55b-12c7-4085-8a0d-ebd006ed8002\",\n \"salary\": {\n \"amount\": 375000,\n \"currency\": \"USD\"\n }\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cadanapay.com/v1/payrolls/{payrollId}/save")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"payrollDate\": \"2026-03-01\",\n \"payPeriod\": {\n \"fromDate\": \"2026-02-01\",\n \"toDate\": \"2026-02-28\"\n },\n \"entries\": [\n {\n \"personId\": \"8ab2ba37-3c37-485d-9af9-122d11c96bf9\",\n \"salary\": {\n \"amount\": 500000,\n \"currency\": \"USD\"\n }\n },\n {\n \"personId\": \"ca49c55b-12c7-4085-8a0d-ebd006ed8002\",\n \"salary\": {\n \"amount\": 375000,\n \"currency\": \"USD\"\n }\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"fxRates": {
"USD-PHP": 58.75,
"USD-EUR": 0.9217
}
}{
"code": "invalid_request_body",
"message": "The request body provided is not valid",
"params": {
"field": "Value is invalid."
}
}Save
Save a payroll
curl --request POST \
--url https://api.cadanapay.com/v1/payrolls/{payrollId}/save \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"payrollDate": "2026-03-01",
"payPeriod": {
"fromDate": "2026-02-01",
"toDate": "2026-02-28"
},
"entries": [
{
"personId": "8ab2ba37-3c37-485d-9af9-122d11c96bf9",
"salary": {
"amount": 500000,
"currency": "USD"
}
},
{
"personId": "ca49c55b-12c7-4085-8a0d-ebd006ed8002",
"salary": {
"amount": 375000,
"currency": "USD"
}
}
]
}
'import requests
url = "https://api.cadanapay.com/v1/payrolls/{payrollId}/save"
payload = {
"payrollDate": "2026-03-01",
"payPeriod": {
"fromDate": "2026-02-01",
"toDate": "2026-02-28"
},
"entries": [
{
"personId": "8ab2ba37-3c37-485d-9af9-122d11c96bf9",
"salary": {
"amount": 500000,
"currency": "USD"
}
},
{
"personId": "ca49c55b-12c7-4085-8a0d-ebd006ed8002",
"salary": {
"amount": 375000,
"currency": "USD"
}
}
]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
payrollDate: '2026-03-01',
payPeriod: {fromDate: '2026-02-01', toDate: '2026-02-28'},
entries: [
{
personId: '8ab2ba37-3c37-485d-9af9-122d11c96bf9',
salary: {amount: 500000, currency: 'USD'}
},
{
personId: 'ca49c55b-12c7-4085-8a0d-ebd006ed8002',
salary: {amount: 375000, currency: 'USD'}
}
]
})
};
fetch('https://api.cadanapay.com/v1/payrolls/{payrollId}/save', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.cadanapay.com/v1/payrolls/{payrollId}/save",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'payrollDate' => '2026-03-01',
'payPeriod' => [
'fromDate' => '2026-02-01',
'toDate' => '2026-02-28'
],
'entries' => [
[
'personId' => '8ab2ba37-3c37-485d-9af9-122d11c96bf9',
'salary' => [
'amount' => 500000,
'currency' => 'USD'
]
],
[
'personId' => 'ca49c55b-12c7-4085-8a0d-ebd006ed8002',
'salary' => [
'amount' => 375000,
'currency' => 'USD'
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.cadanapay.com/v1/payrolls/{payrollId}/save"
payload := strings.NewReader("{\n \"payrollDate\": \"2026-03-01\",\n \"payPeriod\": {\n \"fromDate\": \"2026-02-01\",\n \"toDate\": \"2026-02-28\"\n },\n \"entries\": [\n {\n \"personId\": \"8ab2ba37-3c37-485d-9af9-122d11c96bf9\",\n \"salary\": {\n \"amount\": 500000,\n \"currency\": \"USD\"\n }\n },\n {\n \"personId\": \"ca49c55b-12c7-4085-8a0d-ebd006ed8002\",\n \"salary\": {\n \"amount\": 375000,\n \"currency\": \"USD\"\n }\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.cadanapay.com/v1/payrolls/{payrollId}/save")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"payrollDate\": \"2026-03-01\",\n \"payPeriod\": {\n \"fromDate\": \"2026-02-01\",\n \"toDate\": \"2026-02-28\"\n },\n \"entries\": [\n {\n \"personId\": \"8ab2ba37-3c37-485d-9af9-122d11c96bf9\",\n \"salary\": {\n \"amount\": 500000,\n \"currency\": \"USD\"\n }\n },\n {\n \"personId\": \"ca49c55b-12c7-4085-8a0d-ebd006ed8002\",\n \"salary\": {\n \"amount\": 375000,\n \"currency\": \"USD\"\n }\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cadanapay.com/v1/payrolls/{payrollId}/save")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"payrollDate\": \"2026-03-01\",\n \"payPeriod\": {\n \"fromDate\": \"2026-02-01\",\n \"toDate\": \"2026-02-28\"\n },\n \"entries\": [\n {\n \"personId\": \"8ab2ba37-3c37-485d-9af9-122d11c96bf9\",\n \"salary\": {\n \"amount\": 500000,\n \"currency\": \"USD\"\n }\n },\n {\n \"personId\": \"ca49c55b-12c7-4085-8a0d-ebd006ed8002\",\n \"salary\": {\n \"amount\": 375000,\n \"currency\": \"USD\"\n }\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"fxRates": {
"USD-PHP": 58.75,
"USD-EUR": 0.9217
}
}{
"code": "invalid_request_body",
"message": "The request body provided is not valid",
"params": {
"field": "Value is invalid."
}
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Headers
Required when using a Platform API token. The tenant key identifying which business to operate on.
Path Parameters
The unique identifier for the payroll
Query Parameters
When true, the response is 200 OK with the captured FX rates in the body, keyed as <funding>-<salary> currency pairs. Any other value (or omitting the parameter) returns 204 No Content.
Body
payroll date
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Maximum time the quoted FX rates are valid (RFC 3339). If omitted, spot rates are used.
"2025-06-15T23:59:59Z"
Optional custom fee line items that supplement the standard per-seat subscription fees.
Show child attributes
Show child attributes
Any custom data you want to store
Response
FX rates captured at save time. Returned only when includeFxRates=true. Keys are <funding>-<salary> currency pairs; each value is the number of salary-currency units per unit of funding currency. Salary-currency amounts are divided by the rate to get the funding-currency debit.
Map of <funding>-<salary> currency pair to the captured rate.
Show child attributes
Show child attributes