Skip to content

All versions since 20240617.1

20240617.1

API version: 6.1.0

  • Added Job deletion feature. A job can be deleted if certain conditions are met.
  • The deletion of job and any related data is permanent. Only the events log is retained for future reference.
  • Once the job is deleted, existence of any entity referred in the event log cannot be guaranteed.

20240618.1

API version: 6.2.0

  • Added a new boolean condition called ‘IncludeRemainingTags’ to JobReadModel, WorkData, and ProcessingSteps queries. This will allow us to include the remaining tags for filtered objects.
  • Added a feature that enables us to retrieve the list of RemainingTags for JobReadModel, WorkData, and ProcessingSteps.

20240619.3

API version: 6.2.1

  • Fix output WorkData processing after job completion (size is updated, empty ones are deleted)
  • Fix internal worker communication to API by adding configuration options for internal API host URL

20240919.5

API version: 6.2.2

  • Fix issue that enables to work with versioned and non-versioned bucket for MinIO, Azure Blob Storage and S3 Binary Storage

20241009.4

API version: 6.2.3

  • Added processing step function versioning capability.
  • Validation are set on function name and version. User is prompted while registering if the processing step with same function name and version exist in the DB.
  • The Default value without user input is set to “0”, else user is allowed to input 50 characters for version and for processing step function name limit is 170 chars.
  • Delete Operation on WorkData is now only shown, if it can be executed (internal check if it is used)
  • Performance fixes and better error messages

20241016.4

API version: 6.2.3

  • improved resilience
  • transient storage errors are communicated in 503 with retry-after suggestion in more cases
  • stability fixes

20241018.2

API version: 6.2.4

  • added new admin features manage broken jobs
  • added new filter for jobs createdBefore and createdAfter

20241104.1

API version: 7.1.0

  • Add configured parameters to jobs so it is possible to see what is / was configured
  • Allow jobs to run with default parameters without explicitly resetting them

20241112.1

API version: 7.1.0

  • Internal preparation for workflows

20241118.3

API version: 7.2.0

  • Extend ProcessingStep registration and editing to allow versions to be set and edited
  • ProcessingStep versions are now used every where
  • Fix rename of function did not update internal communication so messages

20241127.4

API version: 7.3.0

  • Add additional navigation links to the relevant WorkData: “Job that produced this work data” and “Processing step that produced this work data”
  • Expand work data query with these additional filter filters:
    • ProducerProcessingStep (Filters WorkData that are produced by the processing step represented by this URL)
    • IsUsed (Filters WorkData by the condition if any job is using them)
  • Expand job query with an additional filter parameter:
    • IsUsingThisWorkData (Filters jobs that are using the work data represented by this URL)
  • Fixed a bug where some collection data slots were not marked as collection. IsCollection property is now correctly derived from min and max files.

20241212.1

API version: 7.3.1

  • Fix missing Name property for DataSlots in Job

20250214.1

API version: 7.3.1

  • Improve security model by passing signed credentials to ProCon for accessing the API
  • Homogenize the URL building so ProCon uses same URLs

20250403.4

API version: 7.4.0

  • Streamed file upload: if a file is big it will now be processed in chunks
  • Added owner field to WorkData, Job, ProcessingStep
  • Fixed issue with admin queries

20250409.1

API version: 7.4.0

  • Fix job could get stuck in pending state if it could not be scheduled internally. Now job will transition to error.

20250506.55

API version: 7.5.0

  • Add action to hide processing steps
  • Add ability to query Processing steps by IsConfigured parameter
  • Job can now show its started time if it has been started
  • WorkData filename is also passed in JobOffer message

20250514.65

API version: 7.6.0

  • Add action to create and configure job with a single HTTP request
  • This new action allows specification of parameters to create a new job, select processing step, configure processing parameters, set tags, toggle whether to output data deletion, set input data slots, and finally start the job.

20250521.67

API version: 7.6.0

  • Improved performance of rapid job setup

20250725.107

API version: 7.6.0

  • Fix JMA version was not show in API

20250725.112

API version: 7.6.0

  • Add function and version naming conventions
    • functions: a-Z, 0-1, ‘’, optional leading ‘’ is allowed
    • versions: a-Z, 0-9, ‘.’, ‘_’ ‘-’
  • Ensure versions do not interfere with routing
  • Cleanup communication

20250728.120

