Skip to main content
Keep a connection open to receive project events without hosting a public HTTPS receiver. This is useful for local development and long-running backend workers. Use Webhook when Photon should push events to your HTTP endpoint instead. Photon uses Socket.IO, not a raw WebSocket protocol. Use socket.io-client in Node.js or another compatible client. A native WebSocket client cannot subscribe to this protocol.

Connect to your project

You need a project and API credential with project:read access to that project. Each connection subscribes to one project. You do not need to create a webhook destination first.
Set PHOTON_PROJECT_ID and PHOTON_API_KEY in your server’s environment. Create the connection without starting it, so you can register listeners first:
Set the project route in path, not in the URL passed to io(). Use Socket.IO’s default namespace. Photon does not support polling.
Keep your credential on the server. A browser cannot supply this authorization header on a websocket-only connection. Direct connections from customer browser applications cannot use this endpoint.

Subscribe and receive events

Before calling socket.connect(), register handlers for connect, delivery, delivery_error, and connect_error. A cursor marks your progress through the event stream. Use it to resume after a disconnection.
  1. On every connect, emit subscribe with { startSeq } and an acknowledgement callback. Use 0 for new events. To resume, use the cursor of the last event you successfully processed. You can also set apiVersion to choose a selectable payload version.
  2. Check the acknowledgement’s ok field. A successful subscription returns the accepted API version, connection ID, cursor, and limits before deliveries begin. Send only one successful subscription per connection.
  3. Handle delivery(event, metadata). The event is the same parsed public JSON object as a webhook for that event and API version. The metadata contains seq, the cursor, and replyExpected.
Use the Node.js example for a queue that processes one event at a time and reconnect handling. The session guide and event guide describe the command and delivery shapes.

Resume without skipping work

Process one event at a time. Save metadata.seq to durable storage only after processing succeeds. If your last processed cursor is 42, reconnect with startSeq: 42, not 43. Cursors can have gaps. Use the value Photon gives you; do not calculate the next value. Store a separate cursor for each project and each independent application that processes its events. Socket.IO reconnects automatically after temporary connection failures. For authentication errors or an explicit server disconnect, fix the cause before you call socket.connect() again. Your application must subscribe again with its saved cursor. Do not reset the cursor to 0 on every connection. That starts with new events and skips the disconnected period. If a handler fails, stop the stream before you process later events. Resume from the last cursor you successfully saved. The server does not wait for your event handler to finish. A reconnection can deliver the same event again, so prevent duplicate work in your handler. Photon can replay only events it still retains. Replay is not an unlimited archive and does not guarantee exactly-once processing. See Cursors and replay and Errors and reconnection for recovery details.

Reply when the event requests it

When metadata.replyExpected is true, the connection can submit a synchronous HTTP response through the Socket.IO reply command. This requires project:write. Send the reply before the event’s deadline expires. It is not a chat message. Send chat replies through the messaging API. See Reply to a webhook event for the reply format and the frame reference for the complete protocol.