Skip to main content

Base URL

All endpoints are accessed via HTTPS on your personal server:
Replace benzhou.tech with your own domain when setting up your personal server.

Authentication

All endpoints use password-based authentication via URL parameter:
The password is defined in SampleCredentials.h and validated by the server before processing requests.

Endpoints

Manage playback state

Controls Spotify playback by executing various actions.
string
required
Authentication password matching server configuration
string
required
Action to perform. Must be one of: playPause, skip, back, loop, vdec, vinc, shuffle

Actions

action
Toggle play/pause state. Mapped from pause/play button (GPIO 25).Source: src/src.ino:366-369
action
Skip to next track. Mapped from skip button (GPIO 26).Source: src/src.ino:371-375
action
Go to previous track or restart current track. Mapped from back button (GPIO 14).Source: src/src.ino:361-364
action
Toggle repeat/loop mode. Mapped from loop button (GPIO 13).Source: src/src.ino:359
action
Decrease volume. Mapped from volume decrease button (GPIO 5).Source: src/src.ino:349-352
action
Increase volume. Mapped from volume increase button (GPIO 12).Source: src/src.ino:354-357
action
Toggle shuffle mode. Mapped from shuffle button (GPIO 4).Source: src/src.ino:347

Request example

HTTP request:

Response

The server should return an HTTP 200 status on success. The ESP32 does not parse the response body for this endpoint.

Get current playback

Retrieves the current playback state including track information, progress, and album art color.
string
required
Authentication password matching server configuration

Request example

HTTP request:

Response

Returns JSON with current playback information:
string
required
Current track title. Displayed on OLED screen (line 2-3).Example: "Bohemian Rhapsody"Extracted at: src/src.ino:248
string
required
Artist name. Displayed on OLED screen (line 4).Example: "Queen"Extracted at: src/src.ino:249
string
required
Album name. Stored but not displayed on screen due to space constraints.Example: "A Night at the Opera"Extracted at: src/src.ino:250
integer
required
Track duration in seconds.Example: 354 (5:54)Extracted at: src/src.ino:251, 259
integer
required
Current playback position in seconds. Used to render progress bar.Example: 120 (2:00)Extracted at: src/src.ino:252, 260
boolean
required
Whether playback is currently paused. When true, progress counter stops incrementing.Example: falseExtracted at: src/src.ino:253, 256
integer
required
Current volume level (0-100). Displayed as icon in top-right corner.Example: 75Icon mapping (src/src.ino:140-148):
  • 67-100: volume_3 (full)
  • 34-66: volume_2 (medium)
  • 1-33: volume_1 (low)
  • 0: volume_0 (muted)
Extracted at: src/src.ino:254, 258
array
required
RGB color array [R, G, B] extracted from album artwork. Each value is 0-255.Example: [45, 52, 71]Used to set RGB LED strip color for ambient lighting that matches the album art.Extracted at: src/src.ino:263-276
The color is faded smoothly over 256 steps when the track changes (src/src.ino:292-304).

Response example

Response parsing

The ESP32 uses a custom JSON parser to extract values:
This lightweight parser avoids the memory overhead of a full JSON library like ArduinoJson.
The response JSON must be properly formatted with keys in this exact order: title, artist, album, duration, progress, paused, volume, color. The parser is not order-independent.

Polling intervals

The ESP32 polls endpoints at different intervals:

Connection handling

The ESP32 maintains a persistent HTTPS connection using HTTP Keep-Alive:
Connection parameters:
  • Protocol: HTTPS (TLS/SSL)
  • Port: 443
  • Host: benzhou.tech (configurable)
  • Keep-Alive: Enabled for connection reuse
  • Timeout: 5000ms for response (src/src.ino:222-229)

Error responses

The ESP32 provides visual feedback for errors using the RGB LED strip:

Timeout handling

Button mapping

Buttons are mapped to actions in the following order:
Buttons are read with INPUT_PULLUP, meaning they read LOW when pressed:

Implementation notes

Why GET instead of POST?

The ESP32 uses GET requests for simplicity. The WiFiClientSecure library makes GET requests straightforward, and since the password is sent over HTTPS, it’s encrypted in transit.

Why custom JSON parsing?

The ESP32 has limited RAM (320KB). Using a full JSON library like ArduinoJson would consume significant memory. The custom extractValue() function is lightweight and sufficient for the simple JSON structure.

Why Keep-Alive?

TLS handshakes are computationally expensive on the ESP32. By maintaining a persistent connection, the device avoids repeated handshakes, significantly improving response time and reducing power consumption.

Next steps

Server setup

Set up your personal proxy server

Hardware assembly

Assemble the MacroBoard hardware