Skip to main content
POST
/
public
/
v1
/
sales-lease-exchange
curl -X POST "$base_url/public/v1/sales-lease-exchange" \
  -H "Authorization: Bearer $api_key" \
  -H "X-Organization-Id: $org_id" \
  -H "Content-Type: application/json" \
  -d '{
    "listing_type": "aircraft",
    "aircraft_type": "A320-200",
    "quantity": 1,
    "incident_related": "No",
    "price_usd": 4500000,
    "country": "US",
    "manufacturer": "Airbus",
    "year_of_manufacture": 2008,
    "registration": "VT-AER1",
    "traceability": "Delta",
    "total_hours": 62000,
    "total_cycles": 31000,
    "description": "Narrowbody, full traceability"
  }'
curl -X POST "$base_url/public/v1/sales-lease-exchange" \
  -H "Authorization: Bearer $api_key" \
  -H "X-Organization-Id: $org_id" \
  -H "Content-Type: application/json" \
  -d '{
    "listing_type": "engine",
    "engine_model": "CFM56-5B",
    "msn": "ESN-9876",
    "cycles_remaining": 12000,
    "available_date": "2026-08-01",
    "condition": "Serviceable",
    "quantity": 1,
    "listing_purpose": ["sale", "lease"],
    "price_usd": 250000,
    "country": "IN",
    "description": "Low-cycle engine, full traceability"
  }'
curl -X POST "$base_url/public/v1/sales-lease-exchange" \
  -H "Authorization: Bearer $api_key" \
  -H "X-Organization-Id: $org_id" \
  -H "Content-Type: application/json" \
  -d '{
    "listing_type": "apu",
    "apu_model": "APS3200",
    "manufacturer": "Pratt & Whitney",
    "msn": "APU-3200-01",
    "available_date": "2026-07-15",
    "condition": "Serviceable",
    "quantity": 1,
    "price_usd": 95000,
    "country": "US",
    "listing_purpose": ["sale"],
    "description": "Serviceable APU, full records"
  }'
import requests

# Aircraft listing
resp = requests.post(
    f"{base_url}/public/v1/sales-lease-exchange",
    headers={"Authorization": f"Bearer {api_key}", "X-Organization-Id": org_id},
    json={
        "listing_type": "aircraft",
        "aircraft_type": "A320-200",
        "quantity": 1,
        "incident_related": "No",
        "price_usd": 4_500_000,
        "country": "US",
    },
)

# Engine listing
resp = requests.post(
    f"{base_url}/public/v1/sales-lease-exchange",
    headers={"Authorization": f"Bearer {api_key}", "X-Organization-Id": org_id},
    json={
        "listing_type": "engine",
        "engine_model": "CFM56-5B",
        "msn": "ESN-9876",
        "cycles_remaining": 12000,
        "available_date": "2026-08-01",
        "condition": "Serviceable",
        "quantity": 1,
        "listing_purpose": ["sale", "lease"],
        "price_usd": 250_000,
        "country": "IN",
    },
)

# APU listing
resp = requests.post(
    f"{base_url}/public/v1/sales-lease-exchange",
    headers={"Authorization": f"Bearer {api_key}", "X-Organization-Id": org_id},
    json={
        "listing_type": "apu",
        "apu_model": "APS3200",
        "manufacturer": "Pratt & Whitney",
        "msn": "APU-3200-01",
        "available_date": "2026-07-15",
        "condition": "Serviceable",
        "quantity": 1,
        "price_usd": 95_000,
        "country": "US",
    },
)
resp.raise_for_status()
listing_id = resp.json()["id"]
{
  "id": "df1e...",
  "org_id": "72f95f4e-...",
  "listing_type": "engine",
  "engine_model_id": "...",
  "engine_model": { "name": "CFM56-5B", "manufacturer": "CFM International", ... },
  "msn": "ESN-9876",
  "condition": "Serviceable",
  "price_usd": 250000,
  "country": "IN",
  "documents": null,
  "images": null,
  "audience": null,
  "status": "active",
  "created_at": "..."
}
{
  "detail": {
    "error_code": "unknown_vocabulary",
    "field": "engine_model",
    "value": "cfm-foo",
    "valid_values": ["CFM56-3", "CFM56-5B", "CFM56-7B", "LEAP-1A", ...],
    "message": "Unknown engine_model: 'cfm-foo'. See valid_values."
  }
}
{
  "detail": {
    "error_code": "vocab_required",
    "message": "engine_model is required for listing_type='engine'"
  }
}
{
  "detail": [
    {
      "type": "value_error",
      "loc": ["body"],
      "msg": "Value error, listing_type='engine' requires the following fields: msn, cycles_remaining, available_date, condition, quantity, listing_purpose",
      "input": { /* the request body you sent */ }
    }
  ]
}
Create a new sales / lease / exchange owned by your organization. These represent whole aircraft, engines, or APUs your team is offering for sale, lease, or exchange.
The public API supports listing_type of aircraft, engine, or apu only. parts and landing_gear are intentionally excluded from the public surface today — existing rows of those types stay readable on GET, but cannot be created via this endpoint and sending either returns 422.