API version: 8.0.0

  • Any variable names, function parameter names, header keys, etc. related to PermissionGroups renamed to PermissionGrants.
  • The OwnerId property of Job, WorkData and ProcessingStep entities is now split into two properties: OwnerId and CreatedBy. CreatedBy is the Id of User who created this resource. OwnerId is the Id of the organization if the user was in an organization context during this entity’s creation, else the user is considered to be in a private context and it’s value is same as CreatedBy.

20250818.127

API version: 8.1.0

  • Add actions to copy WorkData and Processing steps from organization to user and conversely from user to organization.

20250828.128

API version: 8.2.0

  • Add action to delete Processing step. It only succeeds if the step is not used by any job.

20250908.131

API version: 8.3.0

  • Separate admin and normal query for used tags for Jobs, steps and WorkDatas.

20251027.142

API version: 8.5.0

  • Processing steps can now be deprecated.
    • Jobs can not start with deprecated function
    • No RMQ queues maintained for deprecated functions

20251104.151

API version: 8.6.0

  • Add API events, provides an SSE feed with information on changes
  • Add cache headers to EntryPoint, and Root nodes and parameter schemas so clients know they can be cached
  • Allow caching of CORS response
  • New RMQ queue layout, including the organization context
    • no function naming collision between contexts
  • Present registry and SSE endpoint in Info
  • Fix action titles do now contain a title usable in UI

20251117.161

API version: 8.6.0

  • Use the new background worker feature for “restore all job read models” and “restore some job read models” operation.

20251202.175

API version: 8.8.0

  • Processing steps can now be deployed directly via JMA API.
  • Registering or deploying a ProcessingStep now requires CodeContributor permissions
  • A CodeHash must be assigned beforehand to any processing step that is to be deployed. Existing CodeHash cannot be changed but it can be removed by an admin and assigned again by a user with sufficient authority.
  • Afterwards, the processing step can be deployed by optionally configuring these parameters or using default values: ResourcePreset, EntryPoint and Scaling.
  • A deployed step can be re-deployed with a different configuration infinite number of times.
  • A deployed step may be suspended by the user, in which case the configuration is saved but the deployment itself is removed. A suspended deployment can be resumed later with the saved configuration.
  • A processing step that is not platform deployed can optionally be marked as “externally deployed” to provide information that it is externally deployed.
  • Deployments can be removed at any time by the user.

20251209.186

API version: 8.8.0

  • Fix copy PS to user and org did not return new PS ID
  • Add Action classes “Destructive” and “LongRunningBackground” for more information on the effect
  • Add fix OTL metric requested non existing PS Queues if the PS was deprecated
  • Do reverse mapping of grants and roles in info endpoint
  • Add remote endpoint in info HTO which is used to connect with remote workers Info->Remote
  • Now all JMA actions have modern Draft 2020-12 JsonSchemas
    • more properties are now required in the schema to allow the caller to check early

20260113.195

API version: 9.0.0

  • Allow filtering and sorting by versions
  • Allow version ranges to be used (similar to npm)
  • Fix issue with admin query: public ProcessingSteps was not visible when admin was using normal query
  • More actions now require code contributor permission
  • Reworked registering of PS, now only an upload is used and version, function name are taken from manifest
  • ProcessingSteps now contain the ProCon version used when a deployment exists
  • ProcessingStep property edit is more limited now
  • Platform user and owner renamed

20260115.200

API version: 9.1.0

  • Allow filtering ProcessingSteps by ProCon version property, by exact string match

20260130.205

API version: 9.2.0

  • Jobs, WorkData and ProcessingSteps now have TagDetails which holds specifics to the internal representation of tags
    • Migrate internal tag representation to full semantic model
    • Migrate existing tags

20260203.208

API version: 9.3.0

  • Introduce new resource presets for deployment: xsmalland XXLarge
  • Improve error messages for invalid URIs as parameters

20260205.212

API version: 9.3.1

Fix for Job object

  • completedOn was not shown for error jobs
  • startedOn showed wrong time

20260206.218

API version: 9.4.0

  • WorkData can now be marked as ‘secret’. Such WorkData will be forbidden from being downloaded.

20260210.225

API version: 9.5.0

  • If the logs and metrics service URL is provided, all jobs will now contain an external link for logs monitoring. Jobs created from now on will also contain a link for metrics monitoring.

20260220.236

API version: 9.5.0

  • Creation of WorkData placeholders of output dataslots before scheduling a job for execution now happens in parallel.

20260302.239

