Incremental Data Endpoint
Overview
IncrementalData is the Data API operation that exports only the records that changed since a given point in time, identified by a Change Tracking Version. This contrasts with FullData, which always exports the complete current state of an entity.
This endpoint allows the consumer to start a data loader operation for configured entities to extract the latest synchronizations received as incrementals — in other words, it performs a delta operation over the stored data and returns only the information within the requested period.
A client that already holds a full snapshot (obtained via FullData) calls IncrementalData periodically to receive only the delta — new inserts, updates, and deletes — since its last sync point.
Base URL
https://api.youforce.com/data/v1/incrementaldata
Swagger: https://data.youforce.com/data/swagger/index.html
Authentication & Scopes
All requests require a Bearer token in the Authorization header.
IncrementalData is authorized using the same OAuth2 scopes as FullData:
| Base URL pattern | Required scope (read) | Required scope (manage) |
|---|---|---|
https://data.youforce.com/data/v1/ |
youforce-data-api:data:read |
youforce-data-api:jobs:manage |
DPoP support
In addition to standard Bearer token authentication, IncrementalData operations can optionally be protected using DPoP (Demonstrating Proof-of-Possession, RFC 9449), mirroring the security options available for FullData. This provides an additional layer of assurance that the caller holds the private key associated with the token, rather than relying solely on token possession.
Important Considerations
Field selection follows your configuration
If your configurationId mapping restricts which fields are returned (as configured in the Configuration API), IncrementalData respects that same restriction — column projection is applied consistently regardless of whether a record was inserted, updated, or deleted.
Omitting entity returns one job per entity
As with FullData, if entity is omitted from the request body, the operation fans out into one job per entity defined in the configuration mapping, rather than a single job.
Payroll data limitation
There is a limitation on the payroll table (payroll-results entity): The DaaS backend applies a date range filter to this entity: only records within the current and previous calendar years are exported.
Note: this filter does not apply to
Deleterecords forpayroll-results, since deleted records no longer carry aCalculationYearvalue — deletions are always returned regardless of the original record’s year.Examples:
- Today is 1 November 2025 → the API retrieves payroll data from 1 January 2024 onward.
- Today is 15 February 2025 → the API retrieves payroll data from 1 January 2024 onward.
Queueing, concurrency, and limits
Triggered operations — and therefore their jobs — are processed through an internal queue:
- Jobs that cannot start immediately are placed in the queue with status Pending.
- As running jobs complete, pending jobs are automatically picked up and executed.
- A maximum of 20 jobs can run in parallel, per configuration (a tenant can have several clients defined in the Developer Portal).
- Unlike FullData, IncrementalData does not enforce a
maxRequestsPerDaylimit — you can trigger as many incremental operations per day as needed. - However, only one active job per entity is allowed at a time: if a second request targets an entity that already has a job in flight, the API returns
409 Conflict. An in-flight job can be cancelled via the cancel endpoint if needed. - There is no specific concurrency limit per entity or table beyond the limits above.
Developer tips
- Applications should monitor the operation status and wait for completion before submitting another operation for the same client.
- Files can be downloaded as soon as their jobs have been completed, you don’t need to wait for the whole operation to be finished to start the downloading process.
Change Tracking Version
Server Change Tracking assigns a monotonically increasing integer version to every row-level change (INSERT, UPDATE, DELETE) on an enabled table. The Data API backend exposes the current version via:
GET /v1/IncrementalData/ChangeTrackingVersion
→ { "changeTrackingVersion": 123456 }
A client that passes ChangeTrackingVersion: N when calling IncrementalData receives all changes that happened after version N, up to the current version.
Version boundary semantics
| Value passed | Records returned |
|---|---|
N (the version saved just before an operation) |
Changes from N+1 onwards — i.e. the operation itself is included |
N-1 (one before the saved point) |
Changes from N onwards — i.e. a wider window that also includes the operation |
Behavioral note: updates can appear as inserts
If you query from a ChangeTrackingVersion that predates a record’s original insert (for example, using 0 as a full baseline, or a window wide enough to include the insert itself), that record will be reported with Operation: Insert — even if it was subsequently updated. This is because Change Tracking reports the net change within the requested window: since the record didn’t exist at the start of the window, its net change is “created,” regardless of how many updates happened afterward. Deleted records are unaffected by this — a deleted record is always reported as Delete, regardless of window width, since there is no “current state” left to reconcile.
Behavioral note: repeated changes are coalesced
If the same record is changed multiple times within the same queried ChangeTrackingVersion window, IncrementalData returns a single, coalesced entry reflecting the record’s latest state — not one entry per underlying change.
Endpoints
1. Trigger an incremental export
POST /data/v1/incrementaldata
Starts a data loader operation for the selected configured entities. It runs one job per configured entity/table, or a single job if the entity parameter is provided — omitting entity triggers all entities defined in the configuration, each producing its own job and output file.
If a new request is submitted while another request for the same entity is still being processed, the response returns 409 Conflict.
Parameters
| Type | Name | Description |
|---|---|---|
| Header | Authorization |
Bearer token (required) |
| Path | — | None |
| Query | — | None |
| Body | configurationId |
Explicit configuration to apply. If omitted, the default configuration set in the Configuration API is used. |
| Body | fileFormat |
Format of the returned file. Currently only csv and json are accepted. |
| Body | entity |
Entity for which the operation will run. Only one job/output file is created for this entity. If omitted, all entities defined for the configuration are triggered, each producing its own job and output file. |
| Body | version |
Desired version of the entity, if it has multiple versions. If omitted, the latest version is used. |
| Body | changeTrackingVersion |
The change tracking version boundary — only changes after this version are returned. |
Request example
curl --location 'https://api.youforce.com/data/v1/incrementaldata' \
--header 'Authorization: Bearer abc' \
--header 'Content-Type: application/json' \
--data '{
"configurationId": "testing-default-4028868",
"fileFormat": "csv",
"entity": "sickness-case",
"version": 1
}'
Response
202 Accepted — the response body includes the operationId, used for all subsequent queries on this operation:
{
"operationId": "88549862-af91-49c1-9545-683edd948931"
}
2. Check operation status
GET /data/v1/incrementaldata/{operationId}/status
Returns the processing status of each job within the operation, plus the overall operation status.
When jobs within an operation have different outcomes, the overall status may reflect a partial state:
- PartiallyFailed — some jobs failed, the rest completed.
- PartiallyCancelled — some jobs were cancelled, the rest completed.
- PartiallyDeleted — some job files were deleted, the rest completed.
Parameters
| Type | Name | Description |
|---|---|---|
| Header | Authorization |
Bearer token (required) |
| Path | operationId |
Id of the operation returned by the initial POST request |
| Query | — | None |
| Body | — | None |
Request example
curl --location 'https://api.youforce.com/data/v1/incrementaldata/{operationId}/status' \
--header 'Authorization: Bearer abc'
Response
200 OK
| Field | Description |
|---|---|
operationId |
The requested operation Id |
configurationId |
Configuration Id applied for generating the output |
status |
Overall status of the operation: Pending, Completed, Cancelled, Failed (and partial variants above) |
jobs |
Array with the status of each individual job |
jobs[].id |
Job Id |
jobs[].entity |
Entity related to the job |
jobs[].version |
Version of the job being delivered |
jobs[].status |
Status of the job: Pending, Completed, Cancelled, Failed |
jobs[].createdAt |
Date/time the request was created |
jobs[].startedAt |
Date/time the job started |
jobs[].completedAt |
Date/time the job finished |
jobs[].cancelledAt |
Date/time the job was cancelled |
jobs[].failedAt |
Date/time the job failed |
jobs[].failedReason |
Reason the job failed |
jobs[].totalCount |
Total number of rows to be returned |
jobs[].processedCount |
Number of rows processed so far |
jobs[].expirationDate |
Date/time when the generated file will be removed from our systems |
jobs[].links |
Links to download the successfully processed files |
Example — Pending operation
{
"operationId": "88549862-af91-49c1-9545-683edd948931",
"configurationId": "testing-default-4028868",
"status": "Pending",
"jobs": [
{
"id": "0d629dbc-8d49-46df-8c0a-8469a67fd7d3",
"entity": "sickness-case",
"version": 1,
"status": "Pending",
"createdAt": "2025-10-30T13:24:33.078654Z"
}
]
}
Example — Completed operation
{
"operationId": "88549862-af91-49c1-9545-683edd948931",
"configurationId": "testing-default-4028868",
"status": "Completed",
"jobs": [
{
"id": "0d629dbc-8d49-46df-8c0a-8469a67fd7d3",
"entity": "sickness-case",
"version": 1,
"status": "Completed",
"createdAt": "2025-10-30T13:24:33.078654Z",
"startedAt": "2025-10-30T13:25:05.183246Z",
"completedAt": "2025-10-30T13:25:08.219779Z",
"totalCount": 400,
"processedCount": 400,
"expirationDate": "2025-10-31T13:25:08.219808Z",
"links": {
"download": "https://api.youforce.com/data/v1/jobs/0d629dbc-8d49-46df-8c0a-8469a67fd7d3"
}
}
]
}
3. Retry a failed operation
PUT /data/v1/incrementaldata/{operationId}/retry
Retries a failed data loader operation. Only the failed jobs within the operation are retried — jobs that already completed successfully are left untouched.
If the operation has no failed jobs and a retry is triggered, the API returns 404 Not Found.
Parameters
| Type | Name | Description |
|---|---|---|
| Header | Authorization |
Bearer token (required) |
| Path | operationId |
Id of the operation returned by the initial POST request |
| Query | — | None |
| Body | — | None |
Request example
curl --location --request PUT 'https://api.youforce.com/data/v1/incrementaldata/ed41e267-8cbb-4e08-b4bf-60d7a26d7fd8/retry' \
--header 'Authorization: Bearer abc'
Response
202 Accepted
4. Cancel an operation
POST /data/v1/incrementaldata/{operationId}/cancel
Cancels a data loader operation. This stops all jobs of that operation that are still in progress — a job can only be cancelled if it has not completed yet; a completed job cannot be cancelled.
Error responses
| Code | Cause |
|---|---|
400 Bad Request |
The operation has already completed |
404 Not Found |
There are no jobs pending or being processed at the time of the request |
Parameters
| Type | Name | Description |
|---|---|---|
| Header | Authorization |
Bearer token (required) |
| Path | operationId |
Id of the operation returned by the initial POST request |
| Query | — | None |
| Body | — | None |
Request example
curl --location --request POST 'https://api.youforce.com/data/v1/incrementaldata/ed41e267-8cbb-4e08-b4bf-60d7a26d7fd8/cancel' \
--header 'Authorization: Bearer abc'
Response
204 No Content
5. Delete operation files
DELETE /data/v1/incrementaldata/{operationId}
Deletes the files generated by a data loader operation — specifically, all downloadable files belonging to jobs that completed successfully within the specified operation.
Returns 400 Bad Request if the jobs are not yet completed.
Parameters
| Type | Name | Description |
|---|---|---|
| Header | Authorization |
Bearer token (required) |
| Path | operationId |
Id of the operation returned by the initial POST request |
| Query | — | None |
| Body | — | None |
Request example
curl --location --request DELETE 'https://api.youforce.com/data/v1/incrementaldata/ed41e267-8cbb-4e08-b4bf-60d7a26d7fd8' \
--header 'Authorization: Bearer abc'
Response
204 No Content
6. Download a job file
GET /v1/jobs/{jobId}
Downloads the file generated for a specific job (available once the job’s status is Completed, via the links.download field returned by the status endpoint).
Response
The file content in the requested format (csv or json), with an X-Content-MD5 header containing the base64-encoded MD5 hash of the response body — use this to verify the integrity of the downloaded file.
Summary of Key Behaviors
| Scenario | Result |
|---|---|
No entity specified |
All entities in the configuration are exported; one job per entity |
entity specified |
Only that entity is exported; exactly one job |
Querying from before a record’s original insert version (e.g. ChangeTrackingVersion: 0) |
The record is reported as Insert, even if it was later updated |
| Same record changed multiple times within the queried window | Returned as a single, coalesced entry reflecting its latest state |
payroll-results record older than the last year |
Excluded from the result (except Delete records, which are always included) |
| New request for an entity that already has a job in flight | 409 Conflict |
| Cancel an already-completed operation | 400 Bad Request |
| Cancel with no pending/running jobs | 404 Not Found |
| Retry with no failed jobs | 404 Not Found |
| Delete files before jobs complete | 400 Bad Request |