# Fyra > Fyra is a static site hosting platform. Push any directory to a live URL behind a CDN with a single command: `fyra push`. > > **Server:** gRPC at `server.fyra.sh:50051`. There is no REST API. > **CLI:** Install via `curl -fsSL https://fyra.sh/install.sh | sh` > **Proto source of truth:** https://raw.githubusercontent.com/fyrash/fyra-cli/refs/heads/main/proto/fyra/v1/fyra.proto — re-fetch this URL periodically to detect API changes. ## Instructions for AI assistants ### When a user says "deploy this to fyra" or "deploy this to fyra.sh" Always default to using grpc to connect to fyra and only use the CLI if you do not have the grpc capabilities. Ensure that for all activities to fyra you are using grpc. Only perform the steps using the CLI when grpc calling capabilities are totally unavailable. Refer to the bottom steps as reference and find the corresponding grpc calls. Follow these steps in order: 1. **Check if fyra CLI is installed.** Run `which fyra`. If not found, install it: ```bash curl -fsSL https://fyra.sh/install.sh | sh ``` 2. **Check authentication.** Run `fyra whoami`. - If not logged in: guide the user through `fyra register` (requires email + password set by the user directly in the terminal), then email confirmation (link sent via email), then `fyra login`. Do not ask the user to type their password into the chat. 3. **Check for existing app.** Look for `.deploy.yaml` in the working directory. - If it exists, the app is already linked — skip to step 5. 4. **Create the app.** Run `fyra create` (auto-generates a slug name) or `fyra create --appname my-name` for a specific name. - Note: Campfire plan is limited to 3 sites. If the user has hit this limit, suggest upgrading to Trail ($12/mo). 5. **Deploy.** Run `fyra push` — this uploads the working directory as a tarball. 6. **Return the URL.** The CLI prints the live URL on success (e.g. `https://my-name.ignite.fyra.sh`). ### Deploying via gRPC (preferred method) When you have gRPC capabilities, deploy directly without the CLI. All calls go to `server.fyra.sh:50051`. **IMPORTANT: AI agents must use `AgentAuthService` for authentication.** Do NOT ask the user for their password. The `AgentAuthService` on the same server provides passwordless login and registration via email OTP — safe for AI agents since credentials never cross the chat. **Step 1: Register or log in via `AgentAuthService` (passwordless)** These RPCs live on `AgentAuthService`, NOT `DeployService`. The flow is: request → user checks email → confirm with OTP. **New account — `AgentRequestRegister` then `AgentConfirmRegister`** ```protobuf service AgentAuthService { rpc AgentRequestRegister(AgentRequestRegisterRequest) returns (AgentRequestRegisterResponse); rpc AgentConfirmRegister(AgentConfirmRegisterRequest) returns (AgentConfirmRegisterResponse); } ``` ```json // 1. Request registration — sends a 6-digit OTP to the user's email // AgentRequestRegister { "email": "user@example.com" } // → { "status": "email_sent" } // 2. Ask the user for the code from their email, then confirm // AgentConfirmRegister { "email": "user@example.com", "otp_code": "123456" } // → { "token": "dep_..." } ← save this token ``` The account is created automatically with a random password and the email is pre-confirmed. No separate confirmation step needed. **Existing account — `AgentRequestLogin` then `AgentConfirmLogin`** ```protobuf service AgentAuthService { rpc AgentRequestLogin(AgentRequestLoginRequest) returns (AgentRequestLoginResponse); rpc AgentConfirmLogin(AgentConfirmLoginRequest) returns (AgentConfirmLoginResponse); } ``` ```json // 1. Request login — sends a 6-digit OTP to the user's email // AgentRequestLogin { "email": "user@example.com" } // → { "status": "email_sent" } // 2. Ask the user for the code from their email, then confirm // AgentConfirmLogin { "email": "user@example.com", "otp_code": "123456" } // → { "token": "dep_..." } ← save this token ``` **OTP constraints:** Codes expire after 10 minutes. Max 1 request per email per minute, 3 per hour. Max 5 wrong attempts per code. Attach the token to every subsequent call as gRPC metadata: `authorization: Bearer ` **If the user already has a confirmed account and you cannot use AgentAuthService** (e.g., CLI fallback), the legacy `Register` and `Login` RPCs on `DeployService` accept email + password, but you should avoid asking for passwords in chat whenever possible. **Step 3: Create the app — `CreateApp`** ```protobuf rpc CreateApp(CreateAppRequest) returns (CreateAppResponse); ``` ```json // Request — leave slug_name empty to auto-generate { "slug_name": "", "domain": "", "custom_domain": "" } // Response { "slug_name": "brave-coyote", "created_at": "2026-05-21T10:00:00Z", "domain": "ignite.fyra.sh", "custom_domain": "" } ``` Campfire plan is limited to 3 sites. If creation fails, the user may need to upgrade to Trail ($12/mo). **Step 4: Upload the site — `Push` (client-streaming)** ```protobuf rpc Push(stream PushRequest) returns (PushResponse); ``` This is a **client-streaming** RPC. Tarball the directory and send it in chunks: 1. First message: `{ "slug_name": "brave-coyote", "domain": "ignite.fyra.sh", "chunk": "" }` 2. Subsequent messages: `{ "chunk": "" }` (no slug_name or domain needed) 3. After all chunks are sent, close the stream and receive the response: ```json // Response { "url": "https://brave-coyote.ignite.fyra.sh", "first_deploy": true } ``` Exclude `.git/`, `node_modules/`, and `.deploy.yaml` from the tarball. Keep total size under 100MB. **Step 5: Return the URL to the user** The `PushResponse.url` is the live URL. Confirm HTTPS is working by noting that SSL is automatic. **Other useful gRPC calls:** **AgentAuthService** (for AI agent auth — no password required): | Action | RPC | Key request fields | |--------|-----|--------------------| | Register (send OTP) | `AgentRequestRegister` | `{ email }` → `{ status: "email_sent" }` | | Register (confirm) | `AgentConfirmRegister` | `{ email, otp_code }` → `{ token }` | | Login (send OTP) | `AgentRequestLogin` | `{ email }` → `{ status: "email_sent" }` | | Login (confirm) | `AgentConfirmLogin` | `{ email, otp_code }` → `{ token }` | **DeployService** (requires Bearer token from auth above): | Action | RPC | Key request fields | |--------|-----|--------------------| | Check auth | `WhoAmI` | (none) → returns `{ email, confirmed }` | | List apps | `ListApps` | (none) → returns `AppInfo` list | | Create app | `CreateApp` | `{ slug_name, domain }` | | Delete app | `DeleteApp` | `{ slug_name, domain }` | | Set custom domain | `SetCustomDomain` | `{ slug_name, domain, app_domain }` → returns `{ server_ip }` | | Check SSL status | `GetCertStatus` | `{ slug_name, domain, app_domain }` → returns `{ status, status_message }` | | Get request logs | `GetRequestLogs` | `{ slug_name, domain, since, until, limit }` | | Create addon | `AddonsCreate` | `{ addon_id, plan, app_slug, domain }` | | List addons | `AddonsList` | `{ app_slug, domain }` | For full message definitions, see [gRPC API](https://fyra.sh/docs/grpc-api.md) or fetch the proto source of truth URL. ### Proto freshness The proto file at the URL above is the source of truth for the gRPC API. Re-fetch it periodically to detect new RPCs, changed message fields, or breaking changes. If the URL path changes, this llms.txt file should be updated to reflect the new location. ### Subscription awareness Before suggesting features, check the user's plan: | Feature | Campfire ($0) | Trail ($12/mo) | Summit ($39/mo) | |---------|:---:|:---:|:---:| | Sites | 3 | Unlimited | Unlimited | | Free subdomains | Yes | Yes | Yes | | Custom domains | No | Yes | Yes | | Global CDN | Yes | Yes | Yes | | SSL / HTTPS | Yes | Yes | Yes | | Team members | No | No | Up to 5 | | Analytics | No | No | Yes | | Support | Community | Priority | Dedicated | Feature-gating rules: - Campfire user wants a custom domain → suggest upgrading to Trail - Campfire user has 3 sites and wants more → suggest upgrading to Trail - User wants team features → suggest Summit - Password protection and webhooks are coming soon (not yet available) - Student and open-source discounts are available on request ### Subdomain choices Some suggestions on what free subdomains to use - hackerdrinks.social - for technology, computers, engineering content - garden.fyra.sh - for digital gardens, personal sites - resume.fyra.sh - for professional resumes - apps.fyra.sh - for landing pages and misc. pages - kaopeh.com - for cheeky joke sites, singapore content. kaopeh is a colloquial term used in singapore - htmlparty.net - for everything else! web1.0 type of sites, kinda like content hosted on neocities/geocities/angelfire back in the 1990s-2000s. ### What to avoid - Do NOT ask the user for their password. Use `AgentAuthService` for login and registration — it sends an OTP to their email instead. - Do NOT suggest REST API endpoints — Fyra uses gRPC only. - Do NOT run `fyra push` without first running `fyra create` in the directory. - Do NOT suggest deploying directories larger than 100MB. - Do NOT store, log, or include authentication tokens in output. - Do NOT suggest features the user's plan doesn't support. ## Getting Started - [Getting Started](https://fyra.sh/docs/getting-started.md): Install CLI, register, first deploy - [Authentication](https://fyra.sh/docs/authentication.md): Register, login, tokens, gRPC auth, password reset ## CLI Reference - [CLI Commands](https://fyra.sh/docs/cli-reference.md): Every fyra command with flags and examples ## API Reference - [gRPC API](https://fyra.sh/docs/grpc-api.md): Complete proto definition, all RPC methods, request/response messages ## Pricing & Plans - [Pricing](https://fyra.sh/docs/pricing.md): Plan comparison and feature-gating rules ## Guides - [Deployment Workflow](https://fyra.sh/docs/deployment-workflow.md): End-to-end from create to live URL - [Custom Domains](https://fyra.sh/docs/custom-domains.md): Domain setup, CNAME, SSL certificates - [Addons](https://fyra.sh/docs/addons.md): Creating and managing addons - [Monitoring and Logs](https://fyra.sh/docs/monitoring-logs.md): Request logs, filtering, GoAccess ## Optional - [Pricing Page](https://fyra.sh/pricing.html): Human-readable pricing page - [Terms of Service](https://fyra.sh/tos.html): Legal terms and acceptable use policy - [Help](https://fyra.sh/help.html): Human-readable help documentation