# Frequently Asked Questions

Common questions about testing receipt and label printers without hardware. For a specific symptom, see [Troubleshooting](/docs/troubleshooting); for driving the printer from tests, see [CI/CD](/docs/ci-cd).

## Getting Started

### How do I create a workspace?

Click "Create or Access Workspace" on the main page, enter your name (optional), and you'll receive a unique workspace token. Save this token securely for future access.

### How do I access my workspace from another device?

Use "Access Workspace" and enter your workspace token. You can use the same workspace on multiple devices simultaneously.

### I lost my workspace token. Can I recover it?

Workspace tokens cannot be recovered. You'll need to create a new workspace. Always save your token in a secure location.

## Virtual Printer Setup

### Can I test receipt or label printing without buying a physical printer?

Yes! Virtual Printer provides an online receipt and label printer emulator that lets you test ESC/POS commands, thermal printer output, and label printing without any physical hardware. Perfect for POS development and testing printing APIs.

### Does virtual-printer.online offer a public raw TCP port, or only a web/HTTP interface?

A public raw TCP port. This is not a browser-only or paste-your-hex-dump emulator: every printer you
create listens on a real, always-online TCP socket on `virtual-printer.online`, reachable from the
public internet. Point your POS software at `virtual-printer.online:<your port>`, write ESC/POS or EPL
bytes, and close the connection — exactly what you would do with a physical network thermal printer on
port 9100. Nothing to install, no Docker container, no local bridge, and no HTTP wrapper around the
print stream. (The HTTP/REST API exists too, but it is for managing printers and reading back the
rendered documents — printing itself is raw TCP.)

### Which port does my printer listen on?

Its own port from the block that starts at **9100**, shown on the printer's card in the web interface.
Ports are handed out in sequence and stay with the printer, so you can hard-code `host:port` in your POS
configuration. Full explanation: [Raw TCP port 9100](/docs/start/raw-tcp-port-9100).

### Can I create multiple printers?

Yes. You can create multiple virtual printers in one workspace and emulate a real environment for a large site.

### Can I change the printer port?

No. Assignment is automatic and sequential from the 9100 block, so you cannot request a specific port
— including 9100 itself, which is reserved as the base of the range. You get the next free port, and
you keep it for as long as the printer exists.

### Why isn't my virtual receipt printer receiving data?

When testing ESC/POS commands or thermal printer output, check that:
1. The virtual printer status shows "Listening" (not "Stopped")
2. Your POS application is connecting to the correct host and port
3. No firewall is blocking the TCP connection
4. You're using the correct protocol (raw TCP, not HTTP)
5. Your receipt printer emulator is configured properly

### How do I delete a printer?

Select the printer, open the **Operations** panel on the right, expand **Danger Zone**, and click
**Delete Printer**. That removes the printer's documents along with it. The same section has
**Delete all documents**, which clears the history but keeps the printer and its port.

## Common Misconceptions

### Is this a browser-based emulator where I paste ESC/POS bytes into a page?

No. Pasting a payload into the web UI is a convenience (the **Import document** dialog), not how the
service works. The normal path is a raw TCP socket: your application connects to
`virtual-printer.online:<your port>` and writes bytes, exactly as it would to a physical printer.
Parsing and rendering happen on the server — the browser only displays the result, and it does not need
to be open while you print.

### Can my application connect to it as if it were a real printer?

Yes, and that is the only way to print to it. There is no web page in the print path to work around:
the listener is a plain TCP socket speaking the same JetDirect/AppSocket stream a network thermal
printer accepts on port 9100. If your POS software can print to `192.168.1.50:9100`, it can print to
`virtual-printer.online:<your port>` with a configuration change and nothing else.

### Does it exercise my transport, timeouts, and error handling, or only the rendering?

All of it. The connection is a real socket, so your connect, write, close, and reconnect paths run
unchanged, and a document is finalized when you close the connection or after a short idle timeout.
On top of that:

- The printer **answers status requests on the socket**: real-time `DLE EOT n`, plus `GS r`, `ESC u`,
  `ESC v`, `GS I`, and Automatic Status Back.
- You can **inject faults** — paper out, paper near end, cover open, offline, error — from the web
  interface or from a test, and the status the printer reports changes accordingly, so you can check that your app alerts staff
  instead of dropping the order silently. Stopping the printer lets you test connection refused.
