Sim Job Status

View as Markdown

Poll 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.

#statusenum

The status of the job. Terminal values: completed, failed, cancelled, timed_out.

pending | queued | starting | running | completed | failed | cancelled | timed_out

#errorCodeenum | null

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

#statusReasonstring | null

Human-readable explanation paired with errorCode. Null when the job is not terminal or no additional detail is available.

#simcExitCodestring | null

SimC process exit code. Null when the job is not terminal.

#queue.estimatedStartSecondsnumber | null

Estimated seconds until this job begins running. Updated on each poll; not a guarantee. Null when no estimate is available.

#queue.estimatedStartUpdatedAtstring | null

When this estimate was last computed.

#progress.percentnumber | null

Estimated completion percentage (0–100). Null when not yet running.

#progress.stageobject | null

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.

#logEntriesarray | null

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.

#logEntries[].sourceenum

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

#logEntries[].messagestring

The log line text.

#logEntries[].tsnumber

Epoch milliseconds (UTC) when this line was captured.

#startedAtstring | null

When this job began executing. Null when the job has not yet started.

#updatedAtstring | null

When this status was last updated.

#retriedboolean

True if this job was retried automatically because of a platform error. The response reflects the latest retry attempt.

#Polling

  • Stop polling once status is terminal (completed, failed, cancelled, timed_out) and fetch the final result from GET /v1/simc/jobs/{jobId}/result.
  • Aggressive polling can hit your read rate limit. Responses include X-RateLimit-Remaining and X-RateLimit-Reset headers.
  • 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.

JavaScript
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.

JavaScript
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.

JavaScript
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.

JavaScript
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}`)
}