Docs
FAQ & Troubleshooting
Frequently asked
Do I need a physical printer to try this?
No. Pass { mode: "mock" } to new Portix() and every method works identically — print() renders a text preview instead of sending it anywhere.
What platforms does the Runtime run on?
Windows today. Linux and macOS are on the roadmap, built once Windows is validated with real usage.
What printers are supported?
Any ESC/POS thermal printer — over USB via a Windows printer driver, or over network (TCP/9100, the de facto standard on Epson, Xprinter, and most others). See the compatibility grid on the homepage.
Is the SDK free?
Yes, always — the SDK and Runtime are free for production use, with no artificial limits on printers or volume. Paid plans (Production, Scale) add support and operational tooling — organizations, Runtime health, logs, remote configuration — for once Portix is already part of your infrastructure. See /#join for the current plans.
Do I need pairing, or can I just use the admin key?
The admin key is fine for a single app you control. Pairing exists for multi-tenant products (like Kubia) where each installation should get its own scoped token instead of sharing one key across every customer.
Why did pair() resolve instantly without anyone clicking "Allow"?
A pairing request from localhost, 127.0.0.1, or a private-network address (192.168.x.x, 10.x.x.x) is auto-approved with no human involved — the browser's Origin header already proves it's this developer's own machine or LAN, the same trust boundary SSH gives a private network. A request from a real public domain still goes through the normal approve flow.
Why is websocket.totalDisconnects high even though nothing seems broken?
That counter measures exactly what its name says — disconnects, not failed reconnections — because the SDK doesn't implement reconnect-on-drop yet. Every value in it is a disconnect the SDK didn't automatically recover from; a page refresh or network blip both count.
Is PortixOne open source?
Yes, MIT-licensed — the Runtime, SDK, and every device driver. See github.com/portixhq/portixone for what's open vs. the closed Cloud Platform.
Error codes
Every failed request is { error: CODE, message }. What each one means, and what to do about it:
| Code | HTTP | Meaning | Fix |
|---|---|---|---|
| INVALID_API_KEY | 401 | The x-portix-api-key header didn't match the runtime's admin key or a valid paired token. | Check PORTIX_LOCAL_API_KEY on the runtime, or re-run pair() if the token expired. |
| PRINTER_NOT_FOUND | 404 | No printer with that exact name is known to the runtime. | Call listPrinters() and use one of the returned names verbatim. |
| INVALID_PRINT_JOB | 400 | The print job body didn't match the expected shape. | content is required; printerName and copies are optional. |
| INVALID_REQUEST | 400 | A required field was missing from the request body. | Check the endpoint in the Runtime API reference for its required fields. |
| JOB_NOT_FOUND | 404 | No job with that ID, or it isn't visible to this caller. | Paired apps only see their own jobs — use the admin key to see everything. |
| PAIRING_NOT_FOUND | 404 | The pairing code is wrong, already used, or expired. | Call pair() again to get a fresh code. |
| UNTRUSTED_ORIGIN | 403 | The request's Origin header doesn't match the one pinned to this pairing at approval time. | Pair again from the app's real origin. |
| PERMISSION_DENIED | 403 | This paired app is not authorized for the capability it tried to use. | Only print exists as a permission today — check the pairing approval. |
| JOB_NOT_CANCELLABLE | 409 | The job is already printing, completed, failed, or cancelled. | cancel() only works on jobs still pending. |
| PRINTER_BUSY | 409 | The printer is already processing another job. | Retry shortly — the queue will pick it up. |
| PRINTER_OFFLINE | 503 | The printer is unreachable. | Check power, USB/network cable, and that Windows lists it as online. |
| PAPER_OUT | 503 | The printer reported it has no paper. | Reload paper and print again — nothing is lost, the job stays queued. |
| CONNECTION_LOST | 503 | The connection dropped mid-job — e.g. USB unplugged while printing. | Reconnect the printer and retry. |
| PRINTER_TIMEOUT | 503 | The printer didn't respond in time. | Check it's powered on and reachable — this is the usual sign of a wrong IP for network printers. |
| PRINTER_NOT_READY | 503 | The printer reported a real, non-offline problem — paper jam, open door, low toner. | Check the printer itself; the message includes the raw reason. |
| INVALID_DRIVER_CONFIG | 503 | The runtime's printer driver isn't fully configured. | e.g. PORTIX_NETWORK_PRINTER_HOST is required when PORTIX_PRINTER_DRIVER=network. |
| PRINTER_CONNECTION_FAILED | 503 | A generic connection failure not covered by a more specific code above. | Check the printer and the runtime logs for detail. |
Still stuck? Open an issue with what you tried and the exact error — that's the fastest path to a fix or a docs update.