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.
multipart/form-data (curl’s -F does this automatically).
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.
upload only
upload + set audience (one round trip)
python
node
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
The full document URL (URL-encoded).
Response
200 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