Search by

flairuk / laravel-aviationstack

ijeffro

The aviationstack API for Laravel: real-time and historical flights, airport timetables, future schedules, routes, airports, airlines and aircraft, with typed errors and lazy paging.

Package info

github.com/FLAIRUK/laravel-aviationstack

pkg:composer/flairuk/laravel-aviationstack

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-10-05 11:19 UTC

This package is auto-updated.

Last update: 2026-10-05 12:55:58 UTC


README

Aviationstack for Laravel

PHP 8.2+  Laravel 12 or 13  Lint  Tests  Downloads on Packagist  MIT licence  aviationstack API 
 

Aviationstack for Laravel — A fluent client for the aviationstack API: real-time and historical flights, airport timetables, future schedules, routes, and the reference data (airports, airlines, airplanes, aircraft types, taxes, cities, countries).

use FLAIRUK\Aviationstack\Facades\Aviationstack;

Aviationstack::flights()->from('LHR')->to('JFK')->status('active')->get();
Aviationstack::flights()->flight('BA117')->on('2026-09-30')->first();
Aviationstack::timetable('JFK')->arrivals()->status('landed')->get();
Aviationstack::futureFlights('BER', '2026-12-01')->airline('AF')->get();
Aviationstack::airports()->search('heathrow')->first();
Aviationstack::airlines()->lazy()->each(fn (array $airline) => /* … */);

Install

composer require flairuk/laravel-aviationstack

The service provider and the Aviationstack facade are discovered automatically.

AVIATIONSTACK_KEY=…
AVIATIONSTACK_HTTPS=true      # false on the free plan, which refuses HTTPS (error 105)
AVIATIONSTACK_MAX_LIMIT=100   # 1000 on Professional and above
php artisan vendor:publish --tag=aviationstack-config
Key Default
AVIATIONSTACK_KEY — Required. Sent as access_key.
AVIATIONSTACK_HTTPS true Free plans must set false.
AVIATIONSTACK_MAX_LIMIT 100 limit() is clamped to this.
AVIATIONSTACK_TIMEOUT / _CONNECT_TIMEOUT 20 / 5 Seconds.
AVIATIONSTACK_RETRIES / _RETRY_DELAY 1 / 500 Retries on connection failures and 5xx only.

Endpoints

Method API path Named filters
flights() /v1/flights status(), on($date), from(), to(), airline(), airlineName(), flight(), departureDelay($min, $max), arrivalDelay($min, $max), scheduledToDepartOn(), scheduledToArriveOn()
timetable($iata, $type) /v1/timetable departures(), arrivals(), status(), airline(), airlineName(), flight()
futureFlights($iata, $date, $type) /v1/flightsFuture departures(), arrivals(), on(), airline(), flight()
routes() /v1/routes from(), to(), airline(), flight()
airports(), airlines(), airplanes(), aircraftTypes(), taxes(), cities(), countries() /v1/… search() (Basic plan and up)
endpoint($path) anything else —

The code-based filters pick the parameter from the code's shape:

  • from('LHR') sends dep_iata; from('EGLL') sends dep_icao. to() works the same way.
  • airline('BA') sends airline_iata; airline('BAW') sends airline_icao.
  • flight('BA117') sends flight_iata; flight('BAW117') sends flight_icao; flight(117) sends flight_number.

Codes are upper-cased before they are sent.

Use where('param', $value) or wheres([...]) to pass any parameter under the API's own name. Dates can be strings or DateTimeInterface.

Every call on the facade returns a new builder, so filters never carry over from one query to the next.

Results and paging

get() returns a FLAIRUK\Aviationstack\Page:

$page = Aviationstack::flights()->from('LHR')->page(2, perPage: 50)->get();

$page->data;       // array of rows, exactly as the API returned them
$page->total;      // size of the whole result set
$page->offset;     // where this page starts
$page->hasMore();
$page->first();
$page->collect();  // Illuminate\Support\Collection
count($page); foreach ($page as $row) { … }

Rows are left as the API's own arrays. Their field names differ between endpoints: flights uses snake case and timetable uses camel case.

lazy() returns a LazyCollection that fetches page after page as you walk it. Each page is a billed request, so set a limit on large result sets:

Aviationstack::airports()->lazy(maxPages: 5)->take(300)->all();

Errors

Failures throw. They are not turned into empty results, because on a paid API "your quota is spent" must not look the same as "there are no flights".

Exception apilayer types
InvalidAccessKeyException missing_access_key, invalid_access_key, inactive_user, account_on_hold
AccessRestrictedException https_access_restricted, function_access_restricted, api_access_blocked
UsageLimitException usage_limit_reached, daily_usage_limit_reached, fair_use_limit_reached, rate_limit_reached
ConnectionException The API could not be reached.
AviationstackException The base class, and the type for everything else (invalid_api_function, internal_error, maintenance_mode, …).

getCode() returns the apilayer error code (101, 104, 106…), $e->type the error type, and $e->status the HTTP status. An error body is treated as an error even when it arrives with a 200 status.

A missing key throws before any request is sent. So does a missing required parameter on timetable or futureFlights (an InvalidArgumentException).

Rate limits to know about

  • timetable and flightsFuture allow one request every 10 seconds on paid plans, and one every 60 seconds on the free plan.
  • Historical flights go back 12 months.
  • The page size is at most 100 below the Professional plan, and 1000 on it and above.

Testing

composer test
composer format

The tests use Http::fake() and never call the real API.

License

MIT. See LICENSE.md.