# Your first project

Create a Comvi project end to end: languages, keys, translations and a live CDN URL, without writing any app code.

Canonical: https://comvi.io/docs/platform/your-first-project

Go from an empty account to a project deployed on the CDN: a source language, two target
languages, four keys with values, and a URL that returns them as JSON. Connecting an app is
the next page, [Consume translations](/docs/platform/consume-translations).

1. **Create your account**

   Sign up at [app.comvi.io](https://app.comvi.io) with email or Google. Onboarding asks
   for an organization name, then a project name (for example `acme-web`) and a **source
   language**. English is pre-selected. The source language cannot be changed after the
   project exists, so pick the language your team writes in. You land on the Translations
   page.

2. **Add target languages**

   Open **Languages** in the sidebar, click **Add Language**, and add **French (fr)** and
   **German (de)**. Locale codes are canonical BCP-47 (`pt-BR`, `zh-Hant`, `sr-Latn`). If no
   standard code fits, choose **Create custom language...** in the same dialog and give it
   a code such as `de-formal`. Languages are unlimited on every plan.

3. **Create keys**

   Open **Translations**, click **Add Translation**, and create these four keys with their
   English source values:

   | Key | Source value |
   |---|---|
   | `greeting` | `Hello, {name}!` |
   | `welcome_message` | `Welcome to our application` |
   | `nav.home` | `Home` |
   | `nav.settings` | `Settings` |

   `{name}` is an ICU MessageFormat placeholder. Dot notation groups related keys; it is a
   convention, not nesting.

4. **Translate**

   Click any empty value in the French or German row and type the translation:

   | Key | French | German |
   |---|---|---|
   | `greeting` | `Bonjour, {name} !` | `Hallo, {name}!` |
   | `welcome_message` | `Bienvenue dans notre application` | `Willkommen in unserer Anwendung` |
   | `nav.home` | `Accueil` | `Startseite` |
   | `nav.settings` | `Paramètres` | `Einstellungen` |

   Every saved value lands as **Needs Review**, whoever saved it. Two other ways to fill
   values: configure a provider under **Settings → Machine Translation**, select keys and
   click **Translate** in the selection bar ([Machine translation](/docs/platform/machine-translation)),
   or upload `.json` files and `.zip` archives on the **Import** page
   ([Import & export](/docs/platform/import-export)). Machine translation spends MT credits
   from the organization's plan, 20,000 per billing period on the free plan; usage is under
   **Organization → Billing**.

5. **Mark values as reviewed**

   Click the status badge next to a value and choose **Translated**. Marking a value
   Translated needs review permission, which Editor and above have. See
   [Roles & permissions](/docs/platform/roles-permissions).

6. **Deploy to the CDN**

   Open **Settings → Content Deploy** and:

   - Click **Enable Content Deploy**.
   - Tick the three languages under **Locales**.
   - Tick `default` under **Namespaces**.
   - Under **Filter by Status**, tick **Translated** so drafts stay off the CDN.
   - Click **Save Settings**.

   From now on every write schedules a deploy about 5 seconds later, and a steady stream
   of writes is deployed at least every minute. **Deploy Now** next to the CDN endpoint
   pushes the current state immediately.

   > **An empty status filter ships drafts**
>
> Leaving every box under **Filter by Status** unchecked deploys all three statuses,
> including values nobody has reviewed. See [CDN settings](/docs/platform/cdn#cdn-settings).

7. **Fetch a bundle**

   Copy the URL under **CDN Endpoint** on the same page. It ends in a token that identifies
   the project. Request the English bundle:

   `Terminal`

   ```bash
   curl https://cdn.comvi.io/<project-token>/en.json
   ```

   `Response`

   ```json
   {
     "greeting": "Hello, {name}!",
     "welcome_message": "Welcome to our application",
     "nav.home": "Home",
     "nav.settings": "Settings"
   }
   ```

   Swap `en` for `fr` or `de` to fetch the other languages. Keys in the `default` namespace
   sit at the root of the endpoint; every other namespace gets its own folder.

8. **Create an API key (optional)**

   CDN URLs need no key. For the CLI, CI or a custom script, open **Settings → API Keys**,
   click **Create API Key**, name it (for example `github-actions-ci`) and copy the value.
   It is shown once. Keep it in an environment variable or a secrets manager, never in the
   repository. See [API keys](/docs/platform/api-keys).

## What you have

Keys and translations live in the Comvi database, the CDN serves them as JSON per language
and namespace, and an API key lets your tools automate the workflow. None of it is tied to a
framework: a web app, a mobile app, a backend service or a static site generator can read
the same bundles.

## Next steps

- [Consume translations](/docs/platform/consume-translations): Load the bundles into a web, mobile or backend app.
- [Translation lifecycle](/docs/platform/translation-lifecycle): How values move from untranslated to translated, and where deploys fit in.
- [Team management](/docs/platform/team-management): Invite translators, reviewers and developers with role-based access.
- [Machine translation](/docs/platform/machine-translation): Fill first drafts automatically and review them in the editor.
