Sim Job Status
View as MarkdownPoll GET /v1/simc/jobs/{jobId}/status to check on a job in flight. The response covers estimated time to start, the SimC progress percent, and a tail of recent SimC log lines. Skip to the examples for code samples.
#Response
GET /v1/simc/jobs/{jobId}/status
The following fields are included in a successful response. View in full in API Reference.
The status of the job. Terminal values: completed, failed, cancelled, timed_out.
pending | queued | starting | running | completed | failed | cancelled | timed_out
Machine-readable error code for the terminal state. Null when the job is not terminal or completed successfully.
execution_interrupted | execution_timeout | execution_failed | build_unavailable | simulation_error | queue_timeout | input_invalid | insufficient_credits | user_cancelled | internal
Human-readable explanation paired with errorCode. Null when the job is not terminal or no additional detail is available.
SimC process exit code. Null when the job is not terminal.
Estimated seconds until this job begins running. Updated on each poll; not a guarantee. Null when no estimate is available.
When this estimate was last computed.
Estimated completion percentage (0–100). Null when not yet running.
Stage progress detail while the job is running. Null before the job starts running and once it reaches a terminal state. Shape: { current, total, label, percent }. Single-pass jobs report { current: 1, total: 1, label: "initial" } while running. See the API Reference for full field details.
Recent log lines from SimC stdout and stderr while the job is running. Each entry is tagged with its stream (source) and capture time (ts). Full logs are available as downloadable artifacts once the job completes. Null when not running or not requested via include=logEntries.
Which stream the line came from. stderr lines are diagnostic output: SimC warnings, errors, and notes. stdout lines are sim output, progress markers, and results.
stdout | stderr
The log line text.
Epoch milliseconds (UTC) when this line was captured.
When this job began executing. Null when the job has not yet started.
When this status was last updated.
True if this job was retried automatically because of a platform error. The response reflects the latest retry attempt.
#Polling
- Stop polling once
statusis terminal (completed,failed,cancelled,timed_out) and fetch the final result fromGET /v1/simc/jobs/{jobId}/result. - Aggressive polling can hit your read rate limit. Responses include
X-RateLimit-RemainingandX-RateLimit-Resetheaders. - To skip polling entirely, subscribe to terminal job events via webhooks at submit time. See Webhooks.
#Examples
#Job time in queue
This example function logs the status, queue, and progress of a job.
const secretKey = process.env.SIMMIT_SECRET_KEY
async function printJobQueueStatus(jobId) {
// Send GET request to status endpoint
const response = await fetch(
`https://api.simmit.com/v1/simc/jobs/${jobId}/status`,
{ headers: { Authorization: `Bearer ${secretKey}` } }
)
if (!response.ok) {
throw new Error(`Status failed: ${response.statusText}`)
}
const { status, queue } = await response.json()
if (status === 'queued') {
console.log(`Queue time estimate: ${queue.estimatedStartSeconds}s`)
} else {
console.log('Job is not in queue')
}
}
// Use a real job ID
await printJobQueueStatus('123')#Job progress percent
This example function logs the progress.percent. The progress percent is an estimate, derived from the sim's running output.
const secretKey = process.env.SIMMIT_SECRET_KEY
async function printJobProgress(jobId) {
// Send GET request to status endpoint
const response = await fetch(
`https://api.simmit.com/v1/simc/jobs/${jobId}/status`,
{ headers: { Authorization: `Bearer ${secretKey}` } }
)
if (!response.ok) {
throw new Error(`Status failed: ${response.statusText}`)
}
const { status, progress } = await response.json()
if (status !== 'running') {
console.log(`Job is ${status}`)
return
}
if (progress.percent != null) {
console.log(`Progress: ${progress.percent.toFixed(1)}%`)
}
}
// Use a real job ID
await printJobProgress('123')#Job SimC log tail
Pass ?include=logEntries to the status endpoint to get the most recent
stdout/stderr lines while SimC is running. Each entry is tagged with its
stream (source) and capture time (ts). logEntries is null unless the
job is running and you requested it.
const secretKey = process.env.SIMMIT_SECRET_KEY
async function printRecentLogs(jobId) {
const response = await fetch(
// Pass `?include=logEntries`
`https://api.simmit.com/v1/simc/jobs/${jobId}/status?include=logEntries`,
{ headers: { Authorization: `Bearer ${secretKey}` } }
)
if (!response.ok) {
throw new Error(`Status failed: ${response.statusText}`)
}
const { status, logEntries } = await response.json()
if (status !== 'running') {
console.log(`Job is ${status}`)
return
}
for (const { source, message, ts } of logEntries ?? []) {
const time = new Date(ts).toISOString()
console.log(`[${time}] ${source}: ${message}`)
}
}
// Use a real job ID
await printRecentLogs('123')To actually tail, poll on an interval and track the last ts you've seen, filtering entries at or below it. Stop polling once status is terminal (completed, failed, cancelled, timed_out).
#Job is finished
A job is terminal once its status is completed, failed, cancelled, or timed_out. At that point, fetch the result from GET /v1/simc/jobs/{jobId}/result.
const secretKey = process.env.SIMMIT_SECRET_KEY
const TERMINAL_JOB_STATUSES = ['completed', 'failed', 'cancelled', 'timed_out']
async function printIsJobTerminal(jobId) {
// Send GET request to status endpoint
const response = await fetch(
`https://api.simmit.com/v1/simc/jobs/${jobId}/status`,
{ headers: { Authorization: `Bearer ${secretKey}` } }
)
if (!response.ok) {
throw new Error(`Status failed: ${response.statusText}`)
}
const { status } = await response.json()
if (TERMINAL_JOB_STATUSES.includes(status)) {
console.log('Job is terminal, time to fetch the result')
} else {
console.log('Job is not terminal')
}
}
// Use a real job ID
await printIsJobTerminal('123')#Job polling
This example function polls a job's status on a fixed interval, logging queue ETA or running progress on each tick, until the job is terminal. It then fetches the result.
const secretKey = process.env.SIMMIT_SECRET_KEY
const TERMINAL_JOB_STATUSES = ['completed', 'failed', 'cancelled', 'timed_out']
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
async function pollJob(jobId, { intervalMs = 2000 } = {}) {
while (true) {
const response = await fetch(
`https://api.simmit.com/v1/simc/jobs/${jobId}/status`,
{ headers: { Authorization: `Bearer ${secretKey}` } }
)
if (!response.ok) {
throw new Error(`Status failed: ${response.statusText}`)
}
const { status, queue, progress } = await response.json()
if (TERMINAL_JOB_STATUSES.includes(status)) {
console.log(`Job ${status}`)
return status
}
if (status === 'queued' && queue?.estimatedStartSeconds != null) {
console.log(`Queued (eta ~${queue.estimatedStartSeconds}s)`)
} else if (status === 'running' && progress.percent != null) {
console.log(`Running (${progress.percent.toFixed(1)}%)`)
}
await sleep(intervalMs)
}
}
// Poll until the job is terminal, then fetch the result
const status = await pollJob('123')
if (status === 'completed') {
const result = await fetch(`https://api.simmit.com/v1/simc/jobs/123/result`, {
headers: { Authorization: `Bearer ${secretKey}` }
}).then(r => r.json())
console.log(`DPS: ${result.result.summary.mainActor.mean}`)
}