AerScheduler API

Book aircraft, close flights out, invoice them, and pull the numbers back. 280 endpoints, described in OpenAPI 3.1, included on every plan.

Auth
API key, no expiry by default
Format
JSON over HTTPS, OpenAPI 3.1
Limits
300/min per account
Version
v1.0.0

Quickstart

One credential, then you’re working. An administrator creates a key in the console under Settings → API keys. The secret is shown once, right there, and every request after that just carries it. No sign-in step in your integration, and no token to refresh.

1. Store the key
# An administrator creates it in the console:
#   Settings → API keys → Create key
# The secret is shown once, right there.

export AERSCHEDULER_KEY=ask_live_…
2. List your aircraft
curl -s https://api.aerscheduler.com/resources/planes \
  -H "Authorization: Bearer $AERSCHEDULER_KEY"

# → { "data": [ { "id": 12, "name": "N12345", … } ],
#     "pagination": { "total": 6, "hasMore": false, … } }
3. Book one
curl -s -X POST https://api.aerscheduler.com/reservations \
  -H "Authorization: Bearer $AERSCHEDULER_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "title": "Discovery flight",
    "type": "dual",
    "start": "2026-08-04T15:00:00-06:00",
    "end":   "2026-08-04T17:00:00-06:00",
    "timeZoneName": "America/Denver",
    "resource": { "id": 12 }
  }'

Reference

280 endpoints across 27 areas. Click an endpoint for parameters, responses, and an example request.

The flight school itself: membership, invitations, and settings.

People and the roles they hold.

Booking, rescheduling, and closing out flights.

How a booking's cost divides when more than one person is on it. Each person is billed separately, so a shared booking produces one invoice per payer. An organization that sets no rules bills one person for the whole booking.

When people and aircraft are free.

Aircraft, simulators, and rooms.

Who changed what, and when.

Squawks and maintenance reminders.

Billing for completed flights.

Bases of operation.

Sets of members or resources.

Recurring requirements members must stay current on.

Courses, syllabi, enrollments and training records. A course is trained under Part 61 or Part 141; the shape is identical and only the enforcement differs. A published syllabus version is immutable , revising it makes a new version, and an enrollment stays pinned to the one it started under. A student's standing against each requirement is a ledger: entries are only ever appended, and a correction is a reversing entry rather than an edit, so hours flown are always traceable to the lesson that earned them.

What a club or an FBO charges people for belonging, as opposed to for flying. A plan carries a one-time join fee, recurring dues, or both; a membership is one person's copy of a plan with the money snapshotted at the moment it started, so re-pricing a plan never re-prices anybody already on it. Every dues period is a ledger row, and a period is billed because the membership's own cursor says it is owed , never because of what day it happens to be. Dues and join fees are raised as ordinary invoices, so they appear under Invoices and in the revenue reports with everything else.

Files held against members.

Notices to members.

Per-member in-app notifications.

Standby interest, cancellation recovery, and time-limited slot offers.

When org policy requires approval, members submit requests and desk staff approve or decline them before a reservation is created.

Presets over org calendar policy for guest pages and internal slot discovery, plus per-audience calendar visibility settings.

Unauthenticated guest request pages. A guest picks an offering slot, confirms by email, and the front desk approves or declines the request. Members keep booking as they do today.

The reporting engine and saved views.

Field observations.

Health and status.

WebSocket tickets for live console updates (schedule, notifications, billing).

One compact read of what a member needs to see right now, sized for a home-screen widget or a wall display.

Conventions

These hold across the whole API, so you can write one client wrapper and stop thinking about it.

Responses are wrapped

A body-bearing success is { "data": … }. An error is { "message": "…" }, written to be safe to show a user. Three endpoints break this on purpose and say so: /health, the CSV export, and the OAuth redirects.

401 and 403 mean different things

401 means the token is dead. Get a new one. 403 means the token is fine and the answer is still no. Retrying a 403 will never help.

Your organization is implied

The token carries it. You never pass an organization id for your own org, and you can never read another organization’s records.

Money is in cents

Always an integer, never a float. A $165/hr wet rate is 16500.

Times carry an offset

Send start and end with an explicit UTC offset or Z. A bare local datetime is rejected rather than silently booked in the server’s zone. See below.

Parse leniently

