{"openapi":"3.0.1","info":{"title":"geneav Scan API","description":"Scan documents for malware. Backed by ClamAV.","contact":{"name":"geneav","email":"admin@geneav.com"},"version":"v1"},"servers":[{"url":"https://aws.geneav.com","description":"Generated server url"}],"tags":[{"name":"Chat","description":"Ask questions about geneav"},{"name":"Scan","description":"Document malware scanning"},{"name":"Auth","description":"Dashboard sign up / sign in"},{"name":"Marketplace","description":"Microsoft Marketplace subscription lifecycle"},{"name":"Account","description":"Sign up and manage API keys and usage"}],"paths":{"/api/v1/signup":{"post":{"tags":["Account"],"summary":"Sign up","description":"Creates an account and returns its first API key (shown once).","operationId":"signup","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupResponse"}}}}}}},"/api/v1/scan":{"post":{"tags":["Scan"],"summary":"Scan a document","description":"Uploads a single document and returns a malware verdict (clean/infected).","operationId":"scan","requestBody":{"content":{"multipart/form-data":{"schema":{"required":["file"],"type":"object","properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"415":{"description":"Unsupported file type"},"400":{"description":"Missing or empty file"},"503":{"description":"Scan engine unavailable"},"200":{"description":"Scan completed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanResponse"}}}},"413":{"description":"File too large"}}}},"/api/v1/marketplace/resolve":{"post":{"tags":["Marketplace"],"summary":"Resolve a marketplace purchase","description":"Exchanges the landing-page token for the purchased subscription's details and links the purchase to the signed-in account (not yet billed).","operationId":"resolve","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResolveRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionView"}}}}}}},"/api/v1/marketplace/activate":{"post":{"tags":["Marketplace"],"summary":"Activate a marketplace subscription","description":"Confirms the purchase with Microsoft (billing starts) and applies the plan.","operationId":"activate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionView"}}}}}}},"/api/v1/keys":{"get":{"tags":["Account"],"summary":"List API keys","description":"Lists the caller's API keys (secrets are never returned).","operationId":"listKeys","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/KeySummary"}}}}}}},"post":{"tags":["Account"],"summary":"Create API key","description":"Issues an additional API key (plaintext shown once).","operationId":"createKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateKeyRequest"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatedKeyResponse"}}}}}}},"/api/v1/chat":{"post":{"tags":["Chat"],"summary":"Ask the geneav assistant","description":"Sends the conversation so far and returns the assistant's reply. The assistant only answers questions about geneav, its document scanning, and the safety it provides.","operationId":"chat","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatRequest"}}},"required":true},"responses":{"400":{"description":"Empty or malformed conversation"},"502":{"description":"Upstream chat service error"},"200":{"description":"Reply produced","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatReply"}}}},"503":{"description":"Chat not configured or unreachable"}}}},"/api/v1/auth/signup":{"post":{"tags":["Auth"],"summary":"Sign up with a password","description":"Creates a password account and starts a session.","operationId":"signup_1","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupPasswordRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeResponse"}}}}}}},"/api/v1/auth/reset-password":{"post":{"tags":["Auth"],"summary":"Set a new password","description":"Redeems a reset token and replaces the password. The token is single-use.","operationId":"resetPassword","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetPasswordRequest"}}},"required":true},"responses":{"204":{"description":"No Content"}}}},"/api/v1/auth/logout":{"post":{"tags":["Auth"],"summary":"Sign out","description":"Ends the current dashboard session.","operationId":"logout","responses":{"204":{"description":"No Content"}}}},"/api/v1/auth/login":{"post":{"tags":["Auth"],"summary":"Sign in","description":"Verifies email + password and starts a session.","operationId":"login","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeResponse"}}}}}}},"/api/v1/auth/forgot-password":{"post":{"tags":["Auth"],"summary":"Request a password reset","description":"Emails a single-use reset link that expires in 10 minutes. Always returns 202, whether or not the address has an account, so it cannot be used to discover customers.","operationId":"forgotPassword","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForgotPasswordRequest"}}},"required":true},"responses":{"202":{"description":"Accepted"}}}},"/api/v1/usage":{"get":{"tags":["Account"],"summary":"Usage this month","description":"Current-month scan usage against the plan quota.","operationId":"usage","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageResponse"}}}}}}},"/api/v1/marketplace/subscription":{"get":{"tags":["Marketplace"],"summary":"Current marketplace subscription","description":"The signed-in account's live marketplace subscription, or 404 if none.","operationId":"subscription","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionView"}}}}}}},"/api/v1/health":{"get":{"tags":["Scan"],"summary":"Health check","description":"Reports whether the API and scan engine are ready.","operationId":"health","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/v1/chat/suggestions":{"get":{"tags":["Chat"],"summary":"Predefined questions","description":"Returns the questions offered as one-click chips in the chat widget, each with the answer to render. Picking one is answered from this list, so it costs no model tokens. Available even when the assistant itself is not configured.","operationId":"suggestions","responses":{"200":{"description":"Suggestions returned (possibly empty)","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ChatSuggestion"}}}}}}}},"/api/v1/chat/health":{"get":{"tags":["Chat"],"summary":"Chat availability","description":"Reports whether the chat assistant is configured and enabled.","operationId":"chatHealth","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/v1/auth/me":{"get":{"tags":["Auth"],"summary":"Current session","description":"Returns the signed-in account, or 401 if not signed in.","operationId":"me","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeResponse"}}}}}}},"/api/v1/keys/{id}":{"delete":{"tags":["Account"],"summary":"Revoke API key","description":"Permanently revokes one of the caller's API keys.","operationId":"revokeKey","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"No Content"}}}}},"components":{"schemas":{"SignupRequest":{"required":["email"],"type":"object","properties":{"email":{"type":"string"}}},"SignupResponse":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"email":{"type":"string"},"plan":{"type":"string"},"apiKey":{"type":"string"},"keyPrefix":{"type":"string"}}},"ScanResponse":{"type":"object","properties":{"scanId":{"type":"string","description":"Unique id for this scan","example":"a1b2c3d4-e5f6-7890-abcd-ef1234567890"},"status":{"type":"string","description":"Overall verdict","example":"clean","enum":["clean","infected"]},"threat":{"type":"string","description":"Name of the detected threat, or null when clean","nullable":true,"example":"Eicar-Test-Signature"},"fileName":{"type":"string","description":"Original file name","example":"invoice.pdf"},"fileSize":{"type":"integer","description":"File size in bytes","format":"int64","example":48213},"contentType":{"type":"string","description":"Reported content type","nullable":true,"example":"application/pdf"},"scannedAt":{"type":"string","description":"When the scan completed (UTC)","format":"date-time"}},"description":"Result of scanning a single document"},"ResolveRequest":{"type":"object","properties":{"token":{"type":"string"}}},"SubscriptionView":{"type":"object","properties":{"subscriptionId":{"type":"string","format":"uuid"},"offerId":{"type":"string"},"marketplacePlanId":{"type":"string"},"planKey":{"type":"string"},"status":{"type":"string"},"freeTrial":{"type":"boolean"},"autoRenew":{"type":"boolean"},"termStart":{"type":"string","format":"date-time"},"termEnd":{"type":"string","format":"date-time"},"beneficiaryEmail":{"type":"string"}}},"ActivateRequest":{"type":"object","properties":{"subscriptionId":{"type":"string","format":"uuid"}}},"CreateKeyRequest":{"type":"object","properties":{"name":{"type":"string"}}},"CreatedKeyResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"apiKey":{"type":"string"},"keyPrefix":{"type":"string"}}},"ChatMessage":{"type":"object","properties":{"role":{"type":"string","description":"Who sent the message","example":"user","enum":["user","assistant"]},"content":{"type":"string","description":"Message text","example":"What kinds of files can geneav scan?"}},"description":"A single chat message"},"ChatRequest":{"required":["messages"],"type":"object","properties":{"messages":{"type":"array","description":"Conversation history, oldest first; the last entry is the user's new question","items":{"$ref":"#/components/schemas/ChatMessage"}}},"description":"A chat conversation to continue"},"ChatReply":{"type":"object","properties":{"reply":{"type":"string","description":"Assistant's answer","example":"geneav scans documents such as PDFs, Office files, text, and ZIPs for malware."},"model":{"type":"string","description":"Model that produced the reply","example":"gpt-4o-mini"}},"description":"The assistant's reply"},"AttributionPayload":{"type":"object","properties":{"utmSource":{"type":"string"},"utmMedium":{"type":"string"},"utmCampaign":{"type":"string"},"utmTerm":{"type":"string"},"utmContent":{"type":"string"},"referrer":{"type":"string"},"landingPath":{"type":"string"}}},"SignupPasswordRequest":{"required":["email","password"],"type":"object","properties":{"email":{"type":"string"},"password":{"type":"string"},"attribution":{"$ref":"#/components/schemas/AttributionPayload"}}},"MeResponse":{"type":"object","properties":{"email":{"type":"string"},"plan":{"type":"string"},"authProvider":{"type":"string"}}},"ResetPasswordRequest":{"required":["password","token"],"type":"object","properties":{"token":{"type":"string"},"password":{"type":"string"}}},"LoginRequest":{"required":["email","password"],"type":"object","properties":{"email":{"type":"string"},"password":{"type":"string"}}},"ForgotPasswordRequest":{"required":["email"],"type":"object","properties":{"email":{"type":"string"}}},"UsageResponse":{"type":"object","properties":{"plan":{"type":"string"},"period":{"type":"string"},"scansUsed":{"type":"integer","format":"int64"},"scansQuota":{"type":"integer","format":"int64"},"scansRemaining":{"type":"integer","format":"int64"}}},"KeySummary":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"keyPrefix":{"type":"string"},"lastFour":{"type":"string"},"status":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"lastUsedAt":{"type":"string","format":"date-time"}}},"ChatSuggestion":{"type":"object","properties":{"id":{"type":"string","description":"Stable identifier for the suggestion","example":"file-size"},"question":{"type":"string","description":"Question shown on the chip","example":"What is the maximum file size?"},"answer":{"type":"string","description":"Answer rendered when the chip is picked, costing no model tokens","example":"Up to 25 MB per upload. Anything larger returns 413."}},"description":"A predefined question and its canned answer"}}}}