Skip to main content
New Expensify offers multiple methods for tracking distance-based expenses, from real-time GPS tracking to manual waypoint entry. Choose the method that works best for your travel reimbursement needs.

Distance Tracking Methods

New Expensify supports four different ways to track mileage:

GPS Tracking

Real-time tracking that automatically records your route as you drive

Manual Entry

Type in start and end locations with optional waypoints

Map Selection

Select waypoints on an interactive map

Odometer

Enter odometer readings with a photo

GPS Distance Tracking

Real-time GPS tracking provides the most accurate mileage tracking.

Starting GPS Tracking

  1. Open New Expensify and tap the green + button
  2. Select Submit expense or Track expense
  3. Choose the Distance tab
  4. Select GPS tracking
  5. Grant location permissions when prompted
  6. Tap Start trip to begin recording
  7. Drive your route normally
  8. Tap Stop trip when you arrive
  9. Review and submit the expense
function IOURequestStepDistanceGPS({
    route: {
        params: {action, iouType, reportID, transactionID, backTo},
    },
    transaction,
}: IOURequestStepDistanceGPSProps) {
    const [isTracking, setIsTracking] = useState(false);
    const [distanceInMeters, setDistanceInMeters] = useState(0);
    const [waypoints, setWaypoints] = useState<GpsWaypoint[]>([]);

    const startTracking = useCallback(() => {
        setIsTracking(true);
        // Start watching position
        getCurrentPosition(
            (position) => {
                const newWaypoint = {
                    latitude: position.coords.latitude,
                    longitude: position.coords.longitude,
                    timestamp: Date.now(),
                };
                setWaypoints((prev) => [...prev, newWaypoint]);
            },
            (error) => {
                Log.error('GPS Error', error);
            },
            {enableHighAccuracy: true, distanceFilter: 10}
        );
    }, []);

    const stopTracking = useCallback(() => {
        setIsTracking(false);
        // Calculate total distance from waypoints
        const distance = calculateGPSDistance(waypoints);
        setDistanceInMeters(distance);
    }, [waypoints]);

    return (
        <DistanceCounter
            distance={distanceInMeters}
            isTracking={isTracking}
        />
    );
}

GPS Features

Real-time tracking:
  • Live distance counter
  • Current trip duration
  • Waypoint collection
  • Background location tracking (with permission)
Trip management:
  • Pause and resume tracking
  • Add manual waypoints
  • Edit route after completion
  • Save for later submission
GPS tracking requires location permissions. You’ll be prompted to grant access when starting your first trip.

Background Location Tracking

For uninterrupted tracking while using other apps:
function BackgroundLocationPermissionsFlow({
    onPermissionGranted,
    onPermissionDenied,
}: BackgroundLocationPermissionsFlowProps) {
    const requestBackgroundPermission = useCallback(async () => {
        const result = await request(PERMISSIONS.IOS.LOCATION_ALWAYS);
        
        if (result === RESULTS.GRANTED) {
            onPermissionGranted();
        } else {
            onPermissionDenied();
        }
    }, [onPermissionGranted, onPermissionDenied]);

    return (
        <LocationPermissionModal
            startPermissionFlow
            onGrant={requestBackgroundPermission}
            onDeny={onPermissionDenied}
        />
    );
}
Background permissions enable:
  • Tracking continues when app is minimized
  • Automatic waypoint collection
  • No need to keep app open
  • More accurate distance measurement
Background location tracking uses more battery. Some devices may restrict this feature.

GPS Accuracy

Factors affecting GPS accuracy:
Better GPS signal in open areas. Urban canyons and tunnels may reduce accuracy.
Newer devices typically have better GPS receivers.
Heavy clouds or storms can affect GPS signals.
Faster movement may reduce precision of waypoint collection.

Manual Distance Entry

Enter start and end locations manually for flexibility.

