zplflow logo

LabelOps CLI

The zplflow command-line tool lets you manage conversions, async jobs, pipelines, and your account directly from the terminal — no code required.

Availability: Pre-built binaries for Windows, Linux, and macOS on amd64 and arm64 architectures. Published as a single static binary with zero system dependencies.


Installation

Download Pre-built Binary

Platform Architecture Binary
Linux amd64 zplflow_linux_amd64
Linux arm64 zplflow_linux_arm64
macOS amd64 (Intel) zplflow_darwin_amd64
macOS arm64 (Apple Silicon) zplflow_darwin_arm64
Windows amd64 zplflow_windows_amd64.exe
Windows arm64 zplflow_windows_arm64.exe

Download the appropriate binary from GitHub Releases and place it in your PATH.

Linux / macOS Setup

# Download (replace {version}, {os}, {arch} with your values)
curl -L -o zplflow "https://github.com/zplflow/zplflow/releases/download/v{version}/zplflow_{os}_{arch}"

# Make executable and move to PATH
chmod +x zplflow
sudo mv zplflow /usr/local/bin/

# Verify
zplflow version

Windows Setup

# Download the .exe to a directory in your PATH, e.g. C:\Tools\
# Or install via winget (coming soon):

# Verify
zplflow.exe version

Build from Source

git clone https://github.com/zplflow/zplflow.git
cd zplflow
go build -o zplflow ./cmd/cli

The CLI compiles with CGO_ENABLED=0 — no external dependencies required.


Configuration

The CLI needs your API key to authenticate. Provide it via environment variable or flag:

export LABELOPS_API_KEY="lb_live_YOUR_KEY"

This keeps the key out of your shell history.

Command-Line Flag

zplflow --api-key lb_live_YOUR_KEY account balance

Useful for one-off commands or scripting with a different key.

API URL

By default the CLI connects to https://api.zplflow. Override with LABELOPS_API_URL or --api-url:

export LABELOPS_API_URL="https://staging-api.zplflow"

Output Format

All commands support three output modes via --output:

Value Behavior
text Human-readable key-value output (default)
json Raw API response — ideal for piping to jq
table Aligned columns for list endpoints

Commands Reference

Contents: Account · Convert · Estimate · Jobs · Pipeline · Version · Shell Completion


Account

zplflow account balance

Get your tenant’s token balance and reservations.

zplflow account balance
Tenant:        your-company
Balance:       10,000 tokens
Reserved:      3 tokens
# JSON for scripting
zplflow account balance --output json
{"tenant_id":"your-company","balance":10000,"reserved":3}

Estimate

zplflow estimate

Estimate the token cost of a conversion before running it. No payload analysis — purely parameter-based.

# PDF to ZPL estimate
zplflow estimate --operation pdf_to_zpl --dpi 203 --documents 10

# ZPL to PDF estimate
zplflow estimate --operation zpl_to_pdf --dpmm 8dpmm --documents 5
Flag Type Description
--operation string Required. pdf_to_zpl, zpl_to_pdf, or pipeline_run
--dpi int DPI for pdf_to_zpl: 203 or 300
--max-kb int Max KB for pdf_to_zpl
--fit string Fit mode: contain, cover, or stretch
--dpmm string Density for zpl_to_pdf: 8dpmm, 12dpmm, 24dpmm
--documents int Number of documents (default: 1)

Convert

Synchronous conversions with inline payloads. No S3, no async — ideal for real-time label printing.

zplflow convert pdf-to-zpl

Convert a PDF file to ZPL text.

# From file, output to stdout
zplflow convert pdf-to-zpl --file shipping.pdf --dpi 203

# Save to file
zplflow convert pdf-to-zpl --file labels.pdf --dpi 300 --save output.zpl

# Read from stdin (pipe)
cat shipping.pdf | zplflow convert pdf-to-zpl --stdin > label.zpl

# With dimensions and fit
zplflow convert pdf-to-zpl --file large.pdf --dpi 203 --width 101.6 --height 152.4 --unit mm --fit contain
Flag Type Default Description
--file string Input PDF file path
--stdin bool false Read PDF from stdin
--save string Save ZPL to file (default: stdout)
--dpi int 203 203 or 300
--max-kb int Max output KB per page
--width float Label width
--height float Label height
--unit string mm mm or in
--fit string contain contain, cover, or stretch
--allow-degrade bool false Allow quality degradation
--compat-mode bool false Enable compatibility mode
--idempotency-key string auto Override auto-generated key

