Session ID from scheduled jobs

You will need to establish a session from within the Scheduled job.

As a proof of concept I managed to get this working by using the OAuth 2.0 Username-Password Flow. You make a HTTP POST request from Salesforce-to-Salesforce to request an Access Token which can then be used as a Session ID.

You will need to create a new Remote Access Application where you will get Consumer Key (client_id) and Consumer Secret (client_secret). You will also need to create a new Remote Site Setting for the Token Endpoint URL so a POST request can be sent to it.

public class UsernamePasswordFlow {
    String username;
    String password;
    String clientId;
    String clientSecret;
    String tokenEndpoint = '';

    public UsernamePasswordFlow(String username, String password, String clientId, String clientSecret) {
        this.username = username;
        this.password = password;
        this.clientId = clientId;
        this.clientSecret = clientSecret;

    public String requestAccessToken() {
        HttpRequest req = new HttpRequest();
        req.setBody(buildHttpQuery(new Map<String, String> {
            'grant_type' => 'password',
            'username' => username,
            'password' => password,
            'client_id' => clientId,
            'client_secret' => clientSecret

        Http http = new Http();
        HttpResponse resp = http.send(req);

        Map<String, Object> m =
            (Map<String, Object>) JSON.deserializeUntyped(resp.getBody());

        return (String) m.get('access_token');

    static String buildHttpQuery(Map<String, String> queryParams) {
        if (queryParams.isEmpty()) {
            return '';

        String[] params = new String[] {};
        for (String k : queryParams.keySet()) {
            String v = EncodingUtil.urlEncode(queryParams.get(k), 'UTF-8');

            params.add(String.format('{0}={1}', new String[] { k, v }));

        return String.join(params, '&');

Example Usage:

UsernamePasswordFlow upf = new UsernamePasswordFlow(
    '[email protected]',
String sessionId = upf.requestAccessToken();

Unfortunately the drawback to this approach is having the store the credentials, in my case I used a custom settings object to store them. So there are security concerns to take into consideration.

Here's my suggestion:

Use Outbound Messaging, which contains the capability to pass the Session ID for the purpose of you using it to call back.

Set up a workflow rule on a custom object to fire when a record is changed and send the outbound message.

Use your scheduled job to modify the custom object, thus firing the workflow rule and sending the outbound message and session id.