Adding Waypoints

  1. Select Distance when creating an expense
  2. Choose Manual entry
  3. Enter your starting location
    • Type an address or business name
    • Select from recent locations
    • Use current location
  4. Enter your destination
  5. Add intermediate stops (optional)
  6. Review the calculated distance
  7. Adjust if needed
  8. Submit the expense
function IOURequestStepDistance({
    report,
    route: {
        params: {action, iouType, reportID, transactionID},
    },
    transaction,
}: IOURequestStepDistanceProps) {
    const [waypoints, setWaypoints] = useState<WaypointCollection>(
        transaction?.comment?.waypoints ?? {
            waypoint0: {keyForList: 'start_waypoint'},
            waypoint1: {keyForList: 'stop_waypoint'},
        }
    );

    const updateWaypoint = useCallback((index: number, waypoint: Waypoint) => {
        const key = `waypoint${index}`;
        setWaypoints((prev) => ({
            ...prev,
            [key]: waypoint,
        }));
        
        // Update transaction with new waypoints
        updateWaypointsUtil(transactionID, waypoints);
    }, [transactionID, waypoints]);

    const addWaypoint = useCallback(() => {
        const newIndex = Object.keys(waypoints).length;
        const newKey = `waypoint${newIndex}`;
        setWaypoints((prev) => ({
            ...prev,
            [newKey]: {keyForList: `waypoint_${newIndex}`},
        }));
    }, [waypoints]);

    return (
        <DraggableList
            data={Object.entries(waypoints)}
            renderItem={({item, index, drag}) => (
                <DistanceRequestRenderItem
                    waypoint={item[1]}
                    onPress={() => navigateToWaypointPage(index)}
                    onLongPress={drag}
                    onDeleteWaypoint={() => removeWaypoint(transactionID, index)}
                />
            )}
        />
    );
}

Waypoint Features

Location search:
  • Address autocomplete
  • Business name lookup
  • Recent locations list
  • Saved favorite locations
Waypoint management:
  • Reorder via drag and drop
  • Add unlimited stops
  • Delete unnecessary waypoints
  • Edit any waypoint
Distance calculation:
  • Automatic route calculation
  • Updates as waypoints change
  • Uses optimal routing
  • Shows total distance
Save frequently used locations (like your office or home) for quick access in future expenses.

Map-Based Distance Entry

Visually select waypoints on an interactive map.

Using the Map Interface

  1. Select Distance expense type
  2. Choose Map view
  3. Tap on the map to add waypoints
  4. Reorder waypoints by dragging markers
  5. The route draws automatically between points
  6. View distance in the bottom panel
  7. Confirm and submit
Map features:
  • Zoom in/out for precision
  • Pan to different areas
  • Satellite or street view
  • Current location marker
  • Route visualization
The map uses your workspace’s preferred mapping service for accurate routing.

Odometer Distance Entry

Record odometer readings with photo verification.

Submitting Odometer Expenses

  1. Select Distance expense type
  2. Choose Odometer
  3. Enter starting odometer reading
  4. Take a photo of the odometer (optional but recommended)
  5. Enter ending odometer reading
  6. Take another photo of the ending odometer
  7. Review the calculated distance
  8. Submit the expense
