A lightweight REST API that sends raw ESC/POS data to thermal printers over TCP
165
A lightweight REST API that sends raw ESC/POS data to thermal printers over TCP. Accepts base64-encoded ESC/POS binary data via HTTP and forwards it to a network printer on port 9100.
Built with Ruby, Sinatra, and Puma. Ships as a minimal Alpine-based Docker image.
POST /print with base64-encoded ESC/POS dataGET /health endpoint for container orchestrationservices:
escpos-printer-api:
image: escpos-printer-rest-api
build: .
ports:
- "4567:4567"
environment:
- PRINTER_HOST=192.168.2.7 # IP of your thermal printer
- PRINTER_PORT=9100 # default ESC/POS port
# - API_KEY=your-secret-key # uncomment to enable authentication
restart: unless-stopped
docker compose up -d
docker build -t escpos-printer-api .
docker run -d \
--name escpos-printer-api \
-p 4567:4567 \
-e PRINTER_HOST=192.168.2.7 \
-e PRINTER_PORT=9100 \
escpos-printer-api
bundle install
bundle exec puma -C puma.rb
| Variable | Default | Description |
|---|---|---|
PRINTER_HOST | 192.168.2.7 | Default printer IP/hostname. Can be overridden per request. |
PRINTER_PORT | 9100 | Default printer TCP port. Can be overridden per request. |
API_KEY | (unset) | Bearer token for authentication. When unset, all requests are allowed. |
GET /healthHealth check endpoint. Returns 200 OK with:
{"status": "ok"}
POST /printSend ESC/POS data to the printer.
Headers:
| Header | Required | Description |
|---|---|---|
Content-Type | Yes | Must be application/json |
Authorization | Only if API_KEY is set | Bearer <your-api-key> |
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
data | string | Yes | Base64-encoded ESC/POS binary data |
host | string | No | Printer IP/hostname (overrides PRINTER_HOST) |
port | integer | No | Printer TCP port (overrides PRINTER_PORT) |
Example request:
curl -X POST http://localhost:4567/print \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-secret-key" \
-d '{
"data": "G0AbYTEbIRFURVNUIFJFQ0VJUFQKGyEA",
"host": "192.168.2.7",
"port": 9100
}'
Responses:
| Status | Body | Description |
|---|---|---|
200 | {"status": "ok", "bytes": 42} | Data sent to printer successfully |
400 | {"error": "Missing required field: ..."} | Missing data field |
400 | {"error": "Invalid JSON"} | Malformed JSON body |
401 | {"error": "Unauthorized"} | Missing or invalid Bearer token |
502 | {"error": "Printer connection failed: ..."} | Cannot reach printer |
import base64
import requests
# Raw ESC/POS: initialize + "Hello World\n" + partial cut
escpos_data = b'\x1b\x40Hello World\n\x1d\x56\x01'
b64_data = base64.b64encode(escpos_data).decode()
requests.post("http://localhost:4567/print", json={
"data": b64_data
}, headers={
"Authorization": "Bearer your-secret-key"
})
const data = Buffer.from('\x1b\x40Hello World\n\x1d\x56\x01').toString('base64');
fetch('http://localhost:4567/print', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer your-secret-key',
},
body: JSON.stringify({ data }),
});
require "escpos"
require "http"
require "json"
printer = Escpos::Printer.new
printer << Escpos::Helpers.center(Escpos::Helpers.big("HELLO"))
printer << "\n"
printer << Escpos::Helpers.bold("Bold text")
printer << "\n"
printer << Escpos::Helpers.partial_cut
HTTP
.auth("Bearer your-secret-key")
.post("http://localhost:4567/print", json: {
data: printer.to_base64
})
# Encode raw bytes to base64 and print
echo -ne '\x1b\x40Hello from curl\n\x1d\x56\x01' | base64 | \
xargs -I{} curl -X POST http://localhost:4567/print \
-H "Content-Type: application/json" \
-d '{"data": "{}"}'
A test script is included that prints a sample receipt with various ESC/POS features (text styles, alignment, barcodes, etc.):
# Install the escpos gem inline and send a test receipt
PRINTER_HOST=192.168.2.7 API_KEY=your-secret-key ruby test_print.rb
Client REST API Printer
| | |
| POST /print | |
| { "data": "base64..." } | |
|------------------------->| |
| | TCP :9100 |
| | (mutex-serialized) |
| |------------------------>|
| | | 🖨️ prints
| 200 {"status": "ok"} | |
|<-------------------------| |
MIT
Content type
Image
Digest
sha256:43167ef5b…
Size
50.7 MB
Last updated
7 months ago
docker pull alhafoudh/escpos-printer-rest-api:af78321d3e8e2d558ab85e3faec4402f47b3c4f3