Skip to main content

Documentation Index

Fetch the complete documentation index at: https://teardowns.aero/docs/llms.txt

Use this file to discover all available pages before exploring further.

The generic document endpoints for a teardown your org owns. For slot-specific documents (harvest list / OCCM / aircraft-details / non-incident-statement), see the slot endpoints.

Upload

POST /public/v1/teardown/documents/{teardown_id}
Attach a document to one of your teardowns. The URL is also appended to the teardown’s documents[] array so it shows up in detail responses.

Headers

Authorization
string
required
Bearer tdao_live_…
X-Organization-Id
string
required
Content-Type
string
required
multipart/form-data (curl’s -F does this automatically).

Form fields

file
file
required
The file to upload.
audience
string (CSV)
Optional. Comma-separated list of company types to restrict who can see documents on this teardown. Allowed: Airline / Lessor / OEM / MRO / Distributor / Others. Case-insensitive. See audience.

File rules

  • Max size: 50 MB per file.
  • Allowed types: PDF, XLSX, XLS, DOCX, DOC, CSV, JPEG, PNG, WEBP, GIF.
  • One file per call. Loop client-side for batch uploads.

Storage path

Files land at:
{SUPABASE_URL}/storage/v1/object/public/teardowns-media/teardowns/<teardown_id>/documents/<8-hex>_<filename>
The 8-character prefix randomises the path so naming collisions are impossible.

Response

200 OK:
{
  "url": "https://.../teardowns-media/teardowns/<id>/documents/abcd1234_specs.pdf",
  "filename": "specs.pdf",
  "size": 123456,
  "content_type": "application/pdf"
}
The URL is also appended to teardown.documents[] automatically no separate PATCH needed.
curl -X POST "$base_url/public/v1/teardown/documents/$teardown_id" \
  -H "Authorization: Bearer $api_key" \
  -H "X-Organization-Id: $org_id" \
  -F "file=@/absolute/path/to/specs.pdf"

Audience write happens BEFORE the upload

If you send an invalid audience value, you get 422 invalid_audience before the file is uploaded. No orphan storage paths.
{
  "detail": {
    "error_code": "invalid_audience",
    "message": "Unknown audience value(s): ['BogusCo']. Allowed (case-insensitive): ['Airline','Lessor','OEM','MRO','Distributor','Others']",
    "got": ["BogusCo"],
    "allowed": ["Airline","Lessor","OEM","MRO","Distributor","Others"]
  }
}
Sending the same audience the teardown already has is a no-op no audit row written.

Delete by URL

DELETE /public/v1/teardown/documents/{teardown_id}/by-url?url=<encoded-url>
Removes a single document URL from the teardown’s documents[]. Best-effort deletes the underlying storage file.

Query parameters

url
string
required
The full document URL (URL-encoded).

Response

200 OK:
{ "status": "ok" }
Idempotent deleting a URL that isn’t present returns 200 too. The storage delete is best-effort; failures are logged but never fail the call.
encoded_url=$(python3 -c "import urllib.parse,sys;print(urllib.parse.quote(sys.argv[1]))" "$DOC_URL")

curl -X DELETE "$base_url/public/v1/teardown/documents/$teardown_id/by-url?url=$encoded_url" \
  -H "Authorization: Bearer $api_key" \
  -H "X-Organization-Id: $org_id"

See also