New endpoints and new fields on existing responses ship without notice. Ignore fields you don’t recognise; anything that would break a working integration gets a new major version first.

Time zones, and why bookings are strict about them

Scheduling is anchored to the airport’s time zone, not the caller’s device. A booking made for 7am at the field is 7am at the field whether the person making it is in the office, at home, or in another state.

So start and end must carry an explicit UTC offset or Z. A bare 2026-08-04T15:00:00is rejected outright. It would be read in the server’s zone and silently book a different instant than the person picked, and nothing downstream would notice. Send timeZoneName (an IANA zone like America/Denver) alongside, so the booking records which zone it was made in.

Who can book what

Which reservation type a caller may create depends on the roles they hold. Roles are additive, so an instructor who is also a technician gets both sets.

RoleMay create
owner, admin, dispatchersolo, dual, ground, guest, sim, rental, maintenance
instructorsolo, dual, ground, guest, sim
studentsolo, dual, ground, sim
renterrental
technicianmaintenance

Rate limits

Limits are applied per signed-in account, not per IP. A whole school behind one office address does not share one budget.

Per account300 requests / minute, 5,000 / hour
Unauthenticated100 requests / 5 minutes, per IP
Unauthenticated endpointsTighter still, and limited per IP

Every response carries RateLimit-Limit, RateLimit-Remaining, and RateLimit-Reset. A 429 carries Retry-After in seconds. Honour it rather than retrying on a fixed interval.

Pagination: what to know before you build

Every list is capped at 1,000 rows, whether or not you ask for a limit. Pass limit and offset to page:

Page through a list
GET /reservations?startDate=…&endDate=…&limit=100&offset=200

Every list response carries a pagination object beside data:

Shape
{
  "data": [ … ],
  "pagination": {
    "total": 7823,
    "limit": 1000,
    "offset": 0,
    "returned": 1000,
    "hasMore": true
  }
}
  • total: how many there are in all, before the page was taken.
  • returned: how many are in data right now.
  • hasMore: whether another page exists. Check it. Some collections are bigger than one page: our largest school has over 7,000 reservations.

Asking for more than 1,000 gives you 1,000 rather than an error. offset past the end returns an empty data and hasMore: false. Date-ranged endpoints still matter for anything that grows without bound: GET /reservations requires a window, and the reporting engine takes one too. Cursor pagination is planned and will be additive:limit/offset will keep working.

Common questions

Does AerScheduler have an API?
Yes. AerScheduler exposes a REST API covering 280 endpoints across scheduling, aircraft, maintenance, billing, members, and reporting.
Is the API included in the price?
Yes. API access is included on every plan at no extra cost. There is no enterprise tier and no per-call charge.
How do I authenticate with the AerScheduler API?
With an API key, and only with an API key. Create one in the web console under Settings → API keys, then send it as an Authorization: Bearer header on every request. The secret is shown once, when you create it, so store it then. Only a hash is kept.
Who can create an API key?
Any administrator, from Settings → API keys in the web console. That is deliberately not something a key can do. A key cannot create or revoke another key, even one holding the admin role, so a leaked key can never issue itself replacements.
What can an API key do?
Exactly what the roles you gave it allow. A key behaves like a member holding those roles, and every permission rule that applies to a person applies to it. Give a key the least it needs. A key that reads the schedule should be a dispatcher, not an admin. The owner role cannot be granted to a key.
Do keys expire?
Only if you set an expiry when you create one. Otherwise a key works until you revoke it, which takes effect on the very next request. Revoked keys stay listed as revoked rather than disappearing, so anything they created still has something to point at.
Is there an OpenAPI specification?
Yes. The machine-readable OpenAPI 3.1 document is published at https://api.aerscheduler.com/openapi.json and needs no authentication to read. Point any standard client generator at it to produce an SDK in your language.
Are there rate limits?
Yes, and they are applied per signed-in account rather than per IP, so a whole school behind one office address does not share one budget. 300 requests a minute and 5,000 an hour per account. Every response carries RateLimit-Remaining, and a 429 carries Retry-After.
Can I use the API to build a booking page on my own website?
Yes. Availability, resources, and reservations are all exposed, so you can check an aircraft's free windows and create a booking from your own front end.

Building something?

Tell us what you’re integrating and we’ll help. If an endpoint you need doesn’t exist yet, we’d rather hear it now than read about it later.