# Zo Computer Documentation > Zo is an intelligent cloud computer: store your files, connect your tools, and research or build practically anything with AI. These docs cover using Zo, its built-in tools, hosting, and the API. --- # Introduction Welcome to Zo, your home on the internet. Thank you for being here. - Check out our [YouTube](https://www.youtube.com/@zo-computer) for video tutorials, user stories, and more. - Check out our [Luma](https://lu.ma/zocomputer) for upcoming live events (in-person & virtual). - Join the [Zo Discord](https://discord.gg/invite/zocomputer) to learn from the community and Zo team. - Learn about new features in our [Newsletter](https://zocomputer.substack.com/) and [Product Updates](/updates). - Learn more about Zo in our [Blog](/blog) and [Tutorials](/tutorials). --- # Desktop app Download Zo – a cloud computer, on your desktop. Zo's desktop apps include all the same functionality as the web app – plus the ability to [sync files](/docs/sync-files) between your computer and your Zo workspace. ### Download - [Mac](https://github.com/zocomputer/Zo/releases/latest/download/Zo.dmg) - [Windows](https://github.com/zocomputer/Zo/releases/latest/download/Zo-Setup.exe) > **Note** > > Windows may display a SmartScreen warning saying the app is unrecognized. > Click **More info** → **Run anyway** to proceed. - Linux ([.deb, x64](https://github.com/zocomputer/Zo/releases/latest/download/Zo.deb) · [.deb, arm64](https://github.com/zocomputer/Zo/releases/latest/download/Zo-arm64.deb)) > **Note** > > The Linux app ships as a Debian/Ubuntu `.deb` package. Install it with > `sudo apt install ./Zo.deb` (or your distro's package manager). ### Syncing files The Zo desktop app includes built-in [file syncing](/docs/sync-files). Any folder you choose on your computer will stay in sync with your Zo workspace. ![Sync menu in the Zo desktop app](/docs-assets/screenshots/desktop-add-folder.png) *Adding a folder to sync* --- # Subscription Plans, AI credits, and how billing works Zo's [pricing](/pricing) covers two things: your cloud computer (CPU, memory, storage, services) and the AI you use to drive it. The plan you pick mostly changes how much computer you get and how much built-in AI usage comes with it. > **Tip** > > Not sure which plan fits? The [Zo plan guide](/blog/which-zo-plan-is-right-for-you) walks through who each tier is built for. ## Plans at a glance | Plan | Price | AI credits | Hosted services | Compute | | --------- | ------- | ------------------------------------------------------------ | --------------- | ---------------------------- | | **Free** | $0 | Daily free-model usage; premium models with a payment method | 1 | Limited, sleeps when idle | | **Basic** | $18/mo | $10/mo included | 5 | Always-on, 4 CPU / 32 GB RAM | | **Pro** | $64/mo | $40/mo included | 10 | 16 CPU / 128 GB RAM | | **Ultra** | $200/mo | $100/mo included | 50 | 64 CPU / 512 GB RAM | All plans include 100 GB of cloud storage, access to the [Zo MCP Server](/docs/mcp-server), and [bringing your own API keys](/docs/byok). Monthly paid plans add always-on compute, higher limits, included monthly AI credits, and connections for [coding agents](/docs/claude-code) like Claude Code, Codex, and Gemini. ## Your computer On the [free plan](/pricing): - Your computer goes to sleep when idle. When you start Zo, you may see the boot screen. - You'll get plenty of free storage, but limited CPU, memory, and [hosted services](/docs/services). - Hosted services include public websites and custom self-hosted services. They're not reachable while your computer is asleep. - [Private sites](/docs/sites) on your Space don't count against your service limit. Paid plans keep your computer always-on, so [services](/docs/services), [sites](/docs/sites), and [automations](/docs/automations) stay reachable around the clock. ## Your AI Every plan includes Zo's built-in AI models. Free has two states: - Without a payment method, Free includes a daily usage allowance on the basic models. - With a working payment method, Free stays $0/month and can use premium built-in models on pay as you go. Free resource limits still apply, and the computer can still sleep. Premium built-in AI usage is charged at-cost, using the same rates we pay our underlying AI model providers. Zo uses any applicable free allowance first, then applies AI credits before charging your payment method. Monthly plans include credits up front and higher computer limits, but they are not the only way to use premium models. > **Tip** > > If you already pay for Claude, ChatGPT, or Gemini, you can [bring your own API keys](/docs/byok) on any plan and skip Zo-billed model usage for those providers. ## Changing plans Open **Settings → Billing** to upgrade, downgrade, or cancel. Plan changes take effect immediately, and any unused portion of your current period is prorated. --- # Automations Let Zo do the work while you're not at the keyboard An **automation** is Zo running a prompt on a schedule. Same Zo, same files, same [tools](/docs/tools), same integrations, just running on its own when you're not in the conversation. If you can ask Zo to do something in chat, you can ask it to do that thing every morning, every Friday afternoon, or on any cadence you describe. To create one, just ask Zo: "every weekday at 8am, summarize my calendar and email it to me." Zo reads that as a schedule, writes the prompt, and confirms before saving. You can also open the **Automations** tab and hit `+` to set one up by hand. ## Good fits for an automation The best automations have two things in common: they want fresh context every time they run, and they save you from having to remember to ask. Some patterns that work well: | Pattern | What it does | | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | | **Morning briefings** | A single message that pulls together your day before you open your laptop: calendar, unread email, overnight Slack, custom news. | | **Inbox-to-action triage** | Read incoming messages on a schedule and only ping you for the ones that need attention, with a draft attached. | | **Page watchers** | Check a URL on a schedule and only message you when something has changed: a status page, a stock level, a price, a release. | | **Routine reports** | Query a data file or service, format the result, and post it where it belongs (file, email, Slack channel). | | **Habit nudges** | Text yourself a prompt for the habit you're building, conditionally so the nudge doesn't feel robotic. | | **Follow-up drafts** | Use your calendar and history to draft messages after meetings or events, before they pile up. | Example prompts you can copy and adapt: ```text Morning briefing Every weekday at 7:30am, look at my calendar for today, scan for VIP emails since 5pm yesterday, pull the top three Hacker News threads about AI, and email me a one-page brief. ``` ```text Page watcher Every 15 minutes, check the status page at status.example.com. If anything goes from green, text me the affected services and the start time. ``` ```text Routine report Every Friday at 4pm, query my Stripe export for the week's revenue, generate a one-page report in reports/, and post a three-line summary in #finance on Slack. ``` If you'd write the same prompt in chat more than twice a month, it probably wants to be an automation. ## Schedules Tell Zo when to run in plain English and it'll parse the cadence: - "once, tomorrow at 6pm" - "every weekday at 8am" - "every hour" - "the first Monday of every month at 9am" - "every 15 minutes" (for short polls) You can edit the schedule later from the automation's row in the **Automations** tab, or just ask Zo to change it. ## Delivery and notifications By default, an automation runs quietly and writes its result to chat history. You decide how, and whether, it reaches you: | Delivery | When to use it | | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Email**, **SMS**, **Telegram**, **Discord**, or **Slack** | Active pings you actually want to see. | | **No routine notification** | Jobs that maintain state without routine messages: refresh a data export, save a daily snapshot, index a folder. Zo still emails you if the automation fails. | Often the most useful pattern is **conditional notifications**. Ask Zo to ping you only when something is true, and the automation becomes a filter instead of another inbox: - "Text me only if the deploy failed." - "Email me the digest only if there are unread VIP messages." - "DM me only when the price drops below $400." > **Tip** > > If an automation should run the same multi-step routine every time, capture the steps as a [skill](/docs/skills) and have the automation invoke the skill. That way you can also run it on demand from chat, and the prompt stays in one place. ## Reviewing what ran Every automation run is a real Zo conversation, saved to your chat history. Open the **Automations** tab, click any task, and you'll see each past run, the prompt it executed, the tools it used, and the output. If a run misfires, ask Zo to look at it: "open last night's run of my morning brief and tell me why the calendar section was empty." Zo can debug the run and fix the schedule or the prompt. ## What to keep in mind | | | | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Cost** | Automations spend AI credits the same way chat does. A 5-minute schedule adds up. Use long intervals where you can, and reach for conditional notifications to avoid generating expensive output you'll never read. | | **Access** | Automations run with the same access as your chats: files, messages, every connected integration. Use a [persona](/docs/personas) with a narrow tool set if you want to scope what an automation can do. | --- # Personas Toggle different styles for your AI Personas let you have different characters you can chat with in Zo. Different personas can have different styles or behaviors. You can also give them access to different tools. You can switch between personas at any time, and assign different personas to different channels — so Zo could use one persona in Discord and a different one for SMS. ## Prompt One way to use Personas is to make your AI "roleplay" as a specific archetype or personality. Another way to use Personas is to provide context that you always want Zo to know when working on a particular task. For example: - A "tutor" persona might include background context on what you already know, and what you want to practice. Your prompt can encourage the AI to explain things in a particular way, or quiz you with questions in a particular format. - A "writer" persona might include examples of the style of writing you want to emulate, and other guidelines that help the AI write in a particular way. ## Permissions You can control which tools each Persona is allowed to use. This can be useful for keeping a persona focused — e.g. a research assistant that can search the web but can't modify your files, or a coding persona that works with files and shell but doesn't send messages. You can configure permissions when creating or editing a persona in **Settings → AI → Personas**. ### Permission Presets Most personas work well with a permission preset: | Preset | What it can do | | -------------- | --------------------------------------------------------------------------------------------- | | **All access** | Everything — no restrictions | | **Workspace** | Files, web, media, and read access to settings/hosting/commerce — no shell, no communications | | **Read only** | Read files, search the web, and view settings — can't modify anything | | **Chat only** | Conversation only — no tools at all | You can also choose **Custom** to pick individual scopes. When a persona doesn't have access to a tool, that tool is removed from the conversation entirely. Zo won't try to use it or tell you it failed — it simply isn't available. **Full list of available scopes** When using custom scopes, you can grant access to specific categories: | Scope | Description | | ------------------ | ----------------------------------------------------------- | | `files:read` | Read files and search the workspace | | `files:write` | Create and edit files (requires `files:read`) | | `shell:execute` | Run shell commands | | `web:search` | Search web, images, and maps | | `web:browse` | Open and interact with web pages | | `media:generate` | Generate images, video, and diagrams | | `media:transcribe` | Transcribe audio and video | | `comms:email` | Send emails | | `comms:sms` | Send SMS | | `comms:telegram` | Telegram messages | | `comms:discord` | Discord messages and history | | `comms:slack` | Slack messages | | `settings:read` | View personas, agents, and rules | | `settings:manage` | Edit personas, agents, and rules (requires `settings:read`) | | `hosting:read` | View sites and services | | `hosting:manage` | Manage sites and services (requires `hosting:read`) | | `commerce:read` | View payments and orders | | `commerce:manage` | Manage products and payments (requires `commerce:read`) | | `device:use` | Use connected devices | Integration scopes (e.g. `integrations:gmail`, `integrations:linear`) are also available for each connected app. Some scopes have dependencies — enabling a "write" scope automatically enables its corresponding "read" scope. --- # Messaging channels Use Zo from Discord, Slack, Telegram, SMS, and email You can talk to Zo from Discord, Slack, Telegram, SMS, or email. Zo has the same capabilities everywhere — your full workspace, all your connected integrations, code execution, web search, image generation, everything. Conversations from messaging apps also appear in the zo.computer web app under your conversation history. Connect channels in **Settings > Channels** on zo.computer. ## Commands These commands work across Discord, Slack, Telegram, and SMS: - `/new` — start a new conversation - `/conversations` — list and switch between recent conversations - `/status` — show current conversation info (called `/info` in Slack) - `/model [name]` — show or switch the active AI model - `/persona [name]` — show or switch the active persona - `/help` — show available commands Model and persona choices are saved separately for each messaging app (e.g. your Discord model won't affect your Slack model). ## Conversations Each DM, thread, or group has its own conversation history. - **Discord**: each DM and each channel thread is its own conversation. @mentions in channels auto-create a thread. - **Slack**: each DM and each thread is its own conversation. - **Telegram**: each DM or group chat is its own conversation. - **SMS**: your text thread is a single ongoing conversation. Zo periodically starts a fresh conversation with a summary of the previous one. - **Email**: each email to **yourhandle\@zo.computer** starts a new conversation (find your Zo email address in **Settings > Channels**). Use `/new` to start fresh. Use `/conversations` to switch between recent conversations. ## Groups and channels In group contexts (Discord channels, Slack channels, Telegram groups), Zo works differently than in DMs: - **Zo only responds to you.** Even in a shared channel, Zo runs on your workspace and uses your integrations. Other people in the channel can @mention Zo too, but it runs on their own workspace. - **Zo prefixes its messages** with `[yourhandle.zo.computer]` in group contexts so it's clear which workspace is responding. - **Zo doesn't respond to every message.** It only responds when @mentioned (or replied to, on Telegram). In DMs, Zo responds to everything. - **Zo can see recent context.** On Discord and Slack, recent messages from the channel or thread are included as context above your message. ## Discord DM the Zo bot, @mention Zo in any channel (creates a thread), or use the **/zo** slash command. - @mentions in channels automatically create a thread for the conversation - Discord has a 2000-character message limit — long responses are automatically split ## Slack DM the Zo bot, @mention Zo in any channel or thread, or open the **assistant pane**. - Zo can send file attachments (images, documents) in messages - The assistant pane provides a dedicated sidebar for Zo conversations ## Telegram Message the Zo bot directly, or @mention Zo in group chats (bot must be a group admin). - Zo can send media files (images, documents) in messages ## SMS Text your Zo number directly. - Zo keeps responses under 150 words - Zo can send MMS media (images, files) - Zo can text your registered contacts by name ## Email Email **yourhandle\@zo.computer** to start a conversation. No setup required — your Zo address works out of the box. This is a conversational interface, not an inbox. Emails to your Zo address start conversations; they aren't stored as mail. For reading your inbox or sending as you, connect Gmail or Outlook in **Plugins > Integrations** on zo.computer. --- # Browser use The only way for Zo to act on sites that need you signed in Zo has a real Chromium browser running on your computer. You sign into sites in that browser once, and from then on Zo can act on those sites as you: read your feed, click through your dashboard, post a draft, pull a number out of an admin panel, anything you'd otherwise do yourself. To open it, go to **Settings → Tools** and click **Open Zo's browser**. The browser pops up in its own tab. Navigate, sign in, and close it. The session sticks. ## Why you'd use it The browser is Zo's universal fallback. Most of the time, Zo has a faster, cleaner way to do what you're asking, and you should reach for those first when they exist. The browser is for everything else: services that don't have an integration, don't ship a CLI, don't expose an API, and just live behind a sign-in page on the open web. That's the long tail of the web. Niche SaaS, internal tools, customer portals, partner dashboards, vendor admin panels, anywhere you'd normally open a tab and do it yourself. What the browser unlocks for Zo: | Capability | What it covers | | ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Reach the long tail of services** | The single biggest reason the browser exists. If a tool is too small or too internal to have a Zo integration or a public API, the browser is the only way Zo can use it on your behalf. | | **Read what's behind a sign-in** | Your X feed, your Linear inbox, your private dashboards, your usage analytics, your bank, your CMS drafts. Anything that would 302 a logged-out visitor to a sign-in page. | | **Act as you on a site** | Post a tweet, send a message, publish a draft, change a setting, place an order, mark something done. Any click you'd make, Zo can make. | If you find yourself copy-pasting from a logged-in tab into Zo, that's the moment to give Zo the browser instead. ## When to use it The browser is heavier than Zo's other ways of reaching the web. It loads a real page, runs JavaScript, and uses your session, so it's worth it only when nothing lighter will do. The rough hierarchy: | Reach for | When | | ---------------------------------- | ----------------------------------------------------------------------- | | An integration | Zo has one for the service (Gmail, Linear, Slack, Notion, Stripe, etc.) | | A [skill](/docs/skills) | The work is a known, packaged workflow | | A CLI or API | The service ships a tool Zo can run, or an endpoint it can call | | A [web tool](/docs/tools-overview) | The page is publicly readable (read-webpage, web-search, web-research) | | The browser | None of the above exist for the site you're trying to use | A good rule of thumb: if you could share the URL with someone who isn't signed in and they'd see the same thing, use a [web tool](/docs/tools-overview). If a service has its own integration or CLI, use that. The browser is the answer when you'd otherwise just open the tab yourself. ## Authenticated sites Once you've signed into a site, it shows up in **Settings → Tools** as an authenticated site. That list also tells Zo which sites it has access to as you, so when you ask it to "check my Substack stats" it knows it can. You don't have to mention "browser" in your prompts. Zo picks the browser tool on its own when a request points at a site it's signed into. If you want to be explicit, say "in the browser..." or "open Substack and..." > **Warning** > > The browser keeps live cookies for every site you sign into. Anything Zo can do as you in chat, it can also do as you on those sites: read messages, post, send, buy, change settings. Only sign into accounts you're comfortable having Zo act on. If you want Zo to read a site but not take actions on it, run that work through a [persona](/docs/personas) with a limited tool set. ## How sessions behave Sessions persist the same way they do in your own browser. You sign in once, and Zo stays signed in until the site logs you out, expires the session, or you sign out from inside Zo's browser. | Scenario | What happens | | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Two-factor auth** | You'll go through 2FA the first time you sign in. After that, the session is good until the site challenges you again. | | **Magic links** | If a site emails a sign-in link, open it from inside Zo's browser, not your laptop's, so the session lands in the right place. | | **Multiple accounts** | If you need both a personal and a work account on the same site, sign one of them in through a [persona](/docs/personas) so Zo can keep the contexts separate. | ## When Zo gets stuck Live sites change layout, throw popups, and log you out. A few things that usually unblock Zo: | Symptom | What to do | | ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | | **Layout drift on a familiar page** | Ask Zo to take a screenshot and tell you what it sees. From there you can tell it where to click. | | **Logged out without warning** | Open Zo's browser, sign back in, and ask Zo to retry the original request. | | **2FA prompt mid-task** | Open the browser, complete the prompt, and tell Zo to keep going. It'll pick up where it left off. | | **Site looks different than yours** | Zo's browser is a separate session from a different IP. Some sites serve different layouts. Ask Zo to describe what it sees before you debug further. | --- # Tools Learn about Zo's tools Zo has access to a wide range of tools to operate your computer, connect your apps, and navigate the internet. You can type `@` in the chat to mention a specific tool. You can also refer to these tools loosely by name, e.g. "use your image search tool". Mentioning specific tools can make your prompts more precise and reliable. ## Files - [`Create file`](/docs/tools/write-file) – Create a new file or rewrite an existing one with the provided content. - [`Edit file`](/docs/tools/edit-file) – Edit a text file using a sequence of precise edit operations. - [`Edit file fast`](/docs/tools/edit-file-llm) – Merge a large or fuzzy rewrite into a text file using a fast apply LLM. - [`Read file`](/docs/tools/read-file) – Read a file from the computer. - [`List files`](/docs/tools/list-directory) – Directory listing tool that shows files and subdirectories in a tree structure, helping you explore and understand the project organization. - [`Search files`](/docs/tools/grep-search) – Search files by content or filename using ripgrep. - [`Copy file`](/docs/tools/copy-file) – Copy a file or directory on the computer. - [`Find file conversations`](/docs/tools/find-file-conversations) – Find prior conversations linked to one exact workspace file path. - [`Read file conversation`](/docs/tools/read-file-conversation-context) – Read one indexed turn from a prior conversation linked to a workspace file. - [`Transcribe audio`](/docs/tools/transcribe-audio) – Transcribe an audio file and save the transcript next to the original file. - [`Transcribe video`](/docs/tools/transcribe-video) – Transcribe audio from a video file and save the transcript next to the original file. - [`Generate image`](/docs/tools/generate-image) – Generate an image following the provided prompt using an AI image generation model. - [`Edit image`](/docs/tools/edit-image) – Remix an existing image (or images) using an AI image model. - [`Generate video from image`](/docs/tools/generate-video) – Generate a short, 5 second video from an input image using an AI video generation model. - [`Generate diagram`](/docs/tools/generate-d2-diagram) – Generate a block diagram, using D2. ## Web - [`Read webpage`](/docs/tools/read-webpage) – Read the content of a webpage. - [`Open webpage`](/docs/tools/open-webpage) – Open a webpage in Zo's browser. - [`View webpage`](/docs/tools/view-webpage) – View the current page in the browser and get its content plus a screenshot. - [`Use webpage`](/docs/tools/use-webpage) – Interact with the current page using an AI agent. - [`Save webpage`](/docs/tools/save-webpage) – Save webpage content to the user's Articles directory. - [`Search the web`](/docs/tools/web-search) – Search the web using a search engine. - [`Research the web`](/docs/tools/web-research) – Perform an in-depth web search using a more powerful search engine. - [`Find similar links`](/docs/tools/find-similar-links) – Find web pages similar to a given URL. - [`Search images`](/docs/tools/image-search) – Search for images on the web using a search engine. - [`Search X`](/docs/tools/x-search) – Search X (Twitter) for posts and users matching a query. - [`Search Google Maps`](/docs/tools/maps-search) – Search Google Maps for locations. ## Computer - [`Run command`](/docs/tools/bash) – Run a single shell command on the computer. - [`Create site`](/docs/tools/create-website) – Create a site (also known as an app, or a website). - [`Publish site`](/docs/tools/publish-site) – Publish or republish a Zo Site so it gets a dedicated URL and runs a production build. - [`Unpublish site`](/docs/tools/unpublish-site) – Unpublish a Zo Site, removing its dedicated URL. - [`Create service`](/docs/tools/register-user-service) – Register a managed User Service on your Zo server. - [`List services`](/docs/tools/list-user-services) – List managed User Services running on your Zo server. - [`Diagnose service`](/docs/tools/service-doctor) – Diagnose issues and get details about the status of a user\_service. - [`Update service`](/docs/tools/update-user-service) – Update a managed user service on your Zo server. Only specify the fields you want to change; omitted fields keep their existing values. Always restarts the service process. - [`Delete service`](/docs/tools/delete-user-service) – Delete a managed user service on your Zo server. - [`Proxy local service`](/docs/tools/proxy-local-service) – Proxy a local service to a public endpoint using a TCP tunnel, similar to ngrok. - [`Use device`](/docs/tools/use-device) – Run a command on the user's desktop device via the Zo desktop app. ## Integrations - [`Send Discord message`](/docs/tools/send-discord-message) – Send a message to the user via Discord. - [`Send Slack message`](/docs/tools/send-slack-message) – Send a message to the user via Slack. - [`Get Slack info`](/docs/tools/get-slack-info) – Look up Slack workspaces, channels, and members. - [`Get Slack history`](/docs/tools/get-slack-history) – Get message history from a Slack channel or thread. - [`Get Discord history`](/docs/tools/get-discord-history) – Get message history from a Discord channel, thread, or DM. - [`Get Discord info`](/docs/tools/get-discord-info) – Look up Discord servers, channels, threads, or members. - [`Send email`](/docs/tools/send-email-to-user) – Send an email to the user's email address. - [`Send SMS`](/docs/tools/send-sms-to-user) – Send an SMS text message to the USER or a contact. - [`Send Telegram message`](/docs/tools/send-telegram-message) – Send a message to the user via Telegram. - [`Connect Telegram`](/docs/tools/connect-telegram) – Generate a pairing code to connect the user's Telegram account to Zo. - [`List app tools`](/docs/tools/list-app-tools) – List all available tools and configured props for an app connected by the user. - [`Connect integration`](/docs/tools/connect-integration) – Surface an inline Connect button so the user can authorize an OAuth integration. - [`Search app catalog`](/docs/tools/search-app-catalog) – Search Pipedream's full catalog of 1000+ app integrations by keyword. - [`Use integration`](/docs/tools/use-integration) – Run an action on a connected long-tail Pipedream catalog app. - [`Use Gmail`](/docs/tools/use-app-gmail) – Work with the user's connected Gmail account. - [`Use Google Calendar`](/docs/tools/use-app-google-calendar) – Work with the user's connected Google Calendar account. - [`Use Google Drive`](/docs/tools/use-app-google-drive) – Work with the user's connected Google Drive account (includes Google Docs, Sheets, Slides, and Forms). - [`Use Google Sheets`](/docs/tools/use-app-google-sheets) – Work with the user's connected Google Sheets spreadsheets. - [`Use Google Tasks`](/docs/tools/use-app-google-tasks) – Work with the user's connected Google Tasks account. - [`Use OneDrive`](/docs/tools/use-app-microsoft-onedrive) – Work with the user's connected Microsoft OneDrive account via Pipedream. - [`Use Outlook`](/docs/tools/use-app-microsoft-outlook) – Work with the user's connected Microsoft Outlook account. - [`Use Outlook Calendar`](/docs/tools/use-app-microsoft-outlook-calendar) – Work with the user's connected Microsoft Outlook Calendar account. - [`Use Notion`](/docs/tools/use-app-notion) – Work with the user's connected Notion account. - [`Use Linear`](/docs/tools/use-app-linear) – Work with the user's connected Linear workspace. - [`Use Airtable`](/docs/tools/use-app-airtable) – Work with the user's connected Airtable bases. - [`Use Dropbox`](/docs/tools/use-app-dropbox) – Work with the user's connected Dropbox account via Pipedream. - [`Use Spotify`](/docs/tools/use-app-spotify) – Use a tool to work with the user's connected Spotify account. - [`Use X`](/docs/tools/use-app-x) – Work with the user's connected X (Twitter) account. ## Commerce - [`Create product`](/docs/tools/create-stripe-product) – Create a Stripe product on the user's connected account. - [`Create price`](/docs/tools/create-stripe-price) – Create a new price for an existing Stripe product. - [`Create payment link`](/docs/tools/create-stripe-payment-link) – Create a payment link for an existing Stripe price. - [`List payment links`](/docs/tools/list-stripe-payment-links) – List all payment links for the user. - [`Update payment link`](/docs/tools/update-stripe-payment-link) – Update an existing payment link (activate/deactivate). - [`Update product`](/docs/tools/update-stripe-product) – Update an existing Stripe product's name or description. - [`List orders`](/docs/tools/list-stripe-orders) – List all orders (checkout sessions) for the user. - [`Update orders`](/docs/tools/update-stripe-orders) – Update the fulfillment status of one or more orders. ## Automations - [`Create automation`](/docs/tools/create-automation) – Create an automation to run an AI task on a schedule. - [`List automations`](/docs/tools/list-automations) – List all registered automations. - [`Get automation`](/docs/tools/get-automation) – Get full details of a single automation, including the complete instruction text. - [`Edit automation`](/docs/tools/edit-automation) – Edit an existing automation's title, instruction, schedule, preferred communication channel, or model. - [`Delete automation`](/docs/tools/delete-automation) – Delete an existing automation. ## Personalization - [`Create persona`](/docs/tools/create-persona) – Create a new persona for Zo. - [`List personas`](/docs/tools/list-personas) – List all personas for the user. - [`Edit persona`](/docs/tools/edit-persona) – Edit fields of an existing persona. Heavily biased toward additive, surgical changes — there is no full-replacement option. - [`Delete persona`](/docs/tools/delete-persona) – Delete a persona by ID for the current user. - [`Set active persona`](/docs/tools/set-active-persona) – Set the active persona for the current channel (chat, SMS, email, etc.). - [`List available scopes`](/docs/tools/list-available-scopes) – List all available tool permission scopes, presets, and requirement rules. - [`Set persona scopes`](/docs/tools/set-persona-scopes) – Set which tools a persona is allowed to use. - [`Create rule`](/docs/tools/create-rule) – Create a new user rule for Zo. - [`List rules`](/docs/tools/list-rules) – List all rules for the user. - [`Edit rule`](/docs/tools/edit-rule) – Edit an existing rule. - [`Delete rule`](/docs/tools/delete-rule) – Delete a rule by ID. - [`Update user settings`](/docs/tools/update-user-settings) – Update a user setting (name or bio) in Zo. ## Zo Space - [`Read from space`](/docs/tools/get-space-route) – Get a space route by path, including its source code. - [`Write space route`](/docs/tools/write-space-route) – Create a new route or fully rewrite an existing one in the user's zo.space site. - [`Edit space route`](/docs/tools/edit-space-route) – Edit an existing route's code by supplying only the changed sections. - [`Delete from space`](/docs/tools/delete-space-route) – Delete a route from the user's zo.space site. - [`View space`](/docs/tools/list-space-routes) – List all routes in the user's zo.space site. - [`Undo space change`](/docs/tools/undo-space-route) – Undo the last change to a space route, restoring the previous version. - [`Redo space change`](/docs/tools/redo-space-route) – Redo a previously undone space route change, restoring the next version. - [`View route history`](/docs/tools/get-space-route-history) – View the full version history of a space route. - [`Upload asset to space`](/docs/tools/update-space-asset) – Copy a file from the workspace to the user's zo.space assets. - [`Remove asset from space`](/docs/tools/delete-space-asset) – Delete a static asset from the user's zo.space site. - [`List space assets`](/docs/tools/list-space-assets) – List all uploaded assets in the user's zo.space site. - [`Check space`](/docs/tools/get-space-errors) – Get recent errors from the user's zo.space routes. - [`Restart space`](/docs/tools/restart-space-server) – Clean reinstall dependencies, rebuild, and restart the zo.space server. - [`Get space settings`](/docs/tools/get-space-settings) – Get space settings for the user's zo.space site. - [`Update space settings`](/docs/tools/update-space-settings) – Update space settings — space-globally or for a single page route. --- # Skills Create repeatable AI workflows Zo Computer implements [Agent Skills](https://agentskills.io/), a lightweight, open format for extending AI agent capabilities with specialized knowledge and workflows. ## What are Agent Skills? Agent Skills package domain expertise, new capabilities, and repeatable workflows that agents can use. At its core, a skill is a folder containing a SKILL.md file with metadata and instructions that tell an agent how to perform a specific task. This approach keeps agents fast while giving them access to more context on demand. When a task matches a skill's description, the agent reads the full instructions into context and follows them—optionally loading referenced files or executing bundled code as needed. ### Key benefits - **Self-documenting**: A skill author or user can read a SKILL.md file and understand what it does, making skills easy to audit and improve - **Interoperable**: Skills work across any agent that implements the Agent Skills specification - **Extensible**: Skills can range in complexity from simple text instructions to bundled scripts, templates, and reference materials - **Shareable**: Skills are portable and can be easily shared between projects and developers ## Skill structure Skills are stored in the `Skills` folder within your workspace. You can create a new skill using the `Create Skill` action in the command palette, or by asking Zo to create one for you in the chat. ### How skills work in Zo Computer Skills load progressively so Zo stays fast and only pulls in what it needs for the current task: - Metadata is always available from each skill's frontmatter, so Zo knows what a skill does and when to use it. - When a task matches, Zo reads the full `SKILL.md` instructions and follows them. - If the instructions reference supporting files (templates, examples, guides) or scripts, Zo loads or runs those only when needed. Skills can bundle additional files alongside `SKILL.md`, such as: - Instructions: extra guides or reference docs - Code: scripts Zo can run for deterministic tasks - Resources: templates, examples, or other data files Zo only reads or runs these when the skill instructions explicitly call for them. ### Skill directory layout Each skill lives at `Skills//`, where `` is a lowercase slug that matches the `name` in frontmatter. ``` Skills/ └── your-skill-name/ ├── SKILL.md # required ├── scripts/ # optional executable code ├── references/ # optional reference material └── assets/ # optional data files or templates ``` ### The SKILL.md file `SKILL.md` files can include the following frontmatter fields: - `name`: The name of the skill. - `description`: A description of the skill. - `compatibility`: Optional – environment requirements. - `metadata`: Optional – extra metadata. - `allowed-tools`: Optional – space-delimited list of pre-approved tools. ```md --- name: your-skill-name description: Your skill description --- [Clear guidance for AI to execute the skill] ``` --- # Bring your own LLM API Use your own LLM API provider keys Bring your own API keys to use custom models in Zo. Connect keys from OpenAI-compatible, Anthropic-compatible, or Groq endpoints. ## Quick start 1. Go to **Settings > Advanced** 2. Under **Custom Models**, fill in the form with your provider details 3. Click **+** to save 4. Click **Test** to verify the connection 5. Select your custom model from the model picker in chat ## Supported formats | Format | Description | Example providers | | --------- | ------------------------- | -------------------------------------------------------------------------------------------------------------- | | OpenAI | OpenAI-compatible APIs | [OpenAI](https://platform.openai.com), [OpenRouter](https://openrouter.ai), [Together AI](https://together.ai) | | Anthropic | Anthropic-compatible APIs | [Anthropic](https://console.anthropic.com/docs/en/api/overview) | | Groq | Groq API | [Groq](https://groq.com) | > **Info** > > Zo uses streaming and tools, so make sure your provider and model have support > for both. ## Configuration | Field | Description | | -------- | -------------------------------------------------------- | | Name | Display name shown in the model picker | | Base URL | API endpoint (e.g., `https://api.openai.com/v1`) | | API Key | Your provider API key | | Format | API format: OpenAI, Anthropic, or Groq | | Model ID | The model identifier (e.g., `gpt-4o`, `claude-sonnet-4`) | ## Examples ### OpenRouter - **Base URL**: `https://openrouter.ai/api/v1` - **Format**: OpenAI - **Model ID**: `mistralai/ministral-14b-2512` or any [OpenRouter model](https://openrouter.ai/models) ### Anthropic - **Base URL**: `https://api.anthropic.com` - **Format**: Anthropic - **Model ID**: `claude-haiku-4-5-20251001` ### Groq - **Format**: Groq - **Model ID**: `moonshotai/kimi-k2-instruct-0905` ## Using custom models After adding a custom model, it appears in the model picker in chat. Select it like any other model to use it for your conversations. Custom models don't fall back to Zo's built-in models if they fail — ensure your API key is valid and has sufficient credits. --- # Claude Code Use your Claude Code subscription with Zo [Claude Code](https://code.claude.com/docs/en/overview) is Anthropic's agentic coding tool, included with [Pro and Max plans](https://claude.com/pricing). If you have a subscription, you can use it as an AI provider instead of Zo's built-in credits. ## Setup 1. Open the terminal on your Zo and run `claude` to start the login flow 2. Follow the prompts to authenticate with your Claude account > **Info** > > When copying the authentication URL, it may span multiple lines. Combine them into one line before opening in your browser. 3. Go to **Settings > AI Providers** and enable **Claude Code** 4. Select your preferred model ![Claude Code settings in Zo](/docs-assets/screenshots/claude-code-settings.png) 5. Select "Claude Code" from the model picker in chat and you're set --- # Codex Use your OpenAI Codex subscription with Zo [Codex](https://github.com/openai/codex) is OpenAI's agentic coding tool, included with [Plus and Pro plans](https://chatgpt.com/pricing). If you have a subscription, you can use it as an AI provider instead of Zo's built-in credits. ## Setup 1. Open the terminal on your Zo and run `codex` to start the login flow 2. Select **Sign in with Device Code** ![Codex sign-in screen with Device Code option selected](/docs-assets/screenshots/codex-select-device-code.png) 3. You may need to enable device code authorization first in your ChatGPT account. Go to [**Settings > Security**](https://chatgpt.com/#settings/Security) and toggle on **Enable device code authorization for Codex**. ![ChatGPT security settings showing the device code toggle](/docs-assets/screenshots/codex-enable-device-code.png) 4. Codex will display a URL and a one-time code. Open the URL in your browser and enter the code to complete authentication. ![Codex terminal showing the device code and URL](/docs-assets/screenshots/codex-device-code-screen.png) 5. Go to **Settings > AI Providers** and enable **Codex** 6. Select your preferred model ![Codex settings in Zo](/docs-assets/screenshots/codex-settings.png) 7. Select "Codex" from the model picker in chat and you're set --- # API Access Zo programmatically The Zo API lets you interact with your Zo from scripts, automations, or other apps. Authenticate with an access token from **Settings > Advanced**. ## Quick start 1. Go to **Settings > Advanced** and create an access token 2. Copy it immediately — you won't see it again ```bash curl -X POST https://api.zo.computer/zo/ask \ -H "Authorization: Bearer zo_sk_your_key_here" \ -H "Content-Type: application/json" \ -d '{"input": "Hello, Zo!"}' ``` ```json { "output": "Hello! How can I help you today?", "conversation_id": "conv_abc123" } ``` > **Warning** > > Your API key grants full access to your Zo. Keep it secret and never commit it > to version control. ## API reference Base URL: `https://api.zo.computer` **POST /zo/ask** Send a message to your Zo and get a response. **Request** ```json { "input": "Add 52% to the humidity log", "conversation_id": null, "model_name": null, "persona_id": null, "output_format": null, "stream": false } ``` **input (string, required)** Your message to Zo **conversation\_id (string)** Continue an existing conversation **model\_name (string)** Override the default model (use `/models/available` to list options) **persona\_id (string)** Override the active persona (use `/personas/available` to list options) **output\_format (object)** JSON Schema for structured output **stream (boolean, default: false)** Enable streaming mode. Returns Server-Sent Events (SSE) instead of JSON. **Response** ```json { "output": "Done! Added 52% humidity reading for today.", "conversation_id": "conv_abc123" } ``` **output (string | object)** Zo's response. Returns an object if `output_format` was specified. **conversation\_id (string)** ID to continue this conversation in subsequent requests. **Streaming Response** (when `stream: true`) Returns a Server-Sent Events stream with `Content-Type: text/event-stream`. Each event has the format: ``` event: data: ``` **Event Types:** - `FrontendModelResponse` — Text chunk from the model (`data.content`) - `End` — Stream completed (includes `data.output` if `output_format` was specified) - `Error` — Error occurred (`data.message`) The `x-conversation-id` response header contains the conversation ID for follow-up requests. **GET /models/available** List all available models you can use with the `/zo/ask` endpoint. When authenticated with an API key, includes your BYOK (Bring Your Own Key) configurations. **Response** ```json { "models": [ { "model_name": "byok:3d078e43-1465-4d67-a399-35ef1a8ea1e6", "label": "My Custom Model", "vendor": "Custom", "description": "BYOK: openai format", "type": null, "context_window": null, "is_byok": true }, { "model_name": "anthropic:claude-haiku-4-5-20251001", "label": "Haiku 4.5", "vendor": "Anthropic", "description": "Anthropic's fastest model...", "type": "fast", "context_window": 200000, "is_byok": false } ] } ``` **models (array)** List of available models **models\[].model\_name (string)** The value to pass to `model_name` in `/zo/ask` **models\[].label (string)** Human-readable model name **models\[].vendor (string)** Model provider (e.g., "Anthropic", "OpenAI", "Custom") **models\[].description (string | null)** Short description of the model's capabilities **models\[].type (string | null)** Either "fast" or "capable", indicating the model's speed/capability tradeoff **models\[].context\_window (number | null)** Maximum context window size in tokens **models\[].is\_byok (boolean)** Whether this is a BYOK (Bring Your Own Key) model **GET /personas/available** List all configured personas. Use the returned `id` values with the `persona_id` parameter in `/zo/ask` to override the active persona. **Response** ```json { "personas": [ { "id": "a1b2c3d4", "name": "Technical Writer", "prompt": "You are a concise technical writer...", "model": "anthropic:claude-sonnet-4", "image": null }, { "id": "e5f6g7h8", "name": "Data Analyst", "prompt": "You analyze data and produce insights...", "model": null, "image": "https://static.z.computer/img/persona/649a97ba-c7af-4d63-b401-b0660cd91dd2.png" } ] } ``` **personas (array)** List of configured personas **personas\[].id (string)** The value to pass to `persona_id` in `/zo/ask` **personas\[].name (string)** Display name for the persona **personas\[].prompt (string)** System prompt defining the persona's behavior **personas\[].model (string | null)** AI model ID, or null for system default **personas\[].image (string | null)** Avatar image URL ## Examples ### Continuing a conversation Use the returned `conversation_id` to continue the conversation: ```bash curl -X POST https://api.zo.computer/zo/ask \ -H "Authorization: Bearer zo_sk_your_key_here" \ -H "Content-Type: application/json" \ -d '{"input": "What did I just say?", "conversation_id": "conv_abc123"}' ``` ### Structured output Use `output_format` to get responses as structured JSON. This is based on [OpenAI's Structured Outputs](https://platform.openai.com/docs/guides/structured-outputs). ```bash curl -X POST https://api.zo.computer/zo/ask \ -H "Authorization: Bearer zo_sk_your_key_here" \ -H "Content-Type: application/json" \ -d '{ "input": "List 3 programming languages and their main use cases", "output_format": { "type": "object", "properties": { "languages": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string" }, "use_case": { "type": "string" } }, "required": ["name", "use_case"] } } }, "required": ["languages"] } }' ``` ```json { "output": { "languages": [ { "name": "Python", "use_case": "Data science and automation" }, { "name": "JavaScript", "use_case": "Web development" }, { "name": "Go", "use_case": "Backend services and infrastructure" } ] }, "conversation_id": "conv_abc123" } ``` ### Streaming Use `stream: true` to receive responses as Server-Sent Events: ```python import httpx import json with httpx.stream( "POST", "https://api.zo.computer/zo/ask", headers={ "Authorization": "Bearer zo_sk_your_key_here", "Content-Type": "application/json" }, json={"input": "Tell me a short story", "stream": True} ) as response: conv_id = response.headers.get("x-conversation-id") event_type = None for line in response.iter_lines(): if line.startswith("event: "): event_type = line[7:] elif line.startswith("data: "): data = json.loads(line[6:]) if event_type == "FrontendModelResponse": print(data.get("content", ""), end="", flush=True) elif event_type == "End": print() # Newline at end ``` ### Listing available models ```bash curl https://api.zo.computer/models/available \ -H "Authorization: Bearer zo_sk_your_key_here" ``` ### Listing available personas ```bash curl https://api.zo.computer/personas/available \ -H "Authorization: Bearer zo_sk_your_key_here" ``` --- # MCP server Power up any MCP-compatible AI with Zo's tools and context Use the [Zo MCP Server](/docs/mcp-server) to power up any AI that supports MCP with Zo's tools and context. Zo exposes an [MCP (Model Context Protocol)](https://modelcontextprotocol.io) endpoint, so AI tools like [Claude Code](https://claude.ai/code), [Gemini CLI](https://github.com/google-gemini/gemini-cli), [Codex](https://github.com/openai/codex), or any other MCP-compatible tool can access your Zo directly — your files, your connected apps like Gmail and Google Calendar, and all of Zo's tools. ## Why use Zo as an MCP server? Zo is a full Linux server in the cloud with 50+ tools built in: - **Files & shell** — read, write, search, run commands - **Integrations** — Gmail, Calendar, Notion, Linear, Airtable, Dropbox, Spotify - **Capabilities** — web browsing, image generation, scheduled tasks, texting, emailing - **Fully yours** — root access, persistent storage, install anything you want ## Quick start 1. Go to **Settings > Advanced** and create an access token 2. Copy it immediately - you won't see it again 3. Configure your AI tool using the instructions below > **Warning** > > Your API key grants full access to your Zo. Keep it secret and never commit it > to version control. ## Configuration **Claude Code** [Claude Code](https://docs.anthropic.com/en/docs/claude-code) is Anthropic's CLI tool for Claude. ```bash claude mcp add --transport http zo https://api.zo.computer/mcp \ --header "Authorization: Bearer zo_sk_your_key_here" ``` Or add it manually to `~/.claude/settings.json`: ```json { "mcpServers": { "zo": { "type": "http", "url": "https://api.zo.computer/mcp", "headers": { "Authorization": "Bearer zo_sk_your_key_here" } } } } ``` **Claude Desktop** [Claude Desktop](https://claude.ai/download) is Anthropic's desktop app for Claude. Add to your `claude_desktop_config.json`: ```json { "mcpServers": { "zo": { "command": "npx", "args": [ "mcp-remote@latest", "https://api.zo.computer/mcp", "--header", "Authorization: Bearer zo_sk_your_key_here" ] } } } ``` Config file location: `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows). **Cursor** [Cursor](https://cursor.com) is an AI-powered code editor. Add to your Cursor MCP settings (`~/.cursor/mcp.json`): ```json { "mcpServers": { "zo": { "url": "https://api.zo.computer/mcp", "headers": { "Authorization": "Bearer zo_sk_your_key_here" } } } } ``` **Zed** [Zed](https://zed.dev) is a high-performance code editor. Add to your Zed settings (`~/.config/zed/settings.json`): ```json { "context_servers": { "zo": { "settings": {}, "url": "https://api.zo.computer/mcp", "headers": { "Authorization": "Bearer zo_sk_your_key_here" } } } } ``` **OpenCode** [OpenCode](https://opencode.ai) is an open-source AI coding agent for the terminal. Add to your `opencode.json`: ```json { "mcp": { "zo": { "type": "remote", "url": "https://api.zo.computer/mcp", "headers": { "Authorization": "Bearer zo_sk_your_key_here" } } } } ``` **Gemini CLI** [Gemini CLI](https://geminicli.com/) is Google's command-line tool for Gemini. ```bash gemini mcp add zo https://api.zo.computer/mcp --transport http --scope user \ -H "Authorization: Bearer zo_sk_your_key_here" ``` Or add it manually to `~/.gemini/settings.json`: ```json { "mcpServers": { "zo": { "url": "https://api.zo.computer/mcp", "type": "http", "headers": { "Authorization": "Bearer zo_sk_your_key_here" } } } } ``` **Codex** [Codex](https://github.com/openai/codex) is OpenAI's CLI tool. ```bash codex mcp add zo -- npx -y mcp-remote https://api.zo.computer/mcp \ --header "Authorization:Bearer zo_sk_your_key_here" --transport http-only ``` Or add it manually to `~/.codex/config.toml`: ```toml [mcp_servers.zo] command = "npx" args = ["-y", "mcp-remote", "https://api.zo.computer/mcp", "--header", "Authorization:Bearer zo_sk_your_key_here", "--transport", "http-only"] ``` **Other MCP clients** Zo's MCP endpoint uses standard HTTP transport. For any MCP-compatible client, use: | Setting | Value | | ----------- | ------------------------------------------- | | Transport | HTTP | | URL | `https://api.zo.computer/mcp` | | Auth Header | `Authorization: Bearer zo_sk_your_key_here` | If your client only supports stdio transport (not HTTP), you can use [mcp-remote](https://www.npmjs.com/package/mcp-remote) as a bridge. Configure your client to run this command: ```bash npx -y mcp-remote https://api.zo.computer/mcp --header "Authorization:Bearer zo_sk_your_key_here" --transport http-only ``` For example, in a JSON config that expects `command` and `args`: ```json { "command": "npx", "args": ["-y", "mcp-remote", "https://api.zo.computer/mcp", "--header", "Authorization:Bearer zo_sk_your_key_here", "--transport", "http-only"] } ``` ## Available tools All [Zo tools](/docs/tools-overview) are exposed via MCP with identical capabilities: [**File Operations**](/docs/tools/read-file) Read, write, edit files on your Zo computer [**Bash Commands**](/docs/tools/bash) Execute shell commands [**Web Browsing**](/docs/tools/read-webpage) Search the web, read pages, take screenshots [**Image Generation**](/docs/tools/generate-image) Generate and edit images with AI --- # Hosting on Zo Pick between Space, Sites, Services, and zo.pub Your Zo is a personal server, so there's more than one way to put things online from it. Each option is built for a different kind of thing. This page is the map. ## At a glance | You want to... | Use | URL pattern | | -------------------------------------------------------------- | -------------------------- | ------------------------------------------------------- | | Add a page, API, or widget at a single stable domain | [Space](/docs/spaces) | `yourhandle.zo.space` | | Build a full website project that lives in a folder on your Zo | [Sites](/docs/sites) | `sitename-yourhandle.zocomputer.io` | | Run a long-running program (server, database, bot, worker) | [Services](/docs/services) | `*.zocomputer.io` (public) or `*.zo.computer` (private) | | Share a folder of files with a link | [zo.pub](/docs/zo-pub) | `zo.pub//...` | ## Space Every Zo user gets one personal domain at `yourhandle.zo.space`. Space is for quick, focused creations that live at a stable URL: a landing page, a tip calculator, a webhook endpoint, a small React widget. There's no project to set up. Just ask Zo to "make my zo.space home page a personal landing page" or "create an API at /api/data on my zo.space" and it's live. Pages on your Space are private by default (only you can see them when logged in), but you can make them public. APIs are always public, and uploaded assets are always publicly accessible. > **Tip** > > Reach for Space when you have one small thing in mind and you don't want to think about folders, frameworks, or deploys. ## Sites A Site is a full website project that lives as a folder on your Zo. It's built on [Hono](https://hono.dev) and [Bun](https://bun.sh), and if you ask for a database it'll use [SQLite](https://www.sqlite.org) by default. Because the site lives on your personal server, it can read and write files in your workspace, save form responses to a database next to your other files, and pull in any folder you mention while chatting with Zo. Sites are private by default. Only you can open the URL while signed in to your Zo. When you click **Publish**, the site becomes a public [service](/docs/services) at `sitename-yourhandle.zocomputer.io`. > **Tip** > > Reach for Sites when you want a real project you'll keep evolving, or when the site needs to integrate with your files, your AI, or a database. ## Services A service is a long-running process on your Zo: any program that listens on a port or runs in the background. Services give you the most flexibility, because you can run anything Sites doesn't cover, in any technology you want. To set one up, you only need a port, an entrypoint, and a working directory. Open the **Sites** page and go to the **Services** tab to see what's running. Services have three modes: - **`http`** is a web service. It's public by default at `*.zocomputer.io` with no auth. You can also set it private, in which case it lives at `*.zo.computer` and requires you to sign in. - **`tcp`** is a non-HTTP service exposed at a host and port. TCP services are always public. - **`process`** is a supervised background process with no public endpoint. Use it for workers, schedulers, bots, sync loops, or internal-only services bound to localhost (like a Postgres on `127.0.0.1`). Process services don't count toward your hosted-service limit. You can also point a [custom domain](/docs/custom-domains) at any public service or published site. > **Tip** > > Reach for Services when you need a custom server, a database engine, a long-running worker, or anything where you care about the runtime, not just the code. ## zo.pub `zo.pub/` is your public namespace for sharing files. Ask Zo to "publish this folder to zo.pub" and you'll get back a link anyone can open. Visitors don't need a Zo account; they land on a clean listing page and can browse the folder, click any file to view or download it, and grab the whole folder as a zip or tar archive. zo.pub is for sharing, not for running. There's no private mode and no password protection. Anything you publish is fully public. > **Warning** > > Good things to publish to zo.pub: photos, data exports, portfolio PDFs, meeting recordings, static reports, anything you'd otherwise email as a download link. If you need code, auth, or per-user logic, use [Sites](/docs/sites) or [Services](/docs/services) instead. ## Quick decision rule - One page, one API, or one small widget, use [Space](/docs/spaces). - A website project you'll keep building on, use [Sites](/docs/sites). - A long-running custom process, a database, or anything Sites doesn't cover, register a [Service](/docs/services). - A folder of files for someone to download, publish to [zo.pub](/docs/zo-pub). If you want a branded URL on top of any public site or service, attach a [custom domain](/docs/custom-domains). --- # Space Your personal domain at yourhandle.zo.space Every Zo user gets their own personal domain at `yourhandle.zo.space`. This is a lightweight but powerful way to put things on the internet — pages, APIs, and interactive experiences that live at a stable URL. ## What is Zo Space? Zo Space is a streamlined way to create web content without setting up a full project. While [Sites](/docs/sites) are great for building complete, isolated web applications, Zo Space is designed for quick, focused creations — just ask Zo and it's live. If you're not sure which option to pick, the [hosting overview](/docs/hosting) compares Space, Sites, Services, and zo.pub side by side. ## What can you build? **Landing pages** — A personal page with your bio, links, and social profiles. Always available at your handle. **One-off widgets** — Quick interactive tools like calculators, converters, or dashboards. Build something useful in minutes. **API endpoints** — Stable URLs for webhooks, integrations, or data services. Perfect for connecting external services to your Zo. **Mini-apps** — Small React applications with state and interactivity, without the overhead of a full site project. ## Getting started Just ask Zo to create something on your space: - "Make my zo.space home page a landing page with my name and links" - "Create an API at /api/data on my zo.space that returns JSON" - "Build a tip calculator widget on my zo.space" Zo handles the rest — writing the code, deploying it, and making it available at your URL. To view and manage your Space, open the **Sites** page in your Zo and go to the **Space** tab. ## Pages and APIs Zo Space supports two types of routes: **Pages** are React components rendered as full pages. They can be interactive with state, styled with Tailwind CSS, and include icons from Lucide. Pages are private by default (only you can see them when logged in), but you can make them public. **APIs** are backend endpoints that return data. They're always public and can handle webhooks, serve JSON, or integrate with external services. ## Assets To use images or files in your space, ask Zo to upload them as assets. Once uploaded, you can reference them in your pages. Assets are always publicly accessible. --- # Sites Create websites hosted on your Zo server Zo comes with a built-in way to create sites hosted on your Zo server. These sites can be personal apps just for you, or public sites for anyone to access. Sites are one of a few [hosting options](/docs/hosting) on your Zo, alongside [Space](/docs/spaces), [Services](/docs/services), and [zo.pub](/docs/zo-pub). All sites can integrate with the files in your workspace. And your personal apps can even integrate with your AI. To view and manage your sites, open the **Sites** page in your Zo. To get started creating a new site, select **Create site**, and Zo will create a new website template for you in a new folder with the lightning icon . When you select the site's folder, you'll see a preview of the site. Because your site is hosted on your **personal server** along with your other files, you can easily incorporate files from your workspace into your site. This means you can do things like: - Save responses from a form to a database in your workspace. - Integrate any file or folder from your workspace into your site. All you have to do is mention the files or folders you want to incorporate as you chat with Zo. You will get a URL to access your site that looks like this: `sitename-yourhandle.zocomputer.io` > **Tip** > > Zo sites are **private by default**. Only you can access the URL when you're > logged in to your Zo Computer account. To make your site public, click > "Publish". You can think of a private Zo site as an **app just for you**. You can ask Zo to create **any interface you want for your computer**. You can create as many private Zo sites as you want. When you publish a site, this creates a public [service](/docs/services) running on your Zo. ## Learn more You don't have to know how to code to create websites, because Zo can write the code for you. But knowing a bit about what's going on behind the scenes can help you have more productive conversations with Zo. > **Info** > > The built-in site tool is our recommended way to create websites on your Zo. > But of course, you can use [services](/docs/services) to run anything on your Zo, > using any technology you want. Websites have two sides, the **backend** and the **frontend**. - The **backend**, also called the **server**, is the part of your site that runs on your server. - The **frontend**, also called the **client**, is the part of your site that runs in the browser. - Your backend delivers your site's frontend code to the user's browser, and the browser runs your frontend. Zo creates a simple but powerful website template for you using [Hono](https://hono.dev), a popular minimal **web application framework**. **What is a web application framework?** A **web application framework** is a collection of building blocks that make it easy to build rich, interactive web experiences. The building blocks include: - A way to communicate between your frontend and backend, called an **internal API**. An API is a language for exchanging data between two systems. - A way to handle multiple pages on your site, called **routes**. The framework's **router** is responsible for matching incoming requests to the appropriate page. **What are the code files inside my site?** #### Main files These are the main files that you should look at if you're curious about how your site works. - `CLAUDE` – Documentation used by the Zo coding agent when it works on your site. You can edit this file to provide additional guidance to the coding agent. - `index.tsx` – The main code file for your site. This includes both the frontend and backend of your site. For simple sites, Zo will write all the code in a single file. - `package.json` – The software packages that your site's backend uses are listed here. > **Info** > > As your site grows, Zo may create additional code files for the different > components of your site. For example, separating the frontend and backend code > may help make your site easier for Zo to maintain. #### System files You can ignore these files – Zo will take care of them for you. - `zosite.json` – Settings for how your site is hosted on your Zo server. configures your - `tsconfig.json` – Your site uses the TypeScript programming language, and this file site's TypeScript settings. - `.gitignore` – Used to ignore files that should not be tracked in version history. - `bun.lock` – Used to "lock" the versions of software packages used in your site. **What else should I know about my site?** - [Hono](https://hono.dev) is the **web server**. When we call Hono a "server", it's not the same as a "computer server" – it's the the program that handles requests to your site. - [Bun](https://bun.sh) is the **runtime**, which is the environment that runs your web server's code. - Bun is also the **package manager**. As you add more functionality to your site's backend server, Zo may use Bun to install additional software packages. ## What if I want a database? If you ask Zo to create a database for your site, it will use [SQLite](https://www.sqlite.org) by default. SQLite is a good default choice for your database because it's performant and lightweight – your database is **just a file**. > **Info** > > SQLite is our recommended choice for your site's database. But of course, you can use [services](/docs/services) to run any > database you want on your Zo server. > > You can also ask Zo to point your site to an externally hosted database service, such as [Convex > or Supabase](https://www.convex.dev/compare/supabase). **How do I explore my SQLite database?** When you click on your database file (ends with `.db`), you'll see Zo's built-in SQLite explorer. If you want to explore what's in your database or change the shape of your data, just ask Zo. **How does my site connect to SQLite?** When your site's backend connects to your SQLite database, it will use Bun's built-in [SQLite driver](https://bun.com/docs/api/sqlite). ## External building blocks There is a huge amount of high-quality **open-source software packages** that developers have built over the last two decades. As you build your site, you may see Zo installing new open-source software packages to extend the functionality of your site. > **Tip** > > A **package** is a bundle of code published on the internet that can be > installed into your own code project. There are also many complete > **open-source software applications**, which you can ask Zo to help you > install and set up to run on your Zo server. Sometimes, you'll want to extend your site's functionality using **external software services**. **What is Software as a Service (SaaS)?** During the [Software as a Service (SaaS)](https://en.wikipedia.org/wiki/Software_as_a_service) boom of the 2010s, many companies began offering building blocks for application features like payments (Stripe), communications (Twilio), and much more. These services usually offer a generous free tier that is sufficient for most projects. > **Info** > > When you integrate a new external API, your site's **backend** is responsible > for connecting to the API. You may need to provide the necessary credentials > to Zo to access the API. Zo should be able to walk you through the process. --- [**Services**](/docs/services) Want to run your own servers, APIs, databases, or any long-running process? Learn about **services** on your Zo server. --- # Services Run any long-running program on your Zo A **service** is a long-running program on your Zo: a custom web server, a database for your other services to talk to, a Discord bot, a sync loop, or any process you want kept running in the background. Services are the most flexible [hosting option](/docs/hosting) on your Zo. They run inside your Zo's Linux sandbox, so anything that runs on Linux can run here (with some exceptions). To set up or manage a service, just ask Zo. You can also open the **Sites** page and go to the **Services** tab to see what's running. > **Tip** > > Not sure which mode or hosting option fits your use case? Just ask Zo. Describe what you're trying to run and Zo can recommend the best fit. ## Why register a service? You can always start a process by hand in a terminal, but your Zo restarts periodically to pick up updates and snapshots, and that happens even on paid plans. A process you started yourself won't come back after a restart. When you register a service, Zo brings it back up automatically with the same config every time your Zo starts. That's the difference between something that runs and something that stays running. ## What people run as services A few examples of what fits well as a service: - A custom backend in Node, Python, Go, Ruby, Rust, or anything else that runs on Linux - A database like Postgres or Redis that another service on your Zo talks to - A Discord or Telegram bot - A scheduled worker or background sync loop - A WebSocket server If you only need a quick page or API, [Space](/docs/spaces) is simpler. If you want a full website project that integrates with your workspace files, [Sites](/docs/sites) is the better fit. ## The three modes Every service runs in one of three modes. The mode determines whether the service has a public endpoint and how traffic reaches it. ### `http` A web service. Public by default at `*.zocomputer.io` with no built-in auth. Use this for any HTTP server, API, or website. You can also set an HTTP service to **private**, in which case it lives at `*.zo.computer` and requires you to sign in. ### `tcp` A non-HTTP service exposed at a public host and port. Use this for things that don't speak HTTP, like a custom socket protocol, a game server, or an MQTT broker. > **Warning** > > TCP services are always public, with no auth in front of them. Anything you put behind a TCP service should handle its own authentication. Don't expose a database directly over TCP unless it has strong auth turned on. ### `process` A managed background process with no public endpoint. Zo starts it, keeps it running, and restarts it if you change its config. Use this for anything that doesn't need to be reached from outside your Zo: a worker, a scheduler, a bot, a sync loop, or an internal-only service bound to localhost (like a Postgres on `127.0.0.1` that your HTTP service connects to). > **Tip** > > Process services don't count toward your hosted-service limits, so reach for this mode whenever a public endpoint isn't needed. ## Settings When you set up a service, Zo only needs a handful of settings: | Setting | What it is | | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Label | A unique name for the service (lowercase and hyphens), e.g. `my-web-app`. | | Mode | `http`, `tcp`, or `process`. | | Local port | The port your service listens on. Required for `http` and `tcp`. Zo injects this as the `PORT` env var. | | Entrypoint | The command to start your service, e.g. `bun run start` or `python3 app.py`. Optional. If omitted, Zo manages only the tunnel and you're responsible for starting the process yourself. | | Working directory | The folder where the entrypoint runs. Defaults to `/home/workspace`. | | Environment variables | Any extra config your service needs. | A handful of port numbers are reserved for system use; if you pick one, Zo will let you know. ## URLs When you create a public HTTP service, you get **two** URLs: - The **HTTP Proxy URL** is the right pick for most web services like APIs and websites. - The **Direct Tunnel URL** is for non-web traffic, or as a fallback if the HTTP Proxy URL doesn't behave as expected. TCP services get a Direct Tunnel URL with a public host and port. Process services get no public URL. ## Custom domains You can attach a [custom domain](/docs/custom-domains) to any public service, so your URL looks like `app.example.com` instead of `myapp-yourhandle.zocomputer.io`. Custom domains are available on paid plans. ## Status and troubleshooting Open the **Services** tab on the **Sites** page to see what's running. If something's stuck or crashing, ask Zo to take a look. It can diagnose the service, fix the underlying issue, and restart it for you. ## Where Services fit If a [Site](/docs/sites) or [Space](/docs/spaces) covers what you need, those are simpler choices. Reach for Services when you want full control over the runtime, or when you need something Sites and Space don't offer: a database, a bot, a custom protocol, or a long-running worker. --- # zo.pub Publish a folder to your public namespace and share a link Every Zo comes with a public namespace at `zo.pub/`. Ask Zo to publish a folder from your workspace and you'll get a link anyone can open to browse and download the files. > **Info** > > zo.pub is for sharing files, not for running web apps. If you want to build > a website or a custom app, use [Sites](/docs/sites) instead. ## Publish a folder Just ask Zo. A few phrasings that work: - `Publish this folder to zo.pub` - `Give me a link to share these files` - `Make this folder public` > **Tip** > > When Zo is done publishing, it will reply with the `zo.pub/...` URL. Copy it > and send it to whoever needs it. ## What people see when they open the link Visitors don't need a Zo account. They land on a clean listing page with the files in your folder — name, size, date — and can click any file to view or download it. Subfolders are browsable. The whole folder can also be downloaded as a single zip or tar archive. ![A zo.pub collection listing](/docs-assets/screenshots/zo-pub-collection.png) *A published zo.pub folder* ## Your public page `zo.pub/` lists every folder you've published, with a quick summary of each. Anyone with your handle can bookmark this page to see what you're sharing. ![A zo.pub profile page](/docs-assets/screenshots/zo-pub-profile.png) *Your zo.pub profile lists everything you've published* ## URLs | URL | What it shows | | -------------------------------------- | ----------------------------- | | `zo.pub/` | Every folder you've published | | `zo.pub//` | One folder's files | | `zo.pub///` | A single file | ## Updating or removing a folder Ask Zo to update or take it down: - `Update my vacation folder on zo.pub` - `Republish this folder — I added new files` - `Take down the folder I published called "drafts"` Updates replace the contents of the folder at the same URL, so the link you already shared keeps working. ## What zo.pub isn't > **Warning** > > Anything you publish to zo.pub is **public**. There's no private mode and no > password protection. Anyone with the link can open the folder and download > the files. > > If you need per-user access, logins, or custom logic, use [Sites](/docs/sites) or > set up a [custom domain](/docs/custom-domains) with your own auth. Good things to publish: photos, data exports, portfolio PDFs, meeting recordings, static reports, anything you'd otherwise email as a download link. Anything you wouldn't want strangers to see should stay in your Files workspace. --- # Custom domains Use your own domain for public sites and services You can connect your own domain (like `blog.example.com`) to any public site or service running on your Zo. This gives your projects a professional, branded URL instead of the default `yoursite-handle.zocomputer.io`. > **Info** > > Custom domains are available on paid plans. See [pricing](/pricing) for plan limits. ## How it works When you add a custom domain, we: 1. Register your domain with Cloudflare's edge network 2. Automatically provision and manage a TLS certificate for HTTPS 3. Route all traffic from your domain to your service The entire process typically completes within 15 minutes after you've configured your DNS. ## Adding a custom domain 1. **Open Services** Navigate to **Sites** → **Services** in your Zo and find the service you want to add a domain to. 2. **Add domain** Click on the service to open its details panel, then click **Add** in the Custom Domains section. Enter your domain (e.g., `blog.example.com`). 3. **Configure DNS** Add a CNAME record in your domain's DNS settings: | Type | Name | Target | | ----- | ------------------------------ | --------------------- | | CNAME | `blog` (or `@` for subdomains) | `cname.zocomputer.io` | > **Tip** > > If you're using Cloudflare for your domain, set the proxy status to **DNS only** (gray cloud icon) when adding the CNAME record. 4. **Wait for verification** Once your CNAME is configured, Zo will automatically detect it and provision your TLS certificate. This usually takes 1-15 minutes. ## Domain status Your custom domain goes through these states: | Status | Description | | ------------- | ------------------------------------------------- | | Pending CNAME | Waiting for you to add the CNAME record | | Pending SSL | CNAME verified, TLS certificate being provisioned | | Active | Domain is live and serving traffic | | Error | Something went wrong (check DNS configuration) | You can click **Verify now** to manually trigger a verification check. ## Limitations - **Subdomains only**: You must use a subdomain like `blog.example.com` or `app.example.com`. Apex domains (like `example.com`) are not supported because they cannot have CNAME records. - **Plan limits**: The number of custom domains you can add depends on your plan: | Plan | Custom Domains | | ----- | -------------- | | Free | 0 | | Basic | 3 | | Pro | 5 | | Ultra | 10 | - **One domain per service**: Each custom domain can only point to one service at a time. You can transfer a domain to a different service without re-verification. ## Troubleshooting **Domain stuck on 'Pending CNAME'** DNS changes can take time to propagate. Wait a few minutes and click **Verify now**. You can also check your CNAME record using a DNS lookup tool: ```bash dig CNAME blog.example.com ``` The result should show `cname.zocomputer.io` as the target. **Domain stuck on 'Pending SSL'** TLS certificate provisioning typically takes 1-15 minutes. If it's been longer than an hour, check: 1. **CAA records**: If your domain has CAA DNS records, ensure they allow `digicert.com` and `letsencrypt.org`. 2. **Conflicting proxies**: If your domain is already proxied through another Cloudflare zone, you may need to disable that proxy first. **SSL certificate errors in browser** If you see certificate warnings after the domain shows as Active: 1. Wait a few more minutes for certificate propagation 2. Try a hard refresh (Cmd+Shift+R or Ctrl+Shift+R) 3. Try an incognito/private browser window **Domain was working but now shows errors** If your domain stops working: 1. Verify the CNAME record is still configured correctly 2. Check that your service is still running 3. Remove and re-add the domain if the issue persists ## Removing a custom domain To remove a custom domain, expand the service details, find the domain in the Custom Domains section, and click the delete button. The domain will be immediately removed and traffic will stop routing to your service. > **Warning** > > If you delete a service, all custom domains attached to it are automatically removed. --- # Sync files How to sync files from another computer to your Zo The Zo desktop app includes built-in file syncing. Any folder you choose on your computer will stay in sync with your Zo workspace. ## Using the desktop app 1. Download and install the Zo desktop app for [Mac](https://github.com/zocomputer/Zo/releases/latest/download/Zo.dmg) or [Windows](https://github.com/zocomputer/Zo/releases/latest/download/Zo-Setup.exe) 2. Open the app and sign in to your Zo account 3. Click **Sync > Add Folder** in the menu bar (or press ⇧⌘A on Mac) 4. Choose a folder on your computer to sync with your Zo workspace ![Sync menu in the Zo desktop app](/docs-assets/screenshots/desktop-add-folder.png) *Adding a folder to sync* Changes made on either side will automatically sync to the other. --- # Connect GitHub How to connect your GitHub account to Zo [GitHub](https://github.com) is a popular service for hosting and collaborating on software projects. The [GitHub CLI](https://docs.github.com/en/github-cli/github-cli/quickstart) comes pre-installed on your Zo and is the easiest way to connect to GitHub. ## 1. Create a new personal access token To authenticate the GitHub CLI, first [Create a new personal access token (classic)](https://github.com/settings/tokens/new). You must select `repo`, `read:org`, and `gist` (and can select additional permissions if you need these on your Zo). ![GitHub personal access token scopes](/docs-assets/screenshots/github-scopes.png) *Personal access token scopes* Reference: [`gh auth login`](https://cli.github.com/manual/gh_auth_login). ## 2. Authenticate the GitHub CLI After creating your personal access token, authenticate the GitHub CLI by running the following command in your Zo application's terminal: ```bash gh auth login --with-token ``` That's it! You (and your Zo) can now use the GitHub CLI to work with your code and automations on GitHub. To learn more about what the GitHub CLI can do, check out the [manual](https://cli.github.com/manual/). --- # Connect to your server How to use your Zo as a remote development environment You can access your Zo Computer using our built-in [ways to interact with Zo](/docs), but sometimes it's useful to connect to your Zo server directly. This guide will walk you through connecting to your Zo server over SSH. One powerful use case SSH enables is using your Zo as a **remote development environment**, allowing you to use Zo from your favorite IDE running on your computer. **What is SSH?** **Secure Shell Protocol (SSH)** is like a secure phone line to another computer. The secure connection is established using a pair of keys: a **public key** (which can be shared with others), and a **private key** (which is kept secret). Only computers with a known public key registered on your Zo server will be allowed to connect. **What's an IDE?** An **Integrated Development Environment (IDE)** is an application that programmers use to develop software and operate servers. Once you've connected an IDE to your Zo server, you can use it to write code (or edit any text file) on your Zo and run commands. If you don't have a favorite IDE already, we recommend [Cursor](https://cursor.com), the best choice for AI-assisted coding. ## 1. Generate an SSH key on your computer Open the Terminal application on your computer. Run the command below, replacing the email used in the example with your own email address. ```sh ssh-keygen -t ed25519 -C "your_email@example.com" ``` When you're prompted to "Enter a file in which to save the key", you can press Enter to accept the default file location. When you're prompted to "Enter a passphrase", you can press Enter to leave it empty, or choose a passphrase. **Working with SSH key passphrases** For an additional layer of security, you can add a passphrase to your SSH key. In order to avoid entering the passphrase every time you connect, you can securely cache the key in the SSH agent. GitHub has a [helpful guide](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/working-with-ssh-key-passphrases) that you can follow to set this up. Run the command below to view your public key: ```sh cat ~/.ssh/id_ed25519.pub ``` You'll see something like this: `ssh-ed25519 YOUR_ECDSA_PUBLIC_KEY your_email@example.com` ## 2. Register your public key on your Zo Open the Terminal in your Zo application. Run the command below to edit your authorized keys file: ```sh nano ~/.ssh/authorized_keys ``` Paste your public key in the editor. Save and exit the editor by pressing `Ctrl + X`, then `Y`, and finally `Enter`. ## 3. Set up a SSH service on your Zo Open the Sites page in your Zo and navigate to the Services tab. Click **"Add service"** to create a new service and fill in the details below: | | | | --------------------- | --------------------------- | | Label | `ssh` | | Local port | `2222` | | Type | `tcp` | | Entrypoint | `/usr/sbin/sshd -D -p 2222` | | Working directory | Leave empty | | Environment variables | None | When your SSH service is up and running, take note of the **Host** and **Port**. ![How to set up an SSH service to connect to your server](/docs-assets/screenshots/ssh-service-running.png) *An SSH service with port 10872 and host ts1.zocomputer.io* ## 4. Connect to your Zo Open the Terminal on your computer. Run the command below, replacing the port and host with your service's port and host. ```sh ssh -p root@ # example: ssh -p 10000 root@ts1.zo.computer ``` If all is well, you should find yourself inside your Zo. You can exit the SSH session by typing `exit` or `Ctrl + D`. ### Create a shortcut to connect In your computer's terminal, run the command below to edit your SSH configuration file: ```sh nano ~/.ssh/config ``` Paste the following configuration, replacing the **Port** and **HostName** with your service's port and host: ```sh Host zo HostName ts1.zocomputer.io Port 10872 User root ServerAliveInterval 30 ServerAliveCountMax 3 IdentityFile ~/.ssh/id_ed25519 ``` Save and exit the editor by pressing `Ctrl + X`, then `Y`, and finally `Enter`. Now, you can run `ssh zo` to connect to your Zo from your computer's terminal. ## 5. Connect your IDE Different IDEs have different ways to connect to remote servers. In this guide, we'll show you how to connect [Cursor](https://cursor.com) to Zo, but other IDEs can be connected in a similar way. First, install [Cursor's official Remote SSH extension](https://marketplace.cursorapi.com/items/?itemName=anysphere.remote-ssh). In the extension's settings, enter your SSH config file path: ![How to connect Cursor to a remote development server, step 1](/docs-assets/screenshots/ssh-cursor-config.png) Also in the extension's settings, enable Remote Command Execution: ![How to connect Cursor to a remote development server, step 2](/docs-assets/screenshots/ssh-cursor-command.png) In the command palette, find `Remote-SSH: Connect to Host...` and select `zo`. ![How to connect Cursor to a remote development server, step 3](/docs-assets/screenshots/ssh-cursor-connect.png) Another Cursor window will open, connected to your Zo. In this new window, open the `/home/workspace` folder on your Zo. **Why /home/workspace?** The files you can see in the Zo application are in `/home/workspace` on your Zo Computer. ![How to connect Cursor to a remote development server using SSH](/docs-assets/screenshots/ssh-cursor-workspace.png) That's it! Now you can use your Zo from Cursor. ![How to connect Cursor to a remote development server – Done!](/docs-assets/screenshots/ssh-cursor-done.png) --- # Payments Connect Stripe to accept payments and sell products, services, or subscriptions ## Getting started Connect your Stripe account to start accepting payments with Zo. You can sell products, services, or subscriptions using Stripe Connect and integrate payment links into your Zo [space](/docs/spaces) and [sites](/docs/sites). > **Tip** > > **Zo takes 0% of your revenue.** Stripe's standard processing fees still > apply. Go to Settings > Tools to get started with Payments in Zo. You'll need to: 1. **Create a Stripe Connect account** – Select your country and create your account. This cannot be changed after creation. 2. **Complete onboarding** – Stripe will guide you through the setup process, including business verification and bank account details. 3. **Start selling** – Once onboarding is complete, you can create products and accept payments. > **Note** > > You can manage your Stripe account, products, and orders either in Zo's Payments > tab or directly in your Stripe Dashboard. Both interfaces stay in sync. ## Account management The **Account** tab shows your Stripe Connect account status and provides quick access to: - **Complete or update onboarding** – Finish setting up your account or update your business information - **Open Stripe Dashboard** – Access your full Stripe account dashboard - **View pending requirements** – See what information Stripe needs to complete your account setup Your account must be fully onboarded before you can create products or accept payments. ## Products and payment links The **Products** tab lets you create and manage products with payment links that you can share with customers. ### Creating a product 1. Click **Create** in the Products tab 2. Enter your product details: - **Name** – Your product name (required) - **Description** – Optional product description - **Price** – Price in USD (required) 3. Click **Create** to generate a payment link ### Managing payment links Each product gets a payment link URL that you can: - **Copy** – Share the link with customers via email, social media, or embed on your website - **Activate/Deactivate** – Toggle payment links on or off without deleting them - **View in Stripe** – Open the product in your Stripe Dashboard for advanced settings Payment links work immediately once created and activated. Customers can pay using any payment method Stripe supports. ## Orders and fulfillment The **Orders** tab shows all purchases made through your payment links. ### Viewing orders Each order displays: - Product name and price - Customer email (if provided) - Purchase date - Payment status - Fulfillment status ### Marking orders as fulfilled Once a customer completes payment, you can mark orders as fulfilled: 1. Find the order in your Orders list 2. Click **Mark Fulfilled** to update the status 3. This helps you track which orders you've processed You can also export your orders to CSV for record-keeping or external processing. ## Using Stripe Dashboard While Zo provides a streamlined interface for selling, you can manage more advanced settings directly in your Stripe Dashboard. Links to your Stripe Dashboard are available throughout the Payments tab for quick access. ## Selling with Zo You can also ask Zo to help you create products and manage your sales. Zo has access to tools for: - Creating products and payment links - Viewing orders and payment status - Managing your Stripe Connect account - Integrating payment links into your [Zo sites](/docs/sites) Just ask Zo to help you sell something, and it will guide you through the process. Zo knows how to integrate Stripe payment links into your Zo sites, so you can easily add checkout functionality to any site you're building. --- # Control a computer via SSH How to operate another computer using Zo > **Warning** > > Connecting Zo to another computer using SSH is risky. By doing so, you are giving your AI unconstrained access to everything on that computer – a ridiculous thing to do, if it's your personal computer. > > You should only proceed with this guide if you fully understand the risks and are comfortable with the potential > consequences of Zo making mistakes, or falling prey to prompt injection. > > This use case can be an impressive "party trick" (and can be genuinely useful depending on the device you are connecting to), but should not be used regularly unless you are completely comfortable with the security of your setup. ## 1. Generate an SSH key on your Zo Open the Terminal in your Zo application. Run the command below, replacing the email used in the example with your own email address. ```sh ssh-keygen -t ed25519 -C "your_email@example.com" ``` When you're prompted to "Enter a file in which to save the key", you can press Enter to accept the default file location. When you're prompted to "Enter a passphrase", you can press Enter to leave it empty. Run the command below to view your public key: ```sh cat ~/.ssh/id_ed25519.pub ``` You'll see something like this: `ssh-ed25519 YOUR_ECDSA_PUBLIC_KEY your_email@example.com` ## 2. Register your public key on your computer Open your computer's Terminal application. Run the command below to edit your authorized keys file: ```sh nano ~/.ssh/authorized_keys ``` Paste your public key in the editor. Save and exit the editor by pressing `Ctrl + X`, then `Y`, and finally `Enter`. ## 3. Enable SSH access to your computer On macOS, you can enable SSH access by [enabling Remote Login](https://support.apple.com/lt-lt/guide/mac-help/mchlp1066/mac) in your System Settings. ![How to connect to your server using SSH and use it as a remote development environment](/docs-assets/screenshots/ssh-mac-remote-login.png) ## 4. Set up and run ngrok To create a tunnel to your computer, you'll need to sign up for [ngrok](https://ngrok.com/). To install ngrok on macOS, you'll first need to [install Homebrew](https://brew.sh/) by running their install command in your terminal. Then, you can install ngrok by running the following command: ```sh brew install ngrok ``` Log in to your ngrok account by running the command below, replacing $YOUR\_TOKEN with the token from your [ngrok account dashboard](https://dashboard.ngrok.com/get-started/your-authtoken). ```sh ngrok config add-authtoken $YOUR_TOKEN ``` In order to avoid having to update your Zo's SSH configuration every time you run ngrok, we recommend [upgrading your ngrok account](https://ngrok.com/pricing) and reserving a [TCP address](https://dashboard.ngrok.com/tcp-addresses) with a fixed URL. Once you have a TCP address, you can run the following command, replacing the placeholders with the number and port from your TCP address. ```sh ngrok tcp 22 --url=.tcp.ngrok.io: ``` ## 4. Connect to your computer Open the Terminal in your Zo application. Run the command below, replacing the host and port with the values from your TCP address, and the user with your computer's username. (You can run `whoami` in your computer's terminal to find your username.) ```sh ssh -p @ # example: ssh -p 20000 you@5.tcp.ngrok.io ``` If all is well, you should find yourself inside your laptop in your Zo's terminal. You can exit the SSH session by typing `exit` or `Ctrl + D`. ### Create a shortcut to connect In your Zo application's terminal, run the command below to edit your SSH configuration file: ```sh nano ~/.ssh/config ``` Paste the following configuration, replacing the Port, HostName, and User with the same values from the ssh command you used above: ```sh Host laptop HostName Port User ServerAliveInterval 30 ServerAliveCountMax 3 IdentityFile ~/.ssh/id_ed25519 ``` Save and exit the editor by pressing `Ctrl + X`, then `Y`, and finally `Enter`. Now, you can run `ssh laptop` to connect to your computer from your Zo's terminal. To tell Zo how to connect to your computer, you can create a rule instructing Zo to use `ssh laptop` to connect to your computer. ![How to connect to your server using SSH and use it as a remote development environment](/docs-assets/screenshots/ssh-rule.png) > **Tip** > > Your computer must remain turned on with ngrok running and connected to the internet in order to connect to it from > your Zo. --- # Devices Let Zo use your desktop to browse the web, run commands, send messages, and access files The Zo desktop app connects your physical computer to Zo, letting the AI run commands on your machine. You add capabilities to control what Zo can do, each granting specific, scoped permissions. Zo can only use capabilities you explicitly enable. ## Quick start 1. Install the [Zo desktop app](/docs/desktop) 2. Log in (your device registers automatically) 3. Go to **Settings > Tools > Devices** 4. Add capabilities (Browser, Shell, etc.) > **Tip** > > Works best when you refer to your device by name. For example, if you've named your device "Mac", try "use my Mac to check the headlines on CNBC." ## Capabilities **Browser Control** Lets Zo use Chrome on your computer to browse the web, click elements, fill forms, and take screenshots. Powered by [`agent-browser`](https://github.com/vercel-labs/agent-browser), a bundled CLI that drives Chrome via the DevTools Protocol. Requires Google Chrome or another Chromium-based browser installed on your machine. Because this uses your local browser, Zo can interact with sites you're already logged into. **iMessage (macOS only)** Lets Zo send and read iMessages on your computer. Powered by `imsg`, a bundled CLI that reads the macOS Messages database directly. Requires granting Full Disk Access to the Zo desktop app in **System Settings > Privacy & Security**. **Shell Commands** Lets Zo run shell commands on your computer. **File Access** Lets Zo read and manage files on your computer: list, read, copy, move, and create directories. **Custom** Create your own capabilities with a name, permission patterns, and a prompt that tells Zo how to use it. Useful for granting access to specific CLI tools or workflows on your machine. Permissions use glob patterns to control which commands are allowed. For example, `Bash(docker *)` allows any command starting with `docker`, and `!Bash(docker rm *)` denies container removal. Deny rules are checked first, and anything not explicitly allowed is blocked by default. --- # Tools overview Learn about Zo's tools Zo has access to a wide range of tools to operate your computer, use your integrations, and navigate the internet. You can type @ in the chat to mention a specific tool. You can also refer to these tools loosely by name, e.g. “use your image search tool”. Mentioning specific tools can make your prompts more precise and reliable. --- # Create file Create a new file or rewrite an existing one with the provided content. Returns a message indicating success or failure, including the absolute path of the file. ## Parameters **target\_file (string, required)** The absolute path of the file to create or rewrite. **content (string, default: "")** The content to write to the file. Defaults to empty. --- # Edit file Edit a text file using a sequence of precise edit operations. ## Parameters **target\_file (string, required)** The absolute path to the file to edit. **operations (object\[], required)** A list of operations to apply to the file: replace\_block, insert\_after, insert\_before, delete\_block, append\_line. --- # Edit file fast Merge a large or fuzzy rewrite into a text file using a fast apply LLM. ## Parameters **target\_file (string, required)** Absolute path of the file to edit. **code\_edit (string, required)** Specify ONLY the precise lines of code that you wish to edit. Use // ... existing code ... for unchanged sections. **instructions (string, default: "")** Optional. A single sentence in the first person describing what you're changing (e.g. 'I am adding error handling to the fetch call'). Helps disambiguate the edit; omit it for unambiguous edits. --- # Read file Read a file from the computer. Zo Computer supports a wide range of file formats including text, word processing, spreadsheets, presentations, PDFs, ebooks, images, audio, and video. AI that can work with spreadsheets (.xlsx, .xls). AI that can work with Word documents (.docx, .doc). AI that can work with PowerPoint presentations (.pptx). AI that can work with PDF files (.pdf). AI that can transcribe audio files (.mp3, .wav, .m4a). AI that can transcribe and convert video files (.mp4, .mov, .avi). AI that can work with ebooks (.epub). AI that can see and convert images (.png, .jpg, .gif). ## Parameters **target\_file (string, required)** The absolute path of the file to read. **start\_line (number, default: -1)** The 1-indexed line number to start reading from (text files). **end\_line (number, default: -1)** The 1-indexed line number to end reading at, inclusive (text files). **read\_entire\_file (boolean, default: false)** If true, read the entire text file. **pdf\_epub\_start\_page\_1\_indexed (number, default: -1)** The 1-indexed start page for the PDF/EPUB read. **pdf\_epub\_end\_page\_1\_indexed\_inclusive (number, default: -1)** The 1-indexed end page (inclusive) for the PDF/EPUB read. **pdf\_epub\_include\_images (boolean, default: false)** If true, include rendered page images. This is slower and should be used sparingly. --- # List files Directory listing tool that shows files and subdirectories in a tree structure, helping you explore and understand the project organization. ## Parameters **path (string, required)** The absolute path to the directory to list. **ignore (string\[], default: \[])** List of glob patterns to ignore. --- # Search files Search files by content or filename using ripgrep. ## Parameters **query (string, required)** Pattern or fragment to search. **location (string, default: USER)** USER | CONVERSATION | ALL\_CONVERSATIONS (default USER). **case\_sensitive (boolean, default: true)** If true (default), search is case-sensitive; if false, case-insensitive. **exclude\_pattern (string, default: "")** Glob pattern to exclude (e.g. 'node\_modules/\*\*'). **include\_pattern (string, default: "")** Glob pattern to include (e.g. '\*\*/\*.py'). **search\_kind (string, default: content)** 'content' or 'filename'. --- # Copy file Copy a file or directory on the computer. Returns a message with the destination path and the number of bytes copied. ## Parameters **source\_path (string, required)** Absolute path of the file or directory to copy. **dest\_path (string, required)** Absolute destination path on the target. --- # Find file conversations Find prior conversations linked to one exact workspace file path. ## Parameters **file\_path (string, required)** One relative path inside /home/workspace, or its /home/workspace-prefixed form. **limit (number, default: 8)** Maximum candidates to return, from 1 through 8. Defaults to 8. --- # Read file conversation Read one indexed turn from a prior conversation linked to a workspace file. ## Parameters **file\_path (string, required)** The exact workspace path used for discovery. **conversation\_id (string, required)** A conversation ID returned by find\_file\_conversations for that path. --- # Transcribe audio Transcribe an audio file and save the transcript next to the original file. Transcription on Zo Computer is powered by [AssemblyAI](https://www.assemblyai.com/universal-2). ## Parameters **audio\_file\_path (string, required)** Absolute path to the audio file to transcribe. --- # Transcribe video Transcribe audio from a video file and save the transcript next to the original file. Transcription on Zo Computer is powered by [AssemblyAI](https://www.assemblyai.com/universal-2). ## Parameters **video\_file\_path (string, required)** Absolute path to the video file to transcribe. --- # Generate image Generate an image following the provided prompt using an AI image generation model. AI image generation on Zo Computer is powered by Google [Nano Banana](https://deepmind.google/models/gemini-image/flash/) or OpenAI [GPT Image 2](https://openai.com/index/introducing-chatgpt-images-2-0/). The default is set per-user in AI settings. ## Parameters **prompt (string, required)** A description of the desired image. Be specific, precise, and detailed. Use advanced AI image generation prompting techniques to produce visually compelling results. **file\_stem (string, required)** The base name for the output files (e.g., "myimg" will create "myimg\_1.png", "myimg\_2.png", etc.). **n (number, default: 1)** The number of images to generate (between 1 and 10). Defaults to 1. **output\_dir (string, default: "")** The directory where the generated images will be saved. Defaults to /home/workspace/Images. **aspect\_ratio (string, default: 1:1)** The desired image aspect ratio, e.g. "16:9", "1:1", "3:4". **provider (string, default: "")** Which model to use. Defaults to "" (empty), which routes through the user's configured default image provider in AI settings. Pass "google" (Nano Banana — fast and cheap) or "openai" (GPT Image 2 — \~3× more expensive but better prompt adherence and legible rendered text) to override on this call only; use the override when the user explicitly asks for a specific provider or a level of quality only one of them satisfies. --- # Edit image Remix an existing image (or images) using an AI image model. AI image editing on Zo Computer is powered by Google [Nano Banana](https://deepmind.google/models/gemini-image/flash/), which excels at maintaining character consistency for rich storytelling, or OpenAI [GPT Image 2](https://openai.com/index/introducing-chatgpt-images-2-0/) for higher-quality edits at \~3× the cost. The default is set per-user in AI settings. ## Parameters **prompt (string, required)** A description of the desired image. Be specific, precise, and detailed about the desired modifications to the existing image. Use advanced AI image generation prompting techniques to produce visually compelling results. **filepaths (string\[], required)** List of 1 to 3 absolute paths to images to be edited or combined. Edited image will be saved in the same directory as the first input image with the specified suffix. For optimal subject consistency, provide multiple reference images showing different angles/views of the subject. **file\_suffix (string, default: \_edited)** The suffix to append to the output file (e.g., "\_edited" will create "image\_edited.png"). Defaults to "\_edited" if not specified. **provider (string, default: "")** Which model to use. Defaults to "" (empty), which routes through the user's configured default image provider in AI settings. Pass "google" (Nano Banana — fast and cheap) or "openai" (GPT Image 2 — \~3× more expensive but better edit fidelity and legible rendered text) to override on this call only; use the override when the user explicitly asks for a specific provider or a level of quality only one of them satisfies. --- # Generate video from image Generate a short, 5 second video from an input image using an AI video generation model. AI video generation on Zo Computer is powered by [OVI](https://fal.ai/models/fal-ai/ovi/image-to-video). ## Parameters **instruction (string, required)** Description of the desired motion, scene evolution, and audio description. **filepath (string, required)** Absolute path to the source image. The output video will be saved alongside it. **file\_suffix (string, default: \_video)** Suffix appended to the source file's stem for the output (e.g., "\_video"). **orientation (string, default: landscape)** Desired output orientation ("landscape" → 16:9, "portrait" → 9:16). Defaults to "landscape". --- # Generate diagram Generate a block diagram, using D2. D2 is a domain-specific language for diagramming ([https://d2lang.com](https://d2lang.com)). Use this whenever a diagram would clarify the USER's request. Provide raw D2 text only—no markdown fences, comments, or extra prose. Input is saved as `.d2` in the conversation workspace and rendered to `.png` under Images/, which is returned to the USER. ## Parameters **code (string, required)** Valid D2 source (required, plain text). **file\_stem (string, required)** Base filename for both `.d2` and `.png`. **output\_dir (string, default: "")** Optional absolute directory for the PNG (defaults to `/home/workspace/Images`). --- # Read webpage Read the content of a webpage. For standard webpages, the content is saved as Markdown to Zo's workspace for the conversation along with the original HTML file. For file URLs (PDFs, images, audio, video, etc), the file is downloaded to the conversation workspace. This tool can use [Zo's browser](/docs/browser) to visit the page if needed. Using Zo's browser is slower, but can be used to access pages that render dynamic content or require authentication. ## Parameters **url (string, required)** The URL of the webpage to visit. **use\_browser (string, default: "")** Whether to use Zo's browser to visit the page (false by default). --- # Open webpage Open a webpage in Zo's browser. ## Parameters **url (string, required)** The URL of the webpage to open. --- # View webpage View the current page in the browser and get its content plus a screenshot. --- # Use webpage Interact with the current page using an AI agent. ## Parameters **task (string, required)** Specific task with explicit stop condition. Name elements in quotes. **output\_schema (object, default: \{})** Optional flat JSON schema for structured output. Top-level type must be 'object' with 'properties' (dict) and 'required' (list of keys). Each property is either a scalar (type='string'|'number'|'boolean', plus optional 'enum' list for strings) or an array (with 'items' that is a scalar or a flat object whose own properties are scalars). No deeper nesting. Omit when no structured output is needed. --- # Save webpage Save webpage content to the user's Articles directory. Supports YouTube URLs by saving a transcript-based article (video embed + transcript). For standard webpages, the content is saved as Markdown. For file URLs (PDFs, images, audio, video files, etc), the file is downloaded. This tool uses [Zo's browser](/docs/browser) to visit the page and extract clean article content. ## Parameters **url (string, required)** URL of the webpage to save. --- # Search the web Search the web using a search engine. ## Parameters **query (string, required)** Search query. **time\_range (string, default: anytime)** Recency window for results: "anytime", "day", "week", "month", "year" (aliases: "a", "d", "w", "m", "y"), or a shorthand like "4h", "48h", "7d", "2w". "anytime" applies no date filter. Unrecognized values are treated as "anytime". When both an explicit date range and time\_range are given, the explicit dates win. **include\_domains (string\[], default: \[])** List of domains to constrain results. **topic (string, default: general)** "general" (search the whole web — the default) or "news" (articles from news sites). This is the search index, not a subject category: for a topic like finance, jobs, or sports, leave it "general" and put the subject in the query. --- # Research the web Perform an in-depth web search using a more powerful search engine. ## Parameters **query (string, required)** Search query. For people searches, use the person's full name and optionally include disambiguating context (company, role, location). **time\_range (string, default: anytime)** Recency window for results: "anytime", "day", "week", "month", "year" (aliases: "a", "d", "w", "m", "y"), or a shorthand like "4h", "48h", "7d", "2w". "anytime" applies no date filter. Unrecognized values are treated as "anytime". When both an explicit date range and time\_range are given, the explicit dates win. **category (string, default: "")** Focus area for results. One of "company", "research paper", "pdf", "github", "tweet", "personal site", "linkedin profile", "financial report", "people". **include\_domains (string\[], default: \[])** Domains to include. **exclude\_domains (string\[], default: \[])** Domains to exclude. **include\_text (string\[], default: \[])** Text that must appear verbatim in page content. Pass a single short phrase (a few words) — this is the most reliable form. --- # Find similar links Find web pages similar to a given URL. ## Parameters **url (string, required)** The URL to find similar pages for. Must be a complete URL (e.g., [https://example.com/article](https://example.com/article)). **include\_domains (string\[], default: \[])** Only return results from these domains. **exclude\_domains (string\[], default: \[])** Exclude results from these domains. **exclude\_source\_domain (boolean, default: true)** Whether to exclude results from the same domain as the input URL. Defaults to True. --- # Search images Search for images on the web using a search engine. ## Parameters **query (string, required)** The search query for finding images. --- # Search X Search X (Twitter) for posts and users matching a query. ## Parameters **query (string, required)** Natural language prompt describing what to find on X. **allowed\_x\_handles (string\[], default: \[])** Only include posts from these X handles (max 10). Cannot be used with excluded\_x\_handles. **excluded\_x\_handles (string\[], default: \[])** Exclude posts from these X handles (max 10). Cannot be used with allowed\_x\_handles. **time\_range (string, default: anytime)** Recency window for results: "anytime", "day", "week", "month", "year" (aliases: "a", "d", "w", "m", "y"), or a shorthand like "4h", "48h", "7d", "2w". "anytime" applies no date filter. Unrecognized values are treated as "anytime". When both an explicit date range and time\_range are given, the explicit dates win. **from\_date (string, default: "")** Start date (YYYY-MM-DD). If set, only results on/after this date are considered. Takes precedence over time\_range. **to\_date (string, default: "")** End date (YYYY-MM-DD). If set, only results on/before this date are considered. **enable\_image\_understanding (boolean, default: true)** If true, allow the agent to view and interpret images from X posts. **enable\_video\_understanding (boolean, default: true)** If true, allow the agent to view and interpret videos from X posts. --- # Search Google Maps Search Google Maps for locations. ## Parameters **query (string, required)** Natural language prompt describing what to find on Google Maps. **location (string, default: "")** Optional location or area to bias results (city, address, or neighborhood). **open\_now (string, default: "")** If true/false, filter for places that are open now or not open now. **min\_rating (number, default: -1.0)** Optional minimum rating filter (0–5). **included\_type (string, default: "")** Optional place type to focus results (e.g., restaurant, cafe, museum). **price\_level (string, default: "")** Optional price level filter (e.g., "$", "$$", "$$$", "$$$$" or "cheap/moderate/expensive"). **language (string, default: "")** Optional BCP-47 language tag for results (e.g., en-US). **region (string, default: "")** Optional region code to bias results (e.g., us, gb, fr). --- # Run command Run a single shell command on the computer. Zo can execute shell commands in a bash session, allowing for system operations, script execution, and command-line automation. Use cases include: System automation (execute scripts, manage files, automate tasks), Data processing (process files, run analysis scripts, manage datasets), Environment setup (install packages, configure environments). ## Parameters **cmd (string, required)** The shell command string to execute. **cwd (string, default: /home/workspace)** The working directory in which to execute the command. Defaults to the user's workspace root. **timeout (number, default: 0)** Optional time limit in seconds. When set, the command is terminated if it runs longer than this. Defaults to unbounded. **description (string, default: "")** Optional short human-readable label for the command (shown in the UI). Does not affect execution. --- # Create site Create a site (also known as an app, or a website). ## Parameters **name (string, required)** name of the project, e.g. my-app (lowercase, no spaces) **variant (string, default: blank)** template variant to use: blank, blog, event, slides, data (dashboard), marketing (landing page), portfolio (personal site + case studies), kb (markdown knowledge base), waitlist (email-capture coming-soon page), storefront (product grid + Stripe checkout). Default is blank. **parent\_path\_parts (string\[], default: \[])** Workspace-relative (/home/workspace/...parts/name) path segments where the project will be created, e.g. \["projects"] or empty for root of workspace **force (boolean, default: false)** Whether to overwrite an existing directory with the same name. Default False. --- # Publish site Publish or republish a Zo Site so it gets a dedicated URL and runs a production build. Publishing a site creates an HTTP user service under the hood. The site runs a production build and gets a dedicated, memorable URL that works from anywhere — not just the preview iframe. ## What publishing does - Runs the site as a production service (not the dev server) - Assigns a dedicated URL you can share and access from any browser - Public sites (default): URL at \*.zocomputer.io, accessible to anyone without sign-in - Private sites: URL at \*.zo.computer, requires the owner to be signed in ## Before publishing The site is already running (dev server) and accessible to the signed-in user at its authenticated preview URL (zite-\{port}-\{host}.zo.computer) and via the preview iframe in the Zo web app. Publishing upgrades it to a production build with a clean URL. Do NOT use register\_user\_service or update\_user\_service for sites — use this tool instead. The publish config (label, port, entrypoint) is read from the site's zosite.json. ## Parameters **site\_path (string, required)** Required. Workspace-relative directory that contains the site's zosite.json (e.g. 'my-site' or 'projects/my-site'). **public (string, default: "")** Whether the published site is publicly accessible. 'true' (default): URL at \*.zocomputer.io, no sign-in required. 'false': URL at \*.zo.computer, requires owner sign-in. --- # Unpublish site Unpublish a Zo Site, removing its dedicated URL. This deletes the user service backing the site, removing its dedicated URL (whether public or private). The site is no longer accessible at that URL. The site itself is not deleted — it continues running on its dev server and remains accessible to the signed-in user at its authenticated preview URL (zite-\{port}-\{host}.zo.computer) and via the preview iframe in the Zo web app. ## Parameters **site\_path (string, required)** Required. Workspace-relative directory that contains the site's zosite.json (e.g. 'my-site' or 'projects/my-site'). --- # Create service Register a managed User Service on your Zo server. A User Service is an automatically managed process on Zo Computer. Service modes: - "http" — public or private web service with a URL endpoint - "tcp" — public TCP service with a host:port endpoint - "process" — supervised background process with no public endpoint (workers, schedulers, bots, sync loops, or internal-only localhost services like Postgres bound to 127.0.0.1) Use "process" for anything that doesn't need to be reached from outside the host. Process-only services do not count toward hosted-service limits. Visibility (HTTP only): - public (default): reachable at \*.zocomputer.io without auth - private: reachable at \*.zo.computer, requires the owner to sign in. Private services are gated by a feature flag and not available on all accounts. - TCP services are always public. Process services have no endpoint. ## Parameters **label (string, required)** Unique label (per host) for the service. Lowercase and hyphens allowed. e.g. "my-web-app". **mode (string, required)** "http", "tcp", or "process". Use "process" for internal-only localhost services or non-network background processes. **local\_port (number, default: -1)** Localhost port to expose (1-65535, injected as PORT env var). Required for "http" and "tcp". Omit for "process". **entrypoint (string, default: "")** Optional command to run the service, e.g. "python3 -m http.server %(ENV\_PORT)s". If omitted, only the tunnel is managed. **workdir (string, default: "")** Working directory for the service entrypoint. Defaults to /home/workspace. **env\_vars (object, default: \{})** Optional environment variables. PORT will be overridden for networked services and is not set for process-only services. **public (string, default: "")** Whether the service is publicly accessible (defaults to true). Only applies to HTTP services — set to false for a private service at \*.zo.computer that requires sign-in. TCP services are always public; process services have no endpoint. --- # List services List managed User Services running on your Zo server. A User Service is an automatically managed process on Zo Computer. The list includes both public HTTP/TCP services and process-only managed services. `mode` is the canonical service type. HTTP services may include `custom_domains` with each domain, verification status, active flag, CNAME target, and timestamps. Process-only services have no public URL or TCP address and still report `protocol="tcp"` plus `local_port=0` for legacy compatibility, but they may still be listening on localhost if configured to do so. --- # Diagnose service Diagnose issues and get details about the status of a user\_service. ## Parameters **service (string, required)** Service label or service\_id to inspect. --- # Update service Update a managed user service on your Zo server. Only specify the fields you want to change; omitted fields keep their existing values. Always restarts the service process. A User Service is an automatically managed process on Zo Computer. Service modes: - "http" — public or private web service with a URL endpoint - "tcp" — public TCP service with a host:port endpoint - "process" — supervised background process with no public endpoint Visibility (HTTP only): - public: reachable at \*.zocomputer.io without auth - private: reachable at \*.zo.computer, requires the owner to sign in. Private services are gated by a feature flag. - TCP services are always public. Process services have no endpoint. You can change a service's mode in place instead of deleting and recreating it. ## Parameters **service\_id (string, required)** Identifier of the service to update. **label (string, default: "")** Optional. Unique label for the service (lowercase and hyphens). **mode (string, default: "")** Optional new mode: "http", "tcp", or "process". **local\_port (number, default: -1)** Optional. Localhost port for networked services (injected as PORT env var). Required when switching from "process" to "http" or "tcp". **entrypoint (string, default: "")** Optional. Command to run the service. **workdir (string, default: "")** Optional. Working directory for the entrypoint. **env\_vars (object, default: \{})** Optional. Environment variables. PORT will be overridden for networked services and is not set for process-only services. **public (string, default: "")** Optional. Pass true to make the service public, false to make it private (HTTP only). Omit to leave unchanged. Private services are reachable at \*.zo.computer and require sign-in. **enabled (string, default: "")** Optional. Pass "false" to pause the service (stop it running, keep its config/URL/quota) or "true" to resume it. Omit to leave the paused/running state unchanged. --- # Delete service Delete a managed user service on your Zo server. A User Service is an automatically managed process on Zo Computer. Deleting a public service also removes its public route. Deleting a process-only service removes the supervised process definition. ## Parameters **service\_id (string, required)** Identifier of the service to delete. --- # Proxy local service Proxy a local service to a public endpoint using a TCP tunnel, similar to ngrok. Creates a tunnel from the specified local port to a public endpoint and forwards all TCP traffic through it (not just HTTP). Note that the created tunnel is temporary and intended for preview purposes. It is accessed through HTTP, not HTTPS, and it will be discarded eventually, so you cannot rely on it for permanent access or "production" use cases. ## Parameters **local\_port (number, required)** Local port to proxy (must be between 1024-65535). --- # Use device Run a command on the user's desktop device via the Zo desktop app. ## Parameters **device (string, required)** Name of the device to use. Must match a registered device. **command (string, required)** The command to execute on the device. --- # Send Discord message Send a message to the user via Discord. ## Parameters **message (string, required)** The text content. Must be non-empty. **reply\_to\_message\_id (string, default: "")** Optional Discord message ID to reply to. Omit for default reply behavior. **thread\_id (string, default: "")** Optional Discord thread ID to send into. Overrides channel\_id/current context destination. **channel\_id (string, default: "")** Optional Discord channel ID to send into when not targeting a thread. --- # Send Slack message Send a message to the user via Slack. ## Parameters **message (string, required)** The text content (Slack mrkdwn). May be empty when media\_files is provided. **thread\_id (string, default: "")** Optional Slack thread\_ts to send into. Overrides channel\_id/current context destination. **channel\_id (string, default: "")** Optional Slack channel ID to send into when not targeting a thread. **media\_files (string\[], default: \[])** Absolute file paths to send as file attachments (e.g., \["/home/workspace/Images/chart.png"]). --- # Get Slack info Look up Slack workspaces, channels, and members. When called from a Slack conversation, the tool description includes the current channel\_id, thread\_id, and team\_id. These are used as defaults when not specified. ## Parameters **resource (string, default: channels)** What to list: "workspaces", "channels", or "members" (default "channels"). **team\_id (string, default: "")** Slack workspace team ID. Required for channels/members unless the current conversation is in a workspace (then it defaults to that workspace). **limit (number, default: 0)** Max results per page (default 100 for channels/members, max 200). **cursor (string, default: "")** Pagination cursor from a previous response's next\_cursor. --- # Get Slack history Get message history from a Slack channel or thread. When called from a Slack conversation, the tool description includes the current channel\_id, thread\_id, and team\_id. These are used as defaults when not specified. ## Parameters **channel\_id (string, default: "")** Slack channel ID to read from. Omit to use the current conversation's channel. **team\_id (string, default: "")** Slack workspace team ID. Omit to use the current conversation's workspace. **thread\_ts (string, default: "")** Parent message timestamp to read thread replies. Omit for channel-level messages. **latest (string, default: "")** Slack timestamp — fetch messages before this time. **oldest (string, default: "")** Slack timestamp — fetch messages after this time. **cursor (string, default: "")** Pagination cursor from a previous response's next\_cursor. **limit (number, default: 50)** Number of messages to return (1–100, default 50). --- # Get Discord history Get message history from a Discord channel, thread, or DM. When called from a Discord conversation, the tool description includes the current channel\_id, thread\_id, and guild\_id. These are used as defaults when not specified. ## Parameters **channel\_id (string, default: "")** Discord channel, thread, or DM ID to read from. Omit to use the current conversation's channel/thread. **around (string, default: "")** Message ID — fetch messages around this message. Mutually exclusive with before/after. **before (string, default: "")** Message ID — fetch messages older than this. Mutually exclusive with around/after. **after (string, default: "")** Message ID — fetch messages newer than this. Mutually exclusive with around/before. **limit (number, default: 50)** Number of messages to return (1–100, default 50). --- # Get Discord info Look up Discord servers, channels, threads, or members. When called from a Discord conversation, the tool description includes the current channel\_id, thread\_id, and guild\_id. These are used as defaults when not specified. ## Parameters **resource (string, default: channels)** What to list: "guilds", "channels", "threads", or "members" (default "channels"). **guild\_id (string, default: "")** Discord server ID. Required for channels/threads/members unless the current conversation is in a server (then it defaults to that server). **limit (number, default: 1000)** Max members to return when resource='members' (default 1000, max 5000). Ignored for other resources. --- # Send email Send an email to the user's email address. If the user has connected their Gmail account, another way to send email is using the Gmail tool. However, this tool is the simplest and recommended way to send an email to the user. ## Parameters **subject (string, required)** Email subject line. Must be non-empty. **markdown\_body (string, required)** Email body in Markdown. May be empty when attachments are provided. **attachments (string\[], default: \[])** Absolute file paths to attach (total size \<= 10MB). --- # Send SMS Send an SMS text message to the USER or a contact. MMS media file attachments are supported. ## Parameters **message (string, required)** The text content. May be empty when media\_files is provided. **media\_files (string\[], default: \[])** Absolute file paths to send as MMS attachments (e.g., \["/home/workspace/Images/photo.jpg"]). **contact\_name (string, default: "")** Name of a registered contact. If omitted, sends to the USER. --- # Send Telegram message Send a message to the user via Telegram. ## Parameters **message (string, default: "")** The text content to send. Omit or leave empty only when media\_files is provided. **media\_files (string\[], default: \[])** Absolute file paths to send as media attachments. Optional; most messages are text-only. **recipient (string, default: "")** Username or user ID of a specific connected Telegram account. Leave empty in the normal single-account case. There is no contact\_name parameter. --- # Connect Telegram Generate a pairing code to connect the user's Telegram account to Zo. --- # List app tools List all available tools and configured props for an app connected by the user. ## Parameters **app\_slug (string, required)** The app slug to list tools for. --- # Connect integration Surface an inline Connect button so the user can authorize an OAuth integration. ## Parameters **app\_slug (string, required)** The integration to connect, e.g. 'notion', 'gmail', 'google\_calendar', 'github', 'x', 'stripe', 'mcp:linear'. Must match one of the supported slugs (registered Pipedream app, 'x', 'github', 'stripe', or 'mcp:\'). --- # Search app catalog Search Pipedream's full catalog of 1000+ app integrations by keyword. ## Parameters **query (string, required)** Keyword to search the catalog (e.g. 'crm', 'webflow', 'project management'). --- # Use integration Run an action on a connected long-tail Pipedream catalog app. ## Parameters **app\_slug (string, required)** The catalog app slug (from `search_app_catalog`). **tool\_name (string, required)** Exact action name returned by `list_app_tools`. **configured\_props (object, required)** The configured props for the action (e.g., `{"collectionId": "abc123", "name": "New item"}`). **email (string, default: "")** Optional email address to select a specific connected account. --- # Use Gmail Work with the user's connected Gmail account. ## Parameters **tool\_name (string, required)** Exact tool name returned by `list_app_tools`. **configured\_props (object, required)** The configured props for the action (e.g., `{"to": "team@zocomputer.com", "subject": "Subject", "body": "Body"}`) **download\_path (string, default: "")** Optional absolute path to save downloaded file. Falls back to configured\_props\["filename"]. **email (string, default: "")** Optional email address to select a specific connected account. --- # Use Google Calendar Work with the user's connected Google Calendar account. ## Parameters **tool\_name (string, required)** Exact tool name returned by `list_app_tools`. **configured\_props (object, required)** The configured props for the action (e.g., `{"calendarId": "primary", "singleEvents": true, "orderBy": "startTime", "timeMin": "2024-01-01T00:00:00-05:00", "timeMax": "2024-01-02T00:00:00-05:00"}`) **email (string, default: "")** Optional email address to select a specific connected account. --- # Use Google Drive Work with the user's connected Google Drive account (includes Google Docs, Sheets, Slides, and Forms). ## Parameters **tool\_name (string, required)** Exact tool name returned by `list_app_tools`. **configured\_props (object, required)** The configured props for the action (e.g., `{"filePath": "/home/workspace/profile.jpeg", "mimeType": "image/jpeg"}`) **download\_path (string, default: "")** Optional absolute path to save downloaded file. Falls back to configured\_props\["filePath"]. **email (string, default: "")** Optional email address to select a specific connected account. --- # Use Google Sheets Work with the user's connected Google Sheets spreadsheets. ## Parameters **tool\_name (string, required)** Exact tool name returned by `list_app_tools`. **configured\_props (object, required)** The configured props for the action (e.g., `{"spreadsheetId": "abc123", "sheetName": "Sheet1"}`). **email (string, default: "")** Optional email address to select a specific connected account. --- # Use Google Tasks Work with the user's connected Google Tasks account. ## Parameters **tool\_name (string, required)** Exact tool name returned by `list_app_tools`. **configured\_props (object, required)** The configured props for the action (e.g., `{"taskListId": "abc123", "showCompleted": false}`) **email (string, default: "")** Optional email address to select a specific connected account. --- # Use OneDrive Work with the user's connected Microsoft OneDrive account via Pipedream. ## Parameters **tool\_name (string, required)** Exact tool name returned by `list_app_tools`. **configured\_props (object, required)** The configured props for the action (e.g., `{"fileId": "abc123"}` or `{"filePath": "/home/workspace/doc.pdf"}`) **download\_path (string, default: "")** Optional absolute path to save downloaded file. Falls back to configured\_props\["filePath"]. **email (string, default: "")** Optional email address to select a specific connected account. --- # Use Outlook Work with the user's connected Microsoft Outlook account. ## Parameters **tool\_name (string, required)** Exact tool name returned by `list_app_tools`. **configured\_props (object, required)** The configured props for the action (e.g., `{"to": "team@example.com", "subject": "Subject", "body": "Body"}`) **download\_path (string, default: "")** Optional absolute path to save downloaded file. Falls back to configured\_props\["filename"]. **email (string, default: "")** Optional email address to select a specific connected account. --- # Use Outlook Calendar Work with the user's connected Microsoft Outlook Calendar account. ## Parameters **tool\_name (string, required)** Exact tool name returned by `list_app_tools`. **configured\_props (object, required)** The configured props for the action. For list-events: `{"startDateTime": "2024-01-01T00:00:00-05:00", "endDateTime": "2024-01-02T00:00:00-05:00"}`. For create-calendar-event: `{"subject": "Meeting", "start": "2024-01-01T14:00:00", "end": "2024-01-01T14:30:00", "timeZone": "America/New_York"}`. **email (string, default: "")** Optional email address to select a specific connected account. --- # Use Notion Work with the user's connected Notion account. ## Parameters **tool\_name (string, required)** Exact tool name returned by `list_app_tools`. **configured\_props (object, required)** The configured props for the action (e.g., `{"title": "", "sortDirection": "ascending", "pageSize": 100}`) **email (string, default: "")** Optional email address to select a specific connected account. --- # Use Linear Work with the user's connected Linear workspace. ## Parameters **tool\_name (string, required)** Exact tool name returned by `list_app_tools`. **configured\_props (object, required)** The configured props for the action (e.g., `{"teamId": "uuid", "title": "Update integration"}`) **email (string, default: "")** Optional email address to select a specific connected account. --- # Use Airtable Work with the user's connected Airtable bases. ## Parameters **tool\_name (string, required)** Exact tool name returned by `list_app_tools`. **configured\_props (object, required)** The configured props for the action (e.g., `{"baseId": "app123", "tableId": "tbl456"}`). **email (string, default: "")** Optional email address to select a specific connected account. --- # Use Dropbox Work with the user's connected Dropbox account via Pipedream. ## Parameters **tool\_name (string, required)** Exact tool name returned by `list_app_tools`. **configured\_props (object, required)** The configured props for the action (e.g., `{"filePath": "/home/workspace/profile.jpeg", "mimeType": "image/jpeg"}`) **download\_path (string, default: "")** Optional write location for downloaded files on the host filesystem. **email (string, default: "")** Optional email address to select a specific connected account. --- # Use Spotify Use a tool to work with the user's connected Spotify account. ## Parameters **tool\_name (string, required)** Exact tool name from `list_app_tools`, or "spotify-search" to search for music **configured\_props (object, required)** Props for the action. For search: `{"type": "track|album|artist|playlist"}`. For actions: see list\_app\_tools **search\_query (string, default: "")** Search string (required when tool\_name="spotify-search"), e.g., "Drake Hotline Bling" --- # Use X Work with the user's connected X (Twitter) account. ## Parameters **tool\_name (string, required)** Action name from `list_app_tools("x")` (e.g., "x-post-tweet", "x-send-dm", "x-get-dms") **configured\_props (object, required)** Action parameters (e.g., `{"text": "Hello world!"}` for posting) **username (string, default: "")** Optional X username to specify which connected account to use (for multi-account). --- # Create product Create a Stripe product on the user's connected account. Optionally creates a price and payment link. ## Parameters **name (string, required)** Product name (e.g., "Consulting Session", "E-book Download") **description (string, default: "")** Product description (optional) **amount\_cents (number, default: -1)** Price in cents (e.g., 1000 for $10.00). If provided, creates a price and payment link. **currency (string, default: usd)** Currency code (default: "usd") **recurring (object, default: \{})** For subscriptions, provide interval info (e.g., `{"interval": "month", "interval_count": 1}`) **redirect\_url (string, default: "")** URL to redirect customer to after payment (mutually exclusive with hosted\_confirmation\_message) **hosted\_confirmation\_message (string, default: "")** Custom message for Stripe's hosted confirmation page (mutually exclusive with redirect\_url) **testmode (boolean, default: false)** Use test mode (default: false). Test mode is useful for testing before going live. --- # Create price Create a new price for an existing Stripe product. Optionally creates a payment link. ## Parameters **product\_id (string, required)** Existing Stripe product ID (e.g., "prod\_...") **amount\_cents (number, required)** Price in cents (e.g., 2500 for $25.00) **currency (string, default: usd)** Currency code (default: "usd") **recurring (object, default: \{})** For subscriptions, provide interval info (e.g., `{"interval": "month", "interval_count": 1}`) **create\_payment\_link (boolean, default: true)** Whether to create a payment link for this price (default: true) **redirect\_url (string, default: "")** URL to redirect customer to after payment (mutually exclusive with hosted\_confirmation\_message) **hosted\_confirmation\_message (string, default: "")** Custom message for Stripe's hosted confirmation page (mutually exclusive with redirect\_url) **testmode (boolean, default: false)** Use test mode (default: false) --- # Create payment link Create a payment link for an existing Stripe price. ## Parameters **price\_id (string, required)** Existing Stripe price ID (e.g., "price\_...") **redirect\_url (string, default: "")** URL to redirect customer to after payment (mutually exclusive with hosted\_confirmation\_message) **hosted\_confirmation\_message (string, default: "")** Custom message for Stripe's hosted confirmation page (mutually exclusive with redirect\_url) **testmode (boolean, default: false)** Use test mode (default: false) --- # List payment links List all payment links for the user. ## Parameters **testmode (boolean, default: false)** Use test mode (default: false) --- # Update payment link Update an existing payment link (activate/deactivate). ## Parameters **payment\_link\_id (string, required)** Database record ID (uuid) of the payment link to update **active (string, default: "")** Whether the payment link should be active (optional) **testmode (boolean, default: false)** Use test mode (default: false) --- # Update product Update an existing Stripe product's name or description. ## Parameters **product\_id (string, required)** Stripe product ID to update (e.g., "prod\_...") **name (string, default: "")** New product name (optional) **description (string, default: "")** New product description (optional) **testmode (boolean, default: false)** Use test mode (default: false) --- # List orders List all orders (checkout sessions) for the user. ## Parameters **testmode (boolean, default: false)** Use test mode (default: false) --- # Update orders Update the fulfillment status of one or more orders. ## Parameters **order\_ids (string\[], required)** List of order IDs to update (database record IDs) **fulfillment\_status (string, required)** New status - either "fulfilled" or "pending" **testmode (boolean, default: false)** Use test mode (default: false) --- # Create automation Create an automation to run an AI task on a schedule. Automations run on a schedule with an instruction. The automation runs the instruction at the scheduled time. The automation runner is Zo (another instance of yourself, with all the same tools, running on the same computer). Keep this in mind when writing the instruction: it should be specific, detailed, reference specific files, directories, and tools, and include all the context, examples, and nudges needed to give it the best chance of successfully completing the task. delivery\_method is the user's preferred communication channel for routine messages about the run; it does not force every run to send a message. Zo emails the user if the automation fails, including when delivery\_method is None. ## Parameters **rrule (string, required)** RFC 5545 RRULE string (bare RRULE without DTSTART or TZID — system adds these automatically) **instruction (string, required)** Clear, actionable instruction to execute when the automation triggers (include all necessary context) **delivery\_method (string, default: "")** Optional preferred communication channel for routine messages: one of 'email', 'sms', 'telegram', 'slack', 'discord', or None. Failure alerts are emailed even when this is None **model (string, default: "")** Optional model ID. Call tool\_docs('create\_automation') or tool\_docs('edit\_automation') to see available model IDs. User-specific BYOK model IDs in the format 'byok:your\_config\_id' are also accepted. --- # List automations List all registered automations. Automations are scheduled AI tasks with a schedule and an instruction. The automation runs the instruction at the scheduled time. The automation runner is Zo (another instance of yourself, with all the same tools, running on the same computer). --- # Get automation Get full details of a single automation, including the complete instruction text. Use this to read the full, untruncated instruction for an automation. list\_automations truncates instructions to 200 characters. ## Parameters **automation\_id (string, required)** The unique identifier of the automation to retrieve --- # Edit automation Edit an existing automation's title, instruction, schedule, preferred communication channel, or model. Automations run on a schedule with an instruction. The automation runs the instruction at the scheduled time. The automation runner is Zo (another instance of yourself, with all the same tools, running on the same computer). Keep this in mind when writing the instruction: it should be specific, detailed, reference specific files, directories, and tools, and include all the context, examples, and nudges needed to give it the best chance of successfully completing the task. delivery\_method is the user's preferred communication channel for routine messages about the run; it does not force every run to send a message. Zo emails the user if the automation fails, including when delivery\_method is None. ## Parameters **automation\_id (string, required)** The unique identifier of the automation to modify **title (string, default: "")** Optional. New display title for the automation. Omit to keep unchanged. **instruction (string, default: "")** Optional. The new instruction text to replace the existing one. Omit to keep unchanged. **rrule (string, default: "")** Optional. New RFC 5545 RRULE string (bare RRULE without DTSTART or TZID — system adds these automatically). Omit to keep unchanged. **delivery\_method (string, default: "")** Optional preferred communication channel for routine messages. 'email', 'sms', 'telegram', 'slack', 'discord', or 'none' to clear. Failure alerts are emailed even when this is 'none'. Omit to keep unchanged. **model (string, default: "")** Optional model ID. Call tool\_docs('create\_automation') or tool\_docs('edit\_automation') to see available model IDs. User-specific BYOK model IDs in the format 'byok:your\_config\_id' are also accepted. **active (string, default: "")** Optional. True to resume a paused task, False to pause it. Omit to keep unchanged. --- # Delete automation Delete an existing automation. Automations are scheduled AI tasks with a schedule and an instruction. The automation runs the instruction at the scheduled time. ## Parameters **automation\_id (string, required)** The unique identifier of the automation to delete --- # Create persona Create a new persona for Zo. ## Parameters **name (string, required)** Persona display name. **prompt (string, required)** System prompt text for the persona. **image (string, default: "")** Optional image URL for the persona avatar. **image\_hue (number, default: -1)** Optional HSL hue angle (0-360 integer) tinting the chrome Pegasus avatar. Anchors: 0=red, 60=yellow, 120=green, 180=cyan, 240=blue, 300=magenta (wraps at 360). Used when image is unset. Pass -1 to leave unset. **model (string, default: "")** Optional AI model ID. User-specific BYOK model IDs in the format 'byok:your\_config\_id' are also accepted. --- # List personas List all personas for the user. --- # Edit persona Edit fields of an existing persona. Heavily biased toward additive, surgical changes — there is no full-replacement option. ## Parameters **persona\_id (string, required)** Identifier of the persona to update. **name (string, default: "")** New display name, if renaming. **prompt\_edit (string, default: "")** Edit to apply to the prompt. Provide only the changed sections, with '// ... existing content ...' placeholders for unchanged parts. Merged into the existing prompt via LLM. Strongly prefer additive edits. **edit\_instructions (string, default: "")** A short sentence describing what the edit does. Used with prompt\_edit. **image (string, default: "")** New image URL for the avatar, if updating. **image\_hue (number, default: -1)** New HSL hue angle (0-360 integer) tinting the chrome Pegasus avatar. Anchors: 0=red, 60=yellow, 120=green, 180=cyan, 240=blue, 300=magenta (wraps at 360). Pass -1 to leave unchanged. **model (string, default: "")** New AI model ID, if updating. User-specific BYOK model IDs in the format 'byok:your\_config\_id' are also accepted. --- # Delete persona Delete a persona by ID for the current user. ## Parameters **persona\_id (string, required)** Identifier of the persona to delete. --- # Set active persona Set the active persona for the current channel (chat, SMS, email, etc.). ## Parameters **persona\_id (string, required)** Identifier of the persona to set active. --- # List available scopes List all available tool permission scopes, presets, and requirement rules. --- # Set persona scopes Set which tools a persona is allowed to use. ## Parameters **persona\_id (string, required)** Identifier of the persona to update. **scopes (string\[], required)** List of scope names or a single preset alias. --- # Create rule Create a new user rule for Zo. ## Parameters **instruction (string, required)** Instructions for Zo to follow. **condition (string, default: "")** Optional condition for when to apply the rule. No condition means the rule is always applied. --- # List rules List all rules for the user. --- # Edit rule Edit an existing rule. ## Parameters **rule\_id (string, required)** Identifier of the rule to update. **instruction (string, default: "")** New instruction text, if updating. **condition (string, default: "")** New condition expression, if updating. --- # Delete rule Delete a rule by ID. ## Parameters **rule\_id (string, required)** Identifier of the rule to delete. --- # Update user settings Update a user setting (name or bio) in Zo. ## Parameters **field (string, required)** Which setting to update: 'name' or 'bio'. **value (string, required)** The new value for the setting. --- # Read from space Get a space route by path, including its source code. Use this to inspect the code of an existing route before editing it. For a fresh Space, `/` returns the built-in starter homepage with `source: starter`. ## Parameters **path (string, required)** Route path, e.g. '/api/hello' or '/about'. --- # Write space route Create a new route or fully rewrite an existing one in the user's zo.space site. Use for new routes or full rewrites. For edits to an existing route, prefer `edit_space_route` — it sends only the changed sections instead of the entire file. ## Parameters **path (string, required)** Route path starting with '/'. Use '/' for custom home page. **route\_type (string, required)** Either 'api' or 'page'. **code (string, default: "")** Full source code. Required — must be valid TypeScript/TSX with a default export. **public (string, default: "")** Whether the route is publicly accessible. API routes are always public. For pages, omit to preserve current visibility on updates; defaults to False for new pages (True for homepage). --- # Edit space route Edit an existing route's code by supplying only the changed sections. Preferred for edits to existing routes, including the built-in starter homepage at `/`. Use `// ... existing code ...` as a placeholder for unchanged regions; the partial edit is merged against the current route code. ## Parameters **path (string, required)** Route path of the existing route to edit, e.g. '/about' or '/api/hello'. **code\_edit (string, required)** Partial edit — only the changed sections. Use '// ... existing code ...' for unchanged parts. **edit\_instructions (string, default: "")** A sentence describing what the edit does, to help disambiguate. **public (string, default: "")** Optional visibility override for page routes. Omit to preserve current visibility. API routes are always public. --- # Delete from space Delete a route from the user's zo.space site. Deleting a custom `/` route reveals the built-in starter homepage. The starter homepage itself cannot be deleted; use `edit_space_route` to replace it. ## Parameters **path (string, required)** Route path to delete, e.g. '/api/hello' or '/about'. --- # View space List all routes in the user's zo.space site. Returns route paths, types, public/private status, and source. The built-in starter homepage is returned at `/` with `source: starter` until the user customizes it. --- # Undo space change Undo the last change to a space route, restoring the previous version. ## Parameters **path (string, required)** Route path to undo, e.g. '/about' or '/api/hello'. --- # Redo space change Redo a previously undone space route change, restoring the next version. ## Parameters **path (string, required)** Route path to redo, e.g. '/about' or '/api/hello'. --- # View route history View the full version history of a space route. ## Parameters **path (string, required)** Route path to view history for, e.g. '/about' or '/api/hello'. --- # Upload asset to space Copy a file from the workspace to the user's zo.space assets. Assets are served at their asset\_path. Reference in pages: ![](/images/logo.png) ## Parameters **source\_file (string, required)** Path to the source file in the workspace, e.g. '/home/workspace/images/logo.png'. **asset\_path (string, required)** URL path where the asset will be served, starting with '/', e.g. '/images/logo.png'. --- # Remove asset from space Delete a static asset from the user's zo.space site. space site. ## Parameters **asset\_path (string, required)** URL path of the asset to delete, e.g. '/images/logo.png'. --- # List space assets List all uploaded assets in the user's zo.space site. Returns the URL paths and sizes of all assets that can be referenced in pages. --- # Check space Get recent errors from the user's zo.space routes. Use this to debug issues with space routes. Errors are logged when routes fail to load, build, or execute. --- # Restart space Clean reinstall dependencies, rebuild, and restart the zo.space server. Use when the space is crash-looping, stuck serving stale content, or has corrupted node\_modules. --- # Get space settings Get space settings for the user's zo.space site. space site. --- # Update space settings Update space settings — space-globally or for a single page route. ## Parameters **path (string, default: "")** Empty string (default) for space-global settings; route path (e.g. "/" or "/about") for per-page override. **site\_title (string, default: "")** Title override. Pass "default" to clear. **site\_description (string, default: "")** Meta description. Pass "default" to clear. **og\_image\_url (string, default: "")** Asset path for OG image (e.g. "/assets/og.png"). Pass "default" to clear. **favicon\_url (string, default: "")** Asset path for favicon. Space-global only. **custom\_head\_html (string, default: "")** HTML for \. Space-global only. **robots\_txt (string, default: "")** Custom robots.txt. Space-global only. **noindex (string, default: "")** "true" adds noindex/nofollow, "false" removes it, "default" clears any per-page override (inherit from space). **custom\_404\_route (string, default: "")** Custom 404 route path. Space-global only. **lang (string, default: "")** HTML lang attribute. Space-global only. **atproto\_did (string, default: "")** AT Protocol DID. Space-global only. --- # API reference Authentication, the base URL, and Zo's public API surface. The Zo API lets you interact with your Zo from scripts, automations, or other apps. The public surface is small: one endpoint to talk to your Zo, plus discovery endpoints for models and personas. Base URL: `https://api.zo.computer` Download the machine-readable spec: [openapi.json](/docs-assets/openapi.json). ## Authentication Authenticate with a bearer token. Create an access token in **Settings > Advanced** on zo.computer — copy it immediately, you won't see it again. ```bash curl https://api.zo.computer/models/available \ -H "Authorization: Bearer zo_sk_your_key_here" ``` > **Warning** > > Your API key grants full access to your Zo. Keep it secret and never commit > it to version control. ## Endpoints - [`POST /zo/ask`](/docs/api-reference/ask) — send a message to your Zo and get a response (optionally streamed) - [`GET /models/available`](/docs/api-reference/models) — list the models you can use with `/zo/ask` - [`GET /models/catalog`](/docs/api-reference/models#get-modelscatalog) — the full public model catalog (no auth) - [`GET /personas/available`](/docs/api-reference/personas) — list your configured personas For a guided walkthrough with examples, see the [API guide](/docs/api). To use Zo from MCP-compatible AI tools instead, see the [MCP server](/docs/mcp-server). --- # Ask Zo Send a message to your Zo and stream the response. ## POST /zo/ask Send a message to your Zo and get a response. This is the same Zo you talk to in the app — your files, integrations, and tools are all available. ```bash curl -X POST https://api.zo.computer/zo/ask \ -H "Authorization: Bearer zo_sk_your_key_here" \ -H "Content-Type: application/json" \ -d '{"input": "Hello, Zo!"}' ``` ### Request body **input (string, required)** Your message to Zo. **conversation\_id (string)** Continue an existing conversation. Omit to start a new one. **model\_name (string)** Override the default model (use [`GET /models/available`](/docs/api-reference/models) to list options). **persona\_id (string)** Override the active persona (use [`GET /personas/available`](/docs/api-reference/personas) to list options). **output\_format (object)** JSON Schema for structured output. When set, `output` in the response is an object matching the schema instead of a string. **stream (boolean, default: false)** Enable streaming mode. Returns Server-Sent Events (SSE) instead of JSON. ### Response ```json { "output": "Done! Added 52% humidity reading for today.", "conversation_id": "conv_abc123" } ``` **output (string | object)** Zo's response. An object if `output_format` was specified. **conversation\_id (string)** ID to continue this conversation in subsequent requests. ### Streaming response When `stream: true`, the endpoint returns a Server-Sent Events stream with `Content-Type: text/event-stream`. Each event has the format: ``` event: data: ``` Event types: - `FrontendModelResponse` — text chunk from the model (`data.content`) - `End` — stream completed (includes `data.output` if `output_format` was specified) - `Error` — error occurred (`data.message`) The `x-conversation-id` response header contains the conversation ID for follow-up requests. ### Continuing a conversation Use the returned `conversation_id` to continue the conversation: ```bash curl -X POST https://api.zo.computer/zo/ask \ -H "Authorization: Bearer zo_sk_your_key_here" \ -H "Content-Type: application/json" \ -d '{"input": "What did I just ask you?", "conversation_id": "conv_abc123"}' ``` --- # Models List available models and the full model catalog. ## GET /models/available List the models you can use with [`POST /zo/ask`](/docs/api-reference/ask). When authenticated with an API key, the list includes your [BYOK](/docs/byok) (Bring Your Own Key) configurations. ```bash curl https://api.zo.computer/models/available \ -H "Authorization: Bearer zo_sk_your_key_here" ``` ### Response ```json { "models": [ { "model_name": "anthropic:claude-haiku-4-5-20251001", "label": "Haiku 4.5", "vendor": "Anthropic", "description": "Anthropic's fastest model...", "type": "fast", "context_window": 200000, "is_byok": false } ] } ``` **models (array)** List of available models. **models\[].model\_name (string)** The value to pass to `model_name` in `/zo/ask`. **models\[].label (string)** Human-readable model name. **models\[].vendor (string)** Model provider (e.g. "Anthropic", "OpenAI", "Custom"). **models\[].description (string | null)** Short description of the model's capabilities. **models\[].type (string | null)** Either "fast" or "capable", indicating the model's speed/capability tradeoff. **models\[].context\_window (number | null)** Maximum context window size in tokens. **models\[].is\_byok (boolean)** Whether this is a BYOK (Bring Your Own Key) model. ## GET /models/catalog The full public model catalog: the picker model list plus catalog-level metadata (default chat model, featured models, deprecation map). No authentication required. Cached for 5 minutes. ```bash curl https://api.zo.computer/models/catalog ``` ### Response **models (array)** The picker model list, sorted by priority. **default\_chat\_model\_id (string)** Public id of the default chat model. **featured\_model\_ids (array)** Public ids of featured models. **featured\_models\_are\_free (boolean)** When true, featured models are free to use. **featured\_model\_labels (array)** Labels for `featured_model_ids`, in order. **promo\_end\_date (string | null)** Promo end date (YYYY-MM-DD) or null. **deprecation\_map (object)** Map of deprecated public model id → active successor public id. --- # Personas List the personas available in your workspace. ## GET /personas/available List your configured [personas](/docs/personas). Use the returned `id` values with the `persona_id` parameter in [`POST /zo/ask`](/docs/api-reference/ask) to override the active persona. ```bash curl https://api.zo.computer/personas/available \ -H "Authorization: Bearer zo_sk_your_key_here" ``` ### Response ```json { "personas": [ { "id": "a1b2c3d4", "name": "Technical Writer", "prompt": "You are a concise technical writer...", "model": "anthropic:claude-sonnet-4", "image": null } ] } ``` **personas (array)** List of configured personas. **personas\[].id (string)** The value to pass to `persona_id` in `/zo/ask`. **personas\[].name (string)** Display name for the persona. **personas\[].prompt (string)** System prompt defining the persona's behavior. **personas\[].model (string | null)** AI model ID, or null for the system default. **personas\[].image (string | null)** Avatar image URL. --- # Security Keeping you and your data safe is important to us. Zo Computer gives your AI full access to a dedicated computer in the cloud, where it can: - Access the internet and download files and programs - Write code, run programs, and host web services - Control other devices you connect to your Zo Computer Giving AI unconstrained access to a dedicated cloud computer is a powerful paradigm. Our approach is safer than giving AI full access to your own computer or your browser – but it is not without risks. This document explains the security characteristics of Zo Computer and helps users and organizations make an educated risk assessment. For any security-related questions or reports of potential vulnerabilities, email [security@zocomputer.com](mailto:security@zocomputer.com). Zo Computer has been designed from first principles to (1) give users full custody over their files and applications, and (2) provide a more transparent and flexible experience when using a powerful AI agent. - All files are stored using non-proprietary file formats in a portable, open-source container image format. Snapshots of the user's filesystem occur regularly to ensure past data can always be recovered. The user's filesystem data can be provided in container image format if requested. - Whenever possible, services are hosted on the user's personal server. This includes the Zo application itself, sites created by Zo, and software installed by the user or Zo. Our unique decentralized approach enables fundamentally better data custody and portability. Our long-term vision is to enable running Zo on any machine. - As much as is practical for the overall system, we aim to store all AI memories and search indexes personal server using open-weight embedding models and open-source software. Our vision is to enable running all AI inference and agent tools on the user's personal server. ## Our service providers. Zo Computer currently uses the following infrastructure and service providers: - `Infrastructure` - [Modal](https://modal.com/docs/guide/security) `Data storage` Modal provides cloud compute. - [Daytona](https://www.daytona.io/docs/en/security-exhibit) `Data storage` Daytona provides cloud compute. - [Neon](https://neon.tech) `Data storage` Neon hosts PostgreSQL databases used internally by the Zo application. - [Upstash](https://upstash.com) `Data storage` Upstash hosts Redis databases used internally by the Zo application. - [Cloudflare](https://cloudflare.com) `No data access` Cloudflare authenticates and routes traffic to internal services and the user's personal server. No data is retained. - [Vercel](https://vercel.com) `No data access` Vercel is used as a gateway for accessing open-source and proprietary LLM inference. Vercel hosts the non-application website (`www.zo.computer`). - `AI inference` - [OpenAI](https://openai.com) `Partial data access` OpenAI's proprietary models are used for LLM inference and audio transcription. - [Anthropic](https://anthropic.com) `Partial data access` Anthropic's proprietary models are used for LLM inference. - [Google Cloud Vertex AI](https://cloud.google.com/vertex-ai) `Partial data access` Google's proprietary models are used for LLM inference. - [Fireworks](https://fireworks.ai) `Partial data access` Open-source models such as DeepSeek, Kimi, and GLM, which are trained in China, may be served from Fireworks's US-based servers (via the Vercel AI gateway) when selected by the user for LLM inference. - [AssemblyAI](https://assemblyai.com) `No data access` AssemblyAI's proprietary models are used for transcribing audio. - [FAL](https://fal.ai) `No data access` Open-source and proprietary models served on FAL are used for generative AI media inference. - `Agent tools` - [Tavily](https://tavily.com) `No data access` When Zo searches the web, Tavily may be used to provide search results. - [Steel](https://steel.dev) `No data access` When Zo operates a web browser, Steel provides the underlying browser infrastructure. - [Pipedream](https://pipedream.com) `No data access` When you connect Zo to external services like Google Calendar, Google Tasks, Google Drive, or Dropbox, Pipedream facilitates the connection. - `Internal systems` - [Sentry](https://sentry.io) `No data access` Sentry is used to report system errors. - [Logfire](https://pydantic.dev/logfire) `No data access` Logfire is used to trace system performance. - [Posthog](https://posthog.com) `No data access` PostHog collects analytics on usage and pageviews. - [Postmark](https://postmark.com) `No data access` All email processing and delivery is handled by Postmark. Postmark has a 45-day retention period for email address, header, and diagnostic information but does not retain the email contents. - [Telnyx](https://telnyx.com) `No data access` All SMS/MMS processing and delivery is handled by Telnyx. Telnyx has a 10-day retention period for messages. - [Stripe](https://stripe.com) `No data access` All billing is handled through Stripe. Stripe stores personal data (name, email address, payment information) for the purpose of facilitating payment. We do not store personal credit card information for any of our customers. Stripe is certified as “PCI Service Provider Level 1”, which is the highest level of certification in the payments industry. - [Google Workspace](https://google.com) `No data access` We use Google Workspace for internal communication and documents. We may communicate with you about your account over email and to help you use Zo. - [Discord](https://discord.com) `No data access` We use Discord to host the Zo community. We may use Discord to communicate with you about your account and to help you use Zo. “Partial data” means snippets of files or entire files may be selected as context for AI inference requests. "Data storage" refers to the storage of user data files and data related to the user's account. "No data access" means the service provider never has access to user data files. We have no infrastructure, service providers, or investors based in China. ## Our AI system components. The Zo Computer AI system consists of three components: 1. `Zo Application`: The end-user application, running on the user's personal server, provides the user interface, file management, and settings. It communicates with and executes tools as requested by the Zo agent. 2. `Zo Agent`: The AI agent, hosted on Modal with additional providers listed above, handles orchestrating interactions between the user, the LLM, and tools requested by the LLM. 3. `Zo Server`: Internal services, hosted on Modal and Cloudflare with additional providers listed above, handle authentication, user accounts, agent tasks, storage, and usage tracking. ## How Zo AI works. Users can start or continue conversations with Zo. A conversation is a sequential interaction between the user and the Zo agent, which orchestrates interactions between the user, the LLM, and tools requested by the LLM. When a user starts a new conversation, the Zo application, running on the user's personal server, collects local contextual information such as file snippets, metadata about open files, and relevant application state. For additional context, the application may use built-in tools such as Bash commands to provide additional information. The collected context, along with the user’s prompt and conversation history, if applicable, is sent to the Zo agent and then to the LLM inference provider. After processing, the LLM’s response is returned through the Zo agent back to the Zo application. The Zo application displays the response and takes additional actions based on the response, such as using built-in tools requested by the LLM and sending them back to the Zo agent for the next step in the agentic loop. ## We do not train AI on your data. Zo Computer does not train models on user data or activity. Our long-term vision is to allow users to use and train their own open-weight models running on their own personal server. ## Vulnerability disclosures. Zo Computer welcomes feedback from security researchers to help improve our security. If you believe you have discovered a vulnerability, privacy issue, exposed data, or other security issues we want to hear from you. This policy outlines steps for reporting vulnerabilities to us, what we expect, and what you can expect from us. This policy applies to Zo Computer and related digital assets owned, operated, or maintained by Zo Computer Company ### Out of scope - We’re interested in prompt injection and LLM security research, please report findings to us. However, due to the inherent nature of LLMs, these vulnerabilities aren’t typically eligible for bug bounty rewards. - Assets not related to Zo Computer, or not owned by Zo Computer Company, are out of scope. Vulnerabilities discovered or suspected in out-of-scope systems should be reported to the appropriate vendor or authority. ### Our commitments When working with us, according to this policy, you can expect us to: - Respond to your report promptly, and work with you to understand and validate your report. - Strive to keep you informed about the progress of a vulnerability as it is processed. - Work to remediate discovered vulnerabilities in a timely manner, within our operational constraints. - Extend Safe Harbor for your vulnerability research that is related to this policy. ### Our expectations In participating in our vulnerability disclosure program in good faith, we ask that you: - Play by the rules, including following this policy and any other relevant agreements. If there is any inconsistency between this policy and any other applicable terms, the terms of this policy will prevail. - Report any vulnerability you’ve discovered promptly. - Avoid violating the privacy of others, disrupting our systems, destroying data, and/or harming user experience. - Use only the `Official Channels` to discuss vulnerability information with us. - Provide us a reasonable amount of time (at least 30 days from the initial report) to resolve the issue before you disclose it publicly. - Perform testing only on in-scope systems, and respect systems and activities which are out-of-scope. - If a vulnerability provides unintended access to data: Limit the amount of data you access to the minimum required for effectively demonstrating a Proof of Concept; and cease testing and submit a report immediately if you encounter any user data during testing, such as Personally Identifiable Information (PII) or proprietary information. - You should only interact with test accounts you own or with explicit permission from the account holder. - Do not engage in extortion. ### Official channels - Please report security issues via [security@zocomputer.com](mailto:security@zocomputer.com), providing all relevant information. The more details you provide, the easier it will be for us to triage and fix the issue. ### Safe harbor When conducting vulnerability research, according to this policy, we consider this research conducted under this policy to be: - Authorized concerning any applicable anti-hacking laws, and we will not initiate or support legal action against you for accidental, good-faith violations of this policy. - Authorized concerning any relevant anti-circumvention laws, and we will not bring a claim against you for circumvention of technology controls. - Exempt from restrictions in our [Terms of Service](/docs/information/terms) that would interfere with conducting security research, and we waive those restrictions on a limited basis. - Lawful, helpful to the overall security of the Internet, and conducted in good faith. - You are expected, as always, to comply with all applicable laws. If legal action is initiated by a third party against you and you have complied with this policy, we will take steps to make it known that your actions were conducted in compliance with this policy. If at any time you have concerns or are uncertain whether your security research is consistent with this policy, please submit a report through one of our `Official Channels` before going any further. Note that the Safe Harbor applies only to legal claims under the control of the organization participating in this policy, and that the policy does not bind independent third parties. --- # Terms of service Terms of Service last updated: August 8th, 2025 By signing up, installing, downloading, or otherwise accessing or using the services, you agree that you have read and understood, and agree to be bound by these terms (“the agreement”). Zo Computer is a service provided by Zo Computer Company. 1. License. Zo Computer Company grants you a limited, revocable, non-exclusive, non-transferable, non-sublicensable license to access and use Zo Computer (alternatively, the “Services”). You agree to use the Services in accordance with our Acceptable Use Policy. 2. License for User Content. You grant Zo Computer Company a license to access your User Content (which includes any data, text, other works of authorship, source code that you post or transmit to the Services) in order for Zo Computer Company to provide the Services to you. You retain all ownership of and responsibility for your User Content, including obtaining all necessary permissions to provide and make your User Content accessible to the Services. As between the Parties, You retain all right, title, and interest in and to User Content, including any Outputs adopted by You. Notwithstanding the foregoing, Zo Computer Company may retain and store User Content for the sole purpose of providing the Services to You. 3. Ownership of the Services. The Services are owned and operated by Zo Computer Company. As between the parties, Zo Computer Company owns all right, title, and interest in the Services, and You own all right, title, and interest in your User Content. Except as expressly set forth herein, each party retains all right, title, and interest in and to its intellectual property rights. All of Substrate Lab’s trademarks, service marks, and trade names are proprietary to Zo Computer Company or its affiliates. 4. Feedback. You may submit comments or ideas about the Services, such as how to improve it (“Feedback”). By submitting a comment or idea, you agree that your disclosure is gratuitous, unsolicited and without restriction and Zo Computer Company is free to use the comment or idea without any additional compensation to you. 5. Usage Data. Zo Computer Company may collect performance, analytical, or usage data (together, “Usage Data”) derived from your use of the Services to develop, improve, support, and operate our products. Usage Data does not include any User Content. Usage Data is subject to the confidentiality protections under these Terms, provided however that Zo Computer Company may anonymize and aggregate it with other data to be shared publicly 6. Term and Payment. The Term of this Agreement begins on the date that you begin using the Services and terminates as of the last day you use the Services; you will be required to purchase credits in advance. If you incur any charges during your use of the Services that have not been prepaid, you must pay those fees immediately. 7. Warranties. THE SERVICES MADE AVAILABLE PURSUANT TO THESE TERMS ARE PROVIDED ON AN “AS IS” AND “AS AVAILABLE” BASIS WITHOUT WARRANTIES OF ANY KIND, WHETHER EXPRESS, IMPLIED, OR OTHERWISE. WITHOUT LIMITING THE GENERALITY OF THE FOREGOING, TO THE FULLEST EXTENT PERMISSIBLE UNDER APPLICABLE LAW, Zo Computer Company DISCLAIMS, ON BEHALF OF ITSELF AND ITS LICENSORS, ALL WARRANTIES, WHETHER EXPRESS, IMPLIED, OR OTHERWISE, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NONINFRINGEMENT. FURTHER, Zo Computer Company DOES NOT WARRANT THAT THE SERVICES OR CODE DATA OR ANY PART THEREOF (OR YOUR ACCESS THERETO) WILL BE UNINTERRUPTED OR ERROR-FREE, WILL MEET YOUR REQUIREMENTS, OR THAT DEFECTS WILL BE CORRECTED. 8. Limitation of Liability. EACH PARTY WILL BE LIABLE TO THE OTHER PARTY FOR DIRECT DAMAGES ONLY. THE FOLLOWING TYPES OF DAMAGES WILL BE EXCLUDED: INDIRECT DAMAGES, CONSEQUENTIAL DAMAGES, SPECIAL DAMAGES, PUNITIVE DAMAGES, LOST PROFITS, LOST REPUTATION, AND COST OF REPLACEMENT SERVICES. EXCEPT FOR EXCLUDED CATEGORIES, GROSS NEGLIGENCE AND WILLFUL MISCONDUCT, OR WHERE PROHIBITED BY LAW. NEITHER PARTY’S TOTAL LIABILITY TO THE OTHER (AGGREGATED ACROSS ALL CLAIMS ARISING IN CONNECTION WITH THIS ZO COMPUTER LICENSE) WILL EXCEED $100. 9. Governing Law and Jurisdiction. The Agreement will be interpreted according to the laws of the state of New York. The parties submit to the personal jurisdiction of the federal and state courts located in Kings County, New York. 10. Arbitration. In the event of a dispute, you agree to first contact Zo Computer Company at [help@zocomputer.com](mailto:help@zocomputer.com) and attempt to resolve the dispute informally. 11. Waiver. A party’s failure to exercise or enforce any right or provision of the Agreement will not constitute a waiver of such right or provision. Any waiver of any provision of the Agreement will be effective only if in writing and signed by the waiving party. 12. Severability. If any provision of the Agreement is held to be unlawful, void, or for any reason unenforceable, then that provision will be limited or eliminated from the Agreement to the minimum extent necessary and will not affect the validity and enforceability of any remaining provision. 13. Assignment. The Agreement and any rights and licenses granted hereunder, may not be transferred or assigned by either party without written consent, except in connection with a merger, acquisition, reorganization, or sale of substantially all assets. 14. Survival. Upon termination of the Agreement, any provision which, by its nature or express terms should survive, shall survive such termination or expiration. 15. Headings. The heading references herein are for convenience only, do not constitute a part of the Agreement, and will not be deemed to limit or affect any of the provisions hereof. 16. Entire Agreement. This, including the agreements incorporated by reference, constitutes the entire agreement between the Parties relating to the subject matter herein and will not be modified except in writing, signed by both parties, or by a change made by Zo Computer Company as set forth in the Agreement. 17. Claims. To the extent permissible under applicable law, the Parties agree that any cause of action you may have arising out of or related to the Services must commence within eighteen (18) months after the cause of action accrues. Otherwise, such cause of action is permanently barred. 18. Disclosures. The Services are offered by Zo Computer Company, located at 13 Grattan St Unit 102, Brooklyn, NY 11206, and can be reached via email at [help@zocomputer.com](mailto:help@zocomputer.com). --- # Privacy policy Privacy Policy last updated: May 20th, 2026 Zo Computer ("Zo", "we", "us") operates the website at [https://www.zo.computer](https://www.zo.computer) and related services (the "Service"). This Privacy Policy explains what data we collect, how we use it, and the choices you have. If you have any questions, contact us at [help@zocomputer.com](mailto:help@zocomputer.com). ### Table of contents - Introduction - Contact information - Types of data collected - How and where we process data - Details on processing activities - Your rights (GDPR) - State-specific information (CA, VA, CO, CT, UT) - Additional information - Definitions ### Introduction This document explains how Zo collects, uses, and protects your personal data for the purposes described below. "Personal data" means information that identifies you directly or indirectly. Examples include your name, email address, usage data, and device information. Some sections below provide additional, context-specific details. ### Contact information - Address: 13 Grattan St Unit 102, Brooklyn, NY 11206, USA - Email: [help@zocomputer.com](mailto:help@zocomputer.com) ### Types of data collected We collect the following categories of personal data directly or through third parties: - email address - trackers (e.g., cookies and similar technologies) - usage data Unless otherwise noted, data requested by the Service is required to provide the Service. If you choose not to provide required data, we may be unable to deliver parts of the Service. Trackers and other similar technologies are used to provide and improve the Service as described in this policy. You are responsible for any third-party personal data you provide to us. ### Text messaging If you opt in to receive SMS messages from Zo, we may collect the following personal information: - Your mobile phone number - Any information you provide in your message responses - Message delivery and interaction data — timestamps, status, etc. Zo does not sell or share your SMS opt-in data with third parties for their marketing purposes. You can opt out of SMS messages at any time by replying “STOP” to any message. After you opt out, you will no longer receive text messages from us unless you opt in again. To request access to or deletion of your SMS-related data, please contact us at [help@zocomputer.com](mailto:help@zocomputer.com). ### How and where we process data - Methods: We implement technical and organizational safeguards to prevent unauthorized access, disclosure, modification, or destruction of data. Processing uses IT-enabled tools and procedures appropriate to the stated purposes. - Access: Data may be accessible to internal teams (e.g., engineering, support) when necessary to keep the Service operational. - Location: Data is processed at our offices and at locations of service providers. Transfers to other countries may occur as needed to operate the Service. - Retention: Unless otherwise stated, we retain data as long as necessary for the purposes collected, and longer where required by law or with your consent. When retention ends, we delete the data. ### Details on processing activities We process personal data to operate, maintain, and improve the Service; to comply with legal obligations; to respond to enforcement requests; to protect our rights and interests; to detect and prevent fraud and abuse; and for the specific activities described below. #### Analytics We may use analytics services to help us understand usage of the Service (page views, interactions, diagnostic events). These services use trackers and usage data. For information about opting out of analytics provided by your browser or add-ons, refer to the provider documentation. #### Fonts and external content We may use hosted fonts (e.g., Google Fonts) and embed externally hosted content or widgets. These services may collect usage data and use trackers on pages where they are used. See the provider’s privacy documentation for details. #### Bot detection and abuse prevention To protect account signup and login from automated abuse, we use Cloudflare Turnstile, a bot-detection service provided by Cloudflare, Inc. When you sign up or log in, Turnstile runs a challenge that may process technical signals such as your IP address, browser and device characteristics, and interaction data to distinguish humans from automated traffic. Cloudflare processes this data as our service provider and, per its Turnstile Privacy Policy, does not use it to track users or for advertising. For details, see the [Cloudflare Turnstile Privacy Policy](https://www.cloudflare.com/turnstile-privacy-policy/) and the [Cloudflare Privacy Policy](https://www.cloudflare.com/privacypolicy/). #### Contacting us When you contact us (e.g., via email or form), we process the personal data you provide (e.g., name, email, message) to respond to your request. ### Legal bases (EEA/UK/Switzerland) Where required, we rely on one or more of the following legal bases: - your consent - performance of a contract or pre-contractual measures - compliance with legal obligations - legitimate interests pursued by us or a third party, balanced against your interests and rights ### Your rights (GDPR) Subject to legal limits, you have the right to: - withdraw consent - object to processing - access your data - rectify inaccurate data - restrict processing - delete your data - receive your data in a portable format and transmit it to another controller - lodge a complaint with a supervisory authority How to exercise your rights: Contact us using the details above. Requests are free of charge and will be answered as required by law. ### State-specific information (United States) The following sections supplement this policy for residents of specific U.S. states. Terms like "personal information" have the meanings given in the relevant statutes. #### California (CCPA/CPRA) - Categories collected: identifiers; internet or other electronic network activity information. - Sensitive personal information: not collected. - Purposes: operation of the Service; security and fraud prevention; compliance; service improvement; communications. - Retention: no longer than necessary for the purposes collected unless otherwise stated. - Sources: directly from you; indirectly from your use of the Service; from service providers. - Disclosures for a business purpose: to service providers as needed to operate the Service. - Sale or sharing: We do not "sell" or "share" personal information as defined by the CCPA/CPRA. - Opt-out: If you believe your data is sold or shared, contact us; we will honor applicable opt-out rights. - Consumer rights: access, deletion, correction, portability, opt-out (where applicable), and non-discrimination. Submit requests via the contact information above. We will acknowledge within 10 days and respond within the statutory period. #### Virginia (VCDPA), Colorado (CPA), Connecticut (CTDPA), Utah (UCPA) For residents of these states: - Categories collected: identifiers; internet information. - Sensitive data: not collected. - Purposes: operation, security, compliance, service improvement, communications. - Sharing: to service providers to operate the Service. - Sale and targeted advertising: We do not sell personal data or process it for targeted advertising. - Rights: access, correction, deletion, portability, opt-out of certain processing (where applicable), and non-discrimination. Exercise your rights via the contact information above. ### Additional information - Legal requests: We may disclose data when required by law or in response to valid legal process. - Logs and maintenance: We may maintain logs and similar records for operation and security. - Changes to this policy: We may update this policy. We will post updates here and update the “Last updated” date. Where required, we will seek renewed consent. ### Definitions - Personal data: any information that identifies or can reasonably be linked to an identified or identifiable individual. - Usage data: information collected automatically, including IP address, browser type, operating system, referring pages, time of requests, and interaction data. - Tracker: technologies that store or access information on a device (e.g., cookies, pixels, local storage). - Service: the website and related services provided by Zo at zo.computer. --- # Contact How to get in touch For support or general inquiries, email [help@zocomputer.com](mailto:help@zocomputer.com). ### Mailing address ``` Zo Computer Company 13 Grattan St Unit 102 Brooklyn, NY 11206 ```