# Field types

> How fields are coerced from CLI strings and JSON, push examples, and 422 error texts.

## Coercion

`POST /v1/integrations/{slug}/fields` accepts a JSON object `{"key": value}`. Each value is coerced to the type you declared in the editor. If any value fails validation — the entire request is rejected (`422 invalid_fields`) with an error text for each field.

`sparku push` supports two assignment syntaxes:

- `field=value` — sends a **string**, the server coerces it to the field type;
- `field:=json` — sends the value **as is**, parsed as JSON
  (`items:='[{"title":"a"}]'`, `done:=true`, `state:=null`).

`null` (via `field:=null`) clears a field without removing it from the schema.

## Type table

| Type | Value in `push` | Coercion from CLI string | Note |
|---|---|---|---|
| `text` | `"prod"` | taken as-is | truncated to length limit (default 120 chars), not rejected |
| `number` | `72` | `Double(string)` | unit, `min`/`max` for scales and rings; accumulated for graph history |
| `progress` | `0.7` | number 0…1, or `"70%"` | strictly 0…1 after coercion |
| `bool` | `true` | `true/false/yes/no/on/off/1/0` (case-insensitive) | for toggles and equalizer |
| `state` | `"failed"` | string, must be in the field's state list | each state has icon, color, animation, flash on transition |
| `time` | ISO 8601 or `+5m` | `+5m`, `-1h30m`, ISO 8601 | timers tick inside SparkU — no need to push every second |
| `image` | path or base64 (≤ 256 KB) | path `/…` or `~/…`, or base64 (can have `data:...,`) | PNG/JPEG only |
| `url` | `"https://…"` | string with scheme | for button actions; `javascript:` and `data:` rejected |
| `list` | `[{"title": "…"}]` | only `field:=json` | up to 50 rows |

## Push examples for each type

```bash
sparku push deploy title="Production deploy"
sparku push server cpu=37.5
sparku push build progress=70%          # equivalent to progress=0.7
sparku push server ready=true
sparku push build stage=failed          # value must be declared in the field
sparku push timer ends=+5m              # 5 minutes from now
sparku push timer ends=2026-10-01T12:00:00Z   # ISO 8601
sparku push now cover=~/cover.png
sparku push deploy link=https://ci.example.com/builds/482
sparku push queue items:='[{"title": "Build"}, {"title": "Tests", "state": "running"}]'
```

## Time format

One of the following is accepted:

- **Relative offset from now**: `+5m`, `-1h30m`, `+90s`, `+2d`. Units are `d`, `h`, `m`, `s`, can be combined but only in decreasing order (`1h30m`, not `30m1h`). A single `time` field works as both a timer (`+5m` — countdown) and a stopwatch (`-10m` — elapsed time).
- **ISO 8601** with time and timezone (`2026-10-01T12:00:00Z`, with fractions of a second too).
- **UNIX time** — only as a number in `field:=1699999999`, not as a string in `field=…`.

## `list` — row objects

Each element is an object `{"title", "subtitle"?, "value"?, "state"?, "icon"?}` or just a string (becomes `title`). Only `title` is required. At most 50 elements per write.

```bash
sparku push queue items:='[
  "Simple string",
  {"title": "Build", "subtitle": "main", "state": "running"},
  {"title": "Tests", "value": "42/50", "icon": "checkmark"}
]'
```

## `image`

- Absolute path (`/Users/…`) or path with `~` — file must exist and be PNG or JPEG.
- Or content in base64 (can have prefix `data:image/png;base64,` — it's discarded). Limit — 256 KB after decoding; larger is rejected.

## Error texts for 422 (from code)

The `422 invalid_fields` response contains `fields: [{field, message}]`, and the combined message is `field: message; field2: message2`. Examples of real texts:

```
progress: expected 0…1, got 70
progress: expected number 0…1, got "many"
cpu: expected number, got "abc"
ready: expected true or false, got "maybe"
stage: expected one of: queued, running, passed, failed; got "cancelled"
ends: expected time (ISO 8601, +5m, -1h30m, or UNIX time), got "tomorrow"
cover: file not found: /Users/me/cover.png
cover: only PNG and JPEG are supported
cover: base64 not parsed or image larger than 256 KB
link: expected URL with scheme (https://…), got "example.com"
link: scheme "javascript" is not supported
items: expected array, got object
items: at most 50 rows, got 63
items[0]: no title
title: expected string, got array
```

Error for an undeclared field:

```
field not declared in integration "deploy"; available: title, progress, stage
field not declared: integration "deploy" has no fields yet
```

Both texts appear in the API response and in the integration log in Settings.
