Skip to main content

Subscriptions

Subscriptions allow your application to receive automatic updates from Pico as events happen on the shop floor - without constantly polling the API.

Instead of repeatedly asking "did anything change?", you open a connection once and Pico pushes updates to you immediately when:

  • A work order is completed (so you can update inventory in your ERP)
  • An operation definition is created or modified (so you can sync your product catalog)
  • A product structure changes (so you know what components are needed)
  • An operator creates or updates a note during a build (so you can track quality issues or sync with your ticketing system)

Think of it like subscribing to notifications - you tell Pico what events you care about, and it notifies you the moment they happen.

Available Subscriptions

operationsStream

Stream real-time updates for operations (products, subassemblies, and processes).

Use case: Monitor when operation definitions are created or updated in the system.

subscription {
operationsStream {
id
externalId
name
updatedAt
}
}

subOperationsStream

Stream updates for parent-child operation relationships.

Use case: Track changes to product/subassembly structures and their component operations.

subscription {
subOperationsStream {
parentId
subId
subGroup
updatedAt
}
}

operationOrderCompletesStream

Subscribe to work order completion events with full production details.

Use case: Capture completed work orders for ERP integration, including produced serials and consumed materials.

subscription {
operationOrderCompletesStream {
externalOrderId
at
operation {
id
externalId
name
}
operationSummary {
startedAt
consumedSerials {
id
partNo: externalId
serial: value
}
}
endState {
producedSerial
}
}
}

noteEventsStream

Stream real-time updates when operators create or update notes during builds.

Use case: Capture operator notes for quality tracking, issue management, or integration with external ticketing systems.

subscription {
noteEventsStream {
at
id
images
eventType
externalId
metadata
seq
text
type {
tagName
resolveable
partQuantity
id
description
allowsCustomText
}
state {
build {
producedSerial
process { id name }
operationOrder {
externalOrderId
operation { id externalId externalRevision name updatedAt }
}
}
operator { id name }
station { id name }
step { number name }
}
}
}

Filtering Subscriptions

All subscriptions support optional where clauses to filter events:

subscription {
operationsStream(where: { id: { _eq: "prod-123" } }) {
id
name
}
}

Filter for specific operations:

You can subscribe to completions of a specific operation by filtering on the operation ID:

subscription {
operationOrderCompletesStream(where: {
operation: { id: { _eq: "operation-123" } }
}) {
externalOrderId
at
operation {
id
externalId
name
}
operationSummary {
startedAt
}
endState {
producedSerial
}
}
}

Event Identity and Deduplication

All Pico subscriptions provide at-least-once delivery. Consumers should dedupe events using a stable per-event identity combined with a timestamp. The table below lists the unique-identity and timestamp fields each stream exposes so your integration can persist a cursor and reject duplicates on replay or retransmission.

StreamUnique identityTimestamp / cursor field
operationsStreamidupdatedAt
subOperationsStreamparentId + subIdupdatedAt
operationOrderCompletesStreamexternalOrderId + orderIndexat
noteEventsStreamid (with seq for ordering)at

Store (identity, timestamp) for each processed event. On reconnect, resume from the last timestamp and discard any event whose identity you have already acknowledged.

Connection Protocol

Pico supports subscriptions over three transports: WebSocket (graphql-ws), Server-Sent Events (text/event-stream over a persistent HTTP client), and webhooks. This section covers WebSocket and SSE — see the ERP Integration FAQ for the webhook option.

Over WebSocket

Subscriptions over the WebSocket protocol maintain a persistent, bidirectional connection between your application and the Pico API:

  1. Initial Connection: Your client establishes a WebSocket connection to the GraphQL endpoint (typically wss:// for secure connections)
  2. Subscribe: Send your subscription query through the WebSocket connection
  3. Listen: The connection stays open and the server pushes updates to you in real-time as events occur
  4. Automatic Updates: When a work order completes or an operation changes, the server immediately sends the data through the existing connection
  5. Close: The connection remains open until you explicitly unsubscribe or disconnect

Over Server-Sent Events (HTTP)

If a persistent WebSocket is inconvenient for your environment, you can subscribe over HTTP using Server-Sent Events:

  1. Issue an HTTP GET or POST to the GraphQL endpoint with header Accept: text/event-stream.
  2. Keep the HTTP connection open; events arrive as data: {...} frames on a single long-lived response body.
  3. Reconnect by re-issuing the request; use cursor-based replay to pick up missed events (see Event Identity and Deduplication).

Unlike WebSocket, SSE is unidirectional — the server only pushes events. That is sufficient for every Pico subscription because Pico never sends control messages from server to client mid-subscription.

Client Requirements

Your GraphQL client must support WebSocket-based subscriptions or SSE over HTTP. Compatible WebSocket clients include:

  • Apollo Client (with @apollo/client/link/ws)
  • urql (with @urql/exchange-graphql-ws)
  • graphql-ws (standalone library)
  • Relay (with subscription support)

For SSE, any standard HTTP client that can keep a connection open and parse the text/event-stream MIME type is sufficient (for example, curl, Axios, or fetch with a ReadableStream). No specialized subscription library is required.

Connection URL

WebSocket connections typically use:

  • ws://your-pico-api:port/graphql for development
  • wss://your-pico-api/graphql for production (secure WebSocket)

SSE connections use the same host and path as regular GraphQL HTTP requests, with the Accept: text/event-stream header set.

Consult your Pico administrator for the exact endpoint URL.