Skip to content

Repository files navigation

Bambu Gateway

A self-hosted web application for managing Bambu Lab 3D printers over your local network. Provides a REST API and web dashboard for monitoring printer status and submitting print jobs.

Works with any Bambu Lab printer in developer/LAN mode (or in Bambu Cloud mode with experimental support).

An iOS client is also available: BambuGateway iOS — print 3MF files from MakerWorld directly from your phone.

Features

  • Real-time printer status (state, temperatures, print progress, preparation stages)
  • Pause, resume, cancel, and adjust speed of active prints
  • AMS unit info (humidity, temperature) and external spool holder support
  • AMS filament drying control (AMS 2 Pro and AMS HT)
  • Upload, slice and print 3MF files from the browser, including custom filament profiles through orcaslicer-headless
  • Automatic AMS tray matching for project filaments
  • Multi-printer support
  • Optional iOS Live Activities and push notifications via APNs
  • REST API for automation and integration
  • Runs entirely on your local network

Quick Start

You'll need a Bambu Lab printer with Developer Mode enabled — the access code and IP are in the printer's network settings.

Run with Docker (recommended)

docker run -d --name bambu-gateway \
  -p 4844:4844 \
  -v $(pwd)/data:/data \
  ghcr.io/leolobato/bambu-gateway:latest

Or with docker compose:

docker compose up -d

Open http://localhost:4844 and add your printer from the Settings page.

Run from source

Requires Python 3.12+.

git clone https://github.com/leolobato/bambu-gateway.git
cd bambu-gateway
pip install -r requirements.txt
python -m app

Open http://localhost:4844 and add your printer from the Settings page. Runtime state — printer configuration, slice jobs, and their cached 3MF blobs — is saved under ./data/ (gitignored).

iOS push notifications (optional)

The gateway can send push notifications and Live Activity updates to the companion iOS app when a print changes state — paused, failed, completed, cancelled, offline, or flagged by the printer's health-monitoring system. When enabled, the iPhone shows a Live Activity on the Lock Screen and Dynamic Island with progress, remaining time, and current layer, updated in real time even when the app is closed.

Enabling this requires a paid Apple Developer account so you can mint an APNs Auth Key. The four required env vars are:

APNS_KEY_PATH=/path/to/AuthKey_KEYID.p8
APNS_KEY_ID=KEYID
APNS_TEAM_ID=TEAMID
APNS_BUNDLE_ID=org.yourname.BambuGateway
APNS_ENVIRONMENT=sandbox   # or "production" for TestFlight / App Store builds

Leaving any of them empty disables push entirely. The iOS app degrades gracefully in that case — Live Activities still run locally while the app is foregrounded, but remote updates and notifications aren't delivered.

See docs/APNS.md for the full walkthrough: creating the .p8 key, choosing sandbox vs. production, installing the key for Docker deployments, rotating keys, and troubleshooting.

Bambu Cloud mode (optional)

By default the gateway talks to printers directly over your LAN, which requires Developer Mode on each printer. If you'd rather not enable Developer Mode — or your printer isn't on the same network — you can instead connect through your Bambu Cloud account. The gateway logs in to Bambu's cloud and reaches your printers through it, so no IP, access code, or Developer Mode is needed.

Experimental, but working. Cloud mode is opt-in. Printer status, AMS, control commands (pause/resume/cancel/speed), camera, and cloud printing all function today, but the feature is newer and less battle-tested than LAN mode. If it fails to start, the gateway falls back to LAN mode automatically and the cloud endpoints return 503.

Cloud mode works by loading Bambu's official closed-source network plugin (libbambu_networking.so) in an isolated subprocess. The approach — and the Linux bridge that makes the plugin usable outside Bambu's own apps — is based on Jarczak's fork of OrcaSlicer (OrcaSlicer-bambulab), which first demonstrated authenticating and driving cloud printers through that plugin on Linux. The plugin binary is downloaded from Bambu's CDN and verified (ELF magic

  • SHA-256 manifest + pinned ABI version) before use.

x86_64 hosts only. Bambu ships libbambu_networking.so for x86_64 (amd64) only — there is no ARM build, so cloud mode does not work on ARM hosts (Apple Silicon, ARM64 Linux, Raspberry Pi)

1. Turn on cloud mode

Add these to your .env (or -e flags) and restart the container:

BAMBU_CLOUD_ENABLED=true
BAMBU_CLOUD_REGION=US      # use CN for the China region

