Skip to main content

Platform Runs API

Platform Runs are the business-facing batch operations of the quote-to-cash pipeline, exposed as first-class objects: Mediation Run, Usage Rating Run, Rated Transaction Run, Invoice PDF Run, Payment Run, Dunning Run, Journal Run, and multi-stage sequences such as the Re-rating Sequence. Each run wraps one or more job executions behind a single status machine, so you launch and follow a named business operation instead of driving raw job instances.

Billing Runs are the exception: they were already a first-class resource and keep their dedicated endpoints at /api/v1/billingRuns. The run catalog points there.

Prerequisites

A bearer token, per Authentication:

export TOKEN=$(curl -s -X POST "$KEYCLOAK_TOKEN_URL" \
-d "grant_type=client_credentials&client_id=$KEYCLOAK_CLIENT_ID&client_secret=$KEYCLOAK_CLIENT_SECRET" \
| python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")

The run catalog

GET /api/v1/runs/catalog returns every run type with its display name, category, ordered stages, parameter schema, and execution mode. The catalog is the single source of truth: build launch forms and run pages from it rather than hardcoding run types.

curl -s -H "Authorization: Bearer $TOKEN" \
"$BASE_URL/api/v1/runs/catalog" | jq '.[0]'
{
"key": "MEDIATION",
"displayName": "Mediation Run",
"description": "Convert collected CDRs into rateable usage events (EDRs).",
"category": "MEDIATION",
"executionMode": "ON_DEMAND",
"launchable": true,
"sequence": false,
"stages": [
{ "key": "MEDIATION", "jobTemplate": "MediationJob", "jobInstanceCode": "RUN_MEDIATION" }
],
"params": []
}

Two fields drive client behavior:

  • executionMode: MANAGED runs (for example Recurring Rating) are scheduled by the platform and never need a manual launch; ON_DEMAND runs are launched by an operator or an integration.
  • dedicatedResource: when set (the BILLING entry points to /api/v1/billingRuns), the type is catalog-only here and must be driven through its own resource.

Launching a run

curl -s -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{ "runType": "RATED_TRANSACTIONS", "description": "Convert open wallet operations" }' \
"$BASE_URL/api/v1/runs"

The call returns 202 Accepted with the created run. Execution is asynchronous: poll GET /api/v1/runs/{code}.

{
"code": "RUN-3",
"runType": "RATED_TRANSACTIONS",
"status": "RUNNING",
"origin": "AD_HOC",
"steps": [
{
"position": 0,
"stageRunType": "RATED_TRANSACTIONS",
"status": "RUNNING",
"jobInstanceCode": "RUN_RATED_TRANSACTIONS",
"jobExecutionId": 2099
}
]
}

Error contract:

StatusMeaning
409A run of this type is already pending or running
422Unknown run type, catalog-only type (BILLING), or invalid parameters
400Missing runType

Run statuses

PENDINGRUNNINGCOMPLETED | COMPLETED_WITH_ERRORS | FAILED | CANCELLED. COMPLETED_WITH_ERRORS means the run finished but one or more items were rejected (the counters carry the detail). A failed or cancelled step cancels the remaining steps of a sequence.

Sequences

A sequence executes several stages in order; the platform advances the chain as each stage completes. The Re-rating Sequence is a built-in example:

curl -s -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{ "runType": "RE_RATING" }' "$BASE_URL/api/v1/runs"
{
"code": "RUN-4",
"status": "COMPLETED",
"steps": [
{ "stageRunType": "RATING_CANCELLATION", "status": "COMPLETED", "jobExecutionId": 2100 },
{ "stageRunType": "DUPLICATE_BILLED_RTS", "status": "COMPLETED", "jobExecutionId": 2101 },
{ "stageRunType": "RE_RATING_V2", "status": "COMPLETED", "jobExecutionId": 2102 }
]
}

INVOICE_CYCLE (rated transactions → invoice lines → invoicing → XML → PDF) and BILL_TO_CASH (the full pipeline through payment) ship as launchable presets. By default a sequence continues past a stage that completed with item errors; a failed stage always stops it.

History and follow-up

# Paginated history, filterable by runType, status, origin
curl -s -H "Authorization: Bearer $TOKEN" \
"$BASE_URL/api/v1/runs?runType=RE_RATING&status=COMPLETED&limit=20&offset=0"

# One run, with live counters while a step is running
curl -s -H "Authorization: Bearer $TOKEN" "$BASE_URL/api/v1/runs/RUN-4"

Each step links to its jobExecutionId, so drill-down to the technical job execution history stays one hop away.

When a run fails: understand, then resume

A run can end three ways short of success, and each is visible on the ticket:

  • COMPLETED_WITH_ERRORS: the run finished but some items were rejected. The counters carry the split; per-item reasons live in the linked job execution report. Rejected items stay pending, so the next run of the same type picks them up once the cause is fixed. Relaunch is the right action here.
  • FAILED: a step crashed. The run stores the engine's error message (errorMessage), the failed step is marked, and later steps are cancelled.
  • CANCELLED: an operator stopped it; unstarted steps were cancelled.

For FAILED and CANCELLED runs, resume instead of relaunching:

curl -s -X POST -H "Authorization: Bearer $TOKEN" \
"$BASE_URL/api/v1/runs/RUN-12/resume"

202 returns a follow-up run linked through resumedFrom. Steps that completed in the original are carried over as completed, keeping their execution links; execution restarts at the first step that never finished.

{
"code": "RUN-13",
"resumedFrom": "RUN-12",
"status": "RUNNING",
"steps": [
{ "stageRunType": "RATING_CANCELLATION", "status": "COMPLETED", "jobExecutionId": 2100 },
{ "stageRunType": "DUPLICATE_BILLED_RTS", "status": "RUNNING", "jobExecutionId": 2118 },
{ "stageRunType": "RE_RATING_V2", "status": "PENDING" }
]
}

This is safe by construction: every pipeline stage only processes items still waiting (unrated events, unbilled transactions, invoices without documents), and progress is committed in batches as a run advances. Nothing is rated or billed twice on resume. Error contract: 404 unknown run, 409 another run of the type is active, 422 the run is still active or completed all its steps.

Automatic runs: retry once, then alert

Scheduled (managed) runs do not depend on anyone watching. When one fails, the platform retries it once automatically after a short delay (default 15 minutes, run.autoRetry.delayMinutes). The retry is a resume, so it continues from where the failure stopped. If the retry also fails, the platform raises an alert rather than failing silently, and does not retry again.

Two fields on the run expose this:

  • autoRetry: true when the run was created by the automatic retry (not a manual resume).
  • retryState: NONE, RETRIED (this failed run already spawned its one automatic retry), or ALERTED (a failed automatic retry that needs attention).

The always-on alert is the run's ALERTED state, which the Automations screen shows in red, plus an error log entry. When a recipient is configured through run.alert.recipient, an email is also sent. A successful retry leaves no alert.

Cancelling

curl -s -X POST -H "Authorization: Bearer $TOKEN" \
"$BASE_URL/api/v1/runs/RUN-4/cancellation"

202: pending steps are cancelled immediately; a running step is asked to stop through the job engine and the run reaches CANCELLED once the engine confirms. Cancelling a finished run returns 422.

Runs vs jobs

The job engine (job instances, timers, Job Studio chains) stays available under Administration for technical work: scripting jobs, file imports, purges. The run layer never modifies it. Canonical run instances are prefixed RUN_ and are owned by the platform; operator-managed instances (for example M_Job, U_Job) keep working independently.