AeroQuote → AeroPilot Integration Guide

Webhook Configuration

Share this page with the AeroQuote team to configure the integration.

1
Webhook Endpoint URL

Configure AeroQuote to send a

POST
request to this URL whenever a trip is created or updated:

https://aeroquote.aviationopsmanager.com/api/functions/aeroquoteWebhook

⚠️ Make sure to use POST method and include Content-Type: application/json header.

2
Authentication Header

Every request must include this header for security. The value is your AEROPILOT_WEBHOOK_SECRET (set in your AeroPilot environment variables):

x-webhook-secret
Header value: Use the value of the AEROPILOT_WEBHOOK_SECRET environment variable from your AeroPilot app settings. Requests without a valid secret will be rejected with 401 Unauthorized.
3
Request Body (JSON Payload)

The body must be valid JSON with a trip object containing at minimum one leg:

{
  "trip": {
    "trip_number": "AQ-001",
    "client_name": "John Smith",
    "status": "scheduled",
    "aircraft_type": "Citation CJ3",
    "aircraft_tail": "N123AB",
    "departure_date": "2026-05-01",
    "legs": [
      {
        "leg_number": 1,
        "departure_airport": "KMIA",
        "arrival_airport": "KTEB",
        "departure_time": "2026-05-01T08:00:00",
        "arrival_time": "2026-05-01T11:30:00"
      }
    ]
  }
}
FieldTypeNotes
trip.trip_numberstringUsed to match existing trips in AeroPilot
trip.client_namestringCustomer name
trip.statusstringscheduled | in_progress | completed | cancelled
trip.aircraft_typestringAircraft model name
trip.aircraft_tailstringTail number / registration
trip.departure_datestringYYYY-MM-DD format
trip.legs[].leg_numbernumberStarts at 1
trip.legs[].departure_airportstringICAO code (e.g. KMIA)
trip.legs[].arrival_airportstringICAO code (e.g. KTEB)
trip.legs[].departure_timestringISO 8601 or HH:MM
trip.legs[].arrival_timestringISO 8601 or HH:MM
4
AeroQuote-side: Create Backend Function

In your AeroQuote app, create a new backend function named pushTripToAeroPilot and paste this code:

import { createClientFromRequest } from 'npm:@base44/sdk@0.8.25';

Deno.serve(async (req) => {
  try {
    const base44 = createClientFromRequest(req);
    const user = await base44.auth.me();
    if (!user) return Response.json({ error: 'Unauthorized' }, { status: 401 });

    const { trip_id } = await req.json();

    // Fetch the trip from AeroQuote's database
    const trip = await base44.entities.Trip.get(trip_id);
    if (!trip) return Response.json({ error: 'Trip not found' }, { status: 404 });

    // Fetch the trip's legs
    const legs = await base44.entities.TripLeg.filter({ trip_id: trip.id });

    // Build the payload to send to AeroPilot Pro
    const payload = {
      trip: {
        trip_number: trip.trip_number,
        company_id: trip.company_id || '',
        client_name: trip.client_name || '',
        status: trip.status || 'scheduled',
        departure_date: trip.departure_date || null,
        return_date: trip.return_date || null,
        aircraft_type: trip.aircraft_type || '',
        aircraft_tail: trip.aircraft_tail || '',
        assigned_pilots: trip.assigned_pilots || [],
        pic_name: trip.pic_name || '',
        sic_name: trip.sic_name || '',
        notes: trip.notes || '',
        dispatch_notes: trip.dispatch_notes || '',
        legs: legs.map(leg => ({
          leg_number: leg.leg_number,
          departure_airport: leg.departure_airport,
          arrival_airport: leg.arrival_airport,
          departure_time: leg.departure_time || null,
          arrival_time: leg.arrival_time || null,
          status: leg.status || 'planned',
          fbo_departure: leg.fbo_departure || '',
          fbo_arrival: leg.fbo_arrival || '',
          fbo_departure_phone: leg.fbo_departure_phone || '',
          fbo_arrival_phone: leg.fbo_arrival_phone || '',
          fbo_departure_address: leg.fbo_departure_address || '',
          fbo_arrival_address: leg.fbo_arrival_address || '',
          passengers: leg.passengers || 0,
          flight_time_estimated: leg.flight_time_estimated || 0,
          notes: leg.notes || '',
        })),
      }
    };

    // ✅ FILL IN THESE TWO VALUES:
    const AEROPILOT_WEBHOOK_URL = 'YOUR_AEROPILOT_WEBHOOK_URL_HERE';
    const AEROPILOT_WEBHOOK_SECRET = 'YOUR_AEROQUOTE_WEBHOOK_SECRET_VALUE';

    const res = await fetch(AEROPILOT_WEBHOOK_URL, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-webhook-secret': AEROPILOT_WEBHOOK_SECRET,
      },
      body: JSON.stringify(payload),
    });

    const result = await res.json();
    console.log('AeroPilot sync result:', JSON.stringify(result));

    return Response.json({ success: true, result });
  } catch (error) {
    console.error('pushTripToAeroPilot error:', error);
    return Response.json({ error: error.message }, { status: 500 });
  }
});

