An interaction step in a workflow spec suspends the run when the engine reaches it and creates a pending interaction for the targeted reviewer. This guide shows how to start such a run, detect the suspension, fetch the interaction, and submit the response that resumes execution — for any backend service that needs to gate workflow progress on human input.

Before you start

  • You have a Mobius API key exported as MOBIUS_API_KEY. See Create an API key if you do not.
  • Your project handle and API base URL are exported as PROJECT and MOBIUS_BASE_URL.
  • Export REVIEWER_ID as the Mobius user ID of the person who will respond to the interaction.

Walkthrough

  1. Start a run with an inline interaction step by calling POST /v1/projects/{project}/runs. The step declares the interaction type, message, target user, and timeout.

    curl -X POST "$MOBIUS_BASE_URL/v1/projects/$PROJECT/runs" \
      -H "Authorization: Bearer $MOBIUS_API_KEY" \
      -H "Content-Type: application/json" \
      -d "{
        \"spec\": {
          \"name\": \"doc-approval\",
          \"steps\": [{
            \"name\": \"get-approval\",
            \"interaction\": {
              \"type\": \"approval\",
              \"message\": \"Approve document for publication?\",
              \"target\": { \"type\": \"user\", \"id\": \"$REVIEWER_ID\" },
              \"timeout\": \"24h\",
              \"spec\": { \"mode\": \"confirm\" }
            }
          }]
        }
      }"

    Returns a run with status: queued. Capture the id field as RUN_ID.

  2. Subscribe to the run's event stream with GET /v1/projects/{project}/runs/{id}/events. Each SSE frame carries {type, run_id, seq, timestamp, data}. Close the stream when you see a run_updated frame with data.status: suspended.

    curl --no-buffer \
      "$MOBIUS_BASE_URL/v1/projects/$PROJECT/runs/$RUN_ID/events" \
      -H "Authorization: Bearer $MOBIUS_API_KEY"
  3. List the pending interaction for the run with GET /v1/projects/{project}/interactions, filtering by run_id and status=pending. Capture the interaction id as INTERACTION_ID.

    curl "$MOBIUS_BASE_URL/v1/projects/$PROJECT/interactions?run_id=$RUN_ID&status=pending" \
      -H "Authorization: Bearer $MOBIUS_API_KEY"

    Returns { "items": [ { "id": "...", "type": "approval", "status": "pending", ... } ] }.

  4. Submit the reviewer's response with POST /v1/projects/{project}/interactions/{id}/respond. Completing a run-backed interaction automatically delivers the signal that resumes the suspended run.

    curl -X POST \
      "$MOBIUS_BASE_URL/v1/projects/$PROJECT/interactions/$INTERACTION_ID/respond" \
      -H "Authorization: Bearer $MOBIUS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{ "value": true, "comment": "Looks good." }'

    Returns the interaction with status: completed. The run re-enters queued and continues.

Follow-ups

Troubleshooting

  • items is empty in step 3: the run has not yet reached the interaction step. Confirm you received a run_updated frame with status: suspended in step 2 before listing interactions.
  • 409 on respondToInteraction: the interaction is already completed or has expired. Fetch its current state with GET /v1/projects/{project}/interactions/{id} and check the status field.
  • 401 on any call: the API key is missing or revoked. Re-issue with Create an API key and re-export MOBIUS_API_KEY.

See also