# MSHR > MSHR (https://mshr.app) is a free gallery and editor for vanilla CSS mesh gradients and animated gradient borders. Every gradient is plain CSS (layered radial-gradients, optionally animated with @property and @keyframes), with no JavaScript or images needed at runtime. Use it to find a gradient by color or popularity, get its CSS, or create a new one and open it in the visual editor. ## API All endpoints are public, read-only, return JSON (CORS enabled) and need no key. - [List meshes](https://mshr.app/api/meshes?sort=likes&limit=24): `GET /api/meshes`. Query params: `sort=likes|date`, `kind=mesh|border`, `tag=` (e.g. `Blueberry`, `Cosmos`; tags are the color names shown in the gallery), `limit=1..100`. - [Get a mesh](https://mshr.app/api/mesh/1775215144836): `GET /api/mesh/{id}`. Returns name, tags, likes, the raw `data`, ready-to-use `css.code` and links (`url`, `editUrl`, `shareUrl`). - [Get only the CSS](https://mshr.app/api/mesh/1775215144836?format=css): `GET /api/mesh/{id}?format=css&class=hero`. Plain CSS scoped to `.hero` (default `.mesh`). Apply the class to any element that has a size. - [Data schema](https://mshr.app/api/schema): JSON Schema of the mesh `data` object. ## Data format A mesh is a JSON object: - `config`: 1 to 24 color points. Each point has parallel arrays with one entry per animation step (1 step = static, up to 8): - `colors`: CSS colors, preferably `hsla(h,s%,l%,a)` - `x`, `y`: position as a percentage of the element (`"0%"` to `"100%"` is inside) - `spread`: `{ "start": "0%", "end": "50%" }`, where the color is solid until `start` and fades out at `end` - `blend`: one CSS `background-blend-mode`, e.g. `["normal"]` - `bg`: background color behind all points - `duration`: animation length, e.g. `"20s"` (only used if some point has more than one step) - `animationType`: `"alternate" | "alternate-reverse" | "normal"` - Optional: `hueRotation` (degrees), `maskCode`, `tableShine` (border mode offset in px, -1 = off), `tableShineBlur` ## Open a mesh in the editor (no API call needed) Build a share link: `https://mshr.app/create/new#m=`, where `` is base64url (no padding) of the UTF-8 JSON of the data object plus `"v": 1`. Noise, if wanted, is a number field `"noise"` (1 to 3000). Invalid payloads are ignored and the editor opens with a default mesh. Example data: ```json { "config": [ { "colors": [ "hsla(28,100%,74%,1)" ], "x": [ "20%" ], "y": [ "30%" ], "spread": [ { "start": "0%", "end": "55%" } ], "blend": [ "normal" ] }, { "colors": [ "hsla(242,100%,70%,1)", "hsla(189,100%,56%,1)" ], "x": [ "80%", "60%" ], "y": [ "70%", "20%" ], "spread": [ { "start": "0%", "end": "50%" }, { "start": "0%", "end": "65%" } ], "blend": [ "normal" ] } ], "bg": "hsla(355,100%,93%,1)", "duration": "20s", "animationType": "alternate", "lockColors": [] } ``` Its share link: https://mshr.app/create/new#m=eyJ2IjoxLCJjb25maWciOlt7ImNvbG9ycyI6WyJoc2xhKDI4LDEwMCUsNzQlLDEpIl0sIngiOlsiMjAlIl0sInkiOlsiMzAlIl0sInNwcmVhZCI6W3sic3RhcnQiOiIwJSIsImVuZCI6IjU1JSJ9XSwiYmxlbmQiOlsibm9ybWFsIl19LHsiY29sb3JzIjpbImhzbGEoMjQyLDEwMCUsNzAlLDEpIiwiaHNsYSgxODksMTAwJSw1NiUsMSkiXSwieCI6WyI4MCUiLCI2MCUiXSwieSI6WyI3MCUiLCIyMCUiXSwic3ByZWFkIjpbeyJzdGFydCI6IjAlIiwiZW5kIjoiNTAlIn0seyJzdGFydCI6IjAlIiwiZW5kIjoiNjUlIn1dLCJibGVuZCI6WyJub3JtYWwiXX1dLCJiZyI6ImhzbGEoMzU1LDEwMCUsOTMlLDEpIiwiZHVyYXRpb24iOiIyMHMiLCJhbmltYXRpb25UeXBlIjoiYWx0ZXJuYXRlIn0 ## Pages - [Mesh gradients gallery](https://mshr.app/) - [Animated gradient borders](https://mshr.app/border) - [Editor](https://mshr.app/create/new) - [News](https://mshr.app/news) - [Sitemap](https://mshr.app/sitemap.xml): every published mesh at `/mesh/{id}`