The agent
The agent is the program that runs on the machine the printers are attached to. It connects outbound to PrintSocket over a WebSocket, reports the print queues and scales it can see, and prints the jobs you send. Nothing on the machine needs to be reachable from the internet, and nothing on it holds your account's API keys: it holds a credential scoped to that one device.
This page is for the person installing it, which may be you on a test machine or a customer following instructions you wrote. The downloads page has the installers; this page is what happens after the download.
Installing
- Windows. A signed MSI. It installs per machine and starts the tray app at login, for every user. Needs Windows 10 or later, 64-bit.
- macOS. A notarized menu-bar app. Unzip, drag PrintSocket Agent.app to Applications, and open it. A printer icon appears in the menu bar; there is no Dock icon and no window. Needs macOS 12 or later; one universal binary covers Apple Silicon and Intel. The app has to live in Applications: run from Downloads, macOS launches it from a temporary location that does not survive a reboot, and the menu says so with "Move to /Applications for reliable startup" until it is moved.
- Linux. A single static binary,
psagent, with no tray. It discovers printers through CUPS, so CUPS has to be installed and running. Builds for x86-64 and 64-bit ARM.
curl -fsSLo psagent https://downloads.eligian.com/psagent-linux-amd64
chmod +x psagent
sudo mv psagent /usr/local/bin/psagent
Enrolling
Enrollment ties the machine to your account. It starts with a token from POST /enrollment_tokens, or from the dashboard's Add device button, which calls the same thing. Tokens are single-use and expire after an hour, so generate one when you are about to use it.
On Windows and macOS, click the tray or menu-bar icon and choose Enroll this device…. The browser opens a page served by the agent itself on the local machine, you paste the token, and the menu flips to connected. On Linux, or for a scripted install anywhere:
psagent enroll -token enr_...
psagent run
On macOS the binary is inside the bundle, at /Applications/PrintSocket Agent.app/Contents/MacOS/psagent, which is what a management tool would call.
The agent exchanges the token for a device credential and writes it to agent.json in the user's configuration directory: ~/.config/printsocket/ on Linux, ~/Library/Application Support/printsocket/ on macOS, and %AppData%\printsocket\ on Windows. That file is the enrollment. psagent enroll refuses to overwrite one, so re-enrolling a machine means deleting it first.
Running
The desktop builds run as long as the tray app is open, and start at login by default. On Windows the installer sets that; on macOS the app registers a login item on first launch, visible under Login Items in System Settings, and the menu's Start at login toggle turns it off. If the macOS agent crashes, the system restarts it; Quit stops it until it is opened again.
psagent run on Linux runs in the foreground and logs to standard error. To keep it running, put it under the service manager. A user unit is enough, because the agent needs no privileges beyond printing:
# ~/.config/systemd/user/psagent.service
[Unit]
Description=PrintSocket agent
After=network-online.target
[Service]
ExecStart=/usr/local/bin/psagent run
Restart=always
RestartSec=5
[Install]
WantedBy=default.target
systemctl --user enable --now psagent
loginctl enable-linger $USER # keep it running when you are not logged in
journalctl --user -u psagent -f
Once connected, the agent reports every print queue it can see, with capabilities, and repeats the report every minute, so a printer added to the machine appears within that time and one removed from it disappears. The device object's agent_version is the build that is running.
Updating
The tray app checks for a newer release at launch and every six hours, and shows Update available with a download link in the menu when there is one; Check for updates… checks immediately. Updating is manual: on Windows run the new installer, which replaces the files in place, and on macOS quit the agent, replace the app in Applications, and open it again. Enrollment survives updates. On Linux, download the binary again from the same URL and restart the service; the headless build has no update check of its own.
Revoking and re-enrolling
POST /devices/{id}/revoke, or the dashboard's Revoke button, invalidates the device credential. The agent is disconnected at once, its printers go offline, and the device stays in the list as revoked. It cannot be undone and the machine cannot reconnect by itself. To bring the machine back, delete agent.json, generate a new token, and enroll again; it comes back as a new device with a new id.
To take the agent off a machine entirely, revoke it first so the credential is dead, then uninstall it the normal way for the platform: Add or remove programs on Windows, dragging the app to the Trash on macOS, and deleting the binary and the unit file on Linux. The configuration directory can be removed with it.
When a printer shows offline
- Every printer on a device is offline. The device is offline. The agent is not running, the machine is asleep, or it cannot reach
api.printsocket.comon port 443. On the desktop builds the tray icon and its first menu line say which. - One printer is offline while the device is online. The operating system reports the queue but cannot reach the printer: it is powered off, unplugged, or on a network the machine has lost. Fix it where the OS shows it (Printers & scanners, or
lpstat -pon CUPS) and the next report, within a minute, marks it online. - A printer is missing. The queue has been removed from the OS, or on Linux CUPS is not running. Re-add the queue and the printer revives with the same id.
- **Jobs sit at
sentor fail withspool_error.** The OS spooler took the job but could not print it. The job'serror.messagecarries the spooler's own text, which is the same thing the OS print dialog would show.
The dashboard shows the same state, and GET /devices/{id} reports last_seen_at, which is the last time the agent checked in.