piculum

Developer API beta - free keys

Everything the piculum library does locally, callable over HTTPS: check and inspect templates, measure capacity, and seal or open records from environments that can't run the codec themselves. Keys are free during the beta; they exist for quotas and abuse control, not billing.

What touches the server, and what never does

The endpoints come in two tiers, and the line between them is deliberate:

Either way, your artwork never reaches us. Piculum data is written full-pixel, so sealing doesn't need the host picture: /v1/seal takes dimensions and a region and returns just the sealed pixels for you to stamp into your own image locally. Opening needs only the carrier region, so you can crop before uploading. If even the data plane's trust model is more than you want, the npm package does everything on your own machine - this API exists for the places that can't run it.

Get a key

Basics

Template toolchain no secrets

POST /v1/capacity - will it fit?

Pure math, either direction: pixels → usable bytes, or bytes → pixels needed.

curl -X POST https://piculum.com/api/v1/capacity \
  -H "Authorization: Bearer $KEY" -H "content-type: application/json" \
  -d '{"pixels": 12000}'
→ {"pixels": 12000, "usableBytes": 21528}

POST /v1/validate - template QA

Send a v2 mask-definition (the maskJson a template carries) as {"mdf": ...}. Checks structure and that data layers don't share pixels - the overlap case silently corrupts decodes, which is exactly what you want a CI gate to catch.

→ {"ok": true}
→ {"ok": false, "error": "version must be 2."}
→ {"ok": false, "error": "piculum layers overlap: ...", "overlaps": [{"a": "Name", "b": "Notes", "sharedPixels": 214}]}

POST /v1/inspect - what does this template expect?

Same input; returns each layer's label, type, bounding rect, pixel count, and - for data layers - usable capacity and field definition. The bulky bitmaps are never echoed back.

POST /v1/author planned

Build a template from code without the editor. Returns 501 today; the input format is being designed. If you need it, say so - the first integrator shapes it.

Data plane

POST /v1/seal - encode a record

curl -X POST https://piculum.com/api/v1/seal \
  -H "Authorization: Bearer $KEY" -H "content-type: application/json" \
  -d '{
    "payload":  {"kind": "text", "text": "the record"},
    "password": "the password",
    "width": 400, "height": 300,
    "locator":  {"mode": "rect", "x": 40, "y": 60, "regionWidth": 120}
  }'

Payloads can also be {"kind": "html", "html": "..."} (rich text) or {"kind": "file", "name", "mime", "dataBase64"} - a file's name and MIME type round-trip. For rect and non-scatter mask locators the response is the stampable sparse set:

{"ok": true, "width": 400, "height": 300, "pixelsUsed": 78,
 "sparse": {"indices": [18040, 18041, ...], "rgbaBase64": "..."}}

Overwrite those pixels in your local copy of the artwork (index = y * width + x, 4 bytes each from rgbaBase64) and the result decodes anywhere. Scatter and key locators spread pixels by a password-derived order you can't reconstruct, so those return a standalone PNG ("png", base64) instead - as does "includePng": true.

Sealed data, not painted text: the server returns the record's pixels, not the human-visible field text the workbench paints. If you want visible text too, paint it locally (piculum/render, browser-only) before stamping - paint that lands on carrier pixels after the data does will destroy the record.

POST /v1/open - decode a record

curl -X POST https://piculum.com/api/v1/open \
  -H "Authorization: Bearer $KEY" -H "content-type: application/json" \
  -d '{"pngBase64": "...", "password": "the password",
       "locator": {"mode": "rect", "x": 40, "y": 60, "regionWidth": 120}}'
→ {"ok": true, "payload": {"kind": "text", "text": "the record"}}

Omit locator for whole-image piculums. You don't have to upload the whole picture: crop to the carrier region, re-base the locator to the crop (x: 0, y: 0), and send that.

A wrong password, a wrong locator, and a picture with nothing in it are indistinguishable by design - all three come back as 422 decode_failed. There is no "does this PNG contain a piculum?" check, on purpose.

The one rule of care, API edition

A piculum's content lives in exact pixel values. Stamp sparse pixels into lossless RGBA and save as PNG - never through a canvas that resizes, a JPEG step, or a messenger that recompresses. Send the file, not a picture of the file.

Beta terms