function IOURequestStepDistanceOdometer({
    route: {params: {transactionID}},
    transaction,
}: IOURequestStepDistanceOdometerProps) {
    const [odometerStart, setOdometerStart] = useState(
        transaction?.comment?.odometerStart ?? 0
    );
    const [odometerEnd, setOdometerEnd] = useState(
        transaction?.comment?.odometerEnd ?? 0
    );
    const [odometerImages, setOdometerImages] = useState<{
        start?: string;
        end?: string;
    }>({});

    const distance = useMemo(
        () => Math.abs(odometerEnd - odometerStart),
        [odometerEnd, odometerStart]
    );

    const captureOdometerImage = useCallback((position: 'start' | 'end') => {
        // Open camera to capture odometer
        Navigation.navigate(
            ROUTES.MONEY_REQUEST_STEP_ODOMETER_IMAGE.getRoute(
                CONST.IOU.ACTION.CREATE,
                iouType,
                transactionID,
                reportID,
                position
            )
        );
    }, [transactionID, reportID, iouType]);

    return (
        <View>
            <TextInput
                label="Starting odometer"
                value={odometerStart.toString()}
                onChangeText={(value) => setOdometerStart(Number(value))}
                keyboardType="numeric"
            />
            <Button
                text="Capture start photo"
                onPress={() => captureOdometerImage('start')}
            />
            
            <TextInput
                label="Ending odometer"
                value={odometerEnd.toString()}
                onChangeText={(value) => setOdometerEnd(Number(value))}
                keyboardType="numeric"
            />
            <Button
                text="Capture end photo"
                onPress={() => captureOdometerImage('end')}
            />
            
            <Text>Distance: {distance} miles</Text>
        </View>
    );
}
Odometer benefits:
  • Verification for audit purposes
  • Exact mileage tracking
  • Photo proof of readings
  • Simple for company vehicles
Some policies require odometer photos for all distance expenses. Check your workspace requirements.

Distance Rates

Mileage rates vary by workspace and vehicle type.

Standard Mileage Rates

Typical rate structures:
  • IRS standard rate: Current US federal mileage rate
  • Custom rates: Organization-specific rates
  • International rates: Country-specific reimbursement
  • Vehicle type rates: Different rates for cars, motorcycles, etc.
function getDefaultMileageRate(policy: Policy | undefined): MileageRate | undefined {
    if (!policy?.customUnits) {
        return undefined;
    }

    const distanceUnit = Object.values(policy.customUnits).find(
        (unit) => unit.name === CONST.CUSTOM_UNITS.NAME_DISTANCE
    );

    if (!distanceUnit?.rates) {
        return undefined;
    }

    const rates = Object.values(distanceUnit.rates);
    return rates.find((rate) => rate.name === 'Default Rate') ?? rates[0];
}

Selecting a Rate

If multiple rates are available:
  1. After entering distance, select Rate
  2. Choose from available rates:
    • Personal vehicle
    • Company vehicle
    • Motorcycle
    • Custom rates
  3. The amount updates automatically
  4. Review and submit
The most recently used rate is selected by default for faster expense creation.

Rate Calculation

The expense amount is calculated as:
Amount = Distance × Rate
Example:
  • Distance: 50 miles
  • Rate: $0.67 per mile
  • Amount: $33.50
function getDistanceRequestAmount(
    distance: number,
    unit: Unit,
    rate: number
): number {
    // Convert distance to miles if needed
    const distanceInMiles = unit === CONST.CUSTOM_UNITS.DISTANCE_UNIT_MILES
        ? distance
        : convertKilometersToMiles(distance);

    // Calculate amount (rate is in cents)
    const amountInCents = Math.round(distanceInMiles * rate);
    
    return amountInCents;
}

Distance Units

Support for both imperial and metric:

Unit Conversion

  • Miles: Default for US
  • Kilometers: Default for most other countries
  • Automatic conversion based on policy settings
  • Display shows your preferred unit

Changing Units

Your workspace admin configures:
  • Default unit (miles or kilometers)
  • Rate per unit
  • Precision (decimal places)

Editing Distance Expenses

Modify Waypoints

  1. Open the distance expense
  2. Click any waypoint to edit
  3. Change the location
  4. Distance recalculates automatically
  5. Save changes

Reorder Stops

Rearrange waypoints:
  1. Long-press a waypoint
  2. Drag to new position
  3. Drop in place
  4. Route and distance update

Add or Remove Waypoints

Add waypoints:
  • Click Add stop button
  • Enter the location
  • Waypoint inserts in route
Remove waypoints:
  • Swipe left on waypoint (mobile)
  • Click the delete icon (desktop)
  • Confirm removal
Keep at least two waypoints (start and end) for a valid distance expense.

Route Calculation

How New Expensify calculates distances:

