The Custom Scheduled Job Endpoint is used to manage custom scheduled jobs on a given node and module. It supports creating, updating, fetching, triggering, and deleting jobs, as well as viewing their execution history.
All operations live under a single base path:
http://localhost:9000/scheduled-job
Every job is scoped to a node and a module, but these are not part of the URL path. Instead they are supplied:
nodeId and moduleId fields) when creating or updating a job, andnodeId and moduleId) when listing jobs or execution histories.Individual jobs are addressed by their numeric pid (returned when the job is created), not by their scheduledJobId.
Note the following, which are common to the methods below:
nodeId – The ID of the node under which the job lives.moduleId – The ID of the module that defines the target job or route.
For most batch jobs this is the persistence module; for camel routes it is the module that defines the route.
The module must be running, even if the job is set as inactive (ie, you cannot target an archived or stopped module)This method creates a new custom scheduled job on the given node and module.
To invoke:
POST http://localhost:9000/scheduled-job
Content-Type: application/json
The request body is a scheduled job definition:
{
"nodeId": "Master",
"moduleId": "persistence",
"scheduledJobId": "nightly-reindex",
"schedule": "0 0 2 * * ?",
"active": true,
"target": "batch:REINDEX",
"schedulerType": "CLUSTERED",
"parameters": "{\"partitionedUrl\":[{\"url\":\"Patient?\",\"requestPartitionId\":{\"allPartitions\":true}}]}"
}
Note the following body elements:
scheduledJobId – A unique ID, starting with a letter and composed only of letters, numbers, -, and _.schedule – A Quartz cron expression. For example, 0 0 2 * * ? runs every day at 02:00.active – true if the job should run on its schedule, false to leave it defined but inactive.target – The target to invoke, prefixed with batch: for a batch job (e.g. batch:REINDEX) or camel: for a camel route (e.g. camel:direct:my-route).schedulerType – Either CLUSTERED (fires once across the entire cluster) or LOCAL (fires on every node). In a non-clustered environment all jobs are effectively LOCAL.parameters – Optional. A JSON string (escaped) containing the parameters passed to the target job.On success, the server responds with 201 Created and the stored job, including its generated pid and read-only creationDate. Use the pid to address the job in later fetch, update, delete, and trigger calls:
{
"pid": 42,
"nodeId": "Master",
"moduleId": "persistence",
"scheduledJobId": "nightly-reindex",
"schedule": "0 0 2 * * ?",
"active": true,
"target": "batch:REINDEX",
"schedulerType": "CLUSTERED",
"parameters": "{\"partitionedUrl\":[{\"url\":\"Patient?\",\"requestPartitionId\":{\"allPartitions\":true}}]}",
"creationDate": "2026-06-25T02:00:00.000-04:00"
}
This method updates an existing custom scheduled job. The job to update is identified by the numeric pid in the path; any pid in the request body is ignored and overwritten by the path value.
To invoke:
PUT http://localhost:9000/scheduled-job/{pid}
Content-Type: application/json
Note the following path elements:
pid – The numeric PID of the scheduled job to update.The request body is the same scheduled job definition used to create a job. For example, to deactivate the job:
{
"nodeId": "Master",
"moduleId": "persistence",
"scheduledJobId": "nightly-reindex",
"schedule": "0 0 2 * * ?",
"active": false,
"target": "batch:REINDEX",
"schedulerType": "CLUSTERED"
}
On success, the server responds with 200 OK and the updated job definition.
This method returns the custom scheduled jobs defined on the given node and module. Results are paged.
To invoke:
GET http://localhost:9000/scheduled-job?nodeId={node_id}&moduleId={module_id}
All query parameters are optional. You may add the following to filter the results:
nodeId=[String] – Return only jobs defined on this node.moduleId=[String] – Return only jobs defined on this module.isActive=[boolean] – Return only active (true) or inactive (false) jobs.from=[String] – Return jobs created on or after this date/time (ISO-8601).to=[String] – Return jobs created on or before this date/time (ISO-8601).page=[int] – The page index to return.The server will produce a response resembling the following. previousPage and nextPage are null when there is no adjacent page:
{
"list": [
{
"pid": 42,
"nodeId": "Master",
"moduleId": "persistence",
"scheduledJobId": "nightly-reindex",
"schedule": "0 0 2 * * ?",
"active": true,
"target": "batch:REINDEX",
"schedulerType": "CLUSTERED",
"creationDate": "2026-06-25T02:00:00.000-04:00"
}
],
"previousPage": null,
"nextPage": null
}
This method returns a single custom scheduled job by its ID.
To invoke:
GET http://localhost:9000/scheduled-job/{pid}
Note the following path elements:
pid – The numeric PID of the scheduled job to fetch.The server will produce a response resembling the following:
{
"pid": 42,
"nodeId": "Master",
"moduleId": "persistence",
"scheduledJobId": "nightly-reindex",
"schedule": "0 0 2 * * ?",
"active": true,
"target": "batch:REINDEX",
"schedulerType": "CLUSTERED",
"parameters": "{\"partitionedUrl\":[{\"url\":\"Patient?\",\"requestPartitionId\":{\"allPartitions\":true}}]}",
"creationDate": "2026-06-25T02:00:00.000-04:00"
}
This method deletes a custom scheduled job along with all of its execution history.
To invoke:
DELETE http://localhost:9000/scheduled-job/{pid}
Note the following path elements:
pid – The numeric PID of the scheduled job to delete.On success, the server responds with 204 No Content and an empty body.
This method triggers a custom scheduled job immediately, without waiting for its scheduled time to elapse.
To invoke:
POST http://localhost:9000/scheduled-job/{pid}/trigger
Note the following path elements:
pid – The numeric PID of the scheduled job to trigger.On success, the server responds with 204 No Content and an empty body.
This method returns the execution history for custom scheduled jobs on the given node and module. Results are paged.
To invoke:
GET http://localhost:9000/scheduled-job/histories?nodeId={node_id}&moduleId={module_id}
All query parameters are optional. You may add the following to filter the results:
nodeId=[String] – Return only executions on this node.moduleId=[String] – Return only executions on this module.jobId=[String] – Return only executions of the scheduled job with this ID.before=[String] – Return only executions that started before this date/time (ISO-8601).page=[int] – The page index to return.The server will produce a response resembling the following:
{
"list": [
{
"target": "batch:REINDEX",
"jobStatus": "completed",
"nodeId": "Master",
"moduleId": "persistence",
"scheduledJobId": "nightly-reindex",
"scheduledJobPid": 42,
"executionId": 1024,
"executionStart": "2026-06-25T02:00:00.000-04:00",
"executionEnd": "2026-06-25T02:01:06.382-04:00",
"transactionGuid": "0f9c8b1e-2a44-4f0e-9b1a-7d2c5a3e1f00",
"jobId": "fe7e00b8-bfbc-4545-91fe-85b9a1b96296"
}
],
"previous": null,
"next": null
}
The jobStatus field is one of started, completed, or error. For batch targets, jobId is the batch job instance ID, which can be looked up through the Batch Job Endpoint; for camel targets it is absent.
The transactionGuid field ties the execution to an entry in the Transaction Log. You can find that entry by passing the GUID as the transactionId filter to the Transaction Log Endpoint:
GET http://localhost:9000/transaction-log?transactionId={transactionGuid}
This method returns the details of a single scheduled job execution by its numeric history ID.
To invoke:
GET http://localhost:9000/scheduled-job/histories/{history_id}
Note the following path elements:
history_id – The numeric execution (history) ID, as returned in the executionId field of the execution history list.The server will produce a response resembling the following:
{
"target": "batch:REINDEX",
"jobStatus": "completed",
"nodeId": "Master",
"moduleId": "persistence",
"scheduledJobId": "nightly-reindex",
"scheduledJobPid": 42,
"executionId": 1024,
"executionStart": "2026-06-25T02:00:00.000-04:00",
"executionEnd": "2026-06-25T02:01:06.382-04:00",
"transactionGuid": "0f9c8b1e-2a44-4f0e-9b1a-7d2c5a3e1f00",
"jobId": "fe7e00b8-bfbc-4545-91fe-85b9a1b96296",
"parameters": "{\"partitionedUrl\":[{\"url\":\"Patient?\",\"requestPartitionId\":{\"allPartitions\":true}}]}"
}
You are about to leave the Smile Digital Health documentation and navigate to the Open Source HAPI-FHIR Documentation.