> ## Documentation Index
> Fetch the complete documentation index at: https://developer.opus.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Job Audit Log

> Retrieve node-by-node execution data for a job

Opus exposes a node-level audit for every job. The response shows you which nodes have run, which is running now, which are still queued, and which have failed — together with the per-node execution data that the workflow engine produced. Use it for debugging, compliance, or building progress visualisations on top of a running job.

## Path Parameters

<ParamField path="jobExecutionId" type="string" required>
  The ID of the job whose audit log you want to retrieve
</ParamField>

## Headers

<ParamField header="x-service-key" type="string" required>
  Your API authentication key
</ParamField>

## Response

<ResponseField name="nb_nodes" type="number" required>
  Total number of nodes in the workflow.
</ResponseField>

<ResponseField name="executed_nodes" type="string[]" required>
  IDs of nodes that have already finished executing, in the order they ran.
</ResponseField>

<ResponseField name="nb_executed_nodes" type="number" required>
  Number of nodes that have finished executing. Equal to `executed_nodes.length`.
</ResponseField>

<ResponseField name="running_node" type="string" required>
  ID of the node currently executing. Empty string when no node is actively running (for example, between nodes or after the job finishes).
</ResponseField>

<ResponseField name="next_node_to_execute" type="string" required>
  ID of the node scheduled to run next. Empty string when the job has no more nodes queued.
</ResponseField>

<ResponseField name="remaining_nodes_to_execute" type="string[]" required>
  IDs of nodes that are still pending execution.
</ResponseField>

<ResponseField name="failed_nodes" type="string[]" required>
  IDs of nodes that failed during execution.
</ResponseField>

<ResponseField name="nb_failed_nodes" type="number" required>
  Number of failed nodes. Equal to `failed_nodes.length`.
</ResponseField>

<ResponseField name="audit" type="object" required>
  Per-node execution data captured by the engine.

  <Expandable title="Audit Object">
    <ResponseField name="nodes_execution_data" type="object" required>
      Map keyed by node ID. Each value contains the inputs, outputs, and runtime metadata captured when that node executed. The exact shape varies by node type.
    </ResponseField>
  </Expandable>
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl --request GET \
    --url https://operator.opus.com/job/{YOUR_JOB_EXECUTION_ID}/audit \
    --header 'x-service-key: {YOUR_SERVICE_KEY}'
  ```

  ```python Python theme={null}
  import requests

  url = "https://operator.opus.com/job/{YOUR_JOB_EXECUTION_ID}/audit"
  headers = {"x-service-key": "{YOUR_SERVICE_KEY}"}

  response = requests.get(url, headers=headers)
  audit = response.json()

  print(f"Progress: {audit['nb_executed_nodes']}/{audit['nb_nodes']} nodes")
  print(f"Running:  {audit['running_node'] or '(none)'}")
  print(f"Failed:   {audit['nb_failed_nodes']} -> {audit['failed_nodes']}")

  for node_id, data in audit['audit']['nodes_execution_data'].items():
      print(f"\nNode {node_id}:")
      print(data)
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    "https://operator.opus.com/job/{YOUR_JOB_EXECUTION_ID}/audit",
    {
      method: "GET",
      headers: {
        "x-service-key": "{YOUR_SERVICE_KEY}",
      },
    }
  );

  const audit = await response.json();
  console.log(`Progress: ${audit.nb_executed_nodes}/${audit.nb_nodes} nodes`);
  console.log(`Running:  ${audit.running_node || "(none)"}`);
  console.log(`Failed:   ${audit.nb_failed_nodes} -> ${audit.failed_nodes}`);

  for (const [nodeId, data] of Object.entries(audit.audit.nodes_execution_data)) {
    console.log(`\nNode ${nodeId}:`, data);
  }
  ```
</RequestExample>

<ResponseExample>
  ```json 200 Response theme={null}
  {
    "nb_nodes": 5,
    "executed_nodes": ["{NODE_ID_1}", "{NODE_ID_2}"],
    "nb_executed_nodes": 2,
    "running_node": "{NODE_ID_3}",
    "next_node_to_execute": "{NODE_ID_4}",
    "remaining_nodes_to_execute": ["{NODE_ID_4}", "{NODE_ID_5}"],
    "failed_nodes": [],
    "nb_failed_nodes": 0,
    "audit": {
      "nodes_execution_data": {
        "{NODE_ID_1}": {
          "{KEY}": "{VALUE}"
        },
        "{NODE_ID_2}": {
          "{KEY}": "{VALUE}"
        }
      }
    }
  }
  ```
</ResponseExample>