Headers

Authorization
string
required
Bearer tdao_live_…
X-Organization-Id
string
required
Your organization’s UUID.
Content-Type
string
required
application/json

Body

The request body shape depends on the listing_type you pick. Three fields are required on every request regardless of type, and each type then has its own set of required and optional fields on top. Sending a request that’s missing a required field returns 422 with a single error message naming every missing field, so you can fix all of them in one round trip.

Universal required fields (every listing_type)

These three are required on every request, no matter which type you are creating.
listing_type
string
required
One of aircraft, engine, or apu. Sending parts or landing_gear returns 422.
price_usd
number
required
Asking price in USD. UI label: “Price ($) *”.
country
string
required
ISO country code, e.g. IN. UI label: “Country *” / “Location *”.

listing_type = "aircraft"

Mirrors the UI wizard’s Aircraft Details step exactly.

Required for aircraft

aircraft_type
string
required
Human-readable name from the aircraft-types vocabulary, e.g. A320-200. Case-insensitive. Unknown values return 400 unknown_vocabulary with the full allowed list in the body. UI label: “Aircraft Model *”.
quantity
integer
required
How many of this aircraft are on offer. UI label: “Quantity *”. UI form defaults to 1 but the API has no default — send the value explicitly.
Yes or No. UI label: “Incident Related *”.

Optional for aircraft

manufacturer
string
Aircraft manufacturer, e.g. Boeing. UI label: “Manufacturer”.
year_of_manufacture
integer
Year the aircraft was built. UI label: “Year”.
registration
string
Aircraft tail number. UI label: “Tail Number”.
traceability
string
Last operator / traceability history. UI label: “Traceability”.
engines_description
string
Free-text description of the engines on the aircraft. UI label: “Engines”.
apu_description
string
Free-text description of the APU on the aircraft. UI label: “APU”.
total_hours
number
Total airframe hours. UI label: “Total Hours”.
total_cycles
integer
Total airframe cycles. UI label: “Total Cycles”.
description
string
Free-text description shown on the listing detail page. UI label: “Description”.

listing_type = "engine"

Mirrors the UI wizard’s Engine Details step exactly.

Required for engine

engine_model
string
required
Human-readable name from the engine-models vocabulary, e.g. CFM56-5B. Case-insensitive. UI label: “Engine Model *”.
msn
string
required
Engine serial number. UI label: “ESN *”.
cycles_remaining
number
required
Cycles remaining (in hours). UI label: “Cycles Remaining (hours) *”.
available_date
string (date)
required
ISO date the engine is available. UI label: “Available Date *”. UI form defaults to today; the API has no default.
condition
string
required
One of Serviceable, As Removed, Overhauled, Repaired. UI label: “Condition *”.
quantity
integer
required
UI label: “Quantity *”.
listing_purpose
array of string
required
Non-empty array containing any of sale, lease, exchange. Empty array is rejected. UI label: “Sale / Lease / Exchange”.

Optional for engine

manufacturer
string
Engine manufacturer. UI label: “Manufacturer”. The UI auto-fills this from the selected engine model; the API does not.
description
string
Free-text description. UI label: “Description”.

listing_type = "apu"

Mirrors the UI wizard’s APU Details step exactly.

Required for apu

apu_model
string
required
Human-readable name from the apu-models vocabulary, e.g. APS3200. Case-insensitive. UI label: “APU Model *”.
manufacturer
string
required
APU manufacturer, e.g. Honeywell. UI label: “Manufacturer *”. The UI auto-fills this from the selected APU model; the API does not.
msn
string
required
APU serial number. UI label: “SN *”.
available_date
string (date)
required
ISO date the APU is available. UI label: “Available Date *”.
condition
string
required
One of Serviceable, As Removed, Overhauled, Repaired. UI label: “Condition *”.
quantity
integer
required
UI label: “Quantity *”.

Optional for apu

listing_purpose
array of string
Array containing any of sale, lease, exchange. UI label: “Sale / Lease / Exchange”.
description
string
Free-text description. UI label: “Description”.

Strict mode is on for this endpoint. Sending an unknown body key returns 422 and tells you which key was wrong. Common stale names to avoid: aircraft_type_id / engine_model_id / apu_model_id (use the name, not the UUID), location_country (use country), listing_type=parts / listing_type=landing_gear (not supported on the public surface).

Response