API version: 9.6.0

  • Add support for TQL which allows to query tags with semantics for Jobs, ProcessingSteps and WorkData see documentation on details
  • Fix response of ProblemJson had sometimes the wrong ContentType
  • API Version bump to 9.6.0

20260304.241

API version: 9.6.1

  • Fix TQL, allow better quoted string recognition and be more permissive with allowed chars

20260327.284

API version: 9.7.0

  • Add a new Action root with Action Templates and Action Triggers.
  • Action Templates can be created to store a processing configuration. Only processing steps that do not have any input data slots are supported.
  • Cron-based Action Triggers can be created and configured with both 5-field or 6-field cron expressions. Multiple templates can be linked to a trigger to be executed in configured schedules.
  • API Version bump to 9.7.0

20260408.315

API version: 9.7.0

  • Add dataslot support for Action templates.

20260422.318

API version: 9.7.0

  • fix a bug which lead to broken communication when an admin resumed a deployment
  • parallelized lookup of file size and deletion of unused DataSlots after job completion
  • fix missing and wrong log messages in some error cases

20260603.325

API version: 9.7.0

  • Cron Action Triggers now support a TimeZoneId; missing time zones default to UTC.
  • Added trigger activation windows with optional StartsAt and ExpiresAt values; expired triggers are deleted automatically, with optional deletion of associated templates.
  • Added TQL tag query support for Action Templates, matching the query behavior already available for Jobs, ProcessingSteps and WorkData.

20260723.327

API version: 9.8.0

  • Jobs no longer remain in Processing when the worker executing them crashes or is evicted: the platform now automatically fails such jobs — they transition to Error with an explanatory error_description.
  • Admins can now filter job queries by WorkerId.
  • API version bump to 9.8.0

20260820.333

API version: 9.10.0

  • Introduce Folders: Jobs, WorkData and ProcessingSteps can now be organized into a per-owner folder tree. A new Folder resource and a FolderRoot (which holds root-level, unfiled items) are reachable from the entry point.
  • Folders can be created, renamed and moved. Folder names must be unique within their parent folder, and moving a folder into its own subtree is rejected.
  • A folder exposes paginated Children (its subfolders) and Contents (the Jobs, WorkData and ProcessingSteps filed in it, ordered by date) as sub-resources.
  • Jobs, WorkData and ProcessingSteps can be filed into a folder and moved between folders. Their queries gain a folder filter, including an option to match a folder together with its whole subtree (recursive).
  • Each Job, WorkData and ProcessingStep now indicates its containing folder: a ParentFolder link (present only when the item is not at the root) and a FolderPath string property (the root is shown as /).
  • Sub-jobs can optionally inherit their parent job’s folder via InheritParentFolder.
  • Deleting a folder only succeeds when the folder is empty; it is refused if the folder still contains items or child folders (structural delete, no cascade).
  • Clearing a folder (DeleteAllInFolder) best-effort deletes every item in the folder and its descendants (the folders themselves are kept) and returns a per-object report listing each item as deleted or skipped, with a reason for any skip.
  • API version bump to 9.10.0

1.0.0

API version: 9.10.0

Added

  • Multi-tenancy step 1: every request must carry the trusted X-Tenant-Id header. All resources are stamped with the tenant they were created under; processing step queries are scoped to the caller’s tenant. Data created before multi-tenancy belongs to the tenant pinexq.
  • Persistence setup modes OnStartup (default), MigrateAndExit and VerifyOnly (PersistenceSetup:Mode), so schema migration can run as a deploy-time job while runtime pods only verify.
  • Boot-time schema setup is serialised across replicas with a PostgreSQL advisory lock.
  • GET api/Info reports the BuildVersion as the semantic version of the build, derived from the git tag (e.g. 1.0.0+<commit sha>). Container images are tagged with the same version (v1.0.0), the latest tag is no longer published.
  • Server-Sent Event delivery works across multiple replicas: API events are fanned out over a RabbitMQ fanout exchange so a client connected to one replica receives events produced on another. Off by default (ApiEventBackplane:Enabled; exchange RabbitMq:Exchanges:ApiEvents, default api-events-fanout), and single-replica behaviour is unchanged. Delivery is scoped by owner and tenant, failing open when a producer has no tenant context (e.g. a message-driven job update) so events are never dropped.

