How the AirTrail Flight Import Integration Works in TREK: A Technical Deep Dive

The TREK AirTrail flight import integration enables users to connect their AirTrail instance via Bearer API authentication, import flight reservations into trip plans, and optionally synchronize changes bidirectionally between the two systems.

The AirTrail flight import integration in the TREK repository (mauriceboe/TREK) allows travelers to seamlessly pull flight data from a self-hosted AirTrail instance directly into their TREK trip planner. This integration supports secure API credential storage, flexible TLS configuration options, and background synchronization to keep reservation data consistent across both platforms.

Configuring the AirTrail Connection

User Settings and API Credentials

The integration setup begins in Settings → Integrations, where the AirTrailConnectionSection.tsx component renders a configuration form. This interface collects the AirTrail instance URL, a Bearer API key, and optional flags for allowInsecureTls and writeEnabled (write-back synchronization).

When the user clicks Save, the client invokes airtrailApi.saveSettings() to POST the configuration to the server. According to the schema definitions in /shared/src/airtrail/airtrail.schema.ts, the server encrypts the API key before persistence and returns a masked placeholder (••••••••) to the client. This ensures the real secret never exposes itself to browser-based JavaScript, maintaining strict security hygiene.

Testing the Connection

Before importing flights, users can validate their configuration using the Test Connection button. This triggers airtrailApi.test({url, apiKey, allowInsecureTls}), which POSTs to /integrations/airtrail/test. The server attempts a lightweight health check against the AirTrail API and returns a connection status object containing {connected: true, flightCount: number}. The UI surfaces this result as a toast notification, confirming connectivity and displaying the number of available flights before proceeding.

Fetching and Importing Flights

Retrieving Available Flights

Once connected, the import workflow displays a flight picker via AirTrailImportModal.tsx. The client calls airtrailApi.flights() to GET /integrations/airtrail/flights. The server proxies this request to the configured AirTrail instance and normalizes each flight into the AirtrailFlight schema.

This schema—defined in /shared/src/airtrail/airtrail.schema.ts—standardizes fields including id, origin and destination airport codes, departure and arrival dates, airline details, and booking references. The normalized array renders in the modal, allowing users to preview their AirTrail inventory before selection.

Importing Selected Flights into Trips

After the user selects specific flights, the client invokes airtrailApi.import(tripId, flightIds), which POSTs to /trips/:tripId/reservations/import/airtrail. The server creates new reservation records with external_source: 'airtrail' and stores the original AirTrail flight identifier in the external_id field. This linkage preserves the relationship between TREK reservations and their source data.

The server returns an AirtrailImportResult object indicating how many flights were successfully imported and how many were skipped due to existing duplicates. The UI reports these counts to provide clear feedback on the import operation's scope.

Synchronization and Write-Back Features

Bidirectional Sync Support

Imported reservations can maintain live synchronization with AirTrail. Each reservation stores a sync_enabled flag, and the integration configuration tracks writeEnabled to determine if TREK should push local edits back to the AirTrail instance.

The airtrailApi.sync() method triggers a background job that re-fetches the user's AirTrail flight list, updates any changed reservation details in TREK, and flags removed flights as unsynchronized. Throughout the planner UI, reservation lists display AirTrail-specific labels and tooltips—such as "AirTrail – synced" or "AirTrail – not synced"—based on these flags. These status strings reside in the localization files under /shared/src/i18n/*/reservations.ts.

Practical Implementation Examples

// Configure the AirTrail connection
await airtrailApi.saveSettings({
  url: 'https://my-airtrail.example.com',
  apiKey: 'Bearer abc123',
  allowInsecureTls: false,
  writeEnabled: true,
});

// Verify connectivity before importing
const testResult = await airtrailApi.test({
  url: 'https://my-airtrail.example.com',
  apiKey: 'Bearer abc123',
});
if (testResult.connected) {
  console.log(`Connected – ${testResult.flightCount} flights available`);
}

// Retrieve available flights for the import picker
const flights = await airtrailApi.flights(); // Returns AirtrailFlight[]

// Import selected flights into a specific trip
await airtrailApi.import(tripId, ['flight-123', 'flight-456']);

// Trigger manual synchronization (optional)
const syncInfo = await airtrailApi.sync(); // Returns { changed: number }

All client-side API calls are thin wrappers around the core apiClient defined in /client/src/api/client.ts, ensuring consistent error handling and authentication headers across the integration.

Summary

  • Encrypted credential storage: API keys are encrypted server-side and masked in the UI, with configuration handled by AirTrailConnectionSection.tsx and validated against airtrail.schema.ts.
  • Connection validation: The airtrailApi.test() method verifies AirTrail connectivity via /integrations/airtrail/test before allowing imports.
  • Normalized data structure: Flights are transformed into the AirtrailFlight schema during retrieval, ensuring consistent data handling regardless of AirTrail's internal format.
  • External source tracking: Imported reservations carry external_source: 'airtrail' and external_id fields to maintain referential integrity with the source system.
  • Bidirectional synchronization: Optional write-back support and background sync jobs keep TREK reservations aligned with AirTrail changes when sync_enabled and writeEnabled are active.

Frequently Asked Questions

What data format does TREK use when importing AirTrail flights?

TREK normalizes flight data into the AirtrailFlight schema defined in /shared/src/airtrail/airtrail.schema.ts. This Zod-defined structure includes mandatory fields for flight ID, origin and destination IATA codes, departure and arrival dates, airline information, and ancillary booking details.

Is the AirTrail API key stored securely in TREK?

Yes. When airtrailApi.saveSettings() persists configuration, the server encrypts the API key before database storage. The client only receives a masked placeholder (••••••••) in subsequent responses, ensuring the actual Bearer token never exposes itself to browser-based JavaScript or network inspection.

Can TREK sync flight changes back to AirTrail?

Yes, provided the user enabled write-back during initial configuration. When writeEnabled is true and a specific reservation has sync_enabled set, modifications made within TREK can propagate back to the AirTrail instance via the synchronization endpoints, maintaining data consistency across both platforms.

How does TREK handle self-signed TLS certificates?

The integration supports an allowInsecureTls boolean flag in the connection settings. When enabled, TREK permits HTTPS connections to AirTrail instances using self-signed or otherwise untrusted TLS certificates. This flexibility supports local development environments and private network deployments without requiring public CA-signed certificates.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →