Skip to content

AircraftForSale has a new look. Already a member? Sign in and follow the prompts to reach your account.

Developers · v1

Dealer Listings API

Keep a dealer’s aircraft on AircraftForSale in step with their own website or inventory system. JSON over HTTPS, one request per aircraft, safe to repeat.

Quickstart

A dealer creates a key in their dashboard under Settings → Integrations and gives it to whoever builds the connection. Send it on every request as a bearer token, from a server — never from a web page.

1. Check the key
curl https://aircraftforsale.com/api/dealer/v1/me \
  -H "Authorization: Bearer $AFS_KEY"
2. Send an aircraft (create or update)
curl -X PUT https://aircraftforsale.com/api/dealer/v1/listings/STK-1042 \
  -H "Authorization: Bearer $AFS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "2019 Cirrus SR22T G6 GTS",
    "make": "Cirrus",
    "model": "SR22T G6",
    "year": 2019,
    "price": 849000,
    "registration": "N219GT",
    "serialNumber": "1734",
    "totalTime": 640,
    "location": "Scottsdale, AZ, United States",
    "description": "One owner, hangared since new.",
    "sections": { "avionics": "Perspective+ by Garmin\nGFC 700 autopilot" },
    "images": ["https://yoursite.com/aircraft/1042/1.jpg"],
    "agentEmail": "[email protected]"
  }'
3. When it sells
curl -X PUT https://aircraftforsale.com/api/dealer/v1/listings/STK-1042 … -d '{ …same fields…, "status": "sold" }'
Or take it down without a sale
curl -X DELETE https://aircraftforsale.com/api/dealer/v1/listings/STK-1042 \
  -H "Authorization: Bearer $AFS_KEY"

Try any PUT with ?dryRun=true first: it validates the body and tells you how we would file the make and model, without writing anything.

How it works

  • Your id, in the URL. Each aircraft is addressed by your own externalId — a stock number or CMS post id. Keep it stable: it is how we know a second request is the same aircraft.
  • Send the whole aircraft. PUT replaces the listing’s content with what you send; a field you leave out is cleared (except listingType). Sending the same body again changes nothing, so a nightly full sync is fine.
  • No duplicates. If the dealer already has a listing with us for the same registration (or serial number), the first PUT adopts it — outcome: "adopted" — rather than creating a second.
  • Review. New listings are checked by our team before they go live, usually within a business day. Updates to a live listing appear at once. If one is rejected, reviewNote says why; fix it and PUT again to resubmit. GET /me shows whether your account is reviewed or publishes directly.
  • Photos. Send public JPEG, PNG or WebP URLs in display order; the first is the cover. We copy them to our own storage after the response, a few at a time, so photos.pending stays true for a few minutes on a large gallery. URLs we already hold are never downloaded again.
  • Makes and models. Use the names from GET /makes to land in the right category. Anything else is filed under its make and flagged for our team, which shows as a reviewNote.
  • Text. Description and section fields take plain text (line breaks kept) or simple HTML — paragraphs, lists, bold, links. Anything else is removed.

Listing statuses

Every response reports the listing’s status as one of these.

live
on the site
in_review
waiting for our team
rejected
see reviewNote, fix and PUT again to resubmit
sold
withdrawn
taken down (PUT for_sale to relist)
expired
removed
by our team
not_listed
we hold the record but never listed it (e.g. it was sold before you first sent it)

Limits

Every authenticated request counts as one call against the account’s monthly allowance, which resets on the 1st (UTC). Responses carry X-RateLimit-Limit and X-RateLimit-Remaining. There is also a ceiling of 120 requests a minute.

PlanCalls a month
Free2,500Every dealer account
Growth25,000On request
Volume250,000On request

A nightly sync of the whole inventory costs one call per aircraft. To save calls, send only what changed — and remember a resend of an unchanged aircraft still counts.

Errors

Errors are JSON: { "error": { "code", "message", "field"? } }. Branch on code, not on the message. Retry 5xx and 429 with backoff.

CodeHTTPMeaning
unauthorized401No key, not an AircraftForSale key, or a revoked one.
forbidden403API access is switched off for your account. Contact us.
not_found404Nothing has been sent with that externalId.
conflict409Your account has no team members to list aircraft under.
validation_failed422A field is invalid; field names it.
quota_exceeded429This month's calls are used. Retry-After is the seconds to the 1st (UTC).
rate_limited429More than 120 requests a minute. Retry after Retry-After seconds.
internal500Our fault. Retry with backoff; it has been logged.