zplflow convert zpl-to-pdf

Convert a ZPL string to a PDF file.

# From file
zplflow convert zpl-to-pdf --file label.zpl --save output.pdf

# Read from stdin
echo "^XA^FO50,50^ADN,36,20^FDHello^FS^XZ" | zplflow convert zpl-to-pdf --stdin --save hello.pdf

# Custom density and dimensions
zplflow convert zpl-to-pdf --file label.zpl --save out.pdf --dpmm 12dpmm --width 101.6 --height 152.4
Flag Type Default Description
--file string Input ZPL file path
--stdin bool false Read ZPL from stdin
--save string Required. Output PDF file path
--dpmm string 8dpmm 8dpmm, 12dpmm, 24dpmm
--width float Label width
--height float Label height
--unit string mm mm or in
--index int 0 Label index within ZPL
--idempotency-key string auto Override auto-generated key

Note: PDF output is binary — --save is always required. The file path is never written to stdout.


Pipeline

zplflow pipeline apply <pipeline-id>

Apply a pre-defined pipeline transformation to ZPL documents.

# Single ZPL file
zplflow pipeline apply 550e8400-e29b-41d4-a716-446655440000 --zpl-file label.zpl

# Multiple documents via JSON file
zplflow pipeline apply 550e8400-... --json-file batch.json

# Save output to file
zplflow pipeline apply 550e8400-... --zpl-file label.zpl --save transformed.zpl
Flag Type Description
--zpl-file string Single ZPL file to transform
--json-file string JSON file with array of {"zpl_base64":"..."} documents
--save string Save output to file (default: stdout)
--idempotency-key string Override auto-generated key

The pipeline ID is the first positional argument. Find your pipelines in the Admin UI.


Jobs

Async job management for bulk conversions and large files. The CLI handles the full lifecycle: create → upload → start → poll → download.

zplflow job create

Create and automatically start an async job.

# PDF to ZPL async
zplflow job create --operation pdf_to_zpl --file labels.pdf --dpi 203

# ZPL to PDF async
zplflow job create --operation zpl_to_pdf --file label.zpl

# Pipeline run
zplflow job create --operation pipeline_run --file labels.zpl --pipeline-id 550e8400-...
Job ID:         770e8400-e29b-41d4-a716-446655440000
Status:         queued
Tokens Reserved: 2

Monitor: zplflow job wait 770e8400-...

The create command uploads the input file via the presigned S3 URL and starts the job in a single step.

Flag Type Description
--operation string Required. pdf_to_zpl, zpl_to_pdf, or pipeline_run
--file string Input file path
--stdin bool Read input from stdin
--dpi int DPI for pdf_to_zpl
--max-kb int Max KB for pdf_to_zpl
--fit string Fit mode: contain, cover, or stretch
--dpmm string Density for zpl_to_pdf
--width float Label width
--height float Label height
--unit string Unit: mm or in
--pipeline-id string Required for pipeline_run
--allow-degrade bool Allow quality degradation
--compat-mode bool Enable compatibility mode
--idempotency-key string Override auto-generated key

zplflow job list

List all async jobs for your tenant.

# Last 10 jobs
zplflow job list

# Filter by status, with table output
zplflow job list --status succeeded --limit 20

# Paginated
zplflow job list --status failed --cursor next-cursor-token
JOB ID                                STATUS      OPERATION
550e8400-e29b-41d4-a716-446655440000 succeeded   pdf_to_zpl
660e8400-e29b-41d4-a716-446655440000 failed      zpl_to_pdf
Flag Type Default Description
--status string Filter: created, queued, running, succeeded, failed, canceled
--limit int 10 Max jobs to return
--cursor string Pagination cursor

zplflow job get <job-id>

Get detailed status and results for a specific job.

zplflow job get 550e8400-e29b-41d4-a716-446655440000
Job ID:         550e8400-e29b-41d4-a716-446655440000
Operation:      pdf_to_zpl
Status:         succeeded
Tokens:         2 reserved / 2 committed
Results:        1 file(s)
  [0] 12,451 bytes  application/pdf
      URL: https://s3.amazonaws.com/... (expires 2026-01-15T11:00:00Z)
Meta:
  DPI:           203
  Budget KB:     32
  Degraded:      false
  Tile count:    1

zplflow job start <job-id>

Start a job that is in created state.

zplflow job start 550e8400-...
Flag Type Description
--idempotency-key string Override auto-generated key