In cloud mode the LAN printer settings (BAMBU_PRINTER_IP, access code, serial) are ignored — your printers come from your Bambu account instead. The login session is saved under ./data/ and survives restarts, so you only do the steps below once.

2. Log in to your Bambu account

Open the Settings page and use the Cloud Account section:

  1. Click Open Bambu sign-in and log in with your Bambu email and password (including any verification code) in the browser tab that opens.
  2. After signing in, your browser will try to open http://localhost:13618/?ticket=… and show a "this site can't be reached" / "connection refused" page. That's expected. Copy the full URL from the browser's address bar — it contains your one-time login ticket.
  3. Paste that URL into the field and click Complete sign-in.

Once signed in, the Cloud Account section shows your profile and region, and your cloud printers start appearing on the dashboard. The login session is saved under ./data/, so you only do this once.

Configuration

Printer config

Printers are stored in data/printers.json by default (see printers.example.json for the format). The file is created automatically on first run — either seeded from environment variables or empty if none are set. After that, manage printers through the Settings page at /settings. The slice-job store (data/slice_jobs.json plus the data/slice_jobs/ blob dir) is rooted at the same parent.

To use a custom path (e.g. a Docker volume mounted at /data):

python -m app -c /data/printers.json

Environment variables

Variable Default Description
BAMBU_PRINTER_IP Printer IP(s), comma-separated — seeds initial config
BAMBU_PRINTER_ACCESS_CODE Printer access code(s), comma-separated
BAMBU_PRINTER_SERIAL Printer serial number(s), comma-separated
SERVER_HOST 0.0.0.0 Server bind address
SERVER_PORT 4844 Server bind port
LOG_LEVEL INFO Logging level
MAX_FILE_SIZE_MB 200 Maximum upload file size in MB
ORCASLICER_API_URL OrcaSlicer Headless API URL (e.g. http://10.0.1.9:8070) — required for slicing
BAMBU_CLOUD_ENABLED false Connect through your Bambu Cloud account instead of LAN — see Bambu Cloud mode
BAMBU_CLOUD_REGION US Bambu account region: US or CN
APNS_KEY_PATH Path to APNs Auth Key .p8 — see docs/APNS.md. All four APNS_* vars must be set to enable push
APNS_KEY_ID 10-character Key ID from the Apple Developer portal
APNS_TEAM_ID 10-character Team ID from the Apple Developer portal
APNS_BUNDLE_ID Bundle ID of the iOS app receiving push
APNS_ENVIRONMENT production sandbox for dev builds, production for TestFlight / App Store

Environment variables only seed the config on first run when no printers.json exists.

API

Method Path Description
GET /api/health Health check
GET /api/printers List printers with live status
GET /api/printers/{id} Status for a single printer
POST /api/printers/{id}/pause Pause current print
POST /api/printers/{id}/resume Resume paused print
POST /api/printers/{id}/cancel Cancel current print
POST /api/printers/{id}/speed Set print speed (1–4: silent/standard/sport/ludicrous)
GET /api/ams AMS units, trays, and external spool info
POST /api/printers/{id}/ams/{ams_id}/start-drying Start AMS filament drying
POST /api/printers/{id}/ams/{ams_id}/stop-drying Stop AMS filament drying
POST /api/filament-matches Match project filaments to AMS trays
POST /api/print Upload 3MF to default printer
POST /api/print-stream Upload and print with SSE progress
POST /api/print-preview Slice and preview without printing
POST /api/parse-3mf Parse 3MF metadata without printing
POST /api/stl-drafts Import an STL into an orcaslicer-headless draft for preview
GET /api/stl-drafts/{id}/source.stl Stream the cached STL bytes for browser rendering
POST /api/stl-drafts/{id}/layout Apply a preset layout action (auto-orient, rotate, center, arrange, reset)
POST /api/stl-drafts/{id}/3mf Materialize the draft to a 3MF the print flow can consume
GET /api/slicer/machines List slicer machine profiles
GET /api/slicer/processes List slicer process profiles
GET /api/slicer/filaments List slicer filament profiles
GET /api/slicer/plate-types List available plate types
GET /api/settings/printers List configured printers
POST /api/settings/printers Add a printer
PUT /api/settings/printers/{serial} Update a printer
DELETE /api/settings/printers/{serial} Remove a printer
GET /api/uploads/{id} Poll FTP upload progress

Interactive API docs are available at /docs (Swagger UI).

OrcaSlicer Headless Integration

Bambu Gateway integrates with orcaslicer-headless, a headless slicing server built on OrcaSlicer's engine. This enables:

  • Custom filament profiles — use your own filament settings (temperature, flow, pressure advance, etc.) instead of being limited to built-in profiles
  • Headless slicing — slice 3MF files on the server without needing OrcaSlicer's GUI, ideal for running on a Raspberry Pi or NAS
  • Preview before printing — slice a file and review the result before sending it to the printer

Setup

Run the orcaslicer-headless server (see the orcaslicer-headless docs for full setup instructions), then point Bambu Gateway to it:

ORCASLICER_API_URL=http://10.0.1.9:8070

When a slicer URL is configured, the web UI will show machine and filament profile selectors, and unsliced 3MF files will be sliced automatically before printing. Without it, only pre-sliced 3MF files can be printed.

3MF parsing

bambu-gateway does not open .3mf ZIPs. All metadata extraction (plates, filaments, thumbnails, used-filament dispatch, print estimates) goes through orcaslicer-headless's HTTP API, which links libslic3r directly. Set ORCASLICER_API_URL to point at it.

Required endpoints (consumed by app/slicer_client.py):

  • POST /3mf — upload, returns token
  • GET /3mf/{token}/inspect — structured summary
  • GET /3mf/{token}/plates/{n}/thumbnail — PNG bytes
  • DELETE /3mf/{token} — drop cached upload
  • POST /slice/v2 — slice, returns estimate + output token

STL preview workflow

Dropping a .stl on the Print page kicks off a draft preview owned by orcaslicer-headless. The gateway proxies the import, caches the source STL bytes locally so the browser can render them with Three.js, and forwards layout actions to the slicer:

  1. UploadPOST /api/stl-drafts (with machine_profile, process_profile, optional plate_type, auto_orient, arrange, center) imports the STL into the slicer and returns the initial scene plus a source_url for the cached STL bytes.
  2. Preview — the SPA loads source_url with STLLoader, draws the printable bed, and applies each object's mesh_transform then its instance transform so the browser shows what the slicer sees.
  3. LayoutPOST /api/stl-drafts/{id}/layout runs preset actions (auto_orient, rotate_x_90, rotate_x_minus_90, rotate_y_90, rotate_y_minus_90, rotate_z_90, rotate_z_minus_90, center, arrange, reset) and returns the updated scene.
  4. AcceptPOST /api/stl-drafts/{id}/3mf materializes the draft inside orcaslicer-headless and returns a JSON payload with the slicer's input_token, a suggested filename, and the parsed ThreeMFInfo. The SPA forwards an optional preview-render PNG (thumbnail_png_data_url) so the materialized 3MF carries a thumbnail that matches what the user accepted. From there the imported state carries the token forward — slice jobs reference the token instead of re-uploading bytes — and filament mapping, slicing settings, and printer upload work as with an uploaded 3MF.

Slice-job “original” downloads are prepared originals. For uploaded 3MF files and STL-derived projects, the gateway stores a 3MF after applying the selected machine, process, plate type, process overrides, and any STL preview thumbnail, but before slicing. The Jobs page downloads that prepared input so it matches the settings used for the slice.

V1 supports preset actions only — there is no freehand drag/rotate/scale in the browser; orcaslicer-headless remains the authority for STL orientation, arrange, and 3MF generation.

Related Projects

Bambu Gateway is the printer control plane and slicing web app in a suite of self-hosted projects that together replace the Bambu Handy app for printers in Developer Mode — keeping everything on your LAN, with no Bambu cloud.

Self-hosted services

  • Bambu Gateway — this project.
  • orcaslicer-headless — Headless OrcaSlicer wrapped in a REST API. Owns the filament/process/machine profile catalog (including custom user profiles) and does the actual slicing. Other services in the suite call it for slicing and profile data.
  • bambu-spool-helper — Bridge between Spoolman and the printer's AMS. Links real spools to Bambu filament profiles (via orcaslicer-headless) and pushes the settings to a chosen tray over MQTT.

iOS apps

  • bambu-gateway-ios — Phone client for bambu-gateway. Browse printers, import 3MF files (including from MakerWorld), preview G-code, and start prints. Live Activities and push notifications for print state changes.
  • spool-browser — Phone client for bambu-spool-helper and Spoolman. Browse the spool inventory, link Bambu profiles to spools, activate filaments on the AMS, and print physical spool labels over Bluetooth.

License

Bambu Gateway is available under the MIT License. See LICENSE for details.

About

A self-hosted web application for managing Bambu Lab 3D printers over your local network. Provides a REST API and web dashboard for monitoring printer status and submitting print jobs.

Topics

Resources

Stars

4 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages