{"openapi":"3.1.0","info":{"title":"MedTrack AI API","version":"1.0.0","description":"REST API for MedTrack AI — an AI-powered personal health record platform. Upload diagnostic medical reports, extract clinical biomarker metrics, and track health trends over time.","contact":{"name":"MedTrack AI","email":"vinayhadimani99@gmail.com","url":"https://medtrack-ai.live"},"license":{"name":"Proprietary"}},"servers":[{"url":"https://medtrack-ai.live","description":"Production"}],"tags":[{"name":"Authentication","description":"OAuth and session management"},{"name":"Reports","description":"Medical report upload and analysis"},{"name":"Metrics","description":"Biomarker tracking and trends"},{"name":"Files","description":"Uploaded file access"},{"name":"Payments","description":"Subscription and billing"}],"paths":{"/api/auth/google":{"get":{"operationId":"startGoogleOAuth","tags":["Authentication"],"summary":"Start Google OAuth","description":"Initiate the Google OAuth flow and get the redirect URL.","responses":{"200":{"description":"OAuth URL generated","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"}},"required":["url"]}}}}}}},"/api/auth/otp":{"post":{"operationId":"sendOrVerifyOtp","tags":["Authentication"],"summary":"Send or Verify Email OTP / Magic Link","description":"Send a one-time passcode/magic link to an email address or verify an entered code.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"action":{"type":"string","enum":["send","verify"]},"email":{"type":"string","format":"email"},"token":{"type":"string","description":"6-digit OTP code (for verify action)"},"country":{"type":"string","description":"Country code (e.g. IN, US)"}},"required":["email"]}}}},"responses":{"200":{"description":"OTP sent or verified successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"},"user":{"type":"object"}}}}}},"400":{"description":"Invalid email or OTP code"},"429":{"description":"Rate limit exceeded"}}}},"/api/auth/callback":{"get":{"operationId":"oauthCallback","tags":["Authentication"],"summary":"OAuth Callback","description":"Handle the OAuth callback from Supabase.","parameters":[{"name":"code","in":"query","required":true,"schema":{"type":"string"}},{"name":"next","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"307":{"description":"Redirect to app or error page"}}}},"/api/auth/session":{"get":{"operationId":"getSession","tags":["Authentication"],"summary":"Get User Session","description":"Retrieve current user session and subscription info.","responses":{"200":{"description":"Session information","content":{"application/json":{"schema":{"type":"object","properties":{"user":{"type":"object","nullable":true},"subscribed":{"type":"boolean"},"freeRemaining":{"type":"number"},"freeTierLimit":{"type":"number"}},"required":["subscribed","freeRemaining","freeTierLimit"]}}}}}}},"/api/auth/signout":{"post":{"operationId":"signOut","tags":["Authentication"],"summary":"Sign Out","description":"Sign out the current user.","responses":{"200":{"description":"Successfully signed out","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}},"required":["success"]}}}}}}},"/api/reports":{"get":{"operationId":"listReports","tags":["Reports"],"summary":"List Reports","description":"Get a list of all uploaded reports for the current user.","security":[{"sessionCookie":[]}],"responses":{"200":{"description":"List of reports","content":{"application/json":{"schema":{"type":"object","properties":{"reports":{"type":"array","items":{"$ref":"#/components/schemas/ReportSummary"}}},"required":["reports"]}}}}}},"post":{"operationId":"uploadReport","tags":["Reports"],"summary":"Upload Report","description":"Upload one or more medical reports for analysis.","security":[{"sessionCookie":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"},"files":{"type":"array","items":{"type":"string","format":"binary"}}}}}}},"responses":{"200":{"description":"Upload successful","content":{"application/json":{"schema":{"type":"object","properties":{"reportId":{"type":"string"},"success":{"type":"boolean"},"status":{"type":"string"},"metricsExtracted":{"type":"number"},"pageCount":{"type":"number"}},"required":["reportId","success","status","metricsExtracted","pageCount"]}}}},"402":{"description":"Subscription required","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","example":"SUBSCRIPTION_REQUIRED"}}}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Unsupported media type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before trying again"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/reports/{id}":{"get":{"operationId":"getReport","tags":["Reports"],"summary":"Get Report Details","description":"Get details for a specific report.","security":[{"sessionCookie":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Report details","content":{"application/json":{"schema":{"type":"object","properties":{"report":{"$ref":"#/components/schemas/ReportDetail"}},"required":["report"]}}}},"404":{"description":"Report not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"operationId":"deleteReport","tags":["Reports"],"summary":"Delete Report","description":"Delete a specific report.","security":[{"sessionCookie":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successfully deleted","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}},"required":["success"]}}}}}}},"/api/reports/{id}/process-page":{"post":{"operationId":"processPage","tags":["Reports"],"summary":"Process Report Page","description":"Process a specific page of a report for analysis.","security":[{"sessionCookie":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"pageIndex":{"type":"number"},"dataUrl":{"type":"string"},"mimeType":{"type":"string"},"fileName":{"type":"string"},"totalPages":{"type":"number"}},"required":["pageIndex","dataUrl"]}}}},"responses":{"200":{"description":"Page processed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"pageIndex":{"type":"number"},"totalPages":{"type":"number"}},"required":["success","pageIndex","totalPages"]}}}}}}},"/api/reports/{id}/finalize":{"post":{"operationId":"finalizeReport","tags":["Reports"],"summary":"Finalize Report Processing","description":"Mark report processing as complete after all pages are processed.","security":[{"sessionCookie":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Report finalized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"metricsExtracted":{"type":"number"}},"required":["success","metricsExtracted"]}}}}}}},"/api/reports/{id}/retry":{"post":{"operationId":"retryAnalysis","tags":["Reports"],"summary":"Retry Report Analysis","description":"Retry analyzing a failed report.","security":[{"sessionCookie":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Retry successful","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"metricsExtracted":{"type":"number"}},"required":["success","metricsExtracted"]}}}},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/metrics":{"get":{"operationId":"listMetrics","tags":["Metrics"],"summary":"List Metrics","description":"Get all biomarker metrics or a specific metric if name is provided.","security":[{"sessionCookie":[]}],"parameters":[{"name":"name","in":"query","required":false,"schema":{"type":"string"},"description":"Optional name of the metric to fetch"}],"responses":{"200":{"description":"Metrics list or single metric","content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"metrics":{"type":"array","items":{"$ref":"#/components/schemas/MetricGroup"}}},"required":["metrics"]},{"type":"object","properties":{"metric":{"$ref":"#/components/schemas/MetricGroup"}},"required":["metric"]}]}}}}}}},"/api/files/{filename}":{"get":{"operationId":"getFile","tags":["Files"],"summary":"Get Uploaded File","description":"Retrieve a previously uploaded file.","security":[{"sessionCookie":[]}],"parameters":[{"name":"filename","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Binary file stream","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"404":{"description":"File not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/checkout/create-order":{"post":{"operationId":"createOrder","tags":["Payments"],"summary":"Create Checkout Order","description":"Create an order for subscription payment.","security":[{"sessionCookie":[]}],"responses":{"200":{"description":"Order created","content":{"application/json":{"schema":{"type":"object","properties":{"order_id":{"type":"string"},"amount":{"type":"number"},"currency":{"type":"string"},"keyId":{"type":"string","nullable":true}},"required":["order_id","amount","currency"]}}}}}}},"/api/checkout/verify":{"post":{"operationId":"verifyPayment","tags":["Payments"],"summary":"Verify Payment","description":"Verify payment signature from Razorpay.","security":[{"sessionCookie":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"razorpay_order_id":{"type":"string"},"razorpay_payment_id":{"type":"string"},"razorpay_signature":{"type":"string"}},"required":["razorpay_order_id","razorpay_payment_id","razorpay_signature"]}}}},"responses":{"200":{"description":"Payment verified","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"subscription":{"type":"object","properties":{"status":{"type":"string"},"currentPeriodEnd":{"type":"string"}},"required":["status","currentPeriodEnd"]}},"required":["success","subscription"]}}}}}}}},"components":{"securitySchemes":{"sessionCookie":{"type":"apiKey","in":"cookie","name":"sb-*-auth-token","description":"Supabase session cookie set during Google OAuth sign-in"}},"schemas":{"ReportSummary":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"date":{"type":"string","format":"date-time"},"status":{"type":"string"},"metricCount":{"type":"number"}},"required":["id","title","date","status","metricCount"]},"ReportDetail":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"date":{"type":"string","format":"date-time"},"status":{"type":"string"},"metrics":{"type":"array","items":{"$ref":"#/components/schemas/ExtractedMetric"}}},"required":["id","title","date","status","metrics"]},"ExtractedMetric":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"value":{"type":"number"},"unit":{"type":"string"},"referenceRange":{"type":"string","nullable":true}},"required":["id","name","value","unit"]},"MetricGroup":{"type":"object","properties":{"name":{"type":"string"},"unit":{"type":"string"},"history":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date-time"},"value":{"type":"number"},"reportId":{"type":"string"}},"required":["date","value","reportId"]}}},"required":["name","unit","history"]},"ErrorResponse":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}