zplflow job cancel <job-id>

Cancel a queued or running job. Reserved tokens are rolled back.

zplflow job cancel 550e8400-...
Flag Type Description
--idempotency-key string Override auto-generated key

zplflow job wait <job-id>

Poll a job until completion and automatically download the result. The recommended way to handle async jobs.

# Wait for result and save to file
zplflow job wait 550e8400-... --save result.pdf

# Custom timeout (default 5 minutes)
zplflow job wait 550e8400-... --save result.zpl --timeout 10m

# Without --save, prints text results to stdout (use for ZPL output)
zplflow job wait 550e8400-...
Waiting for job 550e8400-... [created]    1s
Waiting for job 550e8400-... [queued]     2s
Waiting for job 550e8400-... [running]    4s
Job succeeded! Saved 12,451 bytes to result.pdf

Polling uses exponential backoff starting at 1 second and capping at 8 seconds.

Flag Type Default Description
--save string File to save result to (required for binary output)
--timeout duration 5m Max wait time (e.g. 30s, 5m, 1h)
--interval duration 1s Initial poll interval

Shell Completion

Generate tab-completion for your shell.

# Bash
zplflow completion bash > /etc/bash_completion.d/zplflow

# Zsh
zplflow completion zsh > "${fpath[1]}/_zplflow"

# Fish
zplflow completion fish > ~/.config/fish/completions/zplflow.fish

# PowerShell
zplflow completion powershell > zplflow.ps1

Version

zplflow version
zplflow version 1.2.3 (commit: abc1234, built: 2026-01-15T10:00:00Z)
go version go1.25.4 linux/amd64
# Short form — handy for scripting
zplflow version --short
1.2.3

Exit Codes

Code Meaning
0 Success
1 API error or invalid parameters
2 Usage error (missing required flag)
3 Authentication error (missing/invalid API key)
4 Network or timeout error

Use exit codes in scripts:

#!/bin/bash
if zplflow job wait "$JOB_ID" --save result.zpl --timeout 5m; then
    echo "Done: $(wc -c < result.zpl) bytes"
else
    code=$?
    echo "Failed with exit code $code"
fi

Idempotency

All POST commands automatically generate a unique Idempotency-Key (UUID v4) per request. This prevents duplicate operations on network retries.

The generated key is printed to stderr:

Idempotency Key: a1b2c3d4-e5f6-7890-abcd-ef1234567890

To reuse a key for explicit retry control:

zplflow convert pdf-to-zpl --file labels.pdf --idempotency-key my-retry-001

Typical Workflows

Quick Sync Convert

export LABELOPS_API_KEY="lb_live_YOUR_KEY"

# PDF → ZPL (result to stdout)
zplflow convert pdf-to-zpl --file shipping.pdf --dpi 203 > label.zpl

# ZPL → PDF (result to file)
zplflow convert zpl-to-pdf --file label.zpl --save output.pdf

Async Batch Processing

# Step 1: Create and start job
JOB_ID=$(zplflow job create --operation pdf_to_zpl --file labels.pdf --dpi 203 --output json | jq -r '.job_id')
echo "Job: $JOB_ID"

# Step 2: Wait for completion
zplflow job wait "$JOB_ID" --save result.zpl

Pipeline in a CI/CD Pipeline

# Apply pipeline transformation
zplflow pipeline apply "$PIPELINE_ID" --zpl-file label.zpl --save transformed.zpl

# Then convert to PDF for preview
zplflow convert zpl-to-pdf --file transformed.zpl --save preview.pdf

Error Messages

The CLI translates API errors into human-readable messages:

HTTP Error Code CLI Output
401 UNAUTHORIZED Invalid API key. Set LABELOPS_API_KEY env var or use --api-key flag.
402 INSUFFICIENT_TOKENS Not enough tokens — ...
403 FORBIDDEN Tenant suspended or access denied.
409 IDEMPOTENCY_CONFLICT Idempotency key conflict — different payload used with the same key.
429 RATE_LIMITED Rate limit exceeded. Try again in a few seconds.

Security

  • The API key is never logged or printed in output
  • Use the environment variable (LABELOPS_API_KEY) to avoid leaking keys in shell history
  • Presigned S3 URLs are never logged
  • Payload content (PDF/ZPL) is never logged
  • Gzip compression is transparent: the CLI sends Accept-Encoding: gzip and compresses large request bodies automatically

Next Steps