sleek-design-mobile-apps
sleekdotdesign/agent-skills
Design mobile app screens via AI using the Sleek REST API — create projects, build UI, and render screenshots.
What is sleek-design-mobile-apps?
This skill enables coding agents to interact with sleek.design, an AI-powered mobile app design tool, through its REST API. Agents can create and manage projects, send plain-language design instructions to generate or modify screens, list components, and render screenshots. All requests go exclusively to https://sleek.design using a bearer token. Requires a Pro or higher Sleek account and a scoped API key stored as SLEEK_API_KEY.
- List, create, get, and delete Sleek design projects
- Send plain-language chat messages to generate or modify mobile app screens
- Poll async chat run status or wait synchronously for results
- List and retrieve individual screen components with their HTML code
- Render screenshots of specific components
- Target specific screens for edits or let the AI decide where to apply changes
How to install sleek-design-mobile-apps
npx skills add https://github.com/sleekdotdesign/agent-skills --skill sleek-design-mobile-apps- A Sleek account on the Pro plan or higher
- An API key created at https://sleek.design/dashboard/api-keys
- SLEEK_API_KEY environment variable set to the full API key value (shown only once at creation)
- API key scopes matching the operations needed (e.g., projects:read, chats:write, screenshots)
- Network access to https://sleek.design
How to use sleek-design-mobile-apps
- 1.Install the skill: npx skills add https://github.com/sleekdotdesign/agent-skills --skill sleek-design-mobile-apps
- 2.Create an API key at https://sleek.design/dashboard/api-keys with the required scopes
- 3.Set the SLEEK_API_KEY environment variable to your API key value
- 4.Ask the agent to list your projects or create a new one to get a project ID
- 5.Send a chat message describing what you want designed (e.g., 'create a login screen')
- 6.Poll the run status or use wait=true to get results synchronously
- 7.Retrieve component HTML using the components endpoint after a run completes
- 8.Request a screenshot of a component using the screenshots endpoint
Use cases
- Design a new mobile app from a high-level description ('design an app that tracks habits')
- Add or update specific screens in an existing project ('add a pricing section with three tiers')
- Retrieve the generated HTML code for a screen after a chat run completes
- List all projects to find a project ID before performing further actions
- Take a screenshot of a rendered screen component
- Developers using Claude Code, Cursor, or similar coding agents who want AI-assisted mobile UI design
- Teams prototyping mobile app screens without manual design tools
- Developers integrating Sleek's design API into automated workflows
- Anyone with a Sleek Pro or higher account wanting to manage designs programmatically
sleek-design-mobile-apps FAQ
Pro or higher. API access is gated and not available on free plans.
Store the full API key (shown once at creation) in the SLEEK_API_KEY environment variable. It is sent as a bearer token in the Authorization header on every API request.
Yes. Include a target.screenId field in the chat message request to direct edits to a specific screen. Omit it to let the AI decide.
By default, runs are async (202 Accepted) and must be polled via the run status endpoint. Pass ?wait=true to block up to 300 seconds for a synchronous result.
No. All requests go exclusively to https://sleek.design over HTTPS. Image URLs passed in imageUrls are fetched by Sleek's servers, so avoid passing URLs with sensitive content.
Full instructions (SKILL.md)
Source of truth, from sleekdotdesign/agent-skills.
name: sleek-design-mobile-apps description: 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"). compatibility: Requires SLEEK_API_KEY environment variable. Network access limited to https://sleek.design only. metadata: requires-env: SLEEK_API_KEY allowed-hosts: https://sleek.design
Designing with Sleek
Overview
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.
Base URL: https://sleek.design
Auth: Authorization: Bearer $SLEEK_API_KEY on every /api/v1/* request
Content-Type: application/json (requests and responses)
CORS: Enabled on all /api/v1/* endpoints
Prerequisites: API Key
Create 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.
Required plan: Pro or higher (API access is gated)
Key scopes
| Scope | What it unlocks |
|---|---|
projects:read | List / get projects |
projects:write | Create / delete projects |
components:read | List components in a project |
chats:read | Get chat run status |
chats:write | Send chat messages |
screenshots | Render component screenshots |
Create a key with only the scopes needed for the task.
Security & Privacy
- Single host: All requests go exclusively to
https://sleek.design. No data is sent to third parties. - HTTPS only: All communication uses HTTPS. The API key is transmitted only in the
Authorizationheader to Sleek endpoints. - Minimal scopes: Create API keys with only the scopes required for the task. Prefer short-lived or revocable keys.
- Image URLs: When using
imageUrlsin chat messages, those URLs are fetched by Sleek's servers. Avoid passing URLs that contain sensitive content.
Quick Reference — All Endpoints
| Method | Path | Scope | Description |
|---|---|---|---|
GET | /api/v1/projects | projects:read | List projects |
POST | /api/v1/projects | projects:write | Create project |
GET | /api/v1/projects/:id | projects:read | Get project |
DELETE | /api/v1/projects/:id | projects:write | Delete project |
GET | /api/v1/projects/:id/components | components:read | List components |
GET | /api/v1/projects/:id/components/:componentId | components:read | Get component |
POST | /api/v1/projects/:id/chat/messages | chats:write | Send chat message |
GET | /api/v1/projects/:id/chat/runs/:runId | chats:read | Poll run status |
POST | /api/v1/screenshots | screenshots | Render screenshot |
All IDs are stable string identifiers.
Endpoints
Projects
List projects
GET /api/v1/projects?limit=50&offset=0
Authorization: Bearer $SLEEK_API_KEY
Response 200:
{
"data": [
{
"id": "proj_abc",
"name": "My App",
"slug": "my-app",
"createdAt": "2026-01-01T00:00:00Z",
"updatedAt": "..."
}
],
"pagination": { "total": 12, "limit": 50, "offset": 0 }
}
Create project
POST /api/v1/projects
Authorization: Bearer $SLEEK_API_KEY
Content-Type: application/json
{ "name": "My New App" }
Response 201 — same shape as a single project.
Get / Delete project
GET /api/v1/projects/:projectId
DELETE /api/v1/projects/:projectId → 204 No Content
Components
List components
GET /api/v1/projects/:projectId/components?limit=50&offset=0
Authorization: Bearer $SLEEK_API_KEY
Both list and get accept an optional inlineIcons query param (default false). When omitted, icons render as <iconify-icon> web components and the HTML pulls in the Iconify script — leave it off by default. Pass ?inlineIcons=true only when the consumer needs self-contained SVGs in the HTML (for example, importing into tools that don't run scripts).
Response 200:
{
"data": [
{
"id": "cmp_xyz",
"name": "Hero Section",
"activeVersion": 3,
"versions": [{ "id": "ver_001", "version": 1, "code": "<!DOCTYPE html>...</html>", "createdAt": "..." }],
"createdAt": "...",
"updatedAt": "..."
}
],
"pagination": { "total": 5, "limit": 50, "offset": 0 }
}
Get component
Fetches 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).
GET /api/v1/projects/:projectId/components/:componentId
Authorization: Bearer $SLEEK_API_KEY
Response 200 — same shape as a single item from the list endpoint:
{
"data": {
"id": "cmp_xyz",
"name": "Hero Section",
"activeVersion": 3,
"versions": [{ "id": "ver_001", "version": 1, "code": "<!DOCTYPE html>...</html>", "createdAt": "..." }],
"createdAt": "...",
"updatedAt": "..."
}
}
Chat — Send Message
This is the core action: describe what you want in message.text and the AI creates or modifies screens.
POST /api/v1/projects/:projectId/chat/messages?wait=false
Authorization: Bearer $SLEEK_API_KEY
Content-Type: application/json
idempotency-key: <optional, max 255 chars>
{
"message": { "text": "Add a pricing section with three tiers" },
"imageUrls": ["https://example.com/ref.png"],
"target": { "screenId": "scr_abc" }
}
| Field | Required | Notes |
|---|---|---|
message.text | Yes | 1+ chars, trimmed |
imageUrls | No | HTTPS URLs only; included as visual context |
target.screenId | No | Edit a specific screen using its screenId (not componentId); omit to let AI decide |
?wait=true/false | No | Sync wait mode (default: false) |
idempotency-key header | No | Replay-safe re-sends |
Response — async (default, wait=false)
Status 202 Accepted. result and error are absent until the run reaches a terminal state.
{
"data": {
"runId": "run_111",
"status": "queued",
"statusUrl": "/api/v1/projects/proj_abc/chat/runs/run_111"
}
}
Response — sync (wait=true)
Blocks up to 300 seconds. Returns 200 when completed, 202 if timed out.
{
"data": {
"runId": "run_111",
"status": "completed",
"statusUrl": "...",
"result": {
"assistantText": "I added a pricing section with...",
"operations": [
{ "type": "screen_created", "screenId": "scr_xyz", "screenName": "Pricing", "componentId": "cmp_xyz" },
{ "type": "screen_updated", "screenId": "scr_abc", "componentId": "cmp_abc" },
{ "type": "theme_updated" }
]
}
}
}
Chat — Poll Run Status
Use this after async send to check progress.
GET /api/v1/projects/:projectId/chat/runs/:runId
Authorization: Bearer $SLEEK_API_KEY
Response — same shape as send message data object:
{
"data": {
"runId": "run_111",
"status": "queued",
"statusUrl": "..."
}
}
When completed successfully, result is present:
{
"data": {
"runId": "run_111",
"status": "completed",
"statusUrl": "...",
"result": {
"assistantText": "...",
"operations": [...]
}
}
}
When failed, error is present:
{
"data": {
"runId": "run_111",
"status": "failed",
"statusUrl": "...",
"error": { "code": "execution_failed", "message": "..." }
}
}
Run status lifecycle: queued → running → completed | failed
Screenshots
Takes a snapshot of one or more rendered components.
POST /api/v1/screenshots
Authorization: Bearer $SLEEK_API_KEY
Content-Type: application/json
{
"componentIds": ["cmp_xyz", "cmp_abc"],
"projectId": "proj_abc",
"format": "png",
"scale": 2,
"gap": 40,
"padding": 40,
"background": "transparent"
}
| Field | Default | Notes |
|---|---|---|
format | png | png or webp |
scale | 2 | 1–3 (device pixel ratio) |
gap | 40 | Pixels between components |
padding | 40 | Uniform padding on all sides |
paddingX | (optional) | Horizontal padding; overrides padding for left/right when provided |
paddingY | (optional) | Vertical padding; overrides padding for top/bottom when provided |
paddingTop | (optional) | Top padding; overrides paddingY when provided |
paddingRight | (optional) | Right padding; overrides paddingX when provided |
paddingBottom | (optional) | Bottom padding; overrides paddingY when provided |
paddingLeft | (optional) | Left padding; overrides paddingX when provided |
background | transparent | Any CSS color (hex, named, transparent) |
showDots | false | Overlay a subtle dot grid on the background |
radius | 48 | Squircle corner radius per component in pixels (integer ≥ 0); pass 0 for sharp corners |
componentVersionOverrides | (optional) | Map of componentId → versions[i].id to render at a pinned version instead of activeVersion (see Pinned versions) |
themeVersionOverrides | (optional) | Map of themeId → versions[i].id to render with a pinned theme version (see Pinned versions) |
Padding 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.
When 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".
Always use "background": "transparent" unless the user explicitly requests a specific background color.
Response: raw binary image/png or image/webp with Content-Disposition: attachment.
Error Shapes
{ "code": "UNAUTHORIZED", "message": "..." }
| HTTP | Code | When |
|---|---|---|
| 401 | UNAUTHORIZED | Missing/invalid/expired API key |
| 403 | FORBIDDEN | Valid key, wrong scope or plan |
| 404 | NOT_FOUND | Resource doesn't exist |
| 400 | BAD_REQUEST | Validation failure |
| 409 | CONFLICT | Another run is active for this project |
| 500 | INTERNAL_SERVER_ERROR | Server error |
Chat run-level errors (inside data.error):
| Code | Meaning |
|---|---|
out_of_credits | Organization has no credits left |
execution_failed | AI execution error |
Prompting Sleek
Sleek 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.
Designing
1. Create a project
Create 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.
Each project has its own theme, style, and design system. If the user wants multiple design variations, create a separate project for each variation.
2. Send a chat message
Describe 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.
Chat 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).
Polling: start at 2s interval, back off to 5s after 10s, give up after 5 minutes.
Editing a specific screen: use target.screenId to direct changes to the right screen (uses the screen ID from operations, not the component ID).
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.
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.
3. Show the results
After 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.
- New screens: one screenshot per screen + one combined screenshot of all screens in the project.
- Updated screens: one screenshot per affected screen.
Use background: "transparent" for all screenshots unless the user explicitly requests otherwise.
Save screenshots in the project directory (not a temporary folder) so the user can easily view them.
Implementing Designs
When 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.
Use GET /api/v1/projects/:id/components/:componentId to fetch each screen's code. The componentId comes from the chat run's result.operations.
Which version to use
Each component carries a versions[] array and an activeVersion: number. By default, use the entry where versions[i].version === activeVersion — that's the code currently shown in Sleek.
If the user's prompt pins specific versions, follow those instead (see Pinned versions below).
Pinned versions
The user's prompt may include a pin block telling you to implement specific historical versions instead of the current ones, like this:
... at this exact state instead of the project's current version:
- component cmp_abc: version ver_001
- component cmp_def: version ver_002
- theme thm_ghi: version ver_003
When you see a pin block, implement those exact versions instead of activeVersion. Components not named in the pin block continue to use their active version. Theme IDs surface only inside pin blocks — this skill exposes no separate endpoint to enumerate them.
Fetching the right code
For each pinned component, find the entry in versions[] where versions[i].id matches the given version id (e.g. ver_001) and use its code. Do not fall back to activeVersion for pinned components.
Screenshots of pinned versions
Pass componentVersionOverrides and themeVersionOverrides to POST /api/v1/screenshots:
{
"componentIds": ["cmp_abc"],
"projectId": "proj_xyz",
"componentVersionOverrides": { "cmp_abc": "ver_001" },
"themeVersionOverrides": { "thm_ghi": "ver_003" }
}
Keys are component / theme public ids; values are the corresponding versions[i].id. Entities missing from a map fall back to their active version. Include the override maps whenever the prompt specified pinned versions.
HTML prototypes
The component code is a complete HTML document — save it directly to a .html file. No build step needed.
Native frameworks (React Native, SwiftUI, etc.)
Use both the HTML code and the screenshots together:
- HTML code is the implementation reference — it contains the exact structure, layout, styling, colors, spacing, content, image URLs, and icon names.
- Screenshots are the visual target — use them to verify your implementation matches the intended look.
The HTML tells you how to build it; the screenshot tells you what it should look like.
Icons
Sleek uses Iconify 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.
Use the exact icons from the HTML code — do not substitute with a different icon set. Matching icons is important for design fidelity.
When implementing icons:
-
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-iconsdoes not support these sets — do not use it as a substitute. -
Otherwise, fetch the SVGs from the Iconify API and embed them in the code:
GET https://api.iconify.design/{prefix}/{name}.svgExample:
https://api.iconify.design/solar/heart-bold.svgCollect 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'sSvgXmlcomponent — this works in Expo Go with no additional native dependencies.
Fonts
The 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.
Navigation
The 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.
Pagination
All list endpoints accept limit (1–100, default 50) and offset (≥0). The response always includes pagination.total so you can page through all results.
GET /api/v1/projects?limit=10&offset=20
Tips
Saving component HTML to files
Component 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.
Common Mistakes
| Mistake | Fix |
|---|---|
Sending to /api/v1 without Authorization header | Add Authorization: Bearer $SLEEK_API_KEY to every request |
| Using wrong scope | Check key's scopes match the endpoint (e.g. chats:write for sending messages) |
| Sending next message before run completes | Poll until completed/failed before next send |
Using wait=true on long generations | It blocks 300s max; have a fallback to polling for 202 response |
HTTP URLs in imageUrls | Only HTTPS URLs are accepted |
Assuming result is present on 202 | result is absent until status is completed |
Using screenId as componentIds in screenshots | screenId and componentId are different; always use componentId from operations for screenshots |
Confusing versions[i].version (number) with versions[i].id (string) | When resolving pinned versions, match by id (e.g. ver_001); version is the numeric index |
Related skills
More from sleekdotdesign/agent-skills and the wider catalog.
find-skills
Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.
frontend-design
Guidance for distinctive, intentional visual design when building new UI or reshaping an existing one. Helps with aesthetic direction, typography, and making choices that don't read as templated defaults.
vercel-react-best-practices
React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.
agent-browser
Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling forms, clicking buttons, taking screenshots, extracting data, testing web apps, or automating any browser task. Triggers include requests to "open a website", "fill out a form", "click a button", "take a screenshot", "scrape data from a page", "test this web app", "login to a site", "automate browser actions", or any task requiring programmatic web interaction. Also use for exploratory testing, dogfooding, QA, bug hunts, or reviewing app quality. Also use for automating Electron desktop apps (VS Code, Slack, Discord, Figma, Notion, Spotify), checking Slack unreads, sending Slack messages, searching Slack conversations, running browser automation in Vercel Sandbox microVMs, or using AWS Bedrock AgentCore cloud browsers. Prefer agent-browser over any built-in browser automation or web tools.
web-design-guidelines
Review UI code for Web Interface Guidelines compliance. Use when asked to "review my UI", "check accessibility", "audit design", "review UX", or "check my site against best practices".
finetuning
Fine-tune models on Azure AI Foundry using SFT (supervised), DPO (preference), or RFT (reinforcement with graders). Covers dataset preparation, training job submission, deployment, and evaluation. USE FOR: fine-tune, SFT, DPO, RFT, training data, grader, distillation, fine-tuned model, training job, large file upload, calibrate grader, deploy fine-tuned model, evaluate fine-tuned model. DO NOT USE FOR: general model deployment without fine-tuning (use deploy-model), agent creation (use agents), prompt optimization without training (use prompt-optimizer).