Changed

  • Portal-api base URLs and job logs/metrics links are resolved per tenant.
  • Registering a processing step rejects parameter schemas with deeply chained $ref definitions.
  • The job-update listener retries commands that hit a version conflict and rejects messages it cannot apply instead of acknowledging them blindly; rejected messages dead-letter into the durable queue Job.All.Updates.Rejected for inspection and replay.

Fixed

  • Leaked RabbitMQ channels in the processing exchange.
  • Folder feature review findings (validation and navigation details).
  • Jobs no longer get stuck at Processing in the read model when the output cleanup of a completion races a concurrent update of the same job; the completion now starts from a clean unit of work.

1.0.1

API version: 9.10.0

Fixed

  • Reading historical event streams no longer fails after a change in assembly version. The computed Event.EventType was persisted into every event — its [JsonIgnore] was System.Text.Json’s, which the Newtonsoft-based Marten event-store serializer does not honour — as an assembly-version-qualified type name, and deserialising it broke whenever the running assembly version differed from the one that wrote the event (as happened on the switch to semantic versioning). The property is now also ignored by Newtonsoft (Foundation.Util 2.2026.902.225), so old events deserialise regardless of assembly version.

2.0.0

API version: 10.0.0

Releases as 2.0.0 (MAJOR). Two of the three MAJOR criteria in README “Choosing the version” apply: the REST contract breaks (the Admin/RestoreJobReadModels endpoint is removed and the input SetFolderSource action takes FolderUrl instead of a Folder path — hence the ApiVersion major step to 10.0.0), and the database change needs manual intervention when upgrading (the event-store cutover is irreversible, drops columns the previous release still reads, installs a legacy-write fence, and requires a maintenance window). RabbitMQ message contracts are unchanged.

Added

  • Action templates can source a collection input data slot from a folder, the same way jobs can (SetFolderSource action on a template input data slot, recursive by default; mutually exclusive with item-by-item selection). The folder is stored as a snapshot path; jobs created from the template — including those started by a trigger — resolve and materialize the folder’s current contents at their own execution time, so a triggered template becomes an “inbox” that processes whatever is in the folder on each run.
  • CreateJob accepts an optional Folder to create the job directly inside a folder (omit for the root). The target folder must exist for the owner, mirroring the MoveToFolder action.
  • Output data slots can be directed into a folder (SetOutputFolder action on a job’s output data slot). The slot stores the folder as a snapshot path; the WorkData produced for that slot is filed into the folder (created if missing) when the output placeholders are built at execution time. An empty or root path clears the target, writing the output to the owner’s root (the default, unchanged behaviour).

Changed

  • Job and template input SetFolderSource actions accept FolderUrl instead of a Folder path. Send an existing folder’s resource URL, or explicit null for the owner’s root. The selected folder must belong to the job/template owner; its current path remains the stored snapshot. Output folder destinations still accept paths and can be created at execution time.
  • Jobs are no longer event-sourced. The event-sourced JobAggregate and its read-model projection are replaced by a single plain Job domain entity persisted through EF Core via JobDto/IJobRepository. Writes now happen in a single transaction guarded by an EntityVersion optimistic-concurrency token (no Marten event store, no dual write, no read-model repair jobs). Job REST payloads and action availability are unchanged (availability is computed live from the domain Job instead of persisted *OpAvailable columns).

Removed

  • The transitive Marten event-store dependency, through Foundation 3. Legacy migration tests use captured PostgreSQL schema and event fixtures, so the test projects do not require Marten either.
  • The Admin/RestoreJobReadModels action and endpoint (route Admin_RestoreJobReadModels). Job read models are no longer a separate projection that can lag, so there is nothing to rebuild.
  • Operator-facing: the second Postgres connection pool PostgresEventStoreDb and the JMA_EventStore health check (the event store shared the main database and is gone).
  • The CopyToOrg and CopyToUser actions on a ProcessingStep, with their endpoints (routes ProcessingStep_CopyPsFromUserToOrg and ProcessingStep_CopyPsFromOrgToUser). Copying a ProcessingStep between a user and an organization never produced a usable step: the copy is given the destination owner, but job offers are routed on the owner (Job.<OwnerId>.<FunctionName>.<Version>.JobOffer) and the copy is created undeployed, so no worker was ever bound to the copy’s routing key and jobs selecting it were offered to a queue nobody consumed. Register the step under the destination owner instead (upload it with that owner’s API key), which binds a worker to the correct key. Copying WorkData between a user and an organization is unaffected and remains available.

