Files
gh-secondsky-sap-skills-ski…/references/rest-api.md
2025-11-30 08:55:10 +08:00

21 KiB

SAP BTP Job Scheduling Service - REST API Reference

Source: https://github.com/SAP-docs/sap-btp-job-scheduling-service/tree/main/docs/40---Using-JOB-SCHDULR-TITLE Last Updated: 2025-11-22


Table of Contents

  1. API Overview
  2. Authentication
  3. Rate Limits
  4. Job APIs
  5. Schedule APIs
  6. Run Log APIs
  7. Node.js Client Library
  8. Java Client Library (XS Advanced)

API Overview

Base URL

[https://jobscheduler-rest.<landscape-domain>](https://jobscheduler-rest.<landscape-domain>)

Example landscapes:

  • eu10.hana.ondemand.com
  • us10.hana.ondemand.com
  • ap10.hana.ondemand.com

General Constraints

Constraint Value
Request body size limit 100 KB
Content-Type application/json
Timezone UTC only
Pagination default 10 items
Maximum pagination 200 items

Request Headers

Authorization: Bearer <access_token>
Content-Type: application/json

Authentication

Lite Plan (HTTP Basic)

curl -X GET "[https://jobscheduler-rest.<domain>/scheduler/jobs"](https://jobscheduler-rest.<domain>/scheduler/jobs") \
  -u "<user>:<password>" \
  -H "Content-Type: application/json"

Credentials from VCAP_SERVICES:

  • user: Username
  • password: Password

Standard Plan (OAuth 2.0)

Token Acquisition - Client Credentials:

# Get access token
curl -X POST "<credentials.uaa.url>/oauth/token" \
  -H "Authorization: Basic $(echo -n '<clientid>:<clientsecret>' | base64)" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials"

Response:

{
  "access_token": "eyJhbGciOiJSUzI1...",
  "token_type": "bearer",
  "expires_in": 43199
}

Token Acquisition - Certificate-Based:

curl -X POST "<certurl>/oauth/token" \
  --cert /path/to/certificate.pem \
  --key /path/to/key.pem \
  -d "grant_type=client_credentials&client_id=<clientid>"

Using Token:

curl -X GET "[https://jobscheduler-rest.<domain>/scheduler/jobs"](https://jobscheduler-rest.<domain>/scheduler/jobs") \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json"

Credential Types

Type Authentication Source
binding-secret clientid + clientsecret VCAP_SERVICES
x509 certificate + key VCAP_SERVICES

Token Caching

Tokens cached up to 12 hours. Scope changes may take time to propagate.


Rate Limits

Limit Types

Limit Response Header
Client limit 429 Too Many Requests retry-after (seconds)
Absolute limit 503 Service Unavailable throttling (milliseconds)

Throttling Behavior

  • When limits approached: Response delayed, throttling header indicates delay
  • When client limit exceeded: 429 response with retry-after
  • When absolute limit exceeded: 503 response

Recovery

  • Both limits stack (combine)
  • retry-after typically < 60 seconds
  • Implement exponential backoff for retries

Job APIs

Create Job

Endpoint: POST /scheduler/jobs

Request Body:

Parameter Required Type Description
name Yes string Job name (no special chars, not only numbers)
description Yes string Job description
action Yes string Fully qualified URL endpoint
active Yes boolean Activation status
httpMethod Yes string GET, POST, PUT, or DELETE
schedules Yes array One or more schedules
startTime No string/object Job start time
endTime No string/object/null Job end time
ansConfig No object Alert Notification config
calmConfig No object Cloud ALM config

Schedule Parameters:

Parameter Required Type Description
active Yes boolean Schedule activation
description No string Schedule description
data No object Payload for action endpoint
startTime No string/object Schedule start
endTime No string/object Schedule end
cron No string Cron expression
time No string One-time execution
repeatInterval No string Recurring interval
repeatAt No string Daily execution time

Note: Specify at most ONE scheduling mode (cron, time, repeatInterval, repeatAt).

Example Request:

POST /scheduler/jobs
{
  "name": "salesReportJob",
  "description": "Generate daily sales report",
  "action": "[https://myapp.cfapps.eu10.hana.ondemand.com/api/reports/sales",](https://myapp.cfapps.eu10.hana.ondemand.com/api/reports/sales",)
  "active": true,
  "httpMethod": "POST",
  "schedules": [{
    "active": true,
    "description": "Daily at 6 AM UTC",
    "repeatAt": "6.00am",
    "startTime": {
      "date": "2025-01-01",
      "format": "YYYY-MM-DD"
    }
  }],
  "ansConfig": {
    "onSuccess": false,
    "onError": true
  },
  "calmConfig": {
    "enabled": true
  }
}

Response (201 Created):

{
  "name": "salesReportJob",
  "description": "Generate daily sales report",
  "action": "[https://myapp.cfapps.eu10.hana.ondemand.com/api/reports/sales",](https://myapp.cfapps.eu10.hana.ondemand.com/api/reports/sales",)
  "active": true,
  "httpMethod": "POST",
  "_id": 42,
  "schedules": [{
    "scheduleId": "5f58c2fb-a428-4f4b-9e1d-312e3be8952c",
    "active": true,
    "type": "recurring"
  }]
}

Location header: /scheduler/jobs/42

Error Response (400):

{
  "error": {
    "code": "INVALID_REQUEST",
    "message": "Invalid data provided",
    "type": "VALIDATION_ERROR",
    "detailedError": "Job name must not contain special characters"
  }
}

Retrieve All Jobs

Endpoint: GET /scheduler/jobs

Query Parameters:

Parameter Type Description
name string Filter by job name
jobId number Filter by job ID
jobType string HTTP_ENDPOINT or CF_TASK
page_size number Results per page (default 10)
offset number Jobs to skip (default 1)
tenantId string Filter by tenant (XSUAA token required)

OData-Style Filtering:

GET /scheduler/jobs?$filter=name eq 'myJob'
GET /scheduler/jobs?$filter=contains(name, 'report')
GET /scheduler/jobs?$filter=name eq 'job1' or name eq 'job2'

Operators: eq, contains(), and, or

Response (200):

{
  "total": 25,
  "results": [
    {
      "_id": 1,
      "name": "salesReportJob",
      "description": "...",
      "action": "...",
      "active": true,
      "httpMethod": "POST",
      "jobType": "HTTP_ENDPOINT",
      "createdAt": "2025-01-15T10:30:00Z",
      "modifiedAt": "2025-01-20T14:00:00Z"
    }
  ],
  "prev_url": null,
  "next_url": "/scheduler/jobs?offset=11&page_size=10"
}

Retrieve Job Details

Endpoints:

  • GET /scheduler/jobs/{jobId}
  • GET /scheduler/jobs?jobId={jobId}
  • GET /scheduler/jobs?name={jobName}

Query Parameters:

Parameter Type Description
displaySchedules boolean Include schedule details

Example:

GET /scheduler/jobs/42?displaySchedules=true

Response (200):

{
  "_id": 42,
  "name": "salesReportJob",
  "description": "Generate daily sales report",
  "action": "[https://myapp.../api/reports/sales",](https://myapp.../api/reports/sales",)
  "active": true,
  "httpMethod": "POST",
  "startTime": null,
  "endTime": null,
  "signatureVersion": 0,
  "ansConfig": { "onSuccess": false, "onError": true },
  "calmConfig": { "enabled": true },
  "schedules": [{
    "scheduleId": "5f58c2fb-...",
    "description": "Daily at 6 AM UTC",
    "type": "recurring",
    "repeatAt": "6.00am",
    "active": true,
    "startTime": { "date": "2025-01-01", "format": "YYYY-MM-DD" }
  }]
}

Configure Job (Update)

Endpoint: PUT /scheduler/jobs/{jobId}

Request Body:

All parameters optional except at least one must be provided:

PUT /scheduler/jobs/42
{
  "active": false,
  "description": "Updated description",
  "httpMethod": "GET"
}

Response (200):

{
  "success": true
}

Configure Job by Name (Create or Update)

Endpoint: PUT /scheduler/jobs/{name}

Purpose: Update an existing job or create a new one using the job name as identifier.

Path Parameter:

  • name (string, required): Job name to update or create

Request Body:

Parameter Required Type Default Description
description No string empty Job description
active No boolean false Activation status
action Yes (create) string - Action endpoint URL
httpMethod No string POST GET, POST, PUT, DELETE
endTime No string/object/null null Job end time
ansConfig No object - Alert Notification config
calmConfig No object - Cloud ALM config

Important: The job name in the request URI must match the job name in the request body.

Example Request:

PUT /scheduler/jobs/dailyReport
{
  "name": "dailyReport",
  "description": "Generate daily sales report",
  "action": "[https://myapp.../api/reports",](https://myapp.../api/reports",)
  "active": true,
  "httpMethod": "POST"
}

Response Codes:

Code Description
200 Job updated successfully
201 New job created
400 Invalid data (validation errors)

Delete Job

Endpoint: DELETE /scheduler/jobs/{jobId}

Behavior:

  • Removes job and all associated data
  • Terminates all schedules (active and inactive)
  • Deletes all run logs

Example:

DELETE /scheduler/jobs/42

Response (200):

{
  "success": true
}

Response (404): Invalid job ID


Schedule APIs

Create Schedule

Endpoint: POST /scheduler/jobs/{jobId}/schedules

Request Body:

{
  "active": true,
  "description": "Every 2 hours",
  "repeatInterval": "2 hours",
  "startTime": {
    "date": "2025-01-01",
    "format": "YYYY-MM-DD"
  },
  "data": {
    "customParam": "value"
  }
}

Response (201):

{
  "scheduleId": "cb5c9def-e2a0-4294-8a51-61e4db373f99",
  "description": "Every 2 hours",
  "type": "recurring",
  "repeatInterval": "2 hours",
  "active": true,
  "startTime": "2025-01-01T00:00:00.000Z",
  "jobId": 42
}

Retrieve Schedules

Endpoint: GET /scheduler/jobs/{jobId}/schedules

Query Parameters:

Parameter Type Default
page_size number 10
offset number 1

Retrieve Schedule Details

Endpoint: GET /scheduler/jobs/{jobId}/schedules/{scheduleId}

Path Parameters:

Parameter Type Description
jobId integer Job identifier
scheduleId string Schedule identifier

Query Parameters:

Parameter Type Description
displayLogs boolean Return schedule run logs (max 200)

Example:

GET /scheduler/jobs/42/schedules/cb5c9def-...?displayLogs=true

Response (200):

{
  "scheduleId": "cb5c9def-e2a0-4294-8a51-61e4db373f99",
  "description": "Every 2 hours",
  "data": {},
  "type": "recurring",
  "cron": null,
  "repeatInterval": "2 hours",
  "active": true,
  "startTime": "2025-01-01T00:00:00.000Z",
  "endTime": null,
  "nextRunAt": "2025-01-20T14:00:00.000Z",
  "logs": [
    {
      "runId": "ea16b621-...",
      "executionTimestamp": "2025-01-20T12:00:05Z",
      "httpStatus": 200,
      "runStatus": "COMPLETED",
      "runState": "SUCCESS"
    }
  ]
}

Response (404): Invalid Job ID


Configure Schedule

Endpoint: PUT /scheduler/jobs/{jobId}/schedules/{scheduleId}

Constraint: Cannot change scheduling modes (e.g., cron to repeatInterval). Only update values within same mode.

Request:

PUT /scheduler/jobs/42/schedules/cb5c9def-...
{
  "active": false,
  "repeatInterval": "4 hours"
}

Delete Schedule

Endpoint: DELETE /scheduler/jobs/{jobId}/schedules/{scheduleId}

Delete All Schedules

Endpoint: DELETE /scheduler/jobs/{jobId}/schedules

Activate/Deactivate All Schedules

Endpoint: POST /scheduler/jobs/{jobId}/schedules/activationStatus

Request:

{
  "activationStatus": true  // or false
}

Response:

{
  "success": true
}

Run Log APIs

Retrieve Run Logs

Endpoint: GET /scheduler/jobs/{jobId}/schedules/{scheduleId}/runs

Query Parameters:

Parameter Type Default Max
page_size number 10 200
offset number 1 -

Response (200):

{
  "total": 150,
  "results": [{
    "runId": "ea16b621-eaa8-4824-8629-ff6e6221bb56",
    "runText": "Completed successfully",
    "httpStatus": 200,
    "executionTimestamp": "2025-01-20T06:00:05Z",
    "scheduleTimestamp": "2025-01-20T06:00:00Z",
    "completionTimestamp": "2025-01-20T06:00:10Z",
    "runStatus": "COMPLETED",
    "runState": "SUCCESS"
  }],
  "prev_url": null,
  "next_url": "/scheduler/jobs/42/schedules/.../runs?offset=11"
}

Timestamp Meanings:

Timestamp Description
scheduleTimestamp When schedule was picked up for calculation
executionTimestamp When scheduler invoked action endpoint
completionTimestamp When scheduler received response

Retrieve Run Log Details

Endpoint: GET /scheduler/jobs/{jobId}/schedules/{scheduleId}/runs/{runId}

Path Parameters:

Parameter Type Description
jobId integer Job identifier
scheduleId string Schedule identifier
runId string Run identifier

Example:

GET /scheduler/jobs/2/schedules/5f58c2fb-.../runs/5646889BB133728EE10000000A61A0D8

Response (200):

{
  "runId": "5646889BB133728EE10000000A61A0D8",
  "runText": "Job completed successfully",
  "httpStatus": 200,
  "executionTimestamp": "2025-01-20T06:00:05Z",
  "scheduleTimestamp": "2025-01-20T06:00:00Z",
  "completionTimestamp": "2025-01-20T06:00:10Z",
  "runStatus": "COMPLETED",
  "runState": "SUCCESS"
}

Response (404): Invalid Job ID


Update Run Log (Async Callback)

Endpoint: PUT /scheduler/jobs/{jobId}/schedules/{scheduleId}/runs/{runId}

Purpose: Application callback to report async job completion status.

Request:

{
  "success": true,
  "message": "Processing completed: 1000 records processed"
}

Response (200):

{
  "success": true
}

Implementation Notes:

  • IDs come from request headers during job invocation
  • Single callback per run (not multiple updates)
  • If not called, status becomes UNKNOWN after timeout

Node.js Client Library

Installation

npm install @sap/jobs-client

Minimum Version: 1.6.3 (for x509 certificate support)

Initialization

const JobSchedulerClient = require('@sap/jobs-client');
const scheduler = new JobSchedulerClient.Scheduler();

// Get credentials from VCAP_SERVICES
const vcapServices = JSON.parse(process.env.VCAP_SERVICES);
const jobSchedulerCredentials = vcapServices.jobscheduler[0].credentials;

Job Management Methods

createJob:

scheduler.createJob({
  url: jobSchedulerCredentials.url
}, {
  name: 'myJob',
  description: 'My scheduled job',
  action: '[https://myapp.../api/process',](https://myapp.../api/process',)
  active: true,
  httpMethod: 'POST',
  schedules: [{
    cron: '* * * * 9 0 0',
    active: true,
    description: 'Daily at 9 AM'
  }]
}, (error, result) => {
  if (error) {
    console.error('Error:', error);
  } else {
    console.log('Job created:', result);
  }
});

fetchJob:

scheduler.fetchJob({
  url: jobSchedulerCredentials.url,
  jobId: 42  // or jobName: 'myJob'
}, (error, result) => { /* ... */ });

updateJob:

scheduler.updateJob({
  url: jobSchedulerCredentials.url,
  jobId: 42
}, {
  active: false
}, (error, result) => { /* ... */ });

deleteJob:

scheduler.deleteJob({
  url: jobSchedulerCredentials.url,
  jobId: 42
}, (error, result) => { /* ... */ });

fetchAllJobs:

scheduler.fetchAllJobs({
  url: jobSchedulerCredentials.url
}, (error, result) => { /* ... */ });

getJobCount:

scheduler.getJobCount({
  url: jobSchedulerCredentials.url
}, (error, result) => {
  console.log('Active jobs:', result.activeJobs);
  console.log('Inactive jobs:', result.inactiveJobs);
});

Schedule Management Methods

// Create schedule
scheduler.createJobSchedule({
  url: jobSchedulerCredentials.url,
  jobId: 42
}, {
  repeatInterval: '2 hours',
  active: true
}, callback);

// Update schedule
scheduler.updateJobSchedule({
  url: jobSchedulerCredentials.url,
  jobId: 42,
  scheduleId: 'cb5c9def-...'
}, {
  active: false
}, callback);

// Delete schedule
scheduler.deleteJobSchedule({
  url: jobSchedulerCredentials.url,
  jobId: 42,
  scheduleId: 'cb5c9def-...'
}, callback);

// Fetch schedules
scheduler.fetchJobSchedules({
  url: jobSchedulerCredentials.url,
  jobId: 42
}, callback);

// Bulk operations
scheduler.activateAllSchedules({ url, jobId }, callback);
scheduler.deactivateAllSchedules({ url, jobId }, callback);
scheduler.deleteAllJobSchedules({ url, jobId }, callback);

Run Log Methods

// Update run log (async callback)
scheduler.updateJobRunLog({
  url: jobSchedulerCredentials.url,
  jobId: jobId,
  scheduleId: scheduleId,
  runId: runId
}, {
  success: true,
  message: 'Processing completed'
}, callback);

// Get run logs
scheduler.getRunLogs({
  url: jobSchedulerCredentials.url,
  jobId: 42,
  scheduleId: 'cb5c9def-...'
}, callback);

// Get action logs
scheduler.getJobActionLogs({ url, jobId }, callback);
scheduler.getScheduleActionLogs({ url, jobId, scheduleId }, callback);

Complete Example

const express = require('express');
const JobSchedulerClient = require('@sap/jobs-client');

const app = express();
const scheduler = new JobSchedulerClient.Scheduler();
const credentials = JSON.parse(process.env.VCAP_SERVICES).jobscheduler[0].credentials;

// Async job endpoint
app.post('/api/process', (req, res) => {
  const jobId = req.headers['x-sap-job-id'];
  const scheduleId = req.headers['x-sap-job-schedule-id'];
  const runId = req.headers['x-sap-job-run-id'];

  // Acknowledge immediately
  res.status(202).json({ message: 'Accepted' });

  // Process asynchronously
  processAsync()
    .then(() => {
      scheduler.updateJobRunLog({
        url: credentials.url,
        jobId: parseInt(jobId),
        scheduleId,
        runId
      }, {
        success: true,
        message: 'Completed successfully'
      }, (err) => {
        if (err) console.error('Failed to update run log:', err);
      });
    })
    .catch((error) => {
      scheduler.updateJobRunLog({
        url: credentials.url,
        jobId: parseInt(jobId),
        scheduleId,
        runId
      }, {
        success: false,
        message: error.message
      }, (err) => {
        if (err) console.error('Failed to update run log:', err);
      });
    });
});

async function processAsync() {
  // Long-running operation
}

app.listen(process.env.PORT || 3000);

Java Client Library (XS Advanced)

Overview

A Java Client Library (java-js-client) is available for SAP HANA Platform XS Advanced environments.

Use Case: For Java-based applications running on SAP HANA XS Advanced.

Note: This library is specific to XS Advanced and not for general Cloud Foundry Java applications. For Cloud Foundry Java apps, use the REST API directly with standard HTTP clients.

Availability

Available through SAP's internal package registry for XS Advanced development.


External References

SAP Documentation

Source Files

  • sap-job-scheduling-service-rest-apis-c513d2d.md
  • authentication-5dca60b.md
  • rate-limits-a9cb164.md
  • create-job-2c1ecb6.md
  • retrieve-all-jobs-b4d3719.md
  • node-js-client-library-9b86127.md
  • All schedule and run log documentation files