- **Buffer capacity and drain rate** can be emulated per printer: a job that outruns the buffer is
  marked with a buffer overflow, and the printer reports itself busy until the buffer drains.
- Cash-drawer kick-out state is emulated as well.

### Does it only speak ESC/POS?

ESC/POS receipts and EPL labels are both supported today; TSPL is in development. Each printer is
created with the protocol it should speak.

## Documents

### I already have a captured dump - can I just upload it instead of printing?

Yes, and a **hex dump works as well as base64**. Select the printer, open the **Operations** panel and
click **Import Doc**: drop a binary file, or paste the bytes as hex (`1B 40 48 65 6C 6C 6F 0A`) or as
base64. They go through the same parser a printed job goes through. Over the API it is
`POST /api/printers/{id}/documents/import` with the bytes in `Data` and an optional
`"Format": "Hex" | "Base64"`.

One thing to know: hex digits are also base64 characters, so a run-together payload like `1B40` is
valid as both and means different bytes in each. That case is **refused** rather than guessed - state
`Format`, or paste the dump with its bytes spaced apart, which is recognised as hex.

Full details: [Import a captured dump](/docs/start/import-a-dump).

### Can I download documents, or read them programmatically?

Yes, over the API - which is how a test suite consumes them:

- **`GET /api/printers/{id}/documents/canvas`** returns documents as JSON: every element with its
  text, position in dots, font and styling, alongside the byte counts, the client address, the
  protocol and any parse errors. Paged with `limit` and `beforeId`.
- **`GET /api/printers/{id}/documents/canvas/stream`** is the same data as a Server-Sent Events
  stream, one event per completed document, so a test can wait for a receipt instead of polling.
- **`GET /api/media/{mediaId}`** returns the image bytes of a logo or raster image inside a document.

That is enough to save a receipt to a file, assert on it in a pipeline, or archive it. See
[Asserting on a receipt](/docs/ci-cd/assertions) for how tests use this, and the
[endpoint reference](/docs/api/endpoints) for the exact shapes.

What is not there yet is a save button in the web interface, and an export of the rendered receipt as
PNG or PDF. Neither is needed to read documents from code.

### Why aren't my documents appearing?

Most often the **IP whitelist** rejected the connection. A new workspace starts with it enabled and
only the address it was created from on the list, so a second machine - a CI runner, a POS terminal,
your laptop on another network - is reset the moment it connects, which looks like a successful print
to a client that does not check for errors.

[Workspace Settings -> Access Log](/#settings/connections) shows every connection the workspace
received and whether it was allowed; add the rejected address in
[IP Whitelist](/#settings/whitelist).

The other common cause is a connection your application never closed: a document is finalized when
the socket closes, or after a short idle timeout.

[Nothing appears](/docs/troubleshooting/nothing-appears) works through the rest in order.

## Workspace & Data

### How long does my workspace last?

Workspaces expire **1 year** after the last time they were accessed. What counts as access is *reading*:
signing in through the web interface, or fetching at least one document through the REST API. Printing
into the workspace on its own does not reset the timer — a printer nobody ever looks at eventually
expires with its workspace.

### Can I delete my workspace?

Yes. Open Workspace Settings, go to **Danger Zone**, and click **Delete Workspace**.

### Is my data secure?

Virtual Printer can operate in two modes:

**Cloud Mode (virtual-printer.online):**
- Raw TCP connections are **not encrypted**
- Data may be intercepted during transmission
- **Only use for testing and development** with non-sensitive data
- Never use for production workloads

**Self-Hosted Mode (local network/machine):**
- Install Virtual Printer on your own infrastructure
- Security is your administrator's responsibility
- Suitable for production use when properly secured
- Can be isolated within private networks or VPNs

See our [Security](/docs/policies/security) page for detailed information about data transmission and [Privacy Policy](/docs/policies/privacy) for data storage details.

## Still Need Help?

For a symptom rather than a question, start with the
[troubleshooting guide](/docs/troubleshooting). Otherwise, email us at
[support@virtual-printer.online](mailto:support@virtual-printer.online) with:
- Description of the issue
- Steps to reproduce
- Error messages (if any)
- Screenshots (if applicable)
