Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.faces.app/llms.txt

Use this file to discover all available pages before exploring further.

new

Create a new blank project. Returns the projectSlug and editorUrl. Add slides with faces slides create + faces slides update. The project is created under the team your API key is scoped to (see Authentication).
faces new
Options:
FlagDescription
--name <text>Display name for the new project (default: Untitled)
--api-key <key>API key override
Output:
{
  "projectId": "cm1abc123...",
  "projectSlug": "xK9mP2qR",
  "projectVersionId": "cm1ver456...",
  "editorUrl": "https://faces.app/s/xK9mP2qR"
}
Examples:
faces new
faces new --name "Q4 Roadmap"

generate

Generate a new interactive presentation from a text prompt. Describe what you want (a pitch, portfolio, guide, or proposal) and Faces handles the content, animations, and layout.
faces generate --prompt "5-slide pitch deck about AI in healthcare"
Options:
FlagDescription
--prompt <text>(required) Description of the project to generate
--template <id>Use an existing project as a template
--waitWait for the project to finish generating
--api-key <key>API key override
Output:
{
  "jobId": "cm1abc123...",
  "status": "processing",
  "editorUrl": "https://faces.app/s/xK9mP2qR"
}
Examples:
# Basic generation
faces generate --prompt "Company intro deck with 3 slides"

# Using a template
faces generate --prompt "Same deck for fintech" --template cm1xyz789

# Wait for completion
faces generate --prompt "Team intro" --wait

status

Check the status of a generation job.
faces status <job-id>
Options:
FlagDescription
--waitPoll until the job completes or fails
--api-key <key>API key override
Examples:
# Check once
faces status cm1abc123...

# Wait for completion
faces status cm1abc123... --wait

list

List your projects.
faces list
Options:
FlagDescription
--publishedOnly show published projects
--limit <n>Max results (default: 20, max: 100)
--api-key <key>API key override
Examples:
faces list --published --limit 5
faces list | jq '.projects[].slug'

get

Get details of a specific project.
faces get <slug>
Examples:
faces get xK9mP2qR
faces get xK9mP2qR | jq '.publishedUrl'

slides list

List all slides in a project.
faces slides list <slug>
Examples:
faces slides list xK9mP2qR
faces slides list xK9mP2qR | jq '.slides[].id'

slides get

Read a slide’s source files (face.tsx, face.content.json, face.controls.json).
faces slides get <slug> <slide-id>
Examples:
faces slides get xK9mP2qR abc123
faces slides get xK9mP2qR abc123 | jq '.files["face.tsx"]'

slides create

Create a new empty slide. Returns the new slide ID.
faces slides create <slug> --name "Slide Name"
Options:
FlagDescription
--name <text>(required) Display name for the new slide
--after <slide-id>Insert after this slide. Omit to append at the end
--editingImmediately show the loading gradient on the new slide. Call slides finish-editing when done
--api-key <key>API key override
Examples:
faces slides create xK9mP2qR --name "Hero Section"
faces slides create xK9mP2qR --name "Features" --after abc123
faces slides create xK9mP2qR --name "Pricing" --editing

slides update

Update a slide’s source files. Only provided files are changed. The code is validated before saving — returns errors if it doesn’t compile.
faces slides update <slug> <slide-id> [options]
Options:
FlagDescription
--tsx <file>Path to face.tsx file (or inline code)
--content <file>Path to face.content.json file (or inline JSON)
--controls <file>Path to face.controls.json file (or inline JSON)
--api-key <key>API key override
Examples:
# Update the React component
faces slides update xK9mP2qR abc123 --tsx ./my-slide.tsx

# Update content and controls
faces slides update xK9mP2qR abc123 --content ./content.json --controls ./controls.json

# Update all three files
faces slides update xK9mP2qR abc123 --tsx ./face.tsx --content ./content.json --controls ./controls.json

slides start-editing