Automatic Routing

const {shouldFetchRoute, validatedWaypoints} = useFetchRoute(
    transaction,
    waypoints,
    action,
    transactionState
);

useEffect(() => {
    if (!shouldFetchRoute || !validatedWaypoints) {
        return;
    }

    // Fetch route from mapping service
    const fetchRoute = async () => {
        try {
            const route = await mapboxAPI.getRoute(validatedWaypoints);
            const distanceInMeters = route.distance;
            
            // Update transaction with route data
            setMoneyRequestDistance(transactionID, distanceInMeters);
        } catch (error) {
            Log.error('Route fetch failed', error);
        }
    };

    fetchRoute();
}, [shouldFetchRoute, validatedWaypoints]);
Routing features:
  • Optimal path between waypoints
  • Real road network routing
  • Avoids impossible routes
  • Updates on waypoint changes
  • Handles one-way streets

Manual Distance Override

For special cases, manually adjust:
  1. Click the distance value
  2. Enter the correct distance
  3. Add a note explaining the change
  4. Save the expense
Manually entered distances may require additional approval or explanation depending on policy.

Distance Violations

Common distance expense issues:

Duplicate Route Detection

src/libs/Violations/ViolationsUtils.ts
function checkForDuplicateRoutes(
    transaction: Transaction,
    allTransactions: Transaction[]
): boolean {
    const routeString = getRouteString(transaction);
    
    return allTransactions.some((t) => {
        if (t.transactionID === transaction.transactionID) {
            return false;
        }
        return getRouteString(t) === routeString &&
               isSameDay(t.created, transaction.created);
    });
}
Duplicate violations occur when:
  • Same route on same day
  • Similar start/end locations
  • Identical distances
Resolution:
  • Verify the expense is legitimate
  • Add distinguishing details
  • Contact approver if needed

Missing Waypoints

Expenses need at least two waypoints:
  • Start location
  • End location
One-waypoint expenses cannot calculate distance and won’t be submittable.

Invalid Locations

Location errors may occur:
  • Not found: Location doesn’t exist
  • Ambiguous: Multiple matches found
  • Invalid: Null Island (0,0 coordinates)
Fix these by:
  • Using more specific addresses
  • Adding city and state
  • Selecting from autocomplete suggestions

Distance Reports

View and analyze your mileage:

Mileage Summary

See totals for:
  • Current month
  • Last month
  • Year-to-date
  • Custom date ranges

Export Distance Data

Download mileage logs:
  • CSV format
  • All distance expenses
  • Filtered by date range
  • Include route details

Best Practices

1

Choose the right method

Use GPS for accuracy, manual entry for quick logging, and odometer for company vehicles.
2

Track immediately

Don’t wait—record distance as soon as the trip completes.
3

Be specific with locations

Use full addresses instead of general areas for better route accuracy.
4

Review before submitting

Check that the calculated distance matches your actual travel.
5

Add trip purpose

Include notes about why you made the trip in the description field.

Troubleshooting

GPS Not Working

Check these items:
  • Location permissions enabled
  • GPS signal available
  • Device location services on
  • App has background permission (if needed)

Route Won’t Calculate

Possible causes:
  • Invalid waypoint location
  • No route between points
  • Network connectivity issue
  • Mapping service error
Try:
  • Verify waypoint addresses
  • Check internet connection
  • Use more specific locations
  • Try manual distance entry

Incorrect Distance

Common reasons:
  • Route includes highways when local roads taken
  • GPS drift or signal loss
  • Waypoints in wrong order
  • Map using airline distance
Solutions:
  • Manually adjust the distance
  • Add more waypoints for accuracy
  • Use odometer method for verification
  • Add explanation in notes

Next Steps

Create an Expense

Learn how to create and submit expenses

Per Diem Expenses

Manage daily allowance expenses

SmartScan

Automatically extract details from receipts

Split Expenses

Share costs with others

Build docs developers (and LLMs) love