✏️ Fill in these two placeholder values before saving:

YOUR_AEROPILOT_WEBHOOK_URL_HERE→ Copy from: AeroPilot app Dashboard → Code → Functions → aeroquoteWebhook → copy the endpoint URL shown in the top-right sidebar
YOUR_AEROQUOTE_WEBHOOK_SECRET_VALUE→ The exact value of AEROPILOT_WEBHOOK_SECRET set in AeroPilot app Settings → Environment Variables
5
AeroQuote-side: Set Up Entity Automation

In your AeroQuote app, create an Entity Automation so the function fires automatically on every trip change:

Entity

Trip

Function to run

pushTripToAeroPilot

Trigger events
create
update

Go to AeroQuote Dashboard → Code → Automations → New Automation → Entity type → select Trip → check create & update → select pushTripToAeroPilot.

6
Expected Response

On success, AeroPilot will respond with

200 OK
:

{
  "success": true,
  "trip_number": "AQ-001",
  "action": "updated",
  "trip_id": "abc123"
}
200 — Success
401 — Invalid secret
400 — Bad payload
AeroPilot → AeroQuote (Inbound)

Use this endpoint to push flight logs, maintenance entries, expenses, and crew duty updates from AeroPilot Pro → AeroQuote.

A
AeroPilot Inbound Endpoint URL

Configure AeroPilot Pro to send a

POST
request to this URL for any data sync:

https://aeroquote.aviationopsmanager.com/api/functions/aeropilotInbound
Same authentication header applies: x-webhook-secret with the value of AEROPILOT_WEBHOOK_SECRET.
B
Payload Types

Every request must include a type field that tells AeroPilot what to sync:

typeWhat it doesRequired fields
trip_updateFull trip data sync (route, aircraft, crew notes, legs)trip.trip_number
trip_statusLightweight status-only updatetrip_number, status
flight_logCreate or update a pilot flight log entrylog.trip_number, log.crew_email
maintenanceCreate or update an aircraft maintenance entrymaintenance.aircraft_tail, maintenance.start_date
expenseAdd a trip expense recordexpense.trip_number, expense.amount
crew_dutyUpdate crew duty status / duty times on a tripduty.crew_email, duty.trip_number

Sample Payloads

Flight Log

{
  "type": "flight_log",
  "log": {
    "trip_number": "AQ-001",
    "crew_email": "pilot@airline.com",
    "role": "PIC",
    "leg": "outbound",
    "origin_airport": "KMIA",
    "destination_airport": "KTEB",
    "out_time": "08:00",
    "off_time": "08:15",
    "on_time": "11:20",
    "in_time": "11:30",
    "flight_hours": 3.08,
    "block_hours": 3.5,
    "landings": 1,
    "night_hours": 0,
    "ifr_hours": 1.5
  }
}

Maintenance

{
  "type": "maintenance",
  "maintenance": {
    "aircraft_tail": "N123AB",
    "maintenance_type": "scheduled",
    "description": "100-hour inspection",
    "start_date": "2026-05-10",
    "end_date": "2026-05-12",
    "status": "scheduled",
    "notes": "AOG until complete"
  }
}

Expense

{
  "type": "expense",
  "expense": {
    "trip_number": "AQ-001",
    "category": "Fuel",
    "description": "Fuel at KTEB",
    "amount": 3200,
    "currency": "USD",
    "vendor_name": "Signature Flight Support",
    "airport_code": "KTEB",
    "fuel_gallons": 450,
    "fuel_price_per_gallon": 7.11,
    "expense_date": "2026-05-01"
  }
}

Crew Duty

{
  "type": "crew_duty",
  "duty": {
    "trip_number": "AQ-001",
    "crew_email": "pilot@airline.com",
    "duty_status": "on_duty",
    "duty_start_time": "07:00",
    "duty_end_time": "13:00"
  }
}