# Quickstart: Your First Agent

This tutorial walks you through building your first AI agent with Polyant in about 10 minutes. By the end you'll have an instance running locally, reachable via the OpenAI-compatible API, and visible in the admin panel.

> For a more detailed walkthrough of the full installation (system requirements, secret generation, first-login flow), see [Installation and Setup](https://docs.polyant.ai/getting-started/install). This page is intentionally compact and focused on getting a working agent end-to-end.

## Prerequisites

- Node.js 24
- Docker & Docker Compose
- An OpenAI or Anthropic API key (for the agent's LLM calls)

## 1. Clone and install

```bash
git clone https://github.com/polyant-ai/polyant.git
cd polyant
npm install
```

## 2. Configure environment

Copy the template and fill in the required values:

```bash
cp .env.example .env
```

Choose the PostgreSQL password before you start the database: Compose declares `POSTGRES_PASSWORD` as required and refuses to start without it. Replace `changeme` in both `POSTGRES_PASSWORD` and the password component of `DATABASE_URL`, which takes precedence when it is set, and use the same connection string in `packages/web/.env.local` below. Percent-encode the password component alone if it contains special characters.

Generate the required secrets:

```bash
# Engine encryption key (32-byte hex, protects instance secrets at rest)
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

# Auth secret (signs session tokens shared between web and engine)
openssl rand -hex 32

# Internal secret (bridges credentials login between web and engine)
openssl rand -hex 32
```

Paste them into `.env` as `ENCRYPTION_KEY`, `AUTH_SECRET`, and `AUTH_INTERNAL_SECRET`.

The simplest first-login path is the **credentials provider** (email + password):

- Set `INITIAL_ADMIN_EMAIL` and `INITIAL_ADMIN_PASSWORD` in `.env` if you want to pick them yourself.
- Without `INITIAL_ADMIN_PASSWORD` no admin is seeded at all: the engine logs that it skipped the seed rather than generating a password into its own log file. Set it and restart.

**Google sign-in is available with managed services.** The open-source build signs in with email and password only. With managed services it is optional: the button only appears when both `GOOGLE_CLIENT_ID` and `GOOGLE_CLIENT_SECRET` are set, from the [Google Cloud Console](https://console.cloud.google.com) → APIs & Services → Credentials.

With managed services, configuring the provider does **not** open sign-in to any Google account. Two product rules decide who is admitted - the organization's SSO domain list and the rule that entry is by invitation - and there is no environment variable for either. See [Who may sign in with Google](https://docs.polyant.ai/admin-panel/authentication#who-may-sign-in-with-google).

### Mirror the auth secrets into `packages/web/.env.local`

Next.js does NOT auto-load the monorepo-root `.env`. The admin panel reads its own `.env.local`, so duplicate the auth-related vars there. Same values you already pasted into `.env`:

```bash
cat > packages/web/.env.local <<'EOF'
AUTH_SECRET=<paste the same value as in .env>
AUTH_INTERNAL_SECRET=<paste the same value as in .env>
DATABASE_URL=postgresql://polyant:<your POSTGRES_PASSWORD>@localhost:5432/polyant
NEXT_PUBLIC_API_URL=http://localhost:4000
INTERNAL_ENGINE_URL=http://localhost:4000
AUTH_TRUST_HOST=true
EOF
```

> `AUTH_TRUST_HOST=true` is required when running on `localhost:3000` (Auth.js validates the request host; without this it rejects sessions with `UntrustedHost` errors).

## 3. Start the database

```bash
docker compose up -d
```

PostgreSQL 16 with pgvector runs on port `5432`.

## 4. Run migrations

```bash
npm run db:migrate
```

This creates all tables: instances, conversations, messages, memories, secrets, channels, skills, etc. A fresh database starts with no agent: you create the first one in step 6.

## 5. Start the engine and admin panel

Open two terminals:

```bash
# Terminal 1 - engine on :4000
npm run dev

# Terminal 2 - admin panel on :3000
npm run dev:web
```

## 5b. Set a new password (first-login only)

After signing in for the first time, you'll be redirected to **`/password-change`** - the seed admin is created with the `must_change_password` flag on.

Type a new password twice and click **Update password**. You then land on the dashboard and Step 6 below picks up.

The first time a new account opens the panel, a full-screen **Guided setup** offers to do steps 6 to 9 for you: a provider and its key, the model, the agent, a test chat, the agent's channels and key, and optional knowledge, followed by a short introduction to the interface. Follow it, or click **Skip all** and continue with the steps below; the **Help** menu in the header reopens it later. See [Overview → First-access guidance](https://docs.polyant.ai/admin-panel/overview#first-access-guidance).

> If your browser's password manager tries to autofill the OLD saved password into the NEW password field, click *outside* the field once to dismiss the popover and re-type - Polyant explicitly tells the extensions to ignore those inputs but some still try.

## 6. Create your first instance

On the login page and in the panel header, use the flag menu in the top-right corner to choose the language.

Open `http://localhost:3000` and sign in with the platform-admin credentials you set via `INITIAL_ADMIN_EMAIL` and `INITIAL_ADMIN_PASSWORD`. With managed services, if you configured Google OAuth, that button is also available.

Open **Agents** in the sidebar, click **Add** and fill in:

| Field       | Value                   |
|-------------|-------------------------|
| Slug        | `hello-world`           |
| Name        | Hello World             |
| Description | My first Polyant agent |

Create the agent first: its **Model** section lets you configure the **Conversation** task, including that agent's provider, model and, in the open-source build, provider key.

The agent's sections are rows in the sidebar, addressed as `?tab=<section>` - there is no tab row. Open **Model**, set the provider and the model, and enter the provider's API key (e.g. `openai_api_key`) in the same section, beside the task that uses it. With managed services there is no key to enter there: open **Providers** and bind the conversation to a [provider connection](https://docs.polyant.ai/admin-panel/provider-connections#binding-an-agents-roles), or the agent answers nothing. Keys a tool needs are entered in that tool's panel on the **Tools** section.

## 7. Customize the prompt

Open the **Prompts** section. You'll see 7 sections - identity, soul, tooling, safety, skills, memory, user-identity. They start **empty**, except `05-skills`, which holds the `{{skillsList}}` placeholder that injects the agent's available skills.

Edit `01-identity` - tell the agent who it is. For example:

```markdown
# Identity

You are Atlas, a helpful assistant that answers coding questions concisely.
Prefer short code examples over long explanations.
```

Save.

## 8. Test the agent

Click **Try** in the page header. A chat drawer opens over the configuration, pinned to this agent - type a question and watch it respond in real time with tool calls and streaming output, while the page behind stays editable.

The workspace-level **Playground** (`/organizations/{org}/workspaces/{ws}/playground`) does the same thing with an agent picker, for when you are comparing agents rather than building one.

> A test chat is a real conversation: it is written to the agent's conversation history like any other channel.

## 9. Call the OpenAI-compatible API

The Playground needs nothing more, but the API does: a new agent starts with its **Web** channel off, and the endpoint answers `404` until you switch it on. It also starts with authentication required, so the channel needs a key first:

1. Open your agent's **Channels** section and select **Web/API**.
2. Leave **Require authentication** on and click **Generate key**. Copy the key and keep it for your client: once saved it can no longer be shown, only replaced. This is the key you create for access to this agent, separate from your model provider's key.
3. Switch **Web channel enabled** on.
4. Click **Save changes** in the page header.

Set `AGENT_API_KEY` in the terminal where you will run the request to the same key you saved:

```bash
export AGENT_API_KEY='<paste your agent API key>'
```

Call the instance with that key:

```bash
curl -s http://localhost:4000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AGENT_API_KEY" \
  -d '{
    "model": "hello-world",
    "messages": [{"role": "user", "content": "Hi, what can you do?"}]
  }'
```

The `model` field is your instance slug. Every instance in the admin panel is exposed as a selectable model.

## What's next?

- **Add memory** - in the **Advanced** section, turn on the **Memory** toggle (`memoryEnabled` in the API payload), and the agent will automatically extract and recall facts from conversations.
- **Connect a channel** - see [Connect a Channel](https://docs.polyant.ai/getting-started/connect-a-channel) to wire up Telegram, Slack, or WhatsApp.
- **Add a tool** - see [Add a Tool](https://docs.polyant.ai/how-to/add-a-tool).
- **Add a skill** - see [Write a Skill](https://docs.polyant.ai/how-to/write-a-skill).
- **Deploy** - see [Deployment](https://docs.polyant.ai/operations/deployment) for Docker, Render, Fly.io, and Kubernetes recipes.
- **Glossary** - unfamiliar with the terms? See [Glossary](https://docs.polyant.ai/concepts/glossary).