Endpoints

Base URL https://aircraftforsale.com/api/dealer/v1

get/me

Your account, plan and usage

A cheap way to check a key works.

get/listings

Every aircraft you have sent

Ordered by externalId. Use it to reconcile your inventory with ours.

get/listings/{externalId}

One aircraft: its status, public URL, review notes and photo progress

put/listings/{externalId}

Create or update an aircraft

Send the whole aircraft each time; a field you leave out is cleared, except listingType. The first request for an externalId creates the listing — unless your account already has a listing with the same registration (or serial number), which is adopted instead of duplicated. Photos are copied after the response; photos.pending is true until they are in. Add ?dryRun=true to see what would happen — including how we would categorise the make and model — without writing anything.

delete/listings/{externalId}

Take an aircraft down (not sold)

The listing leaves the site; its record stays, and a later PUT with for_sale relists it. For a sale, PUT with "status": "sold" instead.

get/makes

Our makes and models

Fixed-wing aircraft. Sending these exact names files a listing in the right category; anything else is filed under its make and flagged for our team. Helicopters are accepted and categorised by our team.

Listing fields

The body of PUT /listings/{externalId}. Required: title, make, model. Unknown fields are refused, so a typo fails loudly.

FieldTypeDescription
statusfor_sale | soldfor_sale lists or updates the aircraft; sold marks it sold (it stays on the site as sold, with its last asking price). A listing still waiting for review never went live, so sold withdraws it instead. To take a listing down without a sale, DELETE it.default "for_sale"
title *stringThe headline, e.g. "2018 Cirrus SR22T G6 GTS".max 200 characters
make *stringManufacturer, e.g. "Cirrus". See GET /makes for our names.max 100 characters
model *stringModel, e.g. "SR22T G6". See GET /makes.max 100 characters
yearinteger or null
pricenumber or nullAsking price in US dollars. Omit or null for "Please call".
registrationstring or nullTail number, e.g. "N123AB".max 20 characters
serialNumberstring or nullmax 50 characters
totalTimenumber or nullTotal airframe time, hours.
locationstring or nullWhere the aircraft is, e.g. "Scottsdale, AZ, United States".max 200 characters
listingTypefor_sale | fractionalfractional for a fractional-ownership offer. Omit to keep the current type.
descriptionstring or nullPlain text (line breaks kept) or simple HTML (paragraphs, lists, bold, links). Anything else is removed.max 100,000 characters
sectionsSections
imagesarray of string (uri)Photo URLs in display order, first is the cover. We copy them to our own storage, so they must be publicly fetchable; JPEG, PNG or WebP. Send the same URLs again and nothing is re-downloaded.max 100
videoUrlstring (uri) or nullA YouTube or Vimeo link.max 500 characters
agentEmailstring (email) or nullThe sales agent for this aircraft. If it matches an agent on your account (Dealer → Settings → Sales agents), enquiries go to them; otherwise to the account's lead address.max 200 characters

sections

The spec sections on the listing page. Omit one to leave it empty.

FieldTypeDescription
airframestringPlain text (line breaks kept) or simple HTML (paragraphs, lists, bold, links). Anything else is removed.max 50,000 characters
enginestringPlain text (line breaks kept) or simple HTML (paragraphs, lists, bold, links). Anything else is removed.max 50,000 characters
avionicsstringPlain text (line breaks kept) or simple HTML (paragraphs, lists, bold, links). Anything else is removed.max 50,000 characters
interiorstringPlain text (line breaks kept) or simple HTML (paragraphs, lists, bold, links). Anything else is removed.max 50,000 characters
exteriorstringPlain text (line breaks kept) or simple HTML (paragraphs, lists, bold, links). Anything else is removed.max 50,000 characters
inspectionstringPlain text (line breaks kept) or simple HTML (paragraphs, lists, bold, links). Anything else is removed.max 50,000 characters
additionalEquipmentstringPlain text (line breaks kept) or simple HTML (paragraphs, lists, bold, links). Anything else is removed.max 50,000 characters
weightsstringPlain text (line breaks kept) or simple HTML (paragraphs, lists, bold, links). Anything else is removed.max 50,000 characters
remarksstringPlain text (line breaks kept) or simple HTML (paragraphs, lists, bold, links). Anything else is removed.max 50,000 characters
Dealer Listings API | AircraftForSale Developers