Fixed

  • Invalid folder paths retain their detailed validation messages instead of returning only “Validation of command parameters failed.”
  • Upgrading from event-sourced jobs now validates and backfills legacy folder-input snapshots within the original cutover migration before destructive schema changes, preserving unresolved, resolved-empty and ordered populated inputs. Inconsistent history aborts the cutover transaction, and the existing startup migration check prevents serving with pending migrations. A database guard rejects legacy job-event appends during pod replacement.
  • Disallowing output data deletion now notifies job subscribers, so the Allow/Disallow actions stop showing a stale state until the next unrelated job change.
  • Resolving a folder-sourced input while a job is being scheduled no longer lets it start on a set that scheduling never prepared. Scheduling now aborts if a slot’s execution snapshot or folder source changed after preparation, leaving the job ready to be scheduled again.
  • Scheduling a job on behalf of another owner no longer fails when one of its output slots targets a folder. The output placeholder is now created for the job’s owner, matching the folder it is filed into; the scheduling user is still recorded as its creator.
  • Scheduling access denials and infrastructure failures no longer change jobs to Error. Folder-input validation failures recheck access, readiness, and the current inputs before failing a job.
  • Scheduling holds the owner’s folder-tree lock while resolving output destinations and committing folders, placeholders, and job references together, preserving the hierarchy during concurrent tree changes.
  • Retrying scheduling after an output-folder edit moves existing placeholders to the current destination without replacing their files or tags. A target change between preparation and scheduling aborts dispatch until the job is prepared again.
  • Reading jobs with large input/output collections no longer multiplies those collections into a single SQL result. Job reads and folder pages load their graphs in a consistent database snapshot, including across transient read retries.
  • Clearing or refreshing a template’s pinned folder inputs removes obsolete usage rows so released files can be deleted. Unchanged selections retain their usage rows, including in other template input slots.
  • Setting a template input’s folder source with an invalid or missing slot index returns HTTP 400 with validation details and preserves the template’s existing configuration and input references.
  • Job input Resolve/ClearResolved and output SetOutputFolder actions are only advertised when the job is editable and the caller has execution permission. Template SetFolderSource/Resolve/ClearResolved actions also check their respective command permissions, following the existing owner/admin rules.
  • A worker status, result, error or output-metadata message that arrives after its job was deleted is acknowledged as a late delivery instead of being dead-lettered into Job.All.Updates.Rejected. Deleting a job removes its row, so such a message can never be applied and the rejected queue only accumulated messages nothing could act on; the skip is logged with the job id, and the worker’s access token is revoked as for any other settled job. Operators should expect fewer messages in Job.All.Updates.Rejected — the remaining ones are genuine failures.

2.0.1

API version: 10.0.0

Fixed

  • Optional input data slots (minSlots=0) can be filled. An empty optional slot counted as configured from the start, so it never offered SelectWorkData, SelectWorkDataCollection or SetFolderSource, and clients failed with “action is not available”. The slot now offers these actions while it is empty or short of its minimum, and only while the job can still be edited.

2.1.0

API version: 10.0.0

