Appearance
Operating the workspace
This page documents the five Administration screens used to observe and run a tenant day to day: Monitoring, Logging (the audit log), Backup, Jobs and My tasks. For the overview of the branch and the permission summary see Administration and DevOps overview.
Monitoring
Monitoring is a single-screen health summary for the tenant. It reads the numbers that the Jobs engine, the Integration Flow engine, the Communication engine, the webhook dispatcher and the platform itself already keep, and reduces each area to one of three states. Tenant administrators and operators use it as the first stop when something looks wrong. For the troubleshooting workflow around it see Monitoring and troubleshooting.
Where to find it: Workspace > Administration > Monitoring. Page key monitoring.
Key concepts
| Term | Meaning |
|---|---|
| Area | One panel: Background jobs, Integration flows, Messages, Webhooks, Platform. |
| Healthy | The area loaded and its attention rule is not triggered. Green chip "Healthy". |
| Needs attention | The area loaded and its attention rule is triggered. Amber chip "Needs attention". |
| Not available to you | The area failed to load for this user, typically because the role lacks the view permission. Grey chip "Not available to you". One failing area does not affect the others. |
| Outbox | The tenant's transactional event queue (outbox_event). Events are pending or dispatching while waiting, failed after exhausting delivery. |
Fields and options
The screen has no editable fields. Header controls: Back and Refresh. The data is loaded once on open and again on each Refresh; there is no automatic polling.
Summary chips shown above the panels:
| Chip | Shown when | Text |
|---|---|---|
| Overall | Always | "Everything you can see is healthy", or "N area(s) need attention" |
| Unavailable | At least one area is unavailable | "N not available to you" (outlined) |
| Timestamp | Always | "Updated" followed by the local time of the last load |
When any area is unavailable an information banner reads "Some areas are hidden because your role cannot view them."
Panels, their content and the rule that turns them to "Needs attention":
| Panel | Content | Attention rule | Source endpoint | Permission |
|---|---|---|---|---|
| Background jobs | Stacked bar of Succeeded, Failed, Dead; "N jobs, N running, N queued, N retrying"; "Failure rate x%, average N ms" | Failed + Dead is greater than 0 | GET /api/v1/jobs/monitoring | none checked |
| Integration flows | Stacked bar of Succeeded, Failed, Dead; "N flows, N running, N queued"; failure rate and average duration | Failed + Dead is greater than 0 | GET /api/v1/integration/flows/monitoring | integration.flow / view |
| Messages | Stacked bar of Delivered, Sent, Pending, Failed; "N messages today" | Failed is greater than 0 | GET /api/v1/communications/messages/monitoring | communication / view |
| Webhooks | Stacked bar of Delivered, Waiting or retrying, Failed for good (last 24 hours); "N of M webhooks switched on" | Failed for good (24 hours) is greater than 0 | GET /api/v1/integration/webhooks | integration.webhook / view |
| Platform | Events waiting to be delivered (and failed, and age of the oldest in minutes when above 1 minute); people signed in; audit events in 24 hours (and failed); database size in MB | Failed outbox events greater than 0, or oldest pending outbox event older than 600 seconds | GET /api/v1/admin/monitoring/platform | admin.monitoring / view |
A bar with no data shows "Nothing has run yet." Failure rate and average duration display "-" until at least one execution has completed. Failure rate is (failed + dead) / (success + failed + dead) for flows and (failed + timeout + dead) / completed for jobs.
The Platform numbers are independent. A number is left out (not shown, not an error) when its source table is not present for the tenant:
| Key | Computed as |
|---|---|
outboxPending | rows of outbox_event for the tenant with status pending or dispatching |
outboxFailed | rows with status failed |
outboxOldestPendingSeconds | age in seconds of the oldest pending or dispatching row |
activeSessions | rows of session_token not revoked and not expired |
auditEvents24h, auditFailures24h | rows of audit_event in the last 24 hours, and those with success = false |
databaseSizeBytes | pg_database_size of the tenant database |
Actions
| Action | Effect | API |
|---|---|---|
| Refresh | Reloads all five areas in parallel; each failure is isolated | The five endpoints above |
| Back | Returns to the Studio home | none |
Procedures
- Open Workspace > Administration > Monitoring.
- Read the overall chip. If it reads "2 areas need attention", find the amber panels.
- For Background jobs with Failed 3 and Dead 1, open Jobs, open the job with failures and retry the DEAD execution.
- For Platform reading "12 events waiting to be delivered, 2 failed (oldest 14 min)", the outbox dispatcher is behind; check the audit log for category
outboxand the server log witherp logs tail.
Permissions
Each panel enforces its own permission on the server, listed in the table above. A tenant administrator holding TENANT_ADMIN passes the privileged gate for admin.monitoring. Without it, the Platform panel shows "Not available to you" and the HTTP response is 403 with the message actor "<name>" lacks admin.monitoring.view permission.
API and CLI
bash
erp api get /api/v1/admin/monitoring/platform
erp api get /api/v1/jobs/monitoring
erp api get /api/v1/integration/flows/monitoring
erp api get /api/v1/communications/messages/monitoring
erp api get /api/v1/integration/webhooksExample Platform response:
json
{
"outboxPending": 12,
"outboxFailed": 2,
"outboxOldestPendingSeconds": 840,
"activeSessions": 7,
"auditEvents24h": 1932,
"auditFailures24h": 4,
"databaseSizeBytes": 48234496
}Limits and behavior
- All numbers are scoped to the current tenant.
databaseSizeBytesis the size of the whole tenant database. - There are no thresholds to configure and no alert delivery. "Needs attention" is derived on each load from the rules above.
Errors and troubleshooting
| Message or symptom | Cause | Fix |
|---|---|---|
| Panel shows "Not available to you" | The API call failed for that area (403, or the engine is not installed) | Grant the view permission named in the table, or ignore if the module is not used |
actor "x" lacks admin.monitoring.view permission | Actor is neither a privileged role holder nor explicitly granted | Assign TENANT_ADMIN or grant admin.monitoring / view |
| Platform panel shows no database size | The numbers are optional; the query failed for this tenant | None; other numbers still show |
Logging
Logging is the viewer for the tenant's centralised audit log. Every audited action in the platform (sign-ins, record changes, configuration changes, workflow actions, permission changes, plugin lifecycle, job operations) is recorded as an audit event. This screen shows today's counters, filters and pages through events, and lets an administrator switch audit categories on or off and choose how events are written. Compliance officers and administrators use it to answer who changed what and when.
Where to find it: Workspace > Administration > Logging. Page key audit-log; the screen title reads "Audit Log".
Key concepts
| Term | Meaning |
|---|---|
| Audit event | One row of audit_event: category, action, entity, actor, module, IP address, result, source, correlation ID and timestamps. |
| Category | The class of event. The database accepts login, logout, crud, configuration, workflow, permission, plugin, job, orchestration, communication, finance, integration, outbox, agent, provisioning, other. The screen offers eight for switching and filtering: login, logout, crud, configuration, workflow, permission, plugin, other. |
| Correlation ID | An identifier that ties together everything produced by one request or business event. Selecting the Trace chip filters the list to that ID. |
| Processing mode | sync writes the event in the caller's request before it returns (default, safest). async returns immediately and writes on a background pool. |
| Source | The component that recorded the event, for example backup, job; defaults to core. |
Fields and options
KPI chips (counts for the current UTC day for this tenant):
| Chip | Counts |
|---|---|
| Total today | All events |
| Logins | Category login |
| Failed logins | Category login with result failure; red when above 0 |
| Config changes | Category configuration |
| Permission changes | Category permission |
| Workflow events | Category workflow |
| Record updates | Category crud |
| Plugin events | Category plugin |
| API calls, AI requests, Security alerts | Always 0 in this release. The tooltips read "No API-call interceptor exists yet - always 0 until one does", "No AI-request tagging exists yet - always 0 until one does", "No security-alert rule exists yet - always 0 until one does". |
Below the chips, three lists show the top five of the day: Top active users, Most modified entities, Most accessed modules (each as "name (count)"). A list is hidden when empty. Most accessed modules only counts events where a module value was supplied.
Category settings panel ("Category settings - enable/disable, and sync/async per category"):
| Field | Type or values | Default | Description |
|---|---|---|---|
| One switch per category | Boolean | On | Turning a category off stops recording new events of that category for this tenant. The check happens before each write, so the change applies to the next event. Existing events are kept. |
| Processing mode | Select: "Sync (safest, blocks briefly)" (sync), "Async (lower latency)" (async) | sync | Tenant-wide. Async uses a bounded background pool (2 core threads, up to 8, queue of 1000) and a failed async write is logged on the server and not retried. |
Filter bar:
| Field | Type or values | Default | Required | Description |
|---|---|---|---|---|
| All categories | Select of categories | All | No | Exact category match |
| Action | Text | empty | No | Exact match on the action name, for example backup.started |
| Entity type | Text | empty | No | Exact match, for example job |
| Actor | Text | empty | No | Exact match on the user or system actor |
| Module | Text | empty | No | Exact match |
| Correlation ID | Text | empty | No | Exact match; whitespace is trimmed |
| IP address | Text | empty | No | Exact match |
| Success/Failure | Select: any, "Success only", "Failure only" | any | No | Filters on the result flag |
| Search | Text (grid toolbar) | empty | No | Case-insensitive contains over action, entity type, entity key and the detail JSON ("Search action, entity or detail") |
The API also accepts from and to (ISO-8601 instants) for a date range on the occurred time. The screen does not expose them.
Event grid columns: Occurred, Category, Action (with entity type and entity key below), Actor, Module, IP, Result (green OK or red FAIL, "-" when not recorded), Source, Trace (first 8 characters of the correlation ID). Several columns are hidden on narrow screens. Page size is 25 per page; events are returned newest first.
Actions
| Action | Effect | API |
|---|---|---|
| Change a filter | Reloads page 1 with the filter | GET /api/v1/authoring/audit/events |
| Trace chip | Sets the Correlation ID filter to that event's ID | same |
| Category switch | Enables or disables recording of that category | PUT /api/v1/authoring/audit/settings/{category} with {"enabled": false} |
| Processing mode select | Sets sync or async | PUT /api/v1/authoring/audit/settings/processing-mode with {"processingMode": "async"} |
Procedures
Trace one change end to end:
- Open Logging and enter Action
job.disabledand Entity typejob. - Select the Trace chip of the event of interest to see every event sharing its correlation ID.
- Read the Actor, IP and Result columns to establish who did it and from where.
Reduce audit write cost for a tenant that performs very large imports:
- In Category settings, leave
configuration,permissionandloginon. - Switch Processing mode to Async (lower latency).
- The change applies to the next event. Switch back to Sync if durability of the very last event matters more than latency.
Statuses and lifecycle
Audit events are append-only and have no status. Category switches and the processing mode are tenant settings stored per tenant (default mode sync).
Permissions
Reading the audit log and its summary needs the privileged action gate on audit.read, and changing or reading the category and processing-mode settings needs it on audit.manage: the actor must hold STUDIO_STAFF, TENANT_OWNER or TENANT_ADMIN, or have the permission granted explicitly, and no rule may deny it. Otherwise the response is HTTP 403 with actor "x" lacks audit.read permission (or audit.manage). The Explorer entry still shows for anyone who can open the Administration branch; the screen then loads empty with the error.
API and CLI
| Method and path | Purpose |
|---|---|
GET /api/v1/authoring/audit/events | Query events: category, action, entityType, actor, module, ipAddress, success, correlationId, search, from, to, pageIndex, pageSize |
GET /api/v1/authoring/audit/kpis | Today's counters and top-five lists |
GET /api/v1/authoring/audit/settings | Category switches (eight rows) |
PUT /api/v1/authoring/audit/settings/{category} | Body {"enabled": true|false} |
GET and PUT /api/v1/authoring/audit/settings/processing-mode | Body {"processingMode": "sync"|"async"} |
bash
erp api get "/api/v1/authoring/audit/events?category=configuration&success=false&pageSize=50"
erp api put /api/v1/authoring/audit/settings/processing-mode --body '{"processingMode":"async"}'For server-side request logs (stack traces), join the response header X-Correlation-Id of a failing call against the log: erp logs tail --grep <correlationId>. See Diagnostics.
Limits and behavior
pageSizeis clamped to 1..500; default 25.- Events have a
regionCode(the node region that processed the event) and a residency-violation flag, used by the multi-region data-residency checks. They are not shown in the grid. - Sensitive details are carried in the detail JSON and are searchable through the Search box.
- The retention period is not configurable in this release; events are not purged by the platform.
Errors and troubleshooting
| Message or symptom | Cause | Fix |
|---|---|---|
| "No audit events match these filters." | Filters too narrow, or the category is switched off | Clear filters; check the category switch |
| Events for a category stop appearing | The category switch is off | Turn the category on again; events during the gap are not recorded |
| A just-performed action is missing in async mode | The background write has not completed, or failed (logged server-side) | Refresh; if absent, switch to sync and check the server log |
| Category in the list that is not in the filter | Categories such as job, outbox, agent exist in the database but are not offered by the screen | Use Search or the API with category=job |
Backup
Backup lists the tenant's database backups, takes a backup on demand and proves that a backup can be restored. It never restores over live data. Tenant administrators use it to confirm that backups run and that they are usable.
Where to find it: Workspace > Administration > Backup. Page key backups; the screen title reads "Backups".
Key concepts
| Term | Meaning |
|---|---|
| Backup | A database dump restricted to the tenant's own data, written to the server's backup storage. Backup type is recorded as schema. |
| Restore check | A test restore of the dump into a temporary database on the same server, followed by a row-count comparison against the counts captured immediately after the dump. The temporary database is dropped afterwards. |
| Backup region | Where the dump file is stored: the tenant's configured backup region when set and allowed by the tenant's data-residency declaration, otherwise the home region. |
| Scheduled backup | A job backup.run ("Backup: Tenant Data Dump") with cron 0 15 2 * * * (02:15 server time daily), concurrency SINGLE, timeout 180 seconds, one attempt. |
Fields and options
Summary chips:
| Chip | Content |
|---|---|
| Last backup | Completion time of the newest successful backup, or "none yet" (warning color) |
| Last restore check | Time of the newest passed restore check, or "never" (warning color) |
| Backups kept | Number of successful backups among the last 50 rows |
| Total size | Sum of their sizes (KB below 1 MB, MB otherwise) |
Grid columns:
| Column | Description |
|---|---|
| Started | Start time with the backup type below it |
| Status | Running, Completed (stored success), Failed |
| Size | File size; "-" when unknown |
| Restore check | "Passed" with the time, or "Not checked" |
| Problem | The error message of a failed backup; "-" otherwise |
The grid shows the 50 most recent records and has search ("Search backups"), a status filter and sortable columns. An empty tenant shows "No backups yet. Use Back up now to take the first one."
Actions
| Action | Effect | API |
|---|---|---|
| Back up now | Runs a backup synchronously and refreshes the grid. Notice "Backup finished." | POST /api/v1/admin/backups |
| Verify restore (row action, completed backups only) | Runs the restore check. Notice Restore check passed. restore verified OK: N table(s), all row counts matched, at TIME. or Restore check found differences. restore verification FAILED: ... | POST /api/v1/admin/backups/{id}/verify |
Both actions disable the buttons while running. Restoring live data from a backup is not offered; the footer note states "To restore your live data from a backup, ask your platform operator."
Procedures
Take and verify a backup:
- Open Backup and select Back up now. A row appears with status Completed and a size, for example 18.4 MB.
- On that row select Verify restore. The Restore check column changes to "Passed" with the time.
- The chips now read a recent Last backup and Last restore check.
Statuses and lifecycle
| Status | Meaning | Next |
|---|---|---|
running | The dump is in progress | success or failed |
success | Dump written; checksum (SHA-256), size and per-table row counts stored | Restore check can be run any number of times; the latest result is stored |
failed | errorMessage holds the reason, for example backup for tenant 7 failed: ... or ... timed out after 120s | None |
Permissions
| Operation | Permission |
|---|---|
| List backups | admin.backup / view |
| Back up now, Verify restore | admin.backup / manage |
Both pass the privileged action gate: the actor must hold STUDIO_STAFF, TENANT_OWNER or TENANT_ADMIN, or have the permission granted explicitly, and no rule may deny it. Otherwise HTTP 403 with actor "x" lacks admin.backup.manage permission. Backups and verifications are audited as category configuration, actions backup.started and backup.verified, entity type backup, source backup. The server path and checksum of the dump are not returned to tenants.
API and CLI
bash
erp api get "/api/v1/admin/backups?limit=20"
erp api post /api/v1/admin/backups
erp api post /api/v1/admin/backups/42/verifylimit defaults to 20 and is clamped to 1..100. The verify response:
json
{
"matched": true,
"summary": "restore verified OK: 143 table(s), all row counts matched, at 2026-10-05T02:31:07Z.",
"mismatches": []
}Limits and behavior
- Only one backup may run per tenant at a time: a second request returns 409
A backup is already running for this tenant. - Backup scope is the tenant's common data. Application data kept in separate application schemas of the tenant database is outside this backup.
- The backup process times out after 120 seconds by default; the operator can change that. Backups are laid out as
region/tenant-<id>/backup-yyyyMMdd-HHmmss.dump. - A restore check compares row counts only. Tables with
vectorcolumns cannot be recreated by the backup database role; they are listed in the summary as left out of the check. The check fails when the stored baseline is empty. - The row-count baseline is the one captured at backup time, so later changes to live data do not cause false failures.
- No retention or pruning is performed by the backup engine.
Errors and troubleshooting
| Message or symptom | Cause | Fix |
|---|---|---|
A backup is already running for this tenant. | A row with status running exists | Wait; a stuck row indicates a crashed process, contact the operator |
No backup N for this tenant. | The ID belongs to another tenant or does not exist | Use an ID from the grid |
| Status Failed with a backup-tool error | Backup tools missing or unreachable database | Operator checks the backup tools and database access |
| Restore check "found differences" | One or more tables differ in row count after restore | Read the mismatch list in the notice; contact the operator, do not rely on that backup |
| Verify restore button missing | The row is not Completed | Only completed backups can be verified |
Jobs
Jobs is the operations console for the tenant's background jobs: each scheduled, manual or event-driven job registered by a module or plugin, its recent executions, and its reliability settings. Administrators use it to see whether jobs run, to run one now, to switch it off, to retry a dead execution and to tune retry behavior. This screen cannot create a new job; jobs are declared by the plugin that owns them or by the generic sweep jobs described in Job and Scheduler Designer and the guides reminder, cadence, compliance and aggregation.
Where to find it: Workspace > Administration > Jobs. Page key jobs.
Key concepts
| Term | Meaning |
|---|---|
| Job | A registered unit of background work with a code, owning plugin, type, optional cron schedule and reliability settings. |
| Execution | One attempt record . A retry creates a new execution with the next attempt number. |
| Job type | SCHEDULED, EVENT, MANUAL, API, WORKFLOW, RECURRING, ONE_TIME. Only SCHEDULED jobs with a cron expression and status ENABLED are dispatched by the scheduler. |
| Scope | TENANT (default) or SYSTEM. |
| Concurrency policy | Whether overlapping executions are allowed (see the table below). |
| Trigger | What created an execution: SCHEDULE, MANUAL, API, EVENT, WORKFLOW, RETRY. |
| Dead | An execution that failed on its last allowed attempt, or whose job definition no longer exists. |
Fields and options
Monitoring chips above the grid: Total jobs, Running, Queued, Retrying, Successful, Failed, Dead, Avg duration (ms), Failure rate (%). Avg duration and Failure rate show "-" with the tooltip "No completed executions yet" until an execution has completed.
Job grid:
| Column | Description | Visible by default |
|---|---|---|
| Job | Name with the job code below | Yes |
| Plugin | Owning plugin ID; select filter | Yes (hidden on narrow screens) |
| Type | Job type tag; select filter | Yes |
| Schedule | Cron expression in monospace, or "-" | Yes (hidden on narrow screens) |
| Priority | CRITICAL, HIGH, NORMAL, LOW | No |
| Concurrency | Concurrency policy | No |
| Status | REGISTERED, ENABLED, DISABLED; select filter | Yes |
Search placeholder: "Search jobs by name, code or plugin". Selecting a row opens the history drawer.
Execution history drawer (right side, 20 per page): columns Started, Trigger, Attempt, Status (tooltip shows the error text), Duration (ms). The header shows the job name and description ("No description." when empty).
Job Settings dialog (title Job Settings - followed by the job name, note "Reliability and priority only - the job's trigger/schedule and business logic are declared by the owning plugin and aren't editable here."):
| Field | Type or allowed values | Default for a new job | Description |
|---|---|---|---|
| Priority | CRITICAL, HIGH, NORMAL, LOW | NORMAL | Label stored with the job |
| Timeout (seconds) | Integer | 300 | Maximum run time of one attempt; on expiry the attempt is recorded as TIMEOUT |
| Concurrency | ALLOW_PARALLEL, SINGLE, PER_TENANT, PER_PARAMETER | SINGLE | See below |
| Max attempts | Integer | 1 | Total attempts including the first. When the attempt number reaches this value, a failure becomes DEAD |
| Backoff | NONE, FIXED, LINEAR, EXPONENTIAL | NONE | Delay strategy between attempts |
| Retry initial delay (seconds) | Integer | 30 | Base delay |
| Retry max delay (seconds) | Integer | 3600 | Upper bound for LINEAR and EXPONENTIAL |
The screen sends all seven values on Save and does no range validation; the server does not validate them either, so enter sensible positive values. Defaults shown are those of a job declared without overrides; a plugin may declare others.
Concurrency policies:
| Policy | Behavior |
|---|---|
ALLOW_PARALLEL | New executions are always queued and run without a lock |
SINGLE | No new execution is queued while one is queued or running. A worker also takes a database advisory lock keyed by the job code, so jobs do not overlap even across several server instances |
PER_TENANT | Advisory lock keyed by job code and tenant; queueing is skipped while one is in flight |
PER_PARAMETER | Treated like PER_TENANT in this release; executions are not distinguished by parameters |
Retry delay formula for attempt number n (the next attempt): FIXED = initial delay; LINEAR = min(initial x n, max); EXPONENTIAL = min(initial x 2 to the power (n-1), max); NONE = 0 (the retry is queued immediately).
Actions
| Action | Where | Effect | API |
|---|---|---|---|
| Execute now (play icon) | Row | Queues a MANUAL execution. Enabled only when the job status is ENABLED. Writes audit job.executed.manual | POST /api/v1/jobs/{jobCode}/execute (optional JSON body is passed to the handler as parameters) |
| Job settings (gear icon) | Row | Opens the dialog; Save writes audit job.configuration.changed | PATCH /api/v1/jobs/{jobCode}/settings |
| Enable / Disable | Row | Sets status ENABLED or DISABLED (audit job.enabled, job.disabled). A disabled job is not scheduled and cannot be run manually | POST /api/v1/jobs/{jobCode}/enable and /disable |
| Row click | Row | Opens the execution history drawer | GET /api/v1/jobs/{jobCode}/executions?pageIndex=&pageSize= |
| Retry (replay icon) | Execution with status FAILED or DEAD | Queues a new RETRY execution with attempt 1 and the same parameters (audit job.retried) | POST /api/v1/job-executions/{id}/retry |
| Cancel (x icon) | Execution with status QUEUED | Marks it CANCELLED (audit job.cancelled) | POST /api/v1/job-executions/{id}/cancel |
Procedures
Re-run a failed nightly job with a longer timeout:
- Open Jobs, search
payroll, and select the row "Payroll sweep" (hcm-payroll.sweep). The drawer shows the last executions; the newest isTIMEOUTthenDEAD. - Close the drawer and select the gear icon. Set Timeout (seconds) to 900, Max attempts to 3, Backoff to Exponential, Retry initial delay to 60 and Save.
- Reopen the drawer and select the replay icon on the DEAD execution. A new row with Trigger
RETRY, Attempt 1 and StatusQUEUEDappears, thenRUNNINGandSUCCESS.
Statuses and lifecycle
Job status:
| Status | Meaning |
|---|---|
REGISTERED | Known to the registry, not switched on |
ENABLED | Scheduled (if cron) and runnable |
DISABLED | Switched off by an administrator |
Execution status and transitions:
| Status | Meaning | Transitions |
|---|---|---|
QUEUED | Waiting for a worker; becomes eligible at availableAt | RUNNING; CANCELLED by Cancel |
RUNNING | Claimed by a worker | SUCCESS; on failure FAILED (retry queued) or DEAD (attempts exhausted); on timeout TIMEOUT (retry queued) or DEAD |
SUCCESS | Handler returned success; result stored | terminal |
FAILED | Attempt failed and another attempt is queued (new execution, Trigger RETRY) | terminal for the row |
TIMEOUT | Attempt exceeded the job timeout; another attempt is queued | terminal for the row |
RETRYING | Defined by the schema; the worker records retries as new QUEUED rows | not used by the worker |
DEAD | Dead-lettered: attempts exhausted, or the job definition no longer exists ("job definition no longer registered"). Audit job.execution.dead | Retry creates a new execution |
CANCELLED | Cancelled by Cancel, or released because the concurrency lock was busy (the same work is re-queued 5 seconds later) | terminal |
If no handler is registered for the job (owning plugin not loaded), the attempt fails with no handler registered for job CODE (owning plugin not loaded) and follows the normal retry rules.
Permissions
Enabling, disabling and changing the settings of a job, and retrying or cancelling an execution, pass the privileged action gate on job.manage (a privileged role or an explicit grant, and no denying rule); otherwise HTTP 403 with actor "x" lacks job.manage permission. Running a job (POST /api/v1/jobs/{jobCode}/execute), listing jobs, monitoring and execution history are not gated by this check: modules start their own jobs on behalf of ordinary users (for example payroll calculation), so running needs a per-job right that is not yet built. Operations are audited with the acting user as Actor.
API and CLI
| Method and path | Purpose |
|---|---|
GET /api/v1/jobs | All jobs of the tenant |
GET /api/v1/jobs/{jobCode} | One job; 404 when unknown |
POST /api/v1/jobs/{jobCode}/execute | Run now; returns {"executionId": n}; 404 unknown job; 422 with {"message": "job x is disabled"} |
POST /api/v1/jobs/{jobCode}/enable, /disable | Switch on or off (204) |
PATCH /api/v1/jobs/{jobCode}/settings | Body: priority, timeoutSeconds, concurrencyPolicy, maxAttempts, retryBackoff, retryInitialDelaySeconds, retryMaxDelaySeconds |
GET /api/v1/jobs/monitoring | Totals, avgDurationMs, failureRatePercent (null until an execution completed) |
GET /api/v1/jobs/{jobCode}/executions | Paged history (pageSize default 25, max 500) |
GET /api/v1/job-executions/{id} | One execution |
POST /api/v1/job-executions/{id}/retry | 422 execution N is not DEAD/FAILED (status=X) otherwise |
POST /api/v1/job-executions/{id}/cancel | 422 execution is not cancellable (not QUEUED, or not found) |
bash
erp api get /api/v1/jobs
erp api post /api/v1/jobs/backup.run/executeerp api supports get, post, put and delete. The settings update is a PATCH; use the Studio screen or an HTTP client with your session token for it.
Limits and behavior
- The scheduler evaluates schedules every 30 seconds. A job is queued when the next cron time after its last dispatch (or creation time) has passed. Cron expressions use six fields, seconds first,, for example
0 15 2 * * *. - Workers poll every 2 seconds, claim at most 5 executions per tenant at a time, and run on a pool of 4 threads.
- Scheduling is skipped for a tenant whose region assignment is
migrating(see Tenant migration). - A timeout cannot forcibly stop Java code. A handler that ignores interruption keeps running in the background after the attempt is recorded as
TIMEOUT. - Every job operation writes an audit event of category
job(see Logging).
Errors and troubleshooting
| Message or symptom | Cause | Fix |
|---|---|---|
| Execute now icon disabled | Job status is not ENABLED | Select Enable |
job x is disabled | API call to execute a disabled job | Enable it first |
execution N is not DEAD/FAILED (status=SUCCESS) | Retry requested for another status | Retry applies to FAILED and DEAD only |
| Many CANCELLED rows with no error | Concurrency lock busy; work was re-queued | Normal for SINGLE jobs under contention |
no handler registered for job x (owning plugin not loaded) | The plugin that owns the job is disabled or not loaded | Enable the plugin in Extensions |
execution exceeded 300s timeout | Handler too slow | Raise Timeout in Job Settings |
My tasks
My tasks is the personal approval inbox. It lists the human approval tasks assigned to the signed-in user by workflows and business rules (the requireApproval action) and lets the user claim, approve, return or reject them. Approvers and line managers use it. Authoring approvals is described in Workflows and rules.
Where to find it: Workspace > Administration > My tasks. Page key task-inbox; the screen title reads "My Tasks".
Key concepts
| Term | Meaning |
|---|---|
| Human task | One approval step of a workflow instance, assigned to one or more candidate approvers. |
| Candidate approver | An identity listed on the task. Only candidates can claim or decide. |
| Approval mode | How several approvers combine: first-response (the first decision decides), all-must-approve (all candidates must approve; one reject or return ends it), quorum (a required number of approvals). |
| Claim | Reserves the task for the current user before deciding. |
| Return | Sends the task back for rework: a third outcome, recorded as decision returned, which the workflow can route separately from rejected. |
Fields and options
Grid columns:
| Column | Description |
|---|---|
| Task | "Task #id" with "Workflow instance N" below |
| Approval | Approval mode; select filter |
| Status | pending or claimed; select filter |
The header shows "N pending for" followed by your user name. The grid has search ("Search my tasks"), refresh, and the empty text "No pending approvals for" followed by your user name. The list contains only tasks in status pending or claimed where the user is a candidate approver.
Return dialog ("Return for rework"): explanatory text "Sends this task back to the requester instead of rejecting it outright. Say what needs fixing - it's recorded with the decision."
| Field | Type | Default | Required | Description |
|---|---|---|---|---|
| What needs to change | Multi-line text | empty | No | Stored as the decision comment (trimmed) and merged into the workflow instance context |
Actions
| Action | Shown when | Effect | API |
|---|---|---|---|
| Claim | Status pending | Reserves the task for you | POST /api/v1/workflows/human-tasks/{id}/claim?approver=<user> |
| Approve | Status claimed | Records approval | POST /api/v1/workflows/human-tasks/{id}/decide with approved: true |
| Return | Status claimed | Opens the dialog; Return sends decision: "returned" and the comment | same |
| Reject | Status claimed | Records rejection (approved: false) | same |
Procedures
- Open My tasks. A row "Task #118 / Workflow instance 54", Approval
first-response, Statuspendingappears. - Select Claim. The status changes to
claimedand the actions Approve, Return, Reject appear. - Select Return, type "Attach the signed quote", select Return. The task leaves your list and the workflow follows its
returnedtransition.
Statuses and lifecycle
| Status | Meaning |
|---|---|
pending | Waiting for a candidate to claim |
claimed | Held by an approver; also the state while a multi-approver mode still waits for more decisions |
approved | Final: approved |
rejected | Final: rejected |
returned | Final: returned for rework |
delegated | Handed to another identity (delegation is not offered on this screen) |
In all-must-approve the task finalizes when everyone has approved, or at the first reject or return. In quorum it finalizes when the required count of approvals is reached, or when too many rejections make the quorum unreachable. A return vetoes in every mode.
Permissions
The user must be a candidate approver. The decision is also checked against the workflow's permission: resource workflow:<workflow name>, action approve, reject or return. Claiming checks candidacy only. Errors: Actor "x" is not a candidate approver for human task N (tenant T) and Actor "x" is not permitted to "approve" workflow "w" (tenant T).
API and CLI
bash
erp api get "/api/v1/workflows/human-tasks?approver=jane.doe"
erp workflow tasks 54
erp workflow instance 54
erp workflow history 54POST /api/v1/workflows/human-tasks/{id}/decide body: approver, approved (boolean), optional decision (approved, rejected, returned; wins over approved), optional comment. POST /api/v1/workflows/human-tasks/bulk-decide takes taskIds, approver, approved, decision, comment and returns per-task success or error; one failing task does not stop the others.
Limits and behavior
- The list shows only the current user's tasks; it is not an administrator's view of everyone's tasks.
- A claim that cannot be granted (already claimed by someone else) returns HTTP 409 and the task stays unclaimed for you.
- Decision comments are stored with the decision and returned in the workflow result as
{"decision": "...", "comment": "..."}.
Errors and troubleshooting
| Message or symptom | Cause | Fix |
|---|---|---|
| Task missing from the list | You are not in the candidate list, or the task is finished | Ask the workflow owner to check the approver rules |
is not a candidate approver | Decision attempted by someone else | Use the assigned identity |
is not permitted to "approve" workflow | Missing workflow:<name> grant | Grant the action in the Permission Designer |
