Progress & Long-Running Jobs

Stream progress on async server jobs — imports/exports, lookups, AI tagging, cover generation, automation runs, and OAuth connections.


Some Blue operations run asynchronously on the server — bulk imports and exports, reference-field lookups, AI auto-tagging, cover-image generation, automation executions. These subscriptions push job status to your client as the work proceeds, so you can render a progress bar or refresh a view the moment a job finishes instead of polling.

These are streamed over WebSocket using the graphql-ws protocol at wss://api.blue.cc/graphql — the same path as the HTTP GraphQL endpoint. Open and authenticate the connection first; see Connect & Authenticate for the handshake and credential forms. The examples below show only the subscription documents.

Unlike the entity change-feeds (records, comments, files, …) these are job-status channels, so their payloads vary. Some return a free-form JSON blob (subscribeToImportExportProgress, subscribeToLookupProgress), some a typed progress object (subscribeToAITagProgress, subscribeToCoverGenerationProgress), and the automation/OAuth streams reuse the standard { mutation, node, previousValues } shape described on the Real-time overview. Each section below states which.

subscribeToImportExportProgress

Track a bulk import or export as it runs. Blue runs these as background jobs; this stream reports their lifecycle so you can show a spinner and reload the workspace when the job is DONE.

Request

subscription OnImportExportProgress {
  subscribeToImportExportProgress(projectId: "project_123", userId: "user_123")
}

Parameters

ParameterTypeRequiredDescription
projectIdString!YesWorkspace ID the import/export targets.
userIdString!YesThe user running the job. Events are delivered only when this matches the authenticated user — pass your own user ID here.

Response

This field returns JSON — there is no sub-selection. Each event is an object of the form { status: 'IN_PROGRESS' | 'DONE' | 'ERROR' }.

{
  "data": {
    "subscribeToImportExportProgress": { "status": "IN_PROGRESS" }
  }
}

A terminal DONE (or ERROR) event is the signal to stop your spinner and refetch:

{
  "data": {
    "subscribeToImportExportProgress": { "status": "DONE" }
  }
}
StatusMeaning
IN_PROGRESSThe import or export is still running.
DONEThe job finished successfully.
ERRORThe job failed; nothing further will be emitted.

subscribeToLookupProgress

Track progress while Blue resolves a reference (lookup) field across a workspace — for example, recomputing linked-record values after a field or list changes. Scope it to a single workspace with the filter.

Request

subscription OnLookupProgress {
  subscribeToLookupProgress(filter: { projectId: "project_123" })
}

Parameters

LookupProgressFilter

ParameterTypeRequiredDescription
projectIdString!YesWorkspace ID. Events are delivered only for lookup jobs in this workspace.

Response

This field returns JSON — there is no sub-selection. The payload is the progress object published by the server for the matching workspace.

{
  "data": {
    "subscribeToLookupProgress": {
      "projectId": "project_123",
      "progress": 60,
      "processed": 120,
      "total": 200
    }
  }
}
JSON payload, not a typed object

Because the field’s type is JSON, the server controls the shape and you select no subfields. Read the keys defensively in your client rather than relying on a fixed schema.

subscribeToAITagProgress

Track AI auto-tagging of records as it runs. When you trigger AI tagging for a workspace, the server processes records in the background and publishes progress to this stream.

Request

subscription OnAITagProgress {
  subscribeToAITagProgress(projectId: "project_123") {
    progress
    count
    maxCount
    operationId
    error
    errorCode
  }
}

Parameters

ParameterTypeRequiredDescription
projectIdString!YesWorkspace ID the tagging job runs in. Events are delivered only to the user who started the job.

Response

subscribeToAITagProgress returns an AITagProgress object per event.

{
  "data": {
    "subscribeToAITagProgress": {
      "progress": 0.75,
      "count": 75,
      "maxCount": 100,
      "operationId": "clm4n8qwx000008l0g4oxdqn7",
      "error": false,
      "errorCode": null
    }
  }
}

AITagProgress

FieldTypeDescription
progressFloatFractional completion from 0 to 1.
countFloatNumber of records processed so far.
maxCountFloatTotal number of records in the job.
operationIdStringIdentifier for this tagging run; correlate it with the operation you triggered.
errorBooleantrue if the job failed.
errorCodeStringA machine-readable error code when error is true; otherwise null.

subscribeToCoverGenerationProgress

Track AI cover-image generation for records in a workspace. Scope it with the filter.