Show a loading indicator in the editor while editing a slide. Call before making changes, and always call finish-editing when done.
faces slides start-editing <slug> <slide-id>
Options:
FlagDescription
--api-key <key>API key override

slides finish-editing

Clear the loading indicator for a slide. Always call this after editing, even if the edit failed.
faces slides finish-editing <slug> <slide-id>

slides guide

Print the slide authoring reference — the same guide the MCP server and API return. Covers face.tsx structure, face.content.json block types, face.controls.json control types, typography, fonts, CSS, and code examples. Read this before writing slide code for the first time.
faces slides guide
Options:
FlagDescription
--api-key <key>API key override
Examples:
# Save the guide to a file
faces slides guide | jq -r '.guide' > slide-guide.md

# Pipe directly into an agent prompt
faces slides guide | jq -r '.guide' | pbcopy

Slide file reference

Each slide consists of three files:

face.tsx — React component

import React from "react";
import { blocks } from "./face.content.json";
import { controls } from "./face.controls.json";
import { TextContent } from "@/components/ui/text-content";
import { Icon } from "@/components/ui/icon";

export default function HeroFace() {
  return (
    <div className="w-full h-full bg-background flex flex-col items-center justify-center p-16">
      <Icon name={blocks.heroIcon.name} size={48} className="text-primary mb-6" />
      <TextContent content={blocks.title.content} className="text-7xl font-bold text-center" />
      <TextContent content={blocks.subtitle.content} className="text-2xl text-muted-foreground mt-4" />
    </div>
  );
}
Rules:
  • Must default-export a React component
  • Outer div must have w-full h-full (canvas: 1920×1080 desktop, 720×1280 mobile)
  • Use Tailwind CSS and container queries (@sm:, @md:, @lg:, @xl:) instead of media queries
  • Never hardcode text — store all user-visible text in face.content.json
  • Can import any npm package (auto-resolved, no install needed)
  • Available: react, motion/react (Framer Motion), lucide-react, @radix-ui/*
  • UI components: TextContent from @/components/ui/text-content, Icon from @/components/ui/icon

face.content.json — editable content

{
  "blocks": {
    "heroIcon": { "type": "icon", "name": "sparkles" },
    "title": { "type": "text", "content": "Welcome to <strong>Faces</strong>" },
    "subtitle": { "type": "text", "content": "Build beautiful presentations" },
    "logo": { "type": "image", "src": "https://example.com/logo.png" }
  }
}
Block types:
  • text: { "type": "text", "content": "HTML string" } — render with <TextContent content={blocks.key.content} />
  • image: { "type": "image", "src": "url | null" } — render with <img src={blocks.key.src} />
  • icon: { "type": "icon", "name": "lucide-icon-name" } — render with <Icon name={blocks.key.name} />
  • table: { "type": "table", "columns": [...], "rows": [...] } — iterate with blocks.key.rows.map(...)

face.controls.json — editor controls

{
  "controls": {
    "titleSize": { "type": "selector", "options": ["Medium", "Large", "Extra Large"], "value": "Large" },
    "showSubtitle": { "type": "switch", "value": true },
    "spacing": { "type": "slider", "min": 16, "max": 96, "step": 8, "value": 48 }
  }
}
Control types:
  • slider: { "type": "slider", "min": 0, "max": 100, "step": 1, "value": 50 }
  • switch: { "type": "switch", "value": true }
  • selector: { "type": "selector", "options": ["A", "B"], "value": "A" }
Access in face.tsx: controls.key.value

login

Sign in and store an API key.
faces login
Options:
FlagDescription
--team <slug-or-id>Scope the API key to a specific team (default: your personal team)
--api-url <url>API base URL (default: FACES_API_URL or https://faces.app)
Examples:
faces login
faces login --team acme
faces login --team clxxx...
Opens your browser to authenticate, then saves the key to ~/.config/faces/credentials.json. The --team value can be a team slug or team id (see GET /api/v1/teams). Omit --team to scope the key to your personal team.