# How to Configure and Enable the FastAPI Webhook API Server in Claude Code Telegram

> Configure and enable your FastAPI webhook API server for Claude Code Telegram. Learn to set environment variables like ENABLE_API_SERVER and API_SERVER_PORT for seamless integration.

- Repository: [Richard A/claude-code-telegram](https://github.com/richardatct/claude-code-telegram)
- Tags: how-to-guide
- Published: 2026-02-20

---

**Set `ENABLE_API_SERVER=true` and `API_SERVER_PORT=9000` in your environment variables to activate the FastAPI webhook server alongside the Telegram bot.**

The Claude Code Telegram bot (`RichardAtCT/claude-code-telegram`) includes an optional FastAPI webhook API server that listens for external events from services like GitHub. When you configure and enable the FastAPI webhook API server, it runs concurrently with the bot on a configurable TCP port, publishing incoming webhooks to the internal **EventBus** for asynchronous processing.

## Configuration Settings and Feature Flags

The server behavior is controlled through Pydantic settings defined in [`src/config/settings.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/config/settings.py) and exposed via feature flags in [`src/config/features.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/config/features.py).

### Enable API Server Flag

The `enable_api_server` boolean field determines whether the FastAPI application starts during bot initialization.

```python

# src/config/settings.py

enable_api_server: bool = Field(False, description="Enable FastAPI webhook server")

```

This value is accessed at runtime through `FeatureFlags.api_server_enabled` in [`src/config/features.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/config/features.py) (lines 60-63), which the main application loop checks before spawning the server task.

### Port Configuration

The `api_server_port` field specifies the TCP port that Uvicorn binds to.

```python

# src/config/settings.py – default value 8080

api_server_port: int = Field(8080, description="Webhook API server port")

```

If the port is already in use, the application will raise a `OSError` during startup, so ensure the chosen port is available in your environment.

## Enabling the Server via Environment Variables

The `Settings` class loads configuration from environment variables or an optional `.env` file (configured via `env_file=".env"`). To enable the webhook server on a custom port, add the following to your environment:

```dotenv
TELEGRAM_BOT_TOKEN=123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
APPROVED_DIRECTORY=/home/user/projects
ENABLE_API_SERVER=true
API_SERVER_PORT=9000

# Optional: secure your webhooks

GITHUB_WEBHOOK_SECRET=supersecret
WEBHOOK_API_SECRET=anothersecret

```

Variable names are case-insensitive and automatically mapped to the Pydantic fields (e.g., `ENABLE_API_SERVER` maps to `enable_api_server`).

## Application Startup Sequence

When `features.api_server_enabled` evaluates to `True`, the `run_application` function in [`src/main.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/main.py) (lines 310-320) creates an asynchronous task to start the server:

```python

# src/main.py – launching the server

if features.api_server_enabled:
    from src.api.server import run_api_server
    api_task = asyncio.create_task(
        run_api_server(event_bus, config, storage.db_manager)
    )
    tasks.append(api_task)

```

This task runs in the same asyncio event loop as the Telegram bot, eliminating the need for separate processes or inter-process communication.

## Webhook Processing Architecture

### FastAPI Application Structure

The `create_api_app` function in [`src/api/server.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/api/server.py) (lines 22-40) constructs the FastAPI instance with two primary endpoints:

- **Health check**: Returns service status
- **Webhook receiver**: `/webhooks/{provider}` route that accepts POST requests from external services

### Event Handling Flow

When a webhook arrives, the `receive_webhook` endpoint (lines 41-115) performs the following:

1. **Signature validation**: Verifies HMAC signatures for GitHub or Bearer tokens for generic webhooks using secrets from the configuration
2. **Deduplication**: Checks SQLite via `storage.db_manager` to prevent processing duplicate delivery IDs
3. **Event publication**: Creates a `WebhookEvent` object and publishes it to the `EventBus` defined in [`src/events/bus.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/events/bus.py)

The Telegram bot components subscribe to the `EventBus` and react to these events asynchronously.

## Testing Your Configuration

After setting `ENABLE_API_SERVER=true` and starting the application, verify the server is listening:

```bash

# Run with debug logging to see startup confirmation

make run-debug

```

Look for the log entry:

```

INFO  API server enabled  port=9000

```

Test the webhook endpoint with cURL:

```bash
curl -X POST "http://localhost:9000/webhooks/custom" \
     -H "Authorization: Bearer anothersecret" \
     -H "Content-Type: application/json" \
     -d '{"event":"test","payload":{"msg":"hello"}}'

```

Expected response:

```json
{
  "status": "accepted",
  "event_id": "a1b2c3d4-..."
}

```

## Summary

- **Enable the server** by setting `ENABLE_API_SERVER=true` in your environment or `.env` file, which maps to the `enable_api_server` field in [`src/config/settings.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/config/settings.py).
- **Configure the port** using `API_SERVER_PORT` (default `8080`), defined in the same settings file and accessed via `settings.api_server_port`.
- **Startup logic** in [`src/main.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/main.py) checks `features.api_server_enabled` and spawns `run_api_server` as an asyncio task when enabled.
- **Architecture** uses [`src/api/server.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/api/server.py) for the FastAPI application, [`src/events/bus.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/events/bus.py) for internal event distribution, and SQLite for webhook deduplication.

## Frequently Asked Questions

### What port does the FastAPI webhook server use by default?

The default port is **8080**, defined in [`src/config/settings.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/config/settings.py) via the `api_server_port` field. You can override this by setting the `API_SERVER_PORT` environment variable to any available TCP port.

### Can I run the webhook server without the Telegram bot?

No. The FastAPI server is designed to run as a **concurrent task within the same asyncio event loop** as the Telegram bot, as implemented in [`src/main.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/main.py). It relies on the shared `EventBus` and database manager initialized by the main application, so it cannot operate as a standalone service.

### How do I secure incoming webhook requests?

The server supports two authentication methods configured via environment variables. For **GitHub webhooks**, set `GITHUB_WEBHOOK_SECRET` to verify HMAC signatures. For **generic webhooks**, set `WEBHOOK_API_SECRET` and include it as a Bearer token in the `Authorization` header. Invalid signatures result in a 401 Unauthorized response.

### Where are webhook events stored before processing?

Incoming webhooks are deduplicated using **SQLite** via the `storage.db_manager` passed to `run_api_server`. The `receive_webhook` endpoint in [`src/api/server.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/api/server.py) checks delivery IDs against the database before publishing events to the `EventBus`, preventing duplicate processing of the same webhook payload.