Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Design mobile app screens and generate visual mockups using the Sleek.design API
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
SKILL.md
1---2name: sleek-design-mobile-apps3description: Use when the user wants to design a mobile app, create screens, build UI, or interact with their Sleek projects. Covers high-level requests ("design an app that does X") and specific ones ("list my projects", "create a new project", "screenshot that screen").4compatibility: Requires SLEEK_API_KEY environment variable. Network access limited to https://sleek.design only.5metadata:6requires-env: SLEEK_API_KEY7allowed-hosts: https://sleek.design8---910# Designing with Sleek1112[](https://sleek.design)1314## Overview1516[sleek.design](https://sleek.design) is an AI-powered mobile app design tool. You interact with it via a REST API at `/api/v1/*` to create projects, describe what you want built in plain language, and get back rendered screens. All communication is standard HTTP with bearer token auth.1718**Base URL**: `https://sleek.design`19**Auth**: `Authorization: Bearer $SLEEK_API_KEY` on every `/api/v1/*` request20**Content-Type**: `application/json` (requests and responses)21**CORS**: Enabled on all `/api/v1/*` endpoints2223---2425## Prerequisites: API Key2627Create API keys at **https://sleek.design/dashboard/api-keys**. The full key value is shown only once at creation — store it in the `SLEEK_API_KEY` environment variable.2829**Required plan**: Pro or higher (API access is gated)3031### Key scopes3233| Scope | What it unlocks |34| ----------------- | ---------------------------- |35| `projects:read` | List / get projects |36| `projects:write` | Create / delete projects |37| `components:read` | List components in a project |38| `chats:read` | Get chat run status |39| `chats:write` | Send chat messages |40| `screenshots` | Render component screenshots |4142Create a key with only the scopes needed for the task.4344---4546## Security & Privacy4748- **Single host**: All requests go exclusively to `https://sleek.design`. No data is sent to third parties.49- **HTTPS only**: All communication uses HTTPS. The API key is transmitted only in the `Authorization` header to Sleek endpoints.50- **Minimal scopes**: Create API keys with only the scopes required for the task. Prefer short-lived or revocable keys.51- **Image URLs**: When using `imageUrls` in chat messages, those URLs are fetched by Sleek's servers. Avoid passing URLs that contain sensitive content.5253---5455## Quick Reference — All Endpoints5657| Method | Path | Scope | Description |58| -------- | --------------------------------------- | ----------------- | ----------------- |59| `GET` | `/api/v1/projects` | `projects:read` | List projects |60| `POST` | `/api/v1/projects` | `projects:write` | Create project |61| `GET` | `/api/v1/projects/:id` | `projects:read` | Get project |62| `DELETE` | `/api/v1/projects/:id` | `projects:write` | Delete project |63| `GET` | `/api/v1/projects/:id/components` | `components:read` | List components |64| `GET` | `/api/v1/projects/:id/components/:componentId` | `components:read` | Get component |65| `POST` | `/api/v1/projects/:id/chat/messages` | `chats:write` | Send chat message |66| `GET` | `/api/v1/projects/:id/chat/runs/:runId` | `chats:read` | Poll run status |67| `POST` | `/api/v1/screenshots` | `screenshots` | Render screenshot |6869All IDs are stable string identifiers.7071---7273## Endpoints7475### Projects7677#### List projects7879```http80GET /api/v1/projects?limit=50&offset=081Authorization: Bearer $SLEEK_API_KEY82```8384Response `200`:8586```json87{88"data": [89{90"id": "proj_abc",91"name": "My App",92"slug": "my-app",93"createdAt": "2026-01-01T00:00:00Z",94"updatedAt": "..."95}96],97"pagination": { "total": 12, "limit": 50, "offset": 0 }98}99```100101#### Create project102103```http104POST /api/v1/projects105Authorization: Bearer $SLEEK_API_KEY106Content-Type: application/json107108{ "name": "My New App" }109```110111Response `201` — same shape as a single project.112113#### Get / Delete project114115```http116GET /api/v1/projects/:projectId117DELETE /api/v1/projects/:projectId → 204 No Content118```119120---121122### Components123124#### List components125126```http127GET /api/v1/projects/:projectId/components?limit=50&offset=0128Authorization: Bearer $SLEEK_API_KEY129```130131Response `200`:132133```json134{135"data": [136{137"id": "cmp_xyz",138"name": "Hero Section",139"activeVersion": 3,140"versions": [{ "id": "ver_001", "version": 1, "code": "<!DOCTYPE html>...</html>", "createdAt": "..." }],141"createdAt": "...",142"updatedAt": "..."143}144],145"pagination": { "total": 5, "limit": 50, "offset": 0 }146}147```148149#### Get component150151Fetches a single component by ID. Use this when you need the code for a specific screen (e.g., after a chat run returns a `componentId` in its operations).152153```http154GET /api/v1/projects/:projectId/components/:componentId155Authorization: Bearer $SLEEK_API_KEY156```157158Response `200` — same shape as a single item from the list endpoint:159160```json161{162"data": {163"id": "cmp_xyz",164"name": "Hero Section",165"activeVersion": 3,166"versions": [{ "id": "ver_001", "version": 1, "code": "<!DOCTYPE html>...</html>", "createdAt": "..." }],167"createdAt": "...",168"updatedAt": "..."169}170}171```172173---174175### Chat — Send Message176177This is the core action: describe what you want in `message.text` and the AI creates or modifies screens.178179```http180POST /api/v1/projects/:projectId/chat/messages?wait=false181Authorization: Bearer $SLEEK_API_KEY182Content-Type: application/json183idempotency-key: <optional, max 255 chars>184185{186"message": { "text": "Add a pricing section with three tiers" },187"imageUrls": ["https://example.com/ref.png"],188"target": { "screenId": "scr_abc" }189}190```191192| Field | Required | Notes |193| ------------------------ | -------- | --------------------------------------------- |194| `message.text` | Yes | 1+ chars, trimmed |195| `imageUrls` | No | HTTPS URLs only; included as visual context |196| `target.screenId` | No | Edit a specific screen using its `screenId` (not `componentId`); omit to let AI decide |197| `?wait=true/false` | No | Sync wait mode (default: false) |198| `idempotency-key` header | No | Replay-safe re-sends |199200#### Response — async (default, `wait=false`)201202Status `202 Accepted`. `result` and `error` are absent until the run reaches a terminal state.203204```json205{206"data": {207"runId": "run_111",208"status": "queued",209"statusUrl": "/api/v1/projects/proj_abc/chat/runs/run_111"210}211}212```213214#### Response — sync (`wait=true`)215216Blocks up to **300 seconds**. Returns `200` when completed, `202` if timed out.217218```json219{220"data": {221"runId": "run_111",222"status": "completed",223"statusUrl": "...",224"result": {225"assistantText": "I added a pricing section with...",226"operations": [227{ "type": "screen_created", "screenId": "scr_xyz", "screenName": "Pricing", "componentId": "cmp_xyz" },228{ "type": "screen_updated", "screenId": "scr_abc", "componentId": "cmp_abc" },229{ "type": "theme_updated" }230]231}232}233}234```235236---237238### Chat — Poll Run Status239240Use this after async send to check progress.241242```http243GET /api/v1/projects/:projectId/chat/runs/:runId244Authorization: Bearer $SLEEK_API_KEY245```246247Response — same shape as send message `data` object:248249```json250{251"data": {252"runId": "run_111",253"status": "queued",254"statusUrl": "..."255}256}257```258259When completed successfully, `result` is present:260261```json262{263"data": {264"runId": "run_111",265"status": "completed",266"statusUrl": "...",267"result": {268"assistantText": "...",269"operations": [...]270}271}272}273```274275When failed, `error` is present:276277```json278{279"data": {280"runId": "run_111",281"status": "failed",282"statusUrl": "...",283"error": { "code": "execution_failed", "message": "..." }284}285}286```287288**Run status lifecycle**: `queued` → `running` → `completed | failed`289290---291292### Screenshots293294Takes a snapshot of one or more rendered components.295296```http297POST /api/v1/screenshots298Authorization: Bearer $SLEEK_API_KEY299Content-Type: application/json300301{302"componentIds": ["cmp_xyz", "cmp_abc"],303"projectId": "proj_abc",304"format": "png",305"scale": 2,306"gap": 40,307"padding": 40,308"background": "transparent"309}310```311312| Field | Default | Notes |313| ------------ | ------------- | --------------------------------------------------------------------- |314| `format` | `png` | `png` or `webp` |315| `scale` | `2` | 1–3 (device pixel ratio) |316| `gap` | `40` | Pixels between components |317| `padding` | `40` | Uniform padding on all sides |318| `paddingX` | _(optional)_ | Horizontal padding; overrides `padding` for left/right when provided |319| `paddingY` | _(optional)_ | Vertical padding; overrides `padding` for top/bottom when provided |320| `paddingTop` | _(optional)_ | Top padding; overrides `paddingY` when provided |321| `paddingRight` | _(optional)_ | Right padding; overrides `paddingX` when provided |322| `paddingBottom` | _(optional)_ | Bottom padding; overrides `paddingY` when provided |323| `paddingLeft` | _(optional)_ | Left padding; overrides `paddingX` when provided |324| `background` | `transparent` | Any CSS color (hex, named, `transparent`) |325| `showDots` | `false` | Overlay a subtle dot grid on the background |326| `radius` | `48` | Squircle corner radius per component in pixels (integer ≥ 0); pass `0` for sharp corners |327328Padding resolves with a cascade: per-side → axis → uniform. For example, `paddingTop` falls back to `paddingY`, which falls back to `padding`. So `{ "padding": 20, "paddingX": 10, "paddingLeft": 5 }` gives top/bottom 20px, right 10px, left 5px.329330When `showDots` is `true`, a dot pattern is drawn over the background color. The dots automatically adapt to the background: dark backgrounds get light dots, light backgrounds get dark dots. This has no effect when `background` is `"transparent"`.331332Always use `"background": "transparent"` unless the user explicitly requests a specific background color.333334Response: raw binary `image/png` or `image/webp` with `Content-Disposition: attachment`.335336---337338## Error Shapes339340```json341{ "code": "UNAUTHORIZED", "message": "..." }342```343344| HTTP | Code | When |345| ---- | ----------------------- | -------------------------------------- |346| 401 | `UNAUTHORIZED` | Missing/invalid/expired API key |347| 403 | `FORBIDDEN` | Valid key, wrong scope or plan |348| 404 | `NOT_FOUND` | Resource doesn't exist |349| 400 | `BAD_REQUEST` | Validation failure |350| 409 | `CONFLICT` | Another run is active for this project |351| 500 | `INTERNAL_SERVER_ERROR` | Server error |352353Chat run-level errors (inside `data.error`):354355| Code | Meaning |356| ------------------ | -------------------------------- |357| `out_of_credits` | Organization has no credits left |358| `execution_failed` | AI execution error |359360---361362## Prompting Sleek363364Sleek has its own AI that plans screen content, visual style, and layout. Pass the user's request to Sleek as-is — don't add details the user didn't ask for. If the user described specific screens and styling, include those. If they just said "build me a running app," send that and let Sleek decide the rest. Sleek produces richer designs when given room to plan, so avoid inventing screen content or layout details that the user didn't specify.365366---367368## Designing369370### 1. Create a project371372Create a project with `POST /api/v1/projects` if one doesn't exist yet. Ask the user for a name, or derive one from the request.373374Each project has its own theme, style, and design system. If the user wants multiple design variations, create a separate project for each variation.375376### 2. Send a chat message377378Describe what to build using `POST /api/v1/projects/:id/chat/messages`. You can use the user's words directly — Sleek's AI interprets natural language. You do not need to decompose the request into screens; send the full intent as a single message and let Sleek decide what screens to create.379380Chat messages are async by default — you get a `runId` and poll for completion with `GET /api/v1/projects/:id/chat/runs/:runId`. You can also use `?wait=true` for a blocking call (up to 300s; falls back to polling if it times out with `202`).381382**Polling**: start at 2s interval, back off to 5s after 10s, give up after 5 minutes.383384**Editing a specific screen**: use `target.screenId` to direct changes to the right screen (uses the screen ID from operations, not the component ID).385386**One run at a time**: only one active run is allowed per project. If you get `409 CONFLICT`, wait for the current run to complete before sending the next message. Messages to different projects can run in parallel — use async polling (not `?wait=true`) when running multiple projects concurrently.387388**Safe retries**: add an `idempotency-key` header (≤255 chars) to replay-safe re-sends. The server returns the existing run rather than creating a duplicate.389390### 3. Show the results391392After every chat run that produces `screen_created` or `screen_updated` operations, **always take screenshots and show them to the user** using `POST /api/v1/screenshots`. Never silently complete a chat run without delivering the visuals.393394- **New screens**: one screenshot per screen + one combined screenshot of all screens in the project.395- **Updated screens**: one screenshot per affected screen.396397Use `background: "transparent"` for all screenshots unless the user explicitly requests otherwise.398399Save screenshots in the project directory (not a temporary folder) so the user can easily view them.400401---402403## Implementing Designs404405When the user wants to implement the designs in code (not just preview them), **always fetch the component HTML code** — do not rely on screenshots alone.406407Use `GET /api/v1/projects/:id/components/:componentId` to fetch each screen's code. The `componentId` comes from the chat run's `result.operations`.408409### HTML prototypes410411The component `code` is a complete HTML document — save it directly to a `.html` file. No build step needed.412413### Native frameworks (React Native, SwiftUI, etc.)414415Use both the HTML code and the screenshots together:416417- **HTML code** is the implementation reference — it contains the exact structure, layout, styling, colors, spacing, content, image URLs, and icon names.418- **Screenshots** are the visual target — use them to verify your implementation matches the intended look.419420The HTML tells you *how* to build it; the screenshot tells you *what* it should look like.421422#### Icons423424Sleek uses [Iconify](https://iconify.design) icons in the format `prefix:name` (e.g., `solar:heart-bold`, `material-symbols:search-rounded`, `lucide:settings`). The most common sets are **Solar**, **Hugeicons**, **Material Symbols** and **MDI**.425426**Use the exact icons from the HTML code** — do not substitute with a different icon set. Matching icons is important for design fidelity.427428When implementing icons:4294301. **Check if the project already has an icon system** that supports the same sets Sleek uses (Solar, Hugeicons, Material Symbols, MDI). If so, use it. Note: `@expo/vector-icons` does **not** support these sets — do not use it as a substitute.4312. **Otherwise, fetch the SVGs from the Iconify API and embed them in the code:**432```433GET https://api.iconify.design/{prefix}/{name}.svg434```435Example: `https://api.iconify.design/solar/heart-bold.svg`436437Collect all icon names from the HTML, fetch their SVGs, and save them as static assets or string constants in the codebase. For **React Native / Expo**, render them with `react-native-svg`'s `SvgXml` component — this works in Expo Go with no additional native dependencies.438439#### Fonts440441The HTML includes Google Fonts via `<link>` tags in the `<head>`. Use the same fonts and weights when implementing in a native framework — extract the font family names and weights from the `<link>` tags.442443#### Navigation444445The designs may include navigation elements like tab bars and headers. Update the project's navigation styling and structure to match the designs — don't just implement the screen content while leaving the default navigation untouched.446447---448449## Pagination450451All list endpoints accept `limit` (1–100, default 50) and `offset` (≥0). The response always includes `pagination.total` so you can page through all results.452453```http454GET /api/v1/projects?limit=10&offset=20455```456457---458459## Tips460461### Saving component HTML to files462463Component code can be large. When saving it to `.html` files, avoid writing the content through your text output — this is slow and wastes tokens. Instead, use shell commands to fetch the API response and write it directly to disk (e.g., pipe the response body into a file). This applies to both single and multiple components.464465---466467## Common Mistakes468469| Mistake | Fix |470| --------------------------------------------------- | ------------------------------------------------------------------------------- |471| Sending to `/api/v1` without `Authorization` header | Add `Authorization: Bearer $SLEEK_API_KEY` to every request |472| Using wrong scope | Check key's scopes match the endpoint (e.g. `chats:write` for sending messages) |473| Sending next message before run completes | Poll until `completed`/`failed` before next send |474| Using `wait=true` on long generations | It blocks 300s max; have a fallback to polling for `202` response |475| HTTP URLs in `imageUrls` | Only HTTPS URLs are accepted |476| Assuming `result` is present on `202` | `result` is absent until status is `completed` |477| Using `screenId` as `componentIds` in screenshots | `screenId` and `componentId` are different; always use `componentId` from operations for screenshots |478