201 Created. The full listing in the shape every GET returns.
curl -X POST "$base_url/public/v1/sales-lease-exchange" \
  -H "Authorization: Bearer $api_key" \
  -H "X-Organization-Id: $org_id" \
  -H "Content-Type: application/json" \
  -d '{
    "listing_type": "aircraft",
    "aircraft_type": "A320-200",
    "quantity": 1,
    "incident_related": "No",
    "price_usd": 4500000,
    "country": "US",
    "manufacturer": "Airbus",
    "year_of_manufacture": 2008,
    "registration": "VT-AER1",
    "traceability": "Delta",
    "total_hours": 62000,
    "total_cycles": 31000,
    "description": "Narrowbody, full traceability"
  }'
curl -X POST "$base_url/public/v1/sales-lease-exchange" \
  -H "Authorization: Bearer $api_key" \
  -H "X-Organization-Id: $org_id" \
  -H "Content-Type: application/json" \
  -d '{
    "listing_type": "engine",
    "engine_model": "CFM56-5B",
    "msn": "ESN-9876",
    "cycles_remaining": 12000,
    "available_date": "2026-08-01",
    "condition": "Serviceable",
    "quantity": 1,
    "listing_purpose": ["sale", "lease"],
    "price_usd": 250000,
    "country": "IN",
    "description": "Low-cycle engine, full traceability"
  }'
curl -X POST "$base_url/public/v1/sales-lease-exchange" \
  -H "Authorization: Bearer $api_key" \
  -H "X-Organization-Id: $org_id" \
  -H "Content-Type: application/json" \
  -d '{
    "listing_type": "apu",
    "apu_model": "APS3200",
    "manufacturer": "Pratt & Whitney",
    "msn": "APU-3200-01",
    "available_date": "2026-07-15",
    "condition": "Serviceable",
    "quantity": 1,
    "price_usd": 95000,
    "country": "US",
    "listing_purpose": ["sale"],
    "description": "Serviceable APU, full records"
  }'
import requests

# Aircraft listing
resp = requests.post(
    f"{base_url}/public/v1/sales-lease-exchange",
    headers={"Authorization": f"Bearer {api_key}", "X-Organization-Id": org_id},
    json={
        "listing_type": "aircraft",
        "aircraft_type": "A320-200",
        "quantity": 1,
        "incident_related": "No",
        "price_usd": 4_500_000,
        "country": "US",
    },
)

# Engine listing
resp = requests.post(
    f"{base_url}/public/v1/sales-lease-exchange",
    headers={"Authorization": f"Bearer {api_key}", "X-Organization-Id": org_id},
    json={
        "listing_type": "engine",
        "engine_model": "CFM56-5B",
        "msn": "ESN-9876",
        "cycles_remaining": 12000,
        "available_date": "2026-08-01",
        "condition": "Serviceable",
        "quantity": 1,
        "listing_purpose": ["sale", "lease"],
        "price_usd": 250_000,
        "country": "IN",
    },
)

# APU listing
resp = requests.post(
    f"{base_url}/public/v1/sales-lease-exchange",
    headers={"Authorization": f"Bearer {api_key}", "X-Organization-Id": org_id},
    json={
        "listing_type": "apu",
        "apu_model": "APS3200",
        "manufacturer": "Pratt & Whitney",
        "msn": "APU-3200-01",
        "available_date": "2026-07-15",
        "condition": "Serviceable",
        "quantity": 1,
        "price_usd": 95_000,
        "country": "US",
    },
)
resp.raise_for_status()
listing_id = resp.json()["id"]
{
  "id": "df1e...",
  "org_id": "72f95f4e-...",
  "listing_type": "engine",
  "engine_model_id": "...",
  "engine_model": { "name": "CFM56-5B", "manufacturer": "CFM International", ... },
  "msn": "ESN-9876",
  "condition": "Serviceable",
  "price_usd": 250000,
  "country": "IN",
  "documents": null,
  "images": null,
  "audience": null,
  "status": "active",
  "created_at": "..."
}
{
  "detail": {
    "error_code": "unknown_vocabulary",
    "field": "engine_model",
    "value": "cfm-foo",
    "valid_values": ["CFM56-3", "CFM56-5B", "CFM56-7B", "LEAP-1A", ...],
    "message": "Unknown engine_model: 'cfm-foo'. See valid_values."
  }
}
{
  "detail": {
    "error_code": "vocab_required",
    "message": "engine_model is required for listing_type='engine'"
  }
}
{
  "detail": [
    {
      "type": "value_error",
      "loc": ["body"],
      "msg": "Value error, listing_type='engine' requires the following fields: msn, cycles_remaining, available_date, condition, quantity, listing_purpose",
      "input": { /* the request body you sent */ }
    }
  ]
}

Notes

  • Listings go directly to active status — there’s no draft path.
  • audience is not set at create time. Attach it on the same call that uploads the first document (see the upload endpoints) or via PATCH later.
  • Use the upload endpoints to attach documents and images.

See also