ModelWorks logoModelWorks

HTTP Watch

Poll a remote HTTP endpoint until pass or fail conditions are met

Introduction HTTP Watch

The circuit.core.http_watch primitive lets you poll any HTTP(S) endpoint at a fixed interval, evaluate pass/fail conditions against the JSON response, and return when a condition is satisfied or throw an error after too many attempts.

When to use: long‑running jobs, external tasks or services where you need to wait for a status change (e.g. image/video generation, analysis pipelines).


Step Definition

JSON
"steps": [
  {
    "name": "wait_for_completion",
    "function": "circuit.core.http_watch",
    "input": {
      "url": "https://api.example.com/jobs/${{ jobId }}",
      "method": "GET",
      "headers": {
        "Authorization": "Bearer ${{ secrets.api_key }}"
      },
      "interval_seconds": 10,
      "max_attempts": 30,
      "timeout_seconds": 600
    },
    "conditions": {
      "pass": [
        { "json_path": "${{ wait_for_completion.output.json_body.status }}", "equals": "SUCCEEDED" }
      ],
      "fail": [
        { "json_path": "${{ wait_for_completion.output.json_body.status }}", "equals": "FAILED" },
        { "status_code": [400,404,500] }
      ]
    },
    "outputs": [
      {
        "name": "resultData",
        "value": "${{ wait_for_completion.output.json_body }}"
      }
    ]
  }
]

input Properties

FieldTypeRequiredDescription
urlstringYesEndpoint URL (template selectors allowed).
methodstringYesHTTP verb (GET,POST,PUT,DELETE,PATCH).
headersobject<string,string>NoMap of request headers (selectors allowed).
interval_secondsnumberYesSeconds between each poll.
max_attemptsnumberYesHow many times to retry before failing.
timeout_secondsnumberYesOverall timeout for each HTTP call.

conditions Block

Controls when to stop polling:

  • pass: array of conditions; all must evaluate to true to succeed.
  • fail: array of conditions; any single true will immediately fail the step.

Each condition object supports:

FieldTypeDescription
json_pathstringSelector into the JSON response (e.g. ${{ step.output.json_body.status }}).
equalsstring or booleanPass/fail when the selected value equals this literal.
not_equalsstring or booleanPass/fail when the selected value does not equal this literal.
status_codearray<number>Fail if the HTTP status code matches any in the list.

Outputs

When the step completes successfully or with an error, its output object includes:

JSON
// JSON-parsed response (if content-type application/json)
wait_for_completion.output.json_body

// Raw headers map
wait_for_completion.output.headers

// HTTP status code
wait_for_completion.output.status

// Total time taken (seconds)
wait_for_completion.output.time_taken

Use selectors in later steps or top‑level outputs:

JSON
"outputs": [
  { "name": "jobResult", "value": "${{ wait_for_completion.output.json_body }}" }
]

Example: Flux Image Generation

JSON
{
  "steps": [
    {
      "name": "submit_job",
      "function": "circuit.core.fetch",
      /* submits image generation and sets flux_job_id */
    },
    {
      "name": "wait_for_image",
      "function": "circuit.core.http_watch",
      "input": {
        "url": "https://api.bfl.ml/v1/get_result?id=${{ flux_job_id }}",
        "method": "GET",
        "interval_seconds": 10,
        "max_attempts": 30,
        "timeout_seconds": 600
      },
      "conditions": {
        "pass": [
          { "json_path": "${{ wait_for_image.output.json_body.status }}", "equals": "Ready" }
        ],
        "fail": [
          { "json_path": "${{ wait_for_image.output.json_body.status }}", "equals": "Error" },
          { "status_code": [400,404,500,422] }
        ]
      }
    },
    {
      "name": "fetch_url",
      "function": "circuit.core.fetch",
      "input": { "url": "${{ wait_for_image.output.json_body.result.sample }}" }
    }
  ],
  "outputs": [
    {
      "name": "imageUrl",
      "value": "${{ fetch_url.output.json_body }}"
    }
  ]
}
  • Submit: POST to start the Flux job and capture flux_job_id.
  • Watch: poll until .status == "Ready", or error on .status == "Error" or HTTP 4xx/5xx.
  • Fetch URL: final GET to retrieve the generated image link.

Best Practices

  • Choose sensible interval_seconds and max_attempts to balance latency vs. load.
  • Always include a fail condition for HTTP errors to prevent infinite loops.
  • Use templated selectors (${{ … }}) to reference intermediate outputs.

Next: Adapters – wire SSE, Webhook, and custom streams directly into your circuits!

On this page

On this page