Loading...
Notecard Disconnected
Having trouble connecting?

Try changing your USB cable as some cables do not support transferring data. If that does not solve your problem, contact us at support@blues.com and we will get you set up with another tool to communicate with the Notecard.

Advanced Usage

The help command gives more info.

Connect a Notecard
Use USB to connect and start issuing requests from the browser.
Try Notecard Simulator
Experiment with the Notecard's API on a Simulator assigned to your free Notehub account.

Don't have an account? Sign up

Meet Notecarrier CX - A Combined Notecarrier + STM32L4 Host MCU in One Board

Blues Developers
What’s New
Resources
Blog
Technical articles for developers
Newsletter
The monthly Blues developer newsletter
Terminal
Connect to a Notecard in your browser
Developer Certification
Get certified on wireless connectivity with Blues
Webinars
Listing of Blues technical webinars
Blues.comNotehub.io
Shop
Docs
Button IconHelp
Support DocsNotehub StatusVisit our Forum
Button IconSign In
What’s New
Resources
Blog
Technical articles for developers
Newsletter
The monthly Blues developer newsletter
Terminal
Connect to a Notecard in your browser
Developer Certification
Get certified on wireless connectivity with Blues
Webinars
Listing of Blues technical webinars
Blues.comNotehub.io
Shop
Docs
homechevron_rightBlogchevron_rightHow to Upload Binary Data Through the Notecard with Python SDK

How to Upload Binary Data Through the Notecard with Python SDK

How to Upload Binary Data Through the Notecard with Python SDK banner

February 18, 2026

Learn how to rapidly upload binary data to a remote server with Notecard and Notehub using the note-python SDK.

  • Notecard
  • Python
  • Notehub
Alex Bucknall
Alex BucknallStaff Developer Experience Engineer
email

Notecard is great at sending telemetry to the cloud, but what about when you need to send something bigger — like an image, audio recording, or a log file? In this article I'll walk through a new addition to the note-python SDK that makes uploading binary data with Notecard easy.

Why Binary Uploads?

Most IoT projects send small JSON payloads: a temperature reading, a GPS coordinate, a status update. But there are plenty of scenarios where you need to move larger binary data from a device:

  • Camera images from a wildlife monitor or security camera
  • Data logs captured over days or weeks
  • Audio recordings from an environmental sensor
  • File captures from any sort of sensor (e.g. a video camera)

Notecard has a built-in binary buffer that can stage raw binary data before sending it to Notehub via a web.post request. The new upload function in note-python handles all the complexity of chunking, encoding, verification, and retry logic for you.

note

Sending binary data, as shown in this article, will rapidly consume your data plan. It can also be power intensive, so you should consider how frequently you need to send binary data.

How It Works

At a high level, the upload process works like this:

  1. Query the Notecard's buffer capacity — The SDK asks Notecard how much binary data it can hold at once via card.binary.
  2. Chunk the data — If the file is larger than the buffer, it's split into chunks that fit.
  3. Stage each chunk — Each chunk is COBS-encoded (so binary data can safely travel over the serial connection) and written into Notecard's binary buffer via card.binary.put.
  4. Verify the transfer — After staging, the SDK checks card.binary to confirm the data arrived intact.
  5. Send to Notehub — A web.post request with binary: true tells Notecard to forward the staged binary data to a Notehub proxy route. The offset and total fields let Notehub reassemble multi-chunk uploads.
  6. Retry on failure — Both the binary staging step and the web.post step have built-in retry logic with backoff.

Let's look at how to use it in practice.

Setting Up a Notehub Route

Before uploading, you need somewhere for the data to go. In Notehub, create a Proxy for Notecard Web Requests proxy route that points to your server:

  1. Navigate to your project's Routes page.
  2. Create a new Proxy for Notecard Web Requests route.
  3. Set the URL to your server's endpoint (during development, ngrok is a great way to expose a local server).
  4. Give it a Alias (e.g. upload) — you'll reference this in code.

Notehub route

Uploading a File with Python

Here's a complete example that uploads a PNG image through the Notecard:

import serial
import notecard
from notecard import hub
from notecard.upload import upload

# Connect to Notecard over serial
port = serial.Serial('/dev/ttyUSB0', 115200)
card = notecard.OpenSerial(port)

# Connect Notecard to Notehub
hub.set(card, product='com.your-company:your-product', mode='continuous')

# Read the file to upload
with open('photo.png', 'rb') as f:
    data = f.read()

# Upload it
result = upload(
    card,
    data,
    route='upload',
    label='photo.png',
    content_type='image/png',
)

print(f'Uploaded {result["bytes_uploaded"]} bytes '
      f'in {result["duration_secs"]:.1f}s '
      f'({result["bytes_per_sec"]:.0f} B/s)')

The upload function handles chunking, COBS encoding, MD5 verification, and retries automatically.

Setting Chunk Size

