Skip to main content
    Ivy Biosciences Docs/Call the platform/API/Real-time/WebSocket Protocol

    WebSocket Protocol

    External clients cannot open a job WebSocket; follow jobs with the SSE job event proxy instead

    realtimewebsocketstreaming

    The platform does not offer a public WebSocket endpoint. The job WebSocket is internal to the compute backend, and external clients cannot connect to it. To follow a job in real time, use the SSE job event proxy. The web app opens the job socket on its own server and relays every update to you over plain HTTP, so you get the same updates without a socket to manage.

    Difficulty

    intermediate

    Time

    6 min

    Prerequisites

    Following a job in real time

    Earlier versions of this page documented a wss:// URL on a separate API host. That host does not serve external traffic, and no WebSocket URL on our domain replaces it. Code that opens a job WebSocket directly will not connect. Move it to the SSE stream below.

    GET https://www.ivybiosciences.com/api/v1/jobs/{jobId}/events
    Authorization: Bearer <clerk_session_token>

    The stream needs a signed-in session: a Clerk session JWT in the Authorization header, or, from a browser on the same origin, the session cookie. An ivy_ API key alone is refused with 503, so a server holding only a key polls GET /api/v1/jobs/{jobId} instead. The route checks that the caller can read the job before it opens the upstream socket.

    BehaviorDetail
    Update cadencePushed as the job changes, typically every 1-5 seconds while it computes
    Terminal statusThe stream closes itself after it relays a terminal status (COMPLETED, SUCCESS, FAILURE, FAILED or CANCELLED)
    Maximum lengthAbout five minutes per connection, then a close event. Open the stream again to keep following a long job
    Guest jobsGET /api/v1/jobs/{jobId}/guest-events?guest_id=guest_... needs no credential

    Update payload

    Each job_update event carries the job's status in data:

    {
      "type": "job_update",
      "data": {
        "job_id": "job_abc123",
        "status": "PROCESSING",
        "progress": 45,
        "phase_name": "main_computation",
        "result": null,
        "error_message": null
      }
    }
    FieldTypeDescription
    data.job_idstringJob identifier
    data.statusstringCurrent status (PENDING, STARTED, PROCESSING, etc.)
    data.progressnumberCompletion percentage (0-100)
    data.phase_namestringCurrent computational phase
    data.resultobject|nullResult data (only when COMPLETED)
    data.error_messagestring|nullError description (only when the job fails)

    The full list of event names (subscribed, job_update, error, close) is in SSE Streaming.


    Implementation Examples

    In a signed-in browser on the same origin, EventSource sends the session cookie and reconnects on its own.

    const source = new EventSource(`/api/v1/jobs/${jobId}/events`)
    
    source.addEventListener("job_update", (event) => {
      const { data } = JSON.parse(event.data)
      console.log(`[${data.phase_name}] ${data.progress}% — ${data.status}`)
    })
    
    source.addEventListener("close", () => source.close())

    If the stream ends before the job finishes, open it again. For a job you only need to check occasionally, poll GET /api/v1/jobs/{jobId} instead.

    Was this page helpful?

    On this page

    On this page

    Loading...