Changed

  • Job updates from workers are consumed from the new single-active-consumer queue Job.All.Updates.SingleActive, one message at a time, so the updates of a job are applied in the order the worker sent them however many instances run. With competing consumers on Job.All.Updates, two instances could apply a job’s “finished” before its error (the failed job ended up completed) or before its result. When a listener stops it finishes the message in processing before a standby takes over. Workers are unaffected: routing keys and message contracts are unchanged. Delivery stays at least once: after a redelivery or a failover an output’s metadata comment can appear twice; its name and tags are unaffected. With more than one instance, an output that receives more than one metadata update can be left with the older one after a failover; a step that writes each output once sends one (README, “Job update messages”; issue #182).
  • Operator-facing: at startup JMA unbinds Job.All.Updates and drains what is left in it before consuming the new queue. The drain acknowledges what it applied only once the queue is empty: an interrupted drain fails the startup and leaves everything it had applied in Job.All.Updates, and the restarted pod applies it again, in order. An update published in the instant of the switch reaches both queues; its copy is skipped by message id, and never applied after a newer update of its job (an update applied a second time appends its output metadata comment again, like any redelivery). Roll this release out with a single instance, scale out afterwards. Once Job.All.Updates is empty it can be deleted together with the job-all-updates-dead-letter broker policy. Rolling back to an earlier release needs a controlled hand-back of the queue (README, “Rolling back to a release without the single-active queue”): deleting Job.All.Updates.SingleActive without it loses the updates only it holds.

Fixed

  • A job update that is valid JSON but no usable message (null, or without header or content) is dead-lettered instead of staying unacknowledged. The same holds for any message whose handler fails unexpectedly, in every listener; with the job-update listener taking one message at a time, such a message would otherwise have stopped all job updates.
  • A job update whose command found the job store temporarily unavailable (a database timeout, lost connection or failover) was dead-lettered at once, and the job’s later updates were applied without it: a failed job’s “finished” without its error left the job completed. It is now retried in place for about three and a half minutes, which holds the job updates behind it until the store is back; only a longer outage dead-letters it.
  • Saving a job that has tags could fail as “resource already exists” when another save of the same job had just committed (every save replaces the job’s tag rows, and the stale save collided with the new ones before its version check). The job-update listener took that for an update already applied and dropped it, and API requests failed. It is now retried like any other concurrent modification.
  • With several instances, an instance whose broker connection recovered re-created the command queues of jobs another instance had already finished (the RabbitMQ client’s automatic recovery re-declares every queue a connection declared and did not delete itself). Job command queues are left out of that recovery; they are durable, so those of running jobs survive a reconnect anyway.

2.1.1

API version: 10.0.0

Fixed

  • Saving a job that has outputs could fail as “resource already exists” when another save of the same job had just committed, like the tag conflict fixed in 2.1.0: every save also replaces the job’s output usage rows, and the stale save collided with the new ones before its version check. When a worker set a job’s tags while the job-update listener saved the job’s start, either the worker’s request failed with 423 (execute_workflow failed, issue #184) or the listener dropped the start, leaving a completed job without its start time and worker. It is now retried like any other concurrent modification. Present since 2.0.0.

2.2.0

API version: 10.1.0

Added

  • UploadWorkData can file the new WorkData into a folder, tag it and mark it secret, all in the commit that creates it (issue #179). Before, each took a follow-up call (MoveToFolder, SetTags, MarkAsSecret), and a client failing between them left the WorkData in the root, untagged or not secret. The properties go in an optional form field UploadWorkDataParameters holding {"Folder": <folder URL>, "Tags": [...], "Secret": true} (every member optional), before or after the file. Sent before the file, an unknown or foreign folder or an invalid tag fails the upload before any content is stored; sent after it, the stored content is removed again. The upload still streams the file without buffering it. The SIREN Upload action of the WorkData root lists the new field (class FileUploadActionWithParameter) and keeps the class FileUploadAction, so existing clients continue to work. Without the field an upload behaves as before.

Fixed

  • Setting a WorkData’s tags with a null tag ({"Tags":[null]}) failed with HTTP 500 instead of a validation error (400).

2.2.1

API version: 10.1.0

Fixed

  • The Gitea release has the generated openapi.json attached again. Every release since the switch to semantic versioning shipped without it.

2.3.0

API version: 10.1.1

Changed

  • An output slot without a target folder now files its produced WorkData into the Job’s folder instead of the Owner’s root. The folder is the one the Job is in when it is scheduled; a Job at the root still writes its outputs to the root. Once a Job is scheduled, moving it does not move its outputs; a retry after a failed scheduling attempt files the already prepared outputs into the Job’s current folder. An explicit target set with SetOutputFolder still takes precedence. This includes sub-jobs created with InheritParentFolder: they sit in the parent’s folder, so their untargeted outputs now land there too.
  • SetOutputFolder with / now pins the output slot to the Owner’s root, so an output of a Job in a folder can still go to the root. Previously / cleared the target like an empty path; an empty path still clears it, and the slot then follows the Job’s folder. A / sent before this change was stored as no target, so such a slot of a not yet scheduled Job now follows the Job’s folder as well.

Fixed

  • DeleteJob checks that the caller may access the Job (issue #197). Any user with a plan grant could delete another Owner’s Job by its id, across tenants, as long as the Job was not running and had no output WorkData. Now only the Job’s Owner or an admin can delete it; anyone else gets 403. The check runs before the sub-job check, so a caller without access no longer sees the ids of the Job’s sub-jobs in the error. Present since job deletion was added in 2024.
  • Creating a sub-job checks that the caller may access the parent Job (issue #198), through CreateSubJob and through RapidJobSetup with a ParentJobUrl. Any user with a plan grant could attach a sub-job to another Owner’s pending or processing Job; that Owner could then no longer delete their Job, and with InheritParentFolder the sub-job carried their folder. Now only the parent’s Owner or an admin can create a sub-job under it; anyone else gets 403. Workers are unaffected: they act as the identity that scheduled the parent, which already passes the same check when reading the Job.

2.4.0

API version: 10.2.0

Added

  • Action templates and cron triggers can be filed in folders, like Jobs, WorkData and ProcessingSteps. Both have a MoveToFolder action (omit the folder to move back to the root), a FolderPath property and a ParentFolder link. CreateActionTemplate and CreateCronTrigger take an optional Folder to create the item directly in a folder. Filing only organizes the item: a template’s own folder does not decide where its jobs go, and a trigger’s schedule and linked templates are unchanged. A trigger and the templates it runs are filed independently.
  • Action templates have a job folder: SetJobFolder sets the folder that jobs created from the template (by a trigger or ExecuteNow) are filed into, shown as JobFolder. It is a path, like an output slot target: the folder, and any missing folders above it, are created when a job is created, under the job’s owner, and renaming or moving the folder does not update the setting. Their outputs then follow the job’s folder. An empty path or / clears it, and jobs are created at the root as before; unlike an output slot, an unset job folder does not fall back to the template’s own folder.
  • The template and trigger queries take the Folder/FolderRecursive filter of the other foldable queries.
  • Folder contents list templates and triggers next to Jobs, WorkData and ProcessingSteps, as ActionTemplate and CronJobTrigger entities. Clients that only know the earlier types can skip them; the total count includes them.
  • The folder children Contains filter accepts actiontemplate and actiontrigger.

Changed

  • DeleteFolder also refuses a folder that holds templates or triggers.
  • The folder Clear action also deletes the templates and triggers in the folder and its descendant folders. It deletes triggers first, then templates, then Jobs, ProcessingSteps and WorkData. Deleting a template unlinks it from every trigger, including triggers outside the folder. The report lists them with the item types ActionTrigger and ActionTemplate.

2.5.0

API version: 10.3.0

Added

  • GET api/Statistics, linked from the entry point as Statistics: the caller’s Owner’s numbers, aggregated by the database instead of paged through item by item. WorkDataCount, UsedStorageInBytes and DeployedProcessingStepCount (the Owner’s own steps deployed on the platform and not deprecated) are totals. JobsCreatedPerUser counts the Jobs created after CreatedAfter (default: 24 hours ago) per creating user. CompletionDays has an entry for every UTC day from CompletedFrom (default: today) on which a Job ended: its Completed and Failed (Error) Jobs, the p50 and p90 run time of the Completed ones in milliseconds, and their count per ProcessingStep function. Hidden Jobs and sub-jobs count. Either window may start at most 366 days back. The resource’s CreateStatisticsQuery action, prefilled with its own windows, answers 201 with the statistics of other windows as Location.

2.6.0

API version: 10.4.0

Added

  • An action template’s job folder can contain date placeholders, filled in each time a job is created from the template (by a trigger or ExecuteNow): {{date}}, {{date+N}} or {{date-N}} (N days, at most 365), each optionally followed by @ and a time zone, the IDs cron triggers accept. SetJobFolder with /reports/{{date+1@Europe/Berlin}}/ files a job created at 00:30 on 2026-10-14 in Berlin into /reports/2026-10-15/. Without a time zone the date is UTC. Dates are always written as yyyy-MM-dd. A placeholder may stand alone as a folder name or inside one, and a path may hold several. JobFolder shows the path as written. SetJobFolder refuses an unknown placeholder, an offset beyond 365 days, an unknown time zone, or a path that would not be valid once filled in. Job folders set before keep their meaning: braces were never allowed in folder names.

2.7.0

API version: 10.5.0

Added

  • Jobs show when they were scheduled for execution as ScheduledAt, next to CreatedAt, StartedAt and CompletedAt: the UTC time the Job moved from ReadyForProcessing to Pending. It is recorded once and does not change afterwards. StartedAt minus ScheduledAt is the time a Job waited for a worker, while StartedAt minus CreatedAt also counts the time it spent being configured before it was scheduled. Jobs that started before this release get their CreatedAt as ScheduledAt (their StartedAt if that is earlier), so their wait reads as before. Other Jobs scheduled before this release, and Jobs not scheduled yet, have no ScheduledAt; the property is then absent.

2.8.0

API version: 11.0.0

Added

  • The statistics, now at GET api/Statistics/Query (see Changed), answer more numbers; every earlier field and parameter keeps its meaning. WorkDataPerUser and WorkDataPerKind split all WorkData of the Owner by creating user and by kind, each with Count and UsedStorageInBytes. Each CompletionDays entry also has ComputeMs, the summed run time of the day’s Completed and failed Jobs that have a start time; TimeToStartP50Ms and TimeToStartP90Ms, how long those Jobs waited from ScheduledAt to their start (absent without a Job that has both); and ProducedBytes, the size of the WorkData they produced through their output slots. UploadDays has an entry for every UTC day from UploadedFrom (default: today) with an upload: the UploadedBytes of the WorkData uploaded that day. ProcessingSteps counts the Jobs that ended from ProcessingStepsFrom (default: today) per ProcessingStep function across its versions: Title (of the step the latest of them ran), Completed, Failed, and the p50 and p90 run time of the Completed ones in milliseconds. Hidden items and sub-jobs count. Both new days may start at most 366 days back, and the CreateStatisticsQuery action takes them too.

Changed

  • GET api/Statistics is now the Statistics Root, linked from the entry point as StatisticsRoot in place of Statistics: it computes nothing and carries the CreateStatisticsQuery action, which rejects a window that starts more than 366 days back with 400 when it is submitted, not when its Location is followed. The statistics moved to GET api/Statistics/Query, with the same query parameters; the action’s Location points there. They no longer carry the action, and they name the windows they cover, defaults filled in: CreatedAfter, CompletedFrom, UploadedFrom and ProcessingStepsFrom. Clients that read the statistics by URL move to GET api/Statistics/Query.

2.8.1

API version: 11.0.1

Fixed

  • The CreateStatisticsQuery action of the Statistics Root is prefilled with the current default windows, so a form generated from it shows them instead of empty fields. Submitting the prefilled values fixes them in the query; omit a window to keep it rolling.
  • Renaming or moving a folder onto the name of an existing sibling answers 423 instead of 500 (#196): the foundation library now maps a unique violation from raw SQL like one from SaveChanges. A database that refuses connections or is in recovery is likewise reported as temporarily unavailable instead of as an internal error.

2.8.2

API version: 11.0.1

Fixed

  • A tag value is a timestamp only in ISO 8601 form, as documented: it must start with a yyyy-MM-dd date. Other text that .NET reads as a date is a string now. A version like Version=1.7.0 was taken for 2000-01-07 and rejected with 400 “Detected timestamp without defining time zone”, as were values like 2.8.1, 10/16/2026, Jan 2026 or 4/3. With a Z or an offset, such a value was stored as a timestamp instead. Versions starting with 0. were not affected. A typed query value {timestamp:...} follows the same rule and rejects any other value as an invalid timestamp. Tag value types also no longer depend on the server’s culture. Tags already stored keep their type. Present since 20260130.205.

2.9.0 Latest

API version: 11.1.0

Added

  • A deployment can state its resources explicitly (#229). The ConfigureDeployment action of a ProcessingStep takes Resources with CpuMillicores, MemoryMiB and DiskGiB, as an alternative to ResourcePreset. A request passes exactly one of the two, otherwise it gets 400. A preset stands for the resources the operator applied for it so far, from XSmall (250 millicores, 512 MiB, 3 GiB) to XXLarge (14000 millicores, 60416 MiB, 300 GiB), so clients that send only ResourcePreset keep working unchanged. The deployment shows CpuMillicores, MemoryMiB and DiskGiB, and ResourcePreset when the values are exactly those of a preset, otherwise null. The action’s prefilled values carry only one of the two: the preset when the resources match one, otherwise the resources.
  • Resources above the resource ceiling are rejected with 400, whether stated explicitly or through a preset; the operator would silently cut them down. The ceiling is set in Deployment:MaxResources (CpuMillicores, MemoryMiB, DiskGiB) and defaults to one ccx43 peak node: 15400 millicores, 60416 MiB and 325 GiB. Set it to the operator’s job.maxResources.* of the namespace when they differ.

Changed

  • The deployment message to the operator carries spec.resources (cpu, memory, disk as Kubernetes quantities, e.g. "500m", "1024Mi", "10Gi") and no longer spec.resourcePreset. This needs operator 0.3.0 or later; deploy that first. After this release, re-apply every existing deployment so its StepFunction gets explicit resources.
  • Existing deployments are migrated to the resources of their preset; the stored preset is dropped.