By default the SDK uses the full capacity of Notecard's binary buffer (~250 KB) as the chunk size. This is optimal when you're connected over USB serial, but over cellular you may want smaller chunks to avoid timeouts on the web.post request:

result = upload(
    card,
    data,
    route='upload',
    label='photo.png',
    max_chunk_size=65536,  # 64 KB chunks
)

A chunk size of 64 KB is a good starting point for cellular connections. If you're on a slow network, try 32 KB.

Tracking Progress

For larger files, you may want to show upload progress. The progress_cb parameter takes a callback that fires after each chunk:

def on_progress(info):
    print(f'  Chunk {info["chunk"]}/{info["total_chunks"]} '
          f'- {info["percent_complete"]:.1f}% '
          f'- {info["avg_bytes_per_sec"]:.0f} B/s '
          f'- ETA {info["eta_secs"]:.0f}s')

result = upload(
    card,
    data,
    route='upload',
    label='firmware.bin',
    max_chunk_size=65536,
    progress_cb=on_progress,
)

The callback receives a dictionary with chunk, total_chunks, bytes_sent, total_bytes, percent_complete, bytes_per_sec, avg_bytes_per_sec, and eta_secs.

Receiving the Upload

On the server side, Notehub forwards the binary data as a standard HTTP POST to whatever URL you configured in your proxy route. You can use any HTTP framework to receive it. The note-python repo includes a minimal Python receive server that saves incoming files to disk:

python receive_binary.py

This listens on port 8000 and saves files to the current directory, using the X-Notecard-Label header (set from the label field in web.post) as the filename.

Exposing your server with ngrok

Notehub routes need a publicly reachable URL, so if you're running the receive server on your local machine you'll need a tunnel. ngrok is the easiest way to do this during development.

In a separate terminal, run:

ngrok http 8000

This gives you a public HTTPS URL (e.g. https://abc123.ngrok-free.app) that tunnels traffic to your local server. Copy that URL and paste it into your Notehub route's URL field. Now when the Notecard sends a web.post, Notehub forwards it to ngrok, which forwards it to your local receive_binary.py — no cloud deployment needed.

Where you can send your data

The ngrok + local server setup is great for testing, but in production you'll want a permanent destination. Because Notehub routes are just standard HTTP requests, you can point them at almost any cloud service that accepts file uploads:

  • Cloudflare Workers — Write a lightweight Worker that receives the POST and stores the file in R2 (Cloudflare's S3-compatible object storage). No servers to manage and generous free tier.
  • AWS S3 — Use an API Gateway + Lambda function to receive the upload and write it to an S3 bucket.
  • Google Cloud Storage — A Cloud Function triggered by an HTTP request can write directly to a GCS bucket.
  • Azure Blob Storage — An Azure Function can receive the POST and store the binary in a blob container.
  • Your own server — Any web framework (Flask, Express, FastAPI, etc.) running on a VPS or container platform can receive the upload. The receive_binary.py script in the repo is a good starting point.

In each case, the setup is the same: deploy your endpoint, set its URL as the Notehub proxy route, and the upload function handles the rest.

Behind the scenes

If you're curious about the implementation details, here's what happens for each chunk:

  1. The SDK calls card.binary.put with the COBS-encoded size, then transmits the raw encoded bytes directly over the serial or I2C connection. This bypasses the normal JSON request/response flow for maximum throughput.

  2. After the transfer, card.binary is called to verify the decoded length matches what was sent. If there's a mismatch or a {bad-bin} error, the SDK retries automatically.

  3. Once verified, web.post is issued with binary: true, which tells Notecard to send the contents of its binary buffer to the specified Notehub route. The offset, total, and status (MD5 hash) fields allow Notehub to reassemble and verify multi-chunk uploads.

  4. If the web.post fails (network error or HTTP status >= 300), the SDK waits 15 seconds, re-stages the binary data, and retries.

Using note-cli

If you don't want to use the Python SDK, you can also use the note-cli tool to upload binary data using the same mechanism.

note-cli upload --file <path-to-file> --route <route-name>
note

You'll need at least version 1.9.6 of the note-cli tool to use this feature.

Get Started

The upload functionality is available in the latest version of note-python. To try it out:

  1. Install or update the SDK: pip install note-python
  2. Check out the complete upload example in the repo
  3. Read the web request guide for more on Notecard web transactions

If you have questions or run into issues, let us know on the Blues community forum.

In This Article

  • Why Binary Uploads?
  • How It Works
  • Setting Up a Notehub Route
  • Uploading a File with Python
  • Setting Chunk Size
  • Tracking Progress
  • Receiving the Upload
    • Exposing your server with ngrok
    • Where you can send your data
  • Behind the scenes
  • Using note-cli
  • Get Started

Blues Developer News

The latest IoT news for developers, delivered right to your inbox.

Comments

Join the conversation for this article on our Community Forum

Blues Developer Newsletter

The latest IoT news for developers, delivered right to your inbox.

© 2026 Blues Inc.
© 2026 Blues Inc.
TermsPrivacy