SparkUAPIExperimentalllms.txtРусский

Sections · 3/11

Concepts

Integration, slug, token, fields, Island, card, priority, and value TTL.

Markdown ↗

Integration#

An integration is what you assemble in Settings: a name, an address (slug), a set of typed fields, and how they appear on the Island (indicator, line, card). The integration structure is static: scripts send values but cannot add a field, button, or element beyond what you configured. One integration gives exactly one indicator and one line on the Island — if you need two lines, they're two separate integrations.

A disabled integration responds with 409 integration_disabled to writes and displays nothing; its configuration and token are preserved.

Slug (address)#

A slug is how a script finds an integration: /v1/integrations/{slug}/…, sparku push {slug} …. Rules:

  • lowercase Latin letters, digits, and hyphens;
  • starts with a letter or digit, doesn't end with a hyphen;
  • no longer than 32 characters.

Valid slug examples: deploy, build, server, home-server. On .sparku import, if the address matches, SparkU picks a free one: deploy → deploy-2.

Token#

Each integration has its own token, issued when it's created. It's stored in Keychain and doesn't protect against other processes under your user — they have access to the socket anyway. Its purpose is addressing, protection from typos and other scripts, and selective access revocation by reissuing the token.

Where to get it. Settings > Custom Integrations > your integration > "Connection" section: the line export SPARKU_TOKEN_<ADDRESS>=… and ready code examples.

How to pass it. Header Authorization: Bearer <token> in every request.

Search order in CLI (sparku tries in order until it finds a non-empty value):

  1. --token <token>
  2. --token-file <path>
  3. environment variable SPARKU_TOKEN_<ADDRESS> (address in uppercase, hyphens → _; for example home-server → SPARKU_TOKEN_HOME_SERVER)
  4. variable SPARKU_TOKEN
  5. variable SPARKU_TOKEN_FILE (path to file with token)

SPARKU_TOKEN without an address suffix is convenient when a script writes to one integration; SPARKU_TOKEN_<ADDRESS> — when writing to several at once.

Fields#

A field is a named, typed slot: a key (progress, cpu), a type (field types), and a label. A field key is lowercase Latin letters, digits, and _, starts with a letter, no longer than 32 characters (it's also an environment variable name SPARKU_FIELD_<KEY> for button shell actions, so hyphens are not allowed). An integration has at most 32 fields.

Writing fields is all or nothing: if any value fails validation, POST …/fields rejects the entire request, and the Island doesn't end up half-updated.

Island: indicator, line, card#

Indicator (collapsed Island, 28 pt slot)#

One per integration. Styles:

Style Shows Source
Icon static SF Symbol —
Ring progress ring with icon or number inside field progress or number with min/max
Value short string up to 4 chars text, number, progress, state, bool
Equalizer animation like "Media" field bool enables motion
Spinner rotating indicator field bool enables rotation

Field state can be assigned separately (stateField) — its value replaces the icon, color, and animation of the indicator without changing its type.

Card line (one per integration)#

Style Shows Source
Text template {title} · {progress} any fields via {key}
Timer live countdown field time
Scale label and mini bar field progress or number with min/max
Avatars stack of circles with initials, "+N" above three field list

Line template ({key}): substitutes the value in the default display for the field type. {{ and }} are literal braces, no format specifiers. Default display: number — up to two decimal places plus unit (21°C, 120 ms), progress — 43%, state — its label, time — countdown to moment or time since moment (4:59, 1:02:03), list — number of lines, boolean — "yes"/"no". No value — em dash (—).

Card (expanded Island)#

Built from a template with slots — there's no free grid to keep the visual row unified with built-in integrations.

Template Model Slots / fields
Value Currency main (number/progress/text), label
Status agents main (state), label, "since" (time)
Progress Pomodoro main (progress/number), label, countdown (time)
Timer Pomodoro main (time), label, ring (progress)
Scales Resource Monitor 2–4 progress/number fields (with min/max) in a row
Limit Claude Code fast window (progress), slow window (progress), label
Metrics agents 2–4 text/number/progress/state/bool/time fields in columns
List Calendar, Todo one list field
Now Media title (text, required), label, cover (image), scale (progress)
Graph — one number field — drawn from accumulated history

The card has a common header and a row of 0–3 controls. A card can request normal or wide width (like built-in integrations) and a suitable compact variant.

Controls and their actions#

A control is a button, capsule button, toggle (controls a bool field), or menu (picks a state field value). Up to three per card. What the tap does is decided by you in the editor, not the script:

Action What happens
event sends an event to listeners GET …/events / sparku listen; without a listener the control is inactive
url opens a link, file, or app (address — static or {field})
shell runs a command; field values are passed only through environment variables SPARKU_FIELD_<KEY>, never substituted into the command text
shortcut launches an app command from the Shortcuts app by name

A listener gets an event for any tap regardless of what action is set above.

Priority#

The Island is a shared resource: the notch border, attention beacon, and dialog queue work as a stack of requests, not "first wins, rest wait". Your custom integration has three priority levels:

  • Low
  • Normal — equal to SparkU's built-in integrations (default)
  • High — above built-in

With equal priority, the request submitted last wins. Updating an already-submitted request doesn't bump it forward: a module reporting progress once a second doesn't steal the slot from one that requested after it.

Value TTL (time-to-live)#

Field values live in memory only and don't survive a SparkU restart — integration configuration is always saved. By default, values live until a SparkU restart or explicit sparku end; an integration can set its own TTL, and a specific request can override it with the ?ttl= parameter:

POST /v1/integrations/deploy/fields?ttl=5m
POST /v1/integrations/deploy/fields?ttl=90

ttl is a number of seconds or 5m / 1h30m (same units as time fields), at most 7 days. Empty or missing parameter — TTL from integration settings. Each new write restarts the TTL count.

sparku push supports the same parameter as the --ttl flag (see CLI).

Binding to a process#

A TTL doesn't help when a script crashes: it wrote "Deploy 40%" and died, and the island keeps showing it until the TTL runs out. Binding solves this differently — values live as long as a process does:

POST /v1/integrations/deploy/fields?bind=process   # the process that sent the request
POST /v1/integrations/deploy/fields?bind=4211      # the process with this PID
POST /v1/integrations/deploy/fields?bind=none      # remove the binding

When the process exits, the values are cleared at once, as with sparku end. The binding stays for later writes without bind; a new bind replaces it. The TTL still applies too — whichever comes first.

bind=process is for programs that keep running themselves (a Python script, a Node service). curl and sparku exit right after the request, so they need the script's PID: in a shell that's ?bind=$, and sparku push --bind fills it in for you.

Notify rate limit#

POST …/notify (flash + line for a few seconds) can be called at most once per 2 seconds per integration. More frequent calls get 429 too_many_notices with a Retry-After header. The limit is separate from writing values through fields — that's accepted without limits, just displayed no more than once per frame.

Number history#

For the graph (template "Graph") and trend, SparkU accumulates history for each numeric field: at most one point per second (a write within the same second replaces the last point), 120 points per field, in memory only — history is lost with values when SparkU restarts.