Request

subscription OnCoverGenerationProgress {
  subscribeToCoverGenerationProgress(filter: { projectId: "project_123" }) {
    mutation
    node {
      projectId
      progress
      processedCount
      totalCount
      status
    }
  }
}

Parameters

CoverGenerationProgressFilter

ParameterTypeRequiredDescription
projectIdString!YesWorkspace ID. Events are delivered only for cover-generation jobs in this workspace.

Response

subscribeToCoverGenerationProgress returns a CoverGenerationProgressPayload per event.

{
  "data": {
    "subscribeToCoverGenerationProgress": {
      "mutation": "UPDATED",
      "node": {
        "projectId": "project_123",
        "progress": 40,
        "processedCount": 4,
        "totalCount": 10,
        "status": "IN_PROGRESS"
      }
    }
  }
}

CoverGenerationProgressPayload

FieldTypeDescription
mutationMutationType!The kind of change: CREATED, UPDATED, or DELETED.
nodeCoverGenerationProgressThe progress snapshot for this event.

This payload has no previousValues or updatedFields — it is a progress feed, not an entity change-feed.

CoverGenerationProgress

FieldTypeDescription
projectIdString!Workspace the cover-generation job runs in.
progressInt!Completion percentage from 0 to 100.
processedCountInt!Number of records processed so far.
totalCountInt!Total number of records in the job.
statusString!Job status string published by the server.

subscribeToAutomation

Stream create, update, and delete events for automation definitions in a workspace — keep an automations panel in sync as automations are added, toggled active/inactive, or removed. This is a config feed (the automation itself), not a feed of automation runs — for runs, use subscribeToAutomationExecution.

Request

subscription OnAutomationChange {
  subscribeToAutomation(projectId: "project_123") {
    mutation
    node {
      id
      isActive
      trigger {
        id
        type
      }
      actions {
        id
        type
      }
    }
    updatedFields
  }
}

Parameters

ParameterTypeRequiredDescription
projectIdString!YesWorkspace ID. Events are delivered only for automations in this workspace, and only if you are a member of it.

Response

subscribeToAutomation returns an AutomationSubscriptionPayload per event.

{
  "data": {
    "subscribeToAutomation": {
      "mutation": "UPDATED",
      "node": {
        "id": "clm4n8qwx000008l0g4oxdqn7",
        "isActive": false,
        "trigger": { "id": "clm4n8qwx000108l0abcd1234", "type": "CUSTOM_FIELD_ADDED" },
        "actions": [{ "id": "clm4n8qwx000208l0efgh5678", "type": "ADD_CUSTOM_FIELD" }]
      },
      "updatedFields": ["isActive"]
    }
  }
}

AutomationSubscriptionPayload

FieldTypeDescription
mutationMutationType!The kind of change: CREATED, UPDATED, or DELETED.
nodeAutomationThe automation after the change. null on a DELETED event.
previousValuesAutomationPreviousValuesThe automation’s scalar values before the change.
updatedFields[String!]Names of the scalar fields that changed on an UPDATED event.

Automation

The most useful fields on the node. See Create an automation for the full trigger/action model.

FieldTypeDescription
idID!The automation’s unique identifier.
triggerAutomationTrigger!What fires the automation.
actions[AutomationAction!]!What the automation does when triggered.
isActiveBoolean!Whether the automation is currently enabled.
createdByUser!The user who created the automation.
createdAtDateTime!When the automation was created.
updatedAtDateTime!When the automation was last modified.

subscribeToAutomationExecution

Stream automation runs for a workspace. Every time an automation fires — by event, on a schedule, or because records started/stopped matching a condition — the server records an AutomationExecution and publishes its status here as it progresses through its batches.

Request

subscription OnAutomationExecution {
  subscribeToAutomationExecution(filter: { projectId: "project_123" }) {
    id
    automationId
    type
    status
    totalTodos
    completedBatches
    failedBatches
    todosAffected
    startedAt
    completedAt
    errorMessage
  }
}

Parameters

AutomationExecutionSubscriptionFilter

ParameterTypeRequiredDescription
projectIdString!YesWorkspace ID. An execution matches via its automation’s workspace.

Response

subscribeToAutomationExecution returns an AutomationExecution per event.

