Skip to main content
Author: Drew Shea, Created: 2025-09-07

Overview

The purpose of this document is to introduce developers to the core concepts around interacting with Xperiflow Jobs from the C# SDK.

info

This is functionality is only available in Xperiflow v4.1.0 or greater.

What are Xperiflow Jobs?

An Xperiflow Job is programmatic workflow. Think of it like a recipe: each step (task) must be done in sequence or in parallel. An Xperiflow Job defines how those steps are executed.

An Xperiflow Job may be comprised of one Xperiflow Task or few or even 10’s of thousands of Xperiflow Tasks.

Xperiflow Jobs are primarily used for intensive quantitative AI operations within SensibleAI applications such as training 1000’s of SensibleAI Forecast models in parallel for hours to even days at a time.

Lastly, Xperiflow Jobs do not return any data. Instead, they alter the state of the data stored within different Xperiflow data services and that data may be accessed via REST Apis, etc.

info

If you are curious to learn more about what Xperiflow Jobs are, please check out: Xperiflow Jobs

info

You can find the list of available jobs that can be programmatically executed along with the appropriate JSON parameters here: https://datasensesoftware.atlassian.net/wiki/x/IwBSaw

Use Cases

The ability to programmatically create, execute, and monitor Xperiflow Jobs provides a lot of opportunities for building interesting new solutions, workflows, and extensions of existing solutions.

Here are just a few interesting ways to make use of programmatically executing routines:

  • SensibleAI Forecast: Schedule end-to-end Prediction and Data Egress Behind 1 Button

    • A SensibleAI Forecast Implementor fully script the execution of a Prediction Job for a SensibleAI Forecast project in production by building a script that invokes the Prediction job, waits for the prediction to complete, and then fires the remaining data pipeline egress code to land the prediction results back in the proper destination.
  • SensibleAI Forecast: Custom Administrator “Heads Up Display” Dashboards

    • For customers with many SensibleAI Forecast projects in production, it can be tedious to for a single Administrator to individually manage every SensibleAI Forecast project
    • You could build a custom dashboard that exposes information on all the SensibleAI Forecast projects that are in production and then allow the Administrator to execute certain jobs like predictions, rebuilds, etc. for all projects at once.
  • SensibleAI Forecast: Custom Event Upload End User Workflows

    • For customers that do not want their end users going in SensibleAI Forecast but still want them providing their “business intuition” into the project through Event, you could set up a custom OenStream workflow that has end users (of particular departments, stores, etc.) provide their event upload CSV file.
    • You could then programmatically execute the any of EventUpload, EventLocationUpload, EventPackageUpload, EventTargetDimensionUpload, EventTargetUpload jobs to properly collect that information and automatically insert it into the project before the next prediction.

Examples

Below, we will walk through common examples of interacting with the Xperiflow Jobs.

Define Input Parameters

In order to run a job that will create a project inside of SensibleAI Forecast, we need to ensure that we provide the proper parameters to properly create and start the job.

The parameters are expected to be in a JSON format, but may be provided as either as JObject, string, or T generic object.

// Parameters needed for SensibleAI Forecast Project Creation
var parameters = new JObject
{
["task_storage"] = new JObject
{
["project_name"] = "My First Project",
["description"] = "I programmatically created this project",
["application"] = "FOR",
["ptype"] = "regression",
["ttype"] = "timeseries",
["vtype"] = "unsupervised",
["viewer_identity_ids"] = null,
["editor_identity_ids"] = null,
["manager_identity_ids"] = null
}
};
info

The parameter JSON schema for every job available can be found here: Xperiflow v4.0.2 Jobs Reference

Create and Start the Job

The XBRApi of Xperiflow Business Rules comes with convenient methods under XBRApi.Conduit for interacting with job orchestration system of Xperiflow.

To create and start a job immediately, we can simply do the following:

// Create and start the job immediately
XperiflowJob job = XBRApi.Conduit.CreateAndStartXperiflowJob(si, "ProjectCreation", parameters);

Alternatively, if we wanted to schedule this job to run in a few hours instead, we could do the following:

// Create and queue the job scheduled for 2 hours from now
var scheduledTime = DateTime.Today.AddHours(2);
var scheduledJob = XBRApi.Conduit.CreateAndStartXperiflowJob(
si,
"ProjectCreation",
parameters,
scheduledTime: scheduledTime
);

Inspect Job Attributes

The XperiflowJob object has many properties on it that can tell you the current status of the job.

// Attributes available for the job
BRApi.ErrorLog.LogObject(si, "Xperiflow Job", job);
Error Log Output:

{
"JobId": 1,
"ActivityType": "project_creation",
"ActivitySource": "onestream",
"ActivityStatus": "queued",
"Parameters": {
"task_storage": {
"project_name": "My First Project",
"description": "I programmatically created this project",
"application": "FOR",
"ptype": "regression",
"ttype": "timeseries",
"vtype": "unsupervised",
"viewer_identity_ids": null,
"editor_identity_ids": null,
"manager_identity_ids": null
}
},
"CreationTime": "2025-09-07T12:37:31.711351",
"QueuedTime": "2025-09-07T12:37:31.711351",
"StartTime": null,
"EndTime": null,
"LastActivityTime": "2025-09-07T12:37:31.711351",
"PercentComplete": 0.0,
"TotalTasks": 0,
"CompletedTasks": 0,
"ServerName": "",
"AppName": "XBR",
"ProjectId": 0,
"CompletedRuntimeDuration": null,
"ReportedRuntimeDuration": null,
"RuntimeDuration": null
}

Waiting for the Job to Finish

