openbambuapi Documentation

repository·main·Indexed 20 days ago

https://github.com/doridian/openbambuapi

Reverse-engineered API documentation for MakerWorld and Bambu Lab Design Services. Includes details on authenticating with the Bambu Lab API, managing print tasks, retrieving printer status, and interacting with IoT, Community, and Design services. Also provides technical guidance on decrypting BambuStudio network logs and analytics bundles, understanding plugin versioning, and bypassing the 'signed studio' gate for custom BambuStudio builds.

Tokens
25.9K
Snippets
87
Records
117
Agent score
66%

What's inside openbambuapi

  1. MakerWorld / Design Services API Overview

    main

    The MakerWorld / Design Services API provides access to Bambu Lab's 3D model sharing platform. It manages 3D models (designs), print profiles (instances), social features, and downloads.

    Base URLs:

    • https://api.bambulab.com/v1
    • https://makerworld.com/api/v1 (Note: This version is Cloudflare-protected)

    Authentication: All endpoints require a Bearer JWT authentication token.

  2. Configure AMS Mapping for multi-color prints

    main

    The ams_mapping parameter in a print.project_file request defines which AMS slot corresponds to each color index in your print file. It uses a reverse indexing system with a fixed array length of 5.

    Mapping Rules

    • Array positions: Represent color indices in the print file (starting from 0).
    • Array values: Represent AMS slot numbers (0-3).
    • -1: Indicates an unused color slot.
    • Padding: Fill unused positions at the beginning of the array with -1.

    Common Patterns

    Colors UsedArray PatternDescription
    1 color[-1, -1, -1, -1, X]Single color uses AMS slot X
    2 colors[-1, -1, -1, X, Y]Colors map to slots X and Y
    3 colors[-1, -1, X, Y, Z]Colors map to slots X, Y, and Z
    4 colors[-1, W, X, Y, Z]Colors map to slots W, X, Y, and Z

    Note: Always set "use_ams": true when providing a mapping.

    {
      "print": {
        "ams_mapping": [-1, -1, -1, 1, 0],
        "use_ams": true,
        "command": "project_file",
        "param": "Metadata/plate_X.gcode"
      }
    }
  3. Implement cloud-relayed video transport dispatch

    main

    Bambu's network plugin surfaces off-LAN video access through a single bambu:///… URL scheme. If you are building a custom client to consume video without using the proprietary network plugin, you must recognize the URL prefix and implement the corresponding transport.

    If you are re-implementing the bambu_network_get_camera_url callback, you can return these URL forms to allow the existing libBambuSource.so to handle the transport automatically.

    bambu:///tutk?uid=<UID>&authkey=<KEY>&passwd=<PW>&region=<R>
    bambu:///agora?app=<APP>&...
    bambu:///local/<host>?...
    bambu:///rtsps___<rtsps-url>
    bambu:///rtsp___<rtsp-url>
  4. Understand the TUTK Camera Protocol

    main

    The Bambu Handy app utilizes the ThroughTek Kalay (TUTK) protocol for P2P camera streaming to printers. Developers working with camera streaming should be aware of the following components and modes:

    • SDK Libraries: libIOTCAPIs, libAVAPIs, libTUTKGlobalAPIs.
    • Connection Methods: IOTC_Connect_ByUID_Parallel, IOTC_Connect_ByUIDEx.
    • Authentication Modes: AV_AUTH_PASSWORD, AV_AUTH_TOKEN, AV_SECURITY_DTLS.
    • Data Transmission Modes: IOTC_DATA_TRANSMIT_INTEGRITY_MODE, IOTC_DATA_TRANSMIT_COMPATIBILITY_MODE, IOTC_DATA_TRANSMIT_ADAPTATION_MODE.
    • Region Configuration: Use TUTK_SDK_Set_Region to set the appropriate region.
  5. Understand the BambuStudio plugin versioning

    main

    The network plugin reports its own version independently of the BambuStudio slicer version. The version string follows the format bambu_network_agent/XX.XX.XX.XX (e.g., bambu_network_agent/02.07.00.50).

    When correlating bug reports or log files, use the agent version string rather than the slicer's user-facing version to identify the network layer state.

  6. How the Studio binary verification (signed studio gate) works

    main

    To prevent unauthorized control of printers, the network plugin requires that the host process be a genuine, Bambu-signed BambuStudio installation before it will sign outbound print.* control commands.

    The Verification Process: Unsigned control commands are silently dropped by post-2025 firmware, resulting in a BAMBU_NETWORK_SIGNED_ERROR (-26) error. The plugin performs Authenticode-verification on two modules using WinVerifyTrust:

    1. The host executable (e.g., bambu-studio.exe).
    2. BambuStudio.dll.

    Pinned Identity Requirements: Verification succeeds only if the certificate's full identity (public key / SPKI) matches the following:

    • Subject: Shanghai Lunkuo Technology Co., Ltd (Note: older builds used Shenzhen Tuozhu Technology Co., Ltd.)
    • Issuer: GlobalSign GCC R45 EV CodeSigning CA 2020

    If verification fails, the plugin logs process_network_msg, unsigned_studio and add sign info failed, and commands are sent unsigned.

  7. AMS Branching and Control with M620/M621

    main

    The M620 and M621 commands are used to create conditional branches for AMS operations. If a condition (like "Enable AMS") is not met, the printer skips all commands until the matching M621 end-of-branch command is found.

    AMS Commands:

    • M620 C#: Calibrate AMS by index #.
    • M620 R#: Refresh AMS by tray index #.
    • M620 P#: Select AMS tray by index #.
    • M620 S#: Starts a branch (e.g., for unloading filament).
    • M621 S#: Ends a branch started by M620 S#.
    • M620 S#A: Starts a branch specifically for filament changes during print.
    • M621 S#A: Ends a branch started by M620 S#A.
  8. Sign MQTT commands with an RSA signature

    main

    For certain command classes (specifically print.*), all MQTT payloads must include a header object containing an RSA-SHA256 signature. This acts as a second layer of authentication after the TLS handshake.

    Required Header Fields:

    • sign_ver: Always "v1.0".
    • sign_alg: Always "RSA_SHA256" (RSA PKCS#1 v1.5 padding, SHA-256 digest).
    • cert_id: The certificate identifier in the format {hex_fingerprint}CN={serialNumber}.bambulab.com.
    • payload_len: The byte length of the canonicalized JSON string used for signing.
    • sign_string: The Base64-encoded RSA-SHA256 signature.

    Signing Process:

    1. Serialize the command payload (everything except the header) into a canonical JSON string.
    2. Sign this string using the private key from the certificate obtained during the exchange.
    3. Base64-encode the resulting signature.
    {
      "user_id": "3469901296",
      "print": {
        "ams_id": 0,
        "command": "extrusion_cali_sel",
        "filament_id": "GFL99",
        "nozzle_diameter": "0.4",
        "nozzle_volume_type": "normal",
        "sequence_id": "2039",
        "timestamp": 1772675132270,
        "tray_id": 3
      },
      "header": {
        "sign_ver": "v1.0",
        "sign_alg": "RSA_SHA256",
        "sign_string": "iq3gpC6U2UijAp+v+YDJduXkPIDO5UaUjq1k72Xw6Ps...",
        "cert_id": "77bcfb6303214f046175eb6681a46d83CN=GLOF3813734089.bambulab.com",
        "payload_len": 225
      }
    }
  9. Canonicalize JSON for signing

    main

    To ensure the signature is valid, the payload must be canonicalized before signing. The signing input is constructed as:

    bytes_to_sign = '{"<top-key>":' + canonical_json(envelope[<top-key>]) + '}'

    Canonical JSON Rules:

    • Keys must be sorted alphabetically (recursively at every depth).
    • No whitespace allowed anywhere.
    • Only , and : are used as separators.

    In Python, use json.dumps(payload, sort_keys=True, separators=(',', ':')) to achieve this.

    import json
    # Example of canonicalization
    json.dumps(payload, sort_keys=True, separators=(",", ":"))
  10. MQTT Request and Report message formats

    main

    All MQTT messages are JSON encoded. Communication follows a request/report pattern using a sequence_id to match responses to commands.

    Request Structure

    Requests include a sequence_id (which should be incremented by 1 for each new command) and the command name.

    Report Structure

    Reports include the same sequence_id used in the request, the command name, and a result field (case-insensitive, e.g., "success"). A reason field may be included if the command failed.

    // Request
    {
        "{TYPE}": {
            "sequence_id": "0",
            "command": "{COMMAND}"
        }
    }
    
    // Report
    {
        "{TYPE}": {
            "sequence_id": "0",
            "command": "{COMMAND}",
            "result": "success",
            "reason": "",
            ...
        }
    }
  11. Validate printer identity using Server Name Indication (SNI)

    main

    To ensure you are communicating with the correct printer and to avoid hostname mismatch errors (e.g., [ERR_TLS_CERT_ALTNAME_INVALID]), you must use Server Name Indication (SNI).

    Because the printer's certificate contains the printer's serial number in the Common Name (CN) field, connecting via a raw IP address (like 192.168.0.5) will fail validation unless SNI is used to tell the server which hostname you are expecting.

    If your library does not support SNI, you must manually verify the certificate's common name or disable hostname validation (not recommended).

  12. Handle printer status reports (print.push_status)

    main

    The print.push_status report provides the current state of the printer. The behavior of this report differs by hardware series:

    • X1 Series: Always responds with the full status object.
    • P1 Series: To optimize performance, the P1P only responds with values that have changed since the last report. To retrieve the complete status object on a P1 series device, use the pushing.pushall request.