{"components":{"schemas":{"ApiKey":{"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_prefix":{"description":"First 12 chars of the key for identification","type":"string"},"name":{"type":"string"}},"type":"object"},"ApiKeyWithSecret":{"description":"API key with full key included. The key is only returned on create — save it immediately.","properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key":{"description":"Full API key (vxk_...) — only shown once","type":"string"},"key_prefix":{"type":"string"},"name":{"type":"string"}},"type":"object"},"Project":{"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"otp_mode":{"enum":["email","phone"],"type":"string"},"updated_at":{"format":"date-time","type":"string"}},"type":"object"},"ProjectWithSecret":{"description":"Project with secret key included. The secret_key is only returned on create and regenerate — save it immediately.","properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"otp_mode":{"enum":["email","phone"],"type":"string"},"secret_key":{"description":"Secret key (vx_sec_...) — only shown once, store securely","type":"string"}},"type":"object"},"User":{"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"email_verified":{"type":"boolean"},"id":{"type":"string"},"name":{"type":"string"},"phone":{"type":"string"},"phone_verified":{"type":"boolean"},"updated_at":{"format":"date-time","type":"string"}},"type":"object"}},"securitySchemes":{"apiKey":{"description":"Developer API key (vxk_...) — used to manage projects and keys programmatically","scheme":"bearer","type":"http"},"projectSecretKey":{"description":"Project secret key (vx_sec_...) — used by the SDK to deliver OTP codes","scheme":"bearer","type":"http"},"sessionCookie":{"description":"Dashboard session cookie — set after OTP verification","in":"cookie","name":"futureauth_session","type":"apiKey"}}},"info":{"contact":{"url":"https://github.com/ethereumdegen/futureauth-sdk"},"description":"Passwordless OTP authentication for Rust apps. FutureAuth delivers verification codes via email (Resend) or SMS (Twilio) — users and sessions live in your own Postgres database.","title":"FutureAuth API","version":"0.2.0"},"openapi":"3.1.0","paths":{"/api/auth/send-otp":{"post":{"operationId":"dashboardSendOtp","requestBody":{"content":{"application/json":{"schema":{"properties":{"email":{"format":"email","type":"string"}},"required":["email"],"type":"object"}}},"required":true},"responses":{"200":{"description":"OTP sent"}},"summary":"Send OTP to sign into the FutureAuth dashboard"}},"/api/auth/session":{"get":{"operationId":"dashboardGetSession","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"user":{"$ref":"#/components/schemas/User"}},"type":"object"}}}},"401":{"description":"Not authenticated"}},"security":[{"sessionCookie":[]}],"summary":"Get the current dashboard session"}},"/api/auth/sign-out":{"post":{"operationId":"dashboardSignOut","responses":{"200":{"description":"Signed out. Clears session cookie."}},"security":[{"sessionCookie":[]}],"summary":"Sign out and revoke the dashboard session"}},"/api/auth/verify-otp":{"post":{"operationId":"dashboardVerifyOtp","requestBody":{"content":{"application/json":{"schema":{"properties":{"code":{"description":"6-character alphanumeric OTP code","type":"string"},"email":{"format":"email","type":"string"}},"required":["email","code"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"user":{"$ref":"#/components/schemas/User"}},"type":"object"}}},"description":"Authenticated. Sets session cookie."},"400":{"description":"Invalid or expired code"}},"summary":"Verify OTP and create a dashboard session"}},"/api/config":{"get":{"operationId":"getConfig","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"email_enabled":{"type":"boolean"},"sms_enabled":{"type":"boolean"}},"type":"object"}}}}},"summary":"Get server configuration (which delivery channels are enabled)"}},"/api/keys":{"get":{"operationId":"listApiKeys","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ApiKey"},"type":"array"}}}}},"security":[{"apiKey":[]},{"sessionCookie":[]}],"summary":"List developer API keys"},"post":{"operationId":"createApiKey","requestBody":{"content":{"application/json":{"schema":{"properties":{"name":{"default":"Untitled","type":"string"}},"type":"object"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyWithSecret"}}},"description":"API key created. IMPORTANT: The full key is only returned once."}},"security":[{"apiKey":[]},{"sessionCookie":[]}],"summary":"Create a developer API key"}},"/api/keys/{id}":{"delete":{"operationId":"deleteApiKey","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Deleted"}},"security":[{"apiKey":[]},{"sessionCookie":[]}],"summary":"Delete a developer API key"}},"/api/projects":{"get":{"operationId":"listProjects","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/Project"},"type":"array"}}},"description":"Array of projects"},"401":{"description":"Not authenticated"}},"security":[{"apiKey":[]},{"sessionCookie":[]}],"summary":"List all projects for the authenticated user"},"post":{"operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"properties":{"name":{"description":"Project name","type":"string"},"otp_mode":{"default":"email","description":"OTP delivery channel","enum":["email","phone"],"type":"string"}},"required":["name"],"type":"object"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectWithSecret"}}},"description":"Project created. IMPORTANT: The secret_key is only returned once — save it immediately."},"400":{"description":"Validation error"},"401":{"description":"Not authenticated"}},"security":[{"apiKey":[]},{"sessionCookie":[]}],"summary":"Create a new project"}},"/api/projects/{id}":{"delete":{"operationId":"deleteProject","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Deleted"},"404":{"description":"Project not found"}},"security":[{"apiKey":[]},{"sessionCookie":[]}],"summary":"Delete a project"},"get":{"operationId":"getProject","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}}},"404":{"description":"Project not found"}},"security":[{"apiKey":[]},{"sessionCookie":[]}],"summary":"Get project details"},"put":{"operationId":"updateProject","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"name":{"type":"string"},"otp_mode":{"enum":["email","phone"],"type":"string"}},"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}}},"404":{"description":"Project not found"}},"security":[{"apiKey":[]},{"sessionCookie":[]}],"summary":"Update a project"}},"/api/projects/{id}/regenerate-keys":{"post":{"operationId":"regenerateProjectKeys","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectWithSecret"}}},"description":"New keys generated. IMPORTANT: The secret_key is only returned once."},"404":{"description":"Project not found"}},"security":[{"apiKey":[]},{"sessionCookie":[]}],"summary":"Regenerate the secret key for a project"}},"/api/v1/otp/send":{"post":{"description":"Called by the SDK to deliver a verification code. Authenticated with project secret key.","operationId":"sendOtp","requestBody":{"content":{"application/json":{"schema":{"properties":{"channel":{"description":"Delivery channel","enum":["email","sms"],"type":"string"},"code":{"description":"The OTP code to deliver","type":"string"},"destination":{"description":"Email address or phone number (E.164)","type":"string"},"project_name":{"description":"Optional project name for branding","type":"string"}},"required":["channel","destination","code"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"ok":{"type":"boolean"}},"type":"object"}}},"description":"OTP delivered"},"400":{"description":"Invalid channel"},"401":{"description":"Invalid or missing secret key"},"503":{"description":"Delivery channel not configured"}},"security":[{"projectSecretKey":[]}],"summary":"Deliver an OTP code via email or SMS"}},"/health":{"get":{"operationId":"healthCheck","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"service":{"example":"futureauth","type":"string"},"status":{"example":"ok","type":"string"}},"type":"object"}}}}},"summary":"Health check"}}},"servers":[{"description":"Current instance","url":"https://future-auth.com"}]}