By default, the C# program from which you created and started your XperiflowJob will “fire and forget” the job (in other words, continue to move on through the rest of your code) unless you decide to “Wait for Completion”.

The XperiflowJob object comes with a method WaitForCompletionAsync which will make your program wait for the job to finish (success or failure) before proceeding.

This is useful in situations when need to have one job complete before you can continue with your next operations (ex: creating and start another job that depends on the first job).

// Halt the execution of this program until the job is completed
var timeout = TimeSpan.FromMinutes(10);
job.WaitForCompletionAsync(timeout).Wait();

// Kick off data load job within that newly created project...

The WaitForCompletionAsync method comes with a timeout parameter. If your job does not finish within the time span, your job will be cancelled. If the timeout is not provided, it defaults to 24 hours.

Warning: Be aware, that OneStream Data Management Tasks will automatically get cancelled if the Task is running for longer than 24 hours. This is because OneStream Data Management servers need to recycle once every 24 hours.

Working with Project Specific Jobs

In order to tell a job to run for a specific SensibleAI Forecast project, we need to provide the project ID to the job on start and creation.

There are many Xperiflow Jobs that are considered project specific jobs. Almost all the jobs run inside of SensibleAI Forecast are considered “Project Specific” jobs. Examples include:

  • Pipeline
  • Prediction
  • Project Copy (because we are copying a specific project)

Below, we can see where we need to provide the project ID in order to have the Job target the right project.

// The ID of the project to copy 
// (Could retrieve this programmatically from the XBRApi.WebSdk)
var projectToCopyId = 5;

// Parameters needed for SensibleAI Forecast Project Copy
var projectCopyParameters = new JObject
{
["task_storage"] = new JObject
{
["new_project_name"] = "My First Project Copied",
}
};

// Create and start the job (ProjectCopy is considered a "Project Specific Job")
XperiflowJob projectCopyJob = XBRApi.Conduit.CreateAndStartXperiflowJob(
si,
"ProjectCopy",
projectCopyParameters,
projectToCopyId // Provided the id of the project to copy
);

Retrieve an Existing Job

You also have the ability to retrieve and inspect jobs that you didn’t kick off programmatically. For example, I could programmatically retrieve a pipeline job for a SensibleAI Forecast project that we created and started from the SensibleAI Forecast UI

var jobId = 12  // example Pipeline Job ID
XperiflowJob retrievedJob = XBRApi.Conduit.GetXperiflowJob(si, jobId);

Appendix

Full Code Example

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading;
using Microsoft.CSharp;
using Newtonsoft.Json.Linq;
using OneStream.Finance.Database;
using OneStream.Finance.Engine;
using OneStream.Shared.Common;
using OneStream.Shared.Database;
using OneStream.Shared.Engine;
using OneStream.Shared.Wcf;
using OneStream.Stage.Database;
using OneStream.Stage.Engine;
using Workspace.XBR.Xperiflow;
using Workspace.XBR.Xperiflow.Conduit.Job;
using Workspace.XBR.Xperiflow.Utilities.Logging.Extensions;

namespace OneStream.BusinessRule.Extender.XBRApiConduitTester
{
public class MainClass
{
public object Main(SessionInfo si, BRGlobals globals, object api, ExtenderArgs args)
{
try
{
BRApi.ErrorLog.LogMessage(si, "Creating job");

// Parameters needed for SensibleAI Forecast Project Creation
var parameters = new JObject
{
["task_storage"] = new JObject
{
["project_name"] = "My First Project",
["description"] = "I programmatically created this project",
["application"] = "FOR",
["ptype"] = "regression",
["ttype"] = "timeseries",
["vtype"] = "unsupervised",
["viewer_identity_ids"] = null,
["editor_identity_ids"] = null,
["manager_identity_ids"] = null
}
};

// Create and start the job immediately
XperiflowJob job = XBRApi.Conduit.CreateAndStartXperiflowJob(si, "ProjectCreation", parameters);

// Attributes available for the job
BRApi.ErrorLog.LogObject(si, "Job", job);

// Halt the execution of this program until the job is completed
var timeout = TimeSpan.FromMinutes(10);
job.WaitForCompletionAsync(timeout).Wait();


///////////////////////////////
// Scheduled Job
///////////////////////////////

// Create and queue the job scheduled for 2 hours from now
// var scheduledTime = DateTime.Today.AddHours(2);
// var scheduledJob = XBRApi.Conduit.CreateAndStartXperiflowJob(
// si,
// "ProjectCreation",
// parameters,
// scheduledTime: scheduledTime
// );

// // Attributes available for the scheduled job
// BRApi.ErrorLog.LogObject(si, "Scheduled Job", scheduledJob);

// Halt the execution of this program until the scheduled job is completed
// scheduledJob.WaitForCompletionAsync().Wait();


// Parameters needed for SensibleAI Forecast Project Copy
var projectToCopyId = 5; // Could also retrieve this programmatically from the XBRApi.WebSdk
var projectCopyParameters = new JObject
{
["task_storage"] = new JObject
{
["new_project_name"] = "My First Project Copied",
}
};

// Create and start the job
XperiflowJob projectCopyJob = XBRApi.Conduit.CreateAndStartXperiflowJob(
si,
"ProjectCopy",
projectCopyParameters,
projectToCopyId
);


var failedJob = XBRApi.Conduit.GetXperiflowJob(si, 8);
BRApi.ErrorLog.LogObject(si, "Failed Job", failedJob);

return null;
}
catch (Exception ex)
{
throw ErrorHandler.LogWrite(si, new XFException(si, ex));
}
}
}
}

Was this page helpful?