API
SG-1no stateimmutable
One URL in, one avatar out. The same seed renders the same avatar on every request, from every replica, forever.
Endpoints
GET /v1/avatar/{seed}.svgimage/svg+xmlGET /v1/avatar/{seed}.pngimage/pngGET /v1/decode/{seed}JSON: spec, hex, palette, cellsGET /healthz200 okshell
curl 'https://sigil.oddkin.co/v1/avatar/ada@lovelace.dev.svg?palette=mono&size=128' curl 'https://sigil.oddkin.co/v1/decode/ada@lovelace.dev?palette=mono'
html
<img src="https://sigil.oddkin.co/v1/avatar/ada@lovelace.dev.svg?palette=mono" width="32" height="32" alt="">
Seeds
The path segment is URL-decoded UTF-8 and hashed exactly as given. Ada@Example.com and ada@example.com are different avatars. For email avatars, lowercase and trim the address before you build the URL. Encode / as %2F.
Parameters
size16–102464Rendered px; the viewBox is always 64.glyphtee | elbow | stubteeBase connection set, rotated per cell.palettespectrum | auto | fire | phosphor | cobalt | monospectrumauto reads hash bits 96–97 and picks fire, phosphor, cobalt or mono. spectrum is explicit only.substratedark | light | nonedarklight switches to the ink ramp.shaperounded | square | circleroundedClip path; rounded is rx 10.paddingnone | some | lotsnoneInsets the grid. some clears the clip for the shape: 4, or 6 for circle. lots is 8.blendtrue | falsetrueGrade joined traces between both shades.elementsmixed | viamixedvia draws every cell as a via.emptynone | few | somesomeShare of blank cells: 0, ≈12.5%, ≈25%. Each level blanks a subset of the next.hash32 hex—Replaces the seed's hash; the seed is ignored.Errors
An invalid parameter returns 400 with the field that failed and what was expected.
{"error": "Expected 32 hex characters.", "field": "hash"}Caching
Output is a pure function of the spec, the seed or hash, and the parameters. Every response carries Cache-Control: public, max-age=31536000, immutable and an ETag of the form "SG-1-<sha1>", and answers If-None-Match with 304.