Sync jobs API reference
This page is the endpoint-by-endpoint reference for the sync jobs API. For a conceptual introduction, the lifecycle, and how to choose between modes, start with the overview. For mode-specific guidance, see DIFF, PATCH, CROSS_SCOPE, and OVERRIDE.
All sync job endpoints are mounted under /persister/synchronization/jobs.
Authentication
Every request needs:
Authorization: Bearer <api-key>jupiterone-account: <account-id>
See Authentication for setup.
Request body properties
The start endpoint accepts these top-level properties:
source
apifor ad-hoc data uploaded by you.integration-externalfor custom integrations.
scope
- Any string. Used to group everything in this sync job for the purposes of comparison on finalize.
- Required when
syncModeisDIFF. - Can only be used when
sourceisapi.
syncMode
DIFF(default): replaces the full dataset in scope. See DIFF.PATCH: adds or updates entities only; never deletes. See PATCH.CROSS_SCOPE: relationships between entities in different scopes. See CROSS_SCOPE.OVERRIDE: pins property values on managed-integration entities. See OVERRIDE.
integrationInstanceId
- Required when referencing a custom integration (when
sourceisintegration-external).
Request flags
ignoreDuplicates
- Instructs the system not to throw an error if there are graph objects with duplicate keys. The latest object wins.
The CREATE_OR_UPDATE mode is deprecated and no longer functions.
Validation
The synchronization API performs comprehensive validation on all uploaded data. The required fields depend on the sync mode; see each mode's page for the full list.
Property constraints
Custom properties:
- Cannot start with underscore (
_) — these are reserved for system properties. - Must be one of:
string,boolean,number,null, or a homogenous array of one of those types.
Invalid values:
- Mixed-type arrays (e.g.,
["string", 123, true]). - Nested objects (except
_rawData). undefined.
Mapped relationships
Mapped relationships (used when one of the related entities isn't directly known) require:
_key,_type,_class._mappingobject with:sourceEntityKey— required, the key of the source entity.targetFilterKeys— required, array of arrays for filtering target entities.targetEntity— required, object describing the target entity.skipTargetCreation— optional boolean.relationshipDirection— optional,"FORWARD"or"REVERSE".
Upload size constraints
Each upload request must contain at least one entity or one relationship. Both arrays can be present in the same request (mode permitting).
Common validation errors
| Error | Cause | Fix |
|---|---|---|
Missing JupiterOne-Account header | Required header not provided. | Include jupiterone-account. |
/entities/0/_key is required | Missing required field. | Add _key (required by DIFF). |
/entities/0 (entity key: "key-1") has invalid property name '_internal' | Property name starts with _. | Rename without the leading underscore. |
/entities/0/_class (entity key: "key-1") has invalid type. Valid types are string or array of strings. | Invalid _class type. | Use a string or array of strings. |
/entities/0/_key: maximum length exceeded | Field exceeds character limit. | Shorten _key to ≤ 7000 characters. |
Relationships are not allowed in PATCH jobs | Relationships uploaded in PATCH mode. | Use DIFF or CROSS_SCOPE. |
Relationship uploads are not allowed for OVERRIDE sync jobs | Relationships uploaded in OVERRIDE mode. | OVERRIDE only accepts entities. |
OVERRIDE sync jobs are limited to 10000 entities per job | Per-job entity cap exceeded. | Split across multiple sync jobs. |
OVERRIDE sync mode is not enabled for this account | Account not on the OVERRIDE allowlist. | Contact JupiterOne support. |
entities must have minimum 1 item | Empty entities array. | Include at least one entity, or omit the array. |
Endpoints
Start a synchronization job
POST /persister/synchronization/jobs
Request:
{
"source": "api",
"syncMode": "DIFF",
"scope": "my-sync-job"
}
Or with a custom integration source:
{
"source": "integration-managed",
"integrationInstanceId": "5465397d-8491-4a12-806a-04792839abe3"
}
Response:
{
"job": {
"source": "api",
"scope": "my-sync-job",
"id": "f445397d-8491-4a12-806a-04792839abe3",
"status": "AWAITING_UPLOADS",
"startTimestamp": 1586915139427,
"numEntitiesUploaded": 0,
"numRelationshipsUploaded": 0,
"numMappedRelationshipsUploaded": 0
}
}
Get status of a synchronization job
GET /persister/synchronization/jobs/{jobId}
Response:
{
"job": {
"source": "api",
"scope": "my-sync-job",
"id": "f445397d-8491-4a12-806a-04792839abe3",
"status": "AWAITING_UPLOADS",
"startTimestamp": 1586915139427,
"numEntitiesUploaded": 0,
"numRelationshipsUploaded": 0,
"numMappedRelationshipsUploaded": 0
}
}
The response carries running counters of the data uploaded so far in this job: total entities, total relationships, and total mapped relationships. After finalize completes, these are the final totals applied to the graph.
Upload a batch of entities and/or relationships
The upload endpoints accept application/json only. Send the body with Content-Type: application/json. Requests may be gzip- or brotli-compressed.
POST /persister/synchronization/jobs/{jobId}/upload
{
"entities": [
{
"_key": "1",
"_class": "DataStore",
"_type": "fake_entity",
"displayName": "my_datastore"
},
{
"_key": "2",
"_class": "Database",
"_type": "fake_entity",
"displayName": "my_database"
}
],
"relationships": [
{
"_key": "a",
"_type": "fake_relationship",
"_class": "IS",
"_fromEntityKey": "1",
"_toEntityKey": "2"
}
]
}
Upload entities only
POST /persister/synchronization/jobs/{jobId}/entities
{
"entities": [
{ "_key": "1", "_type": "fake_entity" }
]
}
Upload relationships only
POST /persister/synchronization/jobs/{jobId}/relationships
{
"relationships": [
{
"_key": "a",
"_type": "fake_relationship",
"_class": "HAS",
"_fromEntityKey": "1",
"_toEntityKey": "2"
}
]
}
Finalize a synchronization job
POST /persister/synchronization/jobs/{jobId}/finalize
Finalize is asynchronous. The response confirms the job has entered finalization; it does not wait for the graph to be updated.
{
"job": {
"id": "f445397d-8491-4a12-806a-04792839abe3",
"status": "FINALIZE_PENDING"
}
}
Poll get status until status is FINISHED (or terminal: ABORTED, FAILED, ERROR).
See also
- Sync jobs overview — concepts and decision guide.
- DIFF, PATCH, CROSS_SCOPE, OVERRIDE — per-mode guidance and scenarios.
- Creating relationships between entities.