# How to Set Up the AirTrail Addon for Flight Import Integration in TREK

> Easily set up the AirTrail addon for flight import integration in TREK. Configure settings and import flights directly into trips via REST endpoints. Get started now!

- Repository: [Maurice/TREK](https://github.com/mauriceboe/TREK)
- Tags: how-to-guide
- Published: 2026-07-04

---

**Enable the AirTrail addon globally in the Admin panel, configure your self-hosted instance URL and API key in Settings, then import flights directly into trips using the dedicated REST endpoints.**

TREK is an open-source travel management platform that integrates with self-hosted AirTrail instances through a dedicated addon. This integration allows users to import flight data directly into trip reservations and optionally synchronize changes back to AirTrail. The setup involves three distinct layers: global addon registration, per-user credential configuration, and flight import processing.

## Enable the AirTrail Addon Globally

Administrators must activate the AirTrail addon before any user can access the integration. The addon definition is hard-coded in [[`server/src/db/seeds.ts`](https://github.com/mauriceboe/TREK/blob/main/server/src/db/seeds.ts)](https://github.com/mauriceboe/TREK/blob/main/server/src/db/seeds.ts) (line 106) and registered in [[`server/src/addons.ts`](https://github.com/mauriceboe/TREK/blob/main/server/src/addons.ts)](https://github.com/mauriceboe/TREK/blob/main/server/src/addons.ts) (line 10).

1. Navigate to **Admin → Add‑ons** in the TREK interface.
2. Locate **AirTrail** (description: *Sync flights from your self‑hosted AirTrail instance*).
3. Toggle the addon **ON** and save.

When disabled, the addon’s `enabled` flag in the `addons` table hides all related UI components and API routes automatically.

## Configure Per-User AirTrail Connections

Each user must provide their AirTrail instance credentials to establish connectivity. The configuration schema is defined in [[`shared/src/airtrail/airtrail.schema.ts`](https://github.com/mauriceboe/TREK/blob/main/shared/src/airtrail/airtrail.schema.ts)](https://github.com/mauriceboe/TREK/blob/main/shared/src/airtrail/airtrail.schema.ts) and validated against `airtrailSettingsSchema`.

1. Go to **Settings → Integrations → AirTrail**.
2. Configure the following fields:
   - **Instance URL**: Your self‑hosted AirTrail address (e.g., `https://flights.example.com`). The server automatically appends `/api` to this URL.
   - **API key**: Bearer token generated in AirTrail under *Settings → Security*.
   - **Allow insecure TLS**: Enable only for LAN instances using self‑signed certificates.
   - **Write back changes**: Optional flag (`writeEnabled`) that pushes TREK reservation edits back to AirTrail.

3. Click **Save** to send a `POST /api/integrations/airtrail` request. The payload is validated and stored in the `users` table, with the `airtrail_api_key` encrypted at rest.
4. Click **Test connection** to verify connectivity via `GET /api/integrations/airtrail`. The endpoint returns connection status and flight count, displaying the API key masked as `••••••••` (enforced by `AIRTRAIL_KEY_MASK` at line 15).

## Import Flights into Trips

Once configured, users can import flights into specific trips using the import endpoints defined in [[`server/src/nest/integrations/airtrail-import.controller.ts`](https://github.com/mauriceboe/TREK/blob/main/server/src/nest/integrations/airtrail-import.controller.ts)](https://github.com/mauriceboe/TREK/blob/main/server/src/nest/integrations/airtrail-import.controller.ts).

1. Open a trip and navigate to the **Reservations** tab.
2. Select **Import → AirTrail**. The UI fetches available flights via `GET /api/integrations/airtrail`, which internally calls `listFlights` in [`airtrailClient.ts`](https://github.com/mauriceboe/TREK/blob/main/airtrailClient.ts).
3. Select desired flights and confirm. The client sends `POST /api/trips/:tripId/reservations/import/airtrail` with a payload matching `airtrailImportSchema` (array of flight IDs).
4. The controller invokes `importAirtrailFlights` from [[`server/src/services/airtrail/airtrailService.ts`](https://github.com/mauriceboe/TREK/blob/main/server/src/services/airtrail/airtrailService.ts)](https://github.com/mauriceboe/TREK/blob/main/server/src/services/airtrail/airtrailService.ts`), which:
   - Retrieves credentials via `getAirtrailCredentials`.
   - Maps flights to reservations using `airtrailMapper.mapFlightToReservation`.
   - Inserts `Reservation` records (type `flight`) into the `reservations` table.

The response follows `airtrailImportResultSchema`, showing successfully imported IDs and skipped entries with reasons (e.g., *already-imported*).

## Optional Background Sync and Write-Back

TREK supports bidirectional synchronization when write‑back is enabled.

- **Real‑time write‑back**: When `writeEnabled` is true, edits to imported reservations trigger `pushReservationToAirtrail` in [[`server/src/services/airtrail/airtrailSync.ts`](https://github.com/mauriceboe/TREK/blob/main/server/src/services/airtrail/airtrailSync.ts)](https://github.com/mauriceboe/TREK/blob/main/server/src/services/airtrail/airtrailSync.ts), posting updates to the AirTrail API.
- **Scheduled polling**: The background task `airtrailSyncTask` in [[`server/src/scheduler.ts`](https://github.com/mauriceboe/TREK/blob/main/server/src/scheduler.ts)](https://github.com/mauriceboe/TREK/blob/main/server/src/scheduler.ts) polls for new flights at intervals defined by the `airtrail_poll_interval_minutes` setting.

## Code Examples

### Enable the Addon via API

```bash
curl -X PATCH https://trek.example.com/api/admin/addons \
  -H "Authorization: Bearer <ADMIN_JWT>" \
  -H "Content-Type: application/json" \
  -d '{"id":"airtrail","enabled":true}'

```

### Configure User Credentials

```bash
curl -X POST https://trek.example.com/api/integrations/airtrail \
  -H "Authorization: Bearer <USER_JWT>" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://flights.myselfhosted.com",
    "apiKey": "my-bearer-token",
    "allowInsecureTls": false,
    "writeEnabled": true
  }'

```

### Test the Connection

```bash
curl -X GET https://trek.example.com/api/integrations/airtrail \
  -H "Authorization: Bearer <USER_JWT>"

```

*Successful response*:

```json
{
  "connected": true,
  "flightCount": 12,
  "url": "https://flights.myselfhosted.com",
  "apiKeyMasked": "••••••••",
  "allowInsecureTls": false,
  "writeEnabled": true
}

```

### Import Flights into a Trip

```bash
curl -X POST https://trek.example.com/api/trips/42/reservations/import/airtrail \
  -H "Authorization: Bearer <USER_JWT>" \
  -H "Content-Type: application/json" \
  -d '{
    "flightIds": ["f123", "f456"]
  }'

```

*Response example*:

```json
{
  "imported": ["f123"],
  "skipped": [
    {
      "flightId": "f456",
      "reason": "already-imported",
      "detail": "Flight already present in this trip"
    }
  ]
}

```

### Push Updates Back to AirTrail (Write-Back)

```typescript
import { pushReservationToAirtrail } from '@trek/server/src/services/airtrail/airtrailSync';

await pushReservationToAirtrail({
  reservationId: 789,
  tripId: 42,
  airline: 'Swiss',
  flightNumber: 'LX123',
  departure: '2026-09-01T10:00:00Z',
  arrival: '2026-09-01T13:00:00Z'
});

```

## Summary

- **Global enablement** is required first via the Admin panel, registering the addon in the database seeds.
- **Per-user configuration** stores encrypted credentials in the `users` table, validated against `airtrailSettingsSchema`.
- **Flight import** uses `POST /api/trips/:tripId/reservations/import/airtrail` to create reservations from AirTrail data.
- **Bidirectional sync** is available through the write‑back flag and background scheduler tasks.

## Frequently Asked Questions

### How do I enable the AirTrail addon in TREK?

Administrators must navigate to **Admin → Add‑ons** and toggle AirTrail to **ON**. This updates the `enabled` flag in the `addons` table and exposes the integration routes defined in [[`server/src/nest/integrations/airtrail.controller.ts`](https://github.com/mauriceboe/TREK/blob/main/server/src/nest/integrations/airtrail.controller.ts)](https://github.com/mauriceboe/TREK/blob/main/server/src/nest/integrations/airtrail.controller.ts).

### Where are AirTrail credentials stored in TREK?

User credentials are stored in the `users` table with the API key encrypted. The schema definition in [[`shared/src/airtrail/airtrail.schema.ts`](https://github.com/mauriceboe/TREK/blob/main/shared/src/airtrail/airtrail.schema.ts)](https://github.com/mauriceboe/TREK/blob/main/shared/src/airtrail/airtrail.schema.ts) defines the structure, while [[`server/src/services/airtrail/airtrailService.ts`](https://github.com/mauriceboe/TREK/blob/main/server/src/services/airtrail/airtrailService.ts)](https://github.com/mauriceboe/TREK/blob/main/server/src/services/airtrail/airtrailService.ts) handles retrieval through `getAirtrailCredentials`.

### Can TREK sync flight changes back to AirTrail?

Yes. When the **Write back changes** option is enabled during configuration, TREK invokes `pushReservationToAirtrail` from [[`server/src/services/airtrail/airtrailSync.ts`](https://github.com/mauriceboe/TREK/blob/main/server/src/services/airtrail/airtrailSync.ts)](https://github.com/mauriceboe/TREK/blob/main/server/src/services/airtrail/airtrailSync.ts) whenever you edit imported reservations, pushing updates to your AirTrail instance via its REST API.

### What happens if I disable the AirTrail addon after configuring it?

Disabling the addon hides all AirTrail UI elements and API routes immediately, though existing imported reservations remain in the database. Users cannot import new flights or sync changes until the addon is re‑enabled by an administrator.