Upload Workforce Absences CSV
const options = {
method: 'POST',
headers: {
'x-api-key': '<x-api-key>',
'x-organization-id': '<x-organization-id>',
'Content-Type': 'application/json'
},
body: JSON.stringify({file_name: '<string>'})
};
fetch('https://api.dcycle.io/v1/own_workforce_absenteeisms_accidents/bulk/csv', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.dcycle.io/v1/own_workforce_absenteeisms_accidents/bulk/csv"
payload = { "file_name": "<string>" }
headers = {
"x-api-key": "<x-api-key>",
"x-organization-id": "<x-organization-id>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)curl --request POST \
--url https://api.dcycle.io/v1/own_workforce_absenteeisms_accidents/bulk/csv \
--header 'Content-Type: application/json' \
--header 'x-api-key: <x-api-key>' \
--header 'x-organization-id: <x-organization-id>' \
--data '
{
"file_name": "<string>"
}
'{
"upload_url": "<string>",
"file_id": "<string>",
"destination_file_key": "<string>",
"file_name": "<string>",
"organization_id": "<string>",
"message": "<string>"
}Upload Workforce Absences CSV
Request a presigned S3 URL to upload an absences and accidents CSV for asynchronous ingestion
POST
/
v1
/
own_workforce_absenteeisms_accidents
/
bulk
/
csv
Upload Workforce Absences CSV
const options = {
method: 'POST',
headers: {
'x-api-key': '<x-api-key>',
'x-organization-id': '<x-organization-id>',
'Content-Type': 'application/json'
},
body: JSON.stringify({file_name: '<string>'})
};
fetch('https://api.dcycle.io/v1/own_workforce_absenteeisms_accidents/bulk/csv', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.dcycle.io/v1/own_workforce_absenteeisms_accidents/bulk/csv"
payload = { "file_name": "<string>" }
headers = {
"x-api-key": "<x-api-key>",
"x-organization-id": "<x-organization-id>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)curl --request POST \
--url https://api.dcycle.io/v1/own_workforce_absenteeisms_accidents/bulk/csv \
--header 'Content-Type: application/json' \
--header 'x-api-key: <x-api-key>' \
--header 'x-organization-id: <x-organization-id>' \
--data '
{
"file_name": "<string>"
}
'{
"upload_url": "<string>",
"file_id": "<string>",
"destination_file_key": "<string>",
"file_name": "<string>",
"organization_id": "<string>",
"message": "<string>"
}← Own Workforce API
Mint a presigned S3 URL and upload an absences and accidents CSV to it. The call ingests nothing by itself: it returns a URL, and the file is parsed asynchronously once it lands.
Records attach to employees by
Prefer the Imports API for new integrations — template
own_workforce_accidents_absenteeisms, documented in Own Workforce Import Templates. That path matters more here than elsewhere: this data has real validation rules — an accident must not duplicate one already recorded for the same employee on the same day, and an absence must not overlap another — and the Imports API reports those as per-row errors before you submit. This endpoint has no validation step, so violations surface after the upload.external_employee_id, so the employees must already exist before you upload their absences.
How it works
1
Ask for a URL
POST here with the file name. You get back upload_url, a file_id and the destination key.2
PUT the file
Upload the CSV bytes to
upload_url. That request goes to S3 and carries no Dcycle headers.3
Wait for ingestion
Poll List Workforce Absences Paginated filtering on the
file_id you were given, and read each row’s status.Request
Headers
string
required
Your API key for authenticationExample:
sk_live_1234567890abcdefstring
required
Your organization UUIDExample:
a8315ef3-dd50-43f8-b7ce-d839e68d51faBody
string
required
Name of the file you are about to uploadExample:
absences_2026.csvResponse
201 Created.
string
Presigned S3 URL.
PUT the file bytes here. Short-lived — request it immediately before uploading.string
Id of the file record, to follow ingestion and later to delete everything from this upload
string
Object key the file will be stored under
string
Echo of the name you sent
string
Organization the upload is attributed to
string
Human-readable confirmation
Example
curl -X POST "https://api.dcycle.io/v1/own_workforce_absenteeisms_accidents/bulk/csv" \
-H "x-api-key: ${DCYCLE_API_KEY}" \
-H "x-organization-id: ${DCYCLE_ORG_ID}" \
-H "Content-Type: application/json" \
-d '{"file_name": "absences_2026.csv"}'
curl -X PUT "${UPLOAD_URL}" --upload-file absences_2026.csv
import os
import requests
headers = {
"x-api-key": os.getenv("DCYCLE_API_KEY"),
"x-organization-id": os.getenv("DCYCLE_ORG_ID"),
}
presigned = requests.post(
"https://api.dcycle.io/v1/own_workforce_absenteeisms_accidents/bulk/csv",
headers=headers,
json={"file_name": "absences_2026.csv"},
).json()
with open("absences_2026.csv", "rb") as handle:
requests.put(presigned["upload_url"], data=handle).raise_for_status()
print("ingesting under file_id", presigned["file_id"])
const axios = require('axios');
const fs = require('fs');
const headers = {
'x-api-key': process.env.DCYCLE_API_KEY,
'x-organization-id': process.env.DCYCLE_ORG_ID
};
axios.post('https://api.dcycle.io/v1/own_workforce_absenteeisms_accidents/bulk/csv',
{ file_name: 'absences_2026.csv' }, { headers })
.then(({ data }) =>
axios.put(data.upload_url, fs.createReadStream('absences_2026.csv'))
.then(() => console.log('ingesting under file_id', data.file_id))
)
.catch(error => console.error(error));
Successful Response
{
"upload_url": "https://dcycle-uploads.s3.eu-west-1.amazonaws.com/...",
"file_id": "dd44ee55-ff66-4077-8188-99aabbccddee",
"destination_file_key": "dcycle/a8315ef3-dd50-43f8-b7ce-d839e68d51fa/own_workforce_absenteeism_accidents/absences_2026.csv",
"file_name": "absences_2026.csv",
"organization_id": "a8315ef3-dd50-43f8-b7ce-d839e68d51fa",
"message": "Presigned URL created successfully"
}
Common Errors
401 Unauthorized
Cause: the key is invalid, or it does not belong to the organization inx-organization-id — the two are looked up as a pair. A request carrying no credentials at all answers AUTH_REQUIRED instead.
{
"detail": "Invalid API key for organization",
"code": "INVALID_API_KEY"
}
403 Forbidden
Cause: the key’s owner is not an enabled member of the organization, or their role cannot write.{
"detail": "Logged User is not Member of Organization",
"code": "LOGGED_USER_NOT_MEMBER"
}
422 Unprocessable Entity
Cause:file_name missing from the body.
{
"detail": [
{
"type": "missing",
"loc": ["body", "file_name"],
"msg": "Field required"
}
]
}
Related Endpoints
Own workforce import templates
Columns and the duplicate/overlap rules
Validate an import
Catch violations before submitting
Was this page helpful?