{"openapi":"3.1.0","info":{"title":"BioAcoustic Database API","version":"1.0.0","description":"Public API for accessing and submitting bioacoustic recordings. Authenticate using an API token generated from the admin panel.","contact":{"email":"admin@example.com"},"license":{"name":"Proprietary"}},"servers":[{"url":"https://your-domain.com/api/v1","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"bao_<token>","description":"API token generated from the admin panel. Format: `bao_<64-char-hex>`"}},"schemas":{"Recording":{"type":"object","properties":{"recordingId":{"type":"string","example":"api-a1b2c3d4"},"speciesSlug":{"type":"string","example":"parus-major"},"speciesCommonName":{"type":"string","example":"Great Tit"},"speciesScientificName":{"type":"string","example":"Parus major"},"recordist":{"type":"string","nullable":true},"recordistUrl":{"type":"string","nullable":true},"date":{"type":"string","example":"2024-01-15","nullable":true},"time":{"type":"string","example":"06:30","nullable":true},"country":{"type":"string","example":"India","nullable":true},"location":{"type":"string","nullable":true},"latitude":{"type":"number","nullable":true},"longitude":{"type":"number","nullable":true},"elevationM":{"type":"number","nullable":true},"callType":{"type":"string","nullable":true},"sex":{"type":"string","nullable":true},"lifeStage":{"type":"string","nullable":true},"quality":{"type":"string","enum":["A","B","C","D","E"],"nullable":true},"duration":{"type":"string","example":"0:15","nullable":true},"remarks":{"type":"string","nullable":true},"license":{"type":"string","nullable":true},"audioUrl":{"type":"string","nullable":true,"description":"Public S3 URL for the audio file"},"sourceUrl":{"type":"string","nullable":true}}},"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"}}}}},"ListMeta":{"type":"object","properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"},"pages":{"type":"integer"}}}},"responses":{"Unauthorized":{"description":"Missing or invalid API token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"RateLimited":{"description":"Too many requests","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Unix timestamp when the window resets"},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/recordings":{"get":{"operationId":"listRecordings","summary":"List recordings","description":"Returns a paginated list of recordings. Use query params to filter.","tags":["Recordings"],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","default":1,"minimum":1}},{"name":"limit","in":"query","schema":{"type":"integer","default":20,"minimum":1,"maximum":100}},{"name":"species","in":"query","description":"Filter by species slug","schema":{"type":"string"}},{"name":"country","in":"query","description":"Filter by country (partial match)","schema":{"type":"string"}},{"name":"callType","in":"query","description":"Filter by call type (partial match)","schema":{"type":"string"}},{"name":"quality","in":"query","description":"Filter by quality grade","schema":{"type":"string","enum":["A","B","C","D","E"]}}],"responses":{"200":{"description":"Paginated list of recordings","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Recording"}},"meta":{"$ref":"#/components/schemas/ListMeta"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}},"post":{"operationId":"createRecording","summary":"Create a recording","description":"Upload a new audio recording. Requires `multipart/form-data`. The audio file is stored in S3.","tags":["Recordings"],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file","speciesSlug"],"properties":{"file":{"type":"string","format":"binary","description":"Audio file (mp3, ogg, wav, flac)"},"speciesSlug":{"type":"string","description":"Species slug, e.g. `parus-major`"},"s3Prefix":{"type":"string","description":"Optional S3 path prefix (defaults to species folder)"},"recordist":{"type":"string"},"recordistUrl":{"type":"string"},"date":{"type":"string","description":"ISO date, e.g. 2024-01-15"},"time":{"type":"string","description":"Time, e.g. 06:30"},"country":{"type":"string"},"location":{"type":"string"},"latitude":{"type":"number"},"longitude":{"type":"number"},"elevationM":{"type":"number"},"callType":{"type":"string"},"callTypeOther":{"type":"string"},"sex":{"type":"string"},"lifeStage":{"type":"string"},"quality":{"type":"string","enum":["A","B","C","D","E"]},"duration":{"type":"string"},"remarks":{"type":"string"},"mp3Url":{"type":"string"},"sourceUrl":{"type":"string"},"license":{"type":"string"}}}}}},"responses":{"201":{"description":"Recording created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"recordingId":{"type":"string"},"s3Key":{"type":"string"},"audioUrl":{"type":"string"}}}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Species not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}}}}