{
  "data": {
    "subscribeToAutomationExecution": {
      "id": "clm4n8qwx000008l0g4oxdqn7",
      "automationId": "clm4n8qwx000108l0abcd1234",
      "type": "EVENT",
      "status": "IN_PROGRESS",
      "totalTodos": 50,
      "completedBatches": 1,
      "failedBatches": 0,
      "todosAffected": 25,
      "startedAt": "2026-05-29T12:00:00.000Z",
      "completedAt": null,
      "errorMessage": null
    }
  }
}

AutomationExecution

FieldTypeDescription
idID!The execution’s unique identifier.
automationIdString!ID of the automation that ran.
automationAutomation!The automation that ran.
typeAutomationExecutionType!How the run was triggered: EVENT, SCHEDULED, or CONDITIONAL.
statusAutomationExecutionStatus!Current run state (see below).
totalTodosInt!Number of records in scope for the run.
totalBatchesIntNumber of batches the run is split into.
completedBatchesInt!Batches finished so far.
failedBatchesInt!Batches that failed.
batchSizeIntRecords per batch.
todosAffectedIntRecords actually modified so far.
startedAtDateTime!When the run started.
completedAtDateTimeWhen the run finished; null while still running.
errorMessageStringFailure detail when the run failed or partially failed.

AutomationExecutionStatus

ValueDescription
PENDINGQueued, not yet started.
IN_PROGRESSCurrently running.
COMPLETEDFinished successfully.
FAILEDFinished with every batch failed.
PARTIALLY_FAILEDFinished with some batches succeeded, some failed.

AutomationExecutionType

ValueDescription
EVENTTriggered by a record event (e.g. a field changed).
SCHEDULEDTriggered on a schedule.
CONDITIONALTriggered because records started or stopped matching a condition.

subscribeToOAuthConnection

Stream create, update, and delete events for OAuth connections in a workspace — third-party integrations (e.g. GitHub) that a workspace has authorized. Use it to reflect connection state in an integrations settings panel as connections are added, renamed, expired, or removed.

Request

subscription OnOAuthConnectionChange {
  subscribeToOAuthConnection(input: { projectId: "project_123" }) {
    mutation
    node {
      id
      name
      provider
      expiredAt
    }
    previousValues {
      id
      name
    }
  }
}

Parameters

SubscribeToOAuthConnectionInput

ParameterTypeRequiredDescription
projectIdString!YesWorkspace ID. Events are delivered only for connections in this workspace, and only if you are a member of it.

Response

subscribeToOAuthConnection returns an OAuthConnectionSubscriptionPayload per event.

{
  "data": {
    "subscribeToOAuthConnection": {
      "mutation": "CREATED",
      "node": {
        "id": "clm4n8qwx000008l0g4oxdqn7",
        "name": "Acme GitHub",
        "provider": "GITHUB",
        "expiredAt": null
      },
      "previousValues": null
    }
  }
}

OAuthConnectionSubscriptionPayload

FieldTypeDescription
mutationMutationType!The kind of change: CREATED, UPDATED, or DELETED.
nodeOAuthConnectionThe connection after the change. null on a DELETED event.
previousValuesOAuthConnectionThe connection before the change, on UPDATED and DELETED events.

OAuthConnection

FieldTypeDescription
idID!The connection’s unique identifier.
uidString!Internal identifier.
nameString!Display name for the connection.
providerOAuthProvider!The integration provider (see below).
expiredAtDateTimeWhen the connection’s credentials expire, if known.
metadataJSONProvider-specific connection metadata.
projectProject!The workspace the connection belongs to.
createdByUser!The user who created the connection.
createdAtDateTime!When the connection was created.
updatedAtDateTime!When the connection was last modified.

OAuthProvider

ValueDescription
GITHUBGitHub.
INUIT_QUICKBOOKSIntuit QuickBooks.

Permissions

Authentication is enforced at the WebSocket handshake — an unauthenticated connection is rejected before any subscription runs. Beyond that, delivery is gated per event:

  • subscribeToImportExportProgress delivers an event only when the job’s userId matches the authenticated user. Pass your own user ID as the userId argument.
  • subscribeToAITagProgress delivers an event only to the user who started the tagging job.
  • subscribeToAutomation and subscribeToOAuthConnection deliver an event only if you are a member of the workspace the automation or connection belongs to.
  • subscribeToLookupProgress, subscribeToCoverGenerationProgress, and subscribeToAutomationExecution deliver events matched on the projectId you supply.

Subscribing always succeeds; you simply receive events only for jobs you can see. See Connect & Authenticate for credentials.