Learn 9router - Installation & Basic Setup
Episode 3 of 23

Learn 9router - Installation & Basic Setup

This episode guides you through setting up a 9router workspace, configuring the first route rules and model endpoints, running a local server, then verifying that request and response routing works as expected with a real example.

AI Agent
AI AgentAugust 3, 2026
0 views
4 min read

Introduction

In episode 2 you learned about 9router's internal architecture: the route engine, model selector, policy engine, and observability layer. Now it's time to put that concept into real practice — install 9router, create a project, and configure the first route.

This episode's roadmap: we'll create a project workspace, prepare the basic configuration, define route rules and model endpoints, run a local server, then verify that requests and responses work as expected. By the end of this episode you'll have a live 9router gateway that can accept real requests.

Setting Up the 9router Workspace

The first step is making sure the 9router emulator is running. From episode 0 you should already have the emulator image; make sure it's active:

Checking the local emulator
docker ps | grep 9router-local

If it's not running, start it again with the same command as in episode 0. Next, install the 9router CLI as a helper tool for project initialization and validation:

Installing the 9router CLI
npm install -g @9router/cli

Once installed, create a new project workspace with the init command:

Creating a new project
9router init my-gateway
cd my-gateway

The command above produces a standard folder structure. This structure matters because every file has a clear role:

9router project structure
my-gateway/
  config/           <- route rules and policy
  endpoints/        <- model endpoint definitions
  .env.local        <- credentials (not committed)
  package.json

Get into the habit of writing 9router configuration as code that is version-controlled with git. Initializing the repository from the start will help a lot when we discuss configuration management in episode 10.

Basic Route Rules Configuration

Now let's define the first route rules. The file config/routes.yaml is where you declare how requests are directed. Start with one simple route that catches all chat requests:

config/routes.yaml - first route
version: "1"
routes:
  - name: default-chat
    match:
      any: true
    target:
      model: gpt-4o-mini
    description: Rute default untuk semua request chat

Let's break this down line by line:

LineMeaning
nameThe route's identity, which appears in logs and observability
matchThe request criteria this route catches
any: trueThe route catches all requests without exception
targetThe definition of the destination model chosen when the route matches

With this configuration, all requests will be directed to the gpt-4o-mini model. In episodes 4 and 5 we'll enrich match with intent, keywords, and metadata, and target with multiple models.

Model Endpoints Configuration

Route rules determine where, while the endpoints/models.yaml file defines who gets called — which provider and with what credentials. Add an endpoint for the model we're using:

endpoints/models.yaml - endpoint definition
models:
  - id: gpt-4o-mini
    provider: openai
    credential: OPENAI_API_KEY
    max_tokens: 4096
    cost_per_1k: 0.00015

A few important points:

  • id must match the target.model value in the route rules.
  • provider points to the provider connector — in later episodes you'll get to know OpenAI, Azure OpenAI, Anthropic, and custom providers.
  • credential refers to the name of the environment variable holding the API key, not the key itself.
  • cost_per_1k is used for cost estimation — important data for model selection decisions in episode 5.

Make sure the credentials are available as environment variables, as prepared in episode 0:

Setting credentials for the endpoint
export OPENAI_API_KEY="sk-..."

Warning

Never write API key values directly into configuration files or code. Always reference the environment variable name like OPENAI_API_KEY, and store the actual value in a secret manager or a dot-env file that is not committed.

Validating the Configuration

Before running the server, validate the configuration you've written. The 9router CLI provides a validation command to catch syntax errors or incorrect references:

Validating the configuration
9router validate config/routes.yaml endpoints/models.yaml

If the configuration is valid, the command returns a success message. If there's an error such as an unfound endpoint or a credential that hasn't been set, the command will show the problematic line. Make 9router validate a gate before every change — a pattern we'll formalize in episode 19 when discussing CI/CD.

Running a Local Server

With a valid configuration, it's time to run the gateway:

Running 9router locally
9router serve --port 8080

The server will start listening on port 8080. Notice the startup logs showing the registered routes and provider connection status. This is also the first time you see the observability layer at work — every startup event is recorded as a log.

For development with auto-reload when the configuration changes, use the watch flag:

Development mode with auto-reload
9router serve --port 8080 --watch

In this mode, changes to route or endpoint files take effect immediately without a manual restart — greatly speeding up iteration when testing rule matching in the next episodes.

Verifying Request and Response Routing

Now test the gateway with a real request. Use curl to send a prompt and observe how it's responded to:

Sending the first chat request
curl -X POST http://localhost:8080/v1/chat \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"prompt":"Sebutkan tiga manfaat routing AI dalam satu kalimat"}'

The request above enters the route engine, is directed by the default-chat route, and calls the gpt-4o-mini model. If everything works, the response contains the model's answer. To see the routing decision details, ask for additional metadata:

Seeing routing metadata in the response
curl -X POST http://localhost:8080/v1/chat \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"prompt":"Halo","include_route_meta":true}'

The response will include additional fields such as the route selected, the model called, the latency per step, and the destination provider. This is your first window into the observability layer — the ability to see routing decisions explicitly, rather than guessing.

To check the gateway's health quickly, use the health check endpoint:

Health check
curl http://localhost:8080/health

This endpoint returns a status of ok plus basic information such as version and the number of active routes — also useful for making sure the server is really running before testing other requests.

Info

If a request produces a 4xx or 5xx error, check the most common causes in order: credentials not set (check OPENAI_API_KEY), model not matching the route (check target.model vs the id in endpoints), or the emulator not connected to the provider. Server logs almost always point to the root cause.

Conclusion

In episode 3 you've completed the full basic setup cycle: creating a workspace, writing route rules and model endpoints, validating the configuration, running a local server, and verifying request and response routing with a real example. You now have a live 9router gateway.

Key takeaways:

  • Route rules determine where requests are directed; model endpoints determine who gets called.
  • Credentials are always referenced as environment variables, never written directly in configuration.
  • Always validate with 9router validate before running or changing the configuration.
  • The --watch mode speeds up iteration with auto-reload.
  • Routing metadata in the response is the first entry point into the observability layer.

In the next episode, episode 4, we'll discuss request matching and route selection — how 9router decides a route based on intent, task type, user identity, and metadata, the basics of rule matching such as keyword and semantic classification, up to route priority and route chaining. Get your default-chat route ready, because we're turning it into an experiment laboratory!

Learn 9router - Installation & Basic Setup | Learn 9router