{"openapi":"3.1.0","info":{"title":"TOTP / 2FA API","version":"1.0.0","description":"Add and test two-factor authentication without wrangling a crypto library. Generate a fresh base32 secret with a ready-to-scan otpauth URI, compute the current time-based one-time code (RFC 6238), verify a code submitted by a user with an adjustable drift window, or build an otpauth:// URI for any secret. Supports SHA-1, SHA-256 and SHA-512, 6 to 8 digits and a custom period, and is fully compatible with Google Authenticator, Authy, 1Password and other authenticator apps. Pure server-side computation with no third-party upstream, so responses are instant and the service is always available. Ideal for adding 2FA to apps, authentication tooling, QA and testing, and no-code automation.","contact":{"name":"PremiumApi","url":"https://www.oanor.com/by/premiumapi"}},"servers":[{"url":"https://api.oanor.com/totp-api","description":"oanor gateway"}],"tags":[{"name":"TOTP"}],"components":{"securitySchemes":{"oanorKey":{"type":"apiKey","in":"header","name":"x-oanor-key","description":"Get your key at https://www.oanor.com/developer/keys"}}},"security":[{"oanorKey":[]}],"paths":{"/v1/code":{"get":{"operationId":"get_v1_code","tags":["TOTP"],"summary":"Current TOTP code","description":"","parameters":[{"name":"secret","in":"query","required":true,"description":"Base32 secret","schema":{"type":"string"},"example":"GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ"},{"name":"algorithm","in":"query","required":false,"description":"SHA1 | SHA256 | SHA512","schema":{"type":"string"},"example":"SHA1"},{"name":"digits","in":"query","required":false,"description":"6, 7 or 8","schema":{"type":"string"},"example":"8"},{"name":"period","in":"query","required":false,"description":"Seconds (default 30)","schema":{"type":"string"},"example":"30"},{"name":"timestamp","in":"query","required":false,"description":"Unix time (default now)","schema":{"type":"string"},"example":"59"}],"security":[{"oanorKey":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"data":{"code":"94287082","digits":8,"period":30,"algorithm":"SHA1","timestamp":59,"seconds_remaining":1},"meta":{"timestamp":"2026-05-30T18:16:47.984Z","request_id":"5f4798da-856b-46b1-be3e-a9fa45561607"},"status":"ok","message":"OK","success":true}}}},"401":{"description":"Missing or invalid x-oanor-key header"},"402":{"description":"Active subscription required"},"429":{"description":"Rate-limit or monthly quota reached"},"502":{"description":"Upstream did not respond"}}}},"/v1/secret":{"get":{"operationId":"get_v1_secret","tags":["TOTP"],"summary":"Generate a secret + otpauth URI","description":"","parameters":[{"name":"issuer","in":"query","required":false,"description":"Issuer name","schema":{"type":"string"},"example":"oanor"},{"name":"account","in":"query","required":false,"description":"Account label","schema":{"type":"string"},"example":"user@example.com"},{"name":"bytes","in":"query","required":false,"description":"Secret bytes 10-64 (default 20)","schema":{"type":"string"},"example":"20"}],"security":[{"oanorKey":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"data":{"hex":"201fae6e22c311a843223e54f30bcf83bc95d1a0","base32":"EAP243RCYMI2QQZCHZKPGC6PQO6JLUNA","issuer":"oanor","secret":"EAP243RCYMI2QQZCHZKPGC6PQO6JLUNA","account":"user@example.com","otpauth_uri":"otpauth://totp/oanor%3Auser%40example.com?secret=EAP243RCYMI2QQZCHZKPGC6PQO6JLUNA&issuer=oanor&algorithm=SHA1&digits=6&period=30"},"meta":{"timestamp":"2026-05-30T18:16:48.035Z","request_id":"24aaf93a-fe32-4f04-8b0f-eabc40655dca"},"status":"ok","message":"OK","success":true}}}},"401":{"description":"Missing or invalid x-oanor-key header"},"402":{"description":"Active subscription required"},"429":{"description":"Rate-limit or monthly quota reached"},"502":{"description":"Upstream did not respond"}}}},"/v1/uri":{"get":{"operationId":"get_v1_uri","tags":["TOTP"],"summary":"Build an otpauth:// URI","description":"","parameters":[{"name":"secret","in":"query","required":true,"description":"Base32 secret","schema":{"type":"string"},"example":"GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ"},{"name":"issuer","in":"query","required":false,"description":"Issuer name","schema":{"type":"string"},"example":"Acme"},{"name":"account","in":"query","required":false,"description":"Account label","schema":{"type":"string"},"example":"bob@example.com"},{"name":"digits","in":"query","required":false,"description":"6, 7 or 8","schema":{"type":"string"},"example":"6"},{"name":"period","in":"query","required":false,"description":"Seconds","schema":{"type":"string"},"example":"30"}],"security":[{"oanorKey":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"data":{"digits":6,"issuer":"Acme","period":30,"account":"bob@example.com","algorithm":"SHA1","otpauth_uri":"otpauth://totp/Acme%3Abob%40example.com?secret=GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ&issuer=Acme&algorithm=SHA1&digits=6&period=30"},"meta":{"timestamp":"2026-05-30T18:16:48.112Z","request_id":"e2639b88-9ad5-407b-bc92-5a85d87f03f8"},"status":"ok","message":"OK","success":true}}}},"401":{"description":"Missing or invalid x-oanor-key header"},"402":{"description":"Active subscription required"},"429":{"description":"Rate-limit or monthly quota reached"},"502":{"description":"Upstream did not respond"}}}},"/v1/verify":{"get":{"operationId":"get_v1_verify","tags":["TOTP"],"summary":"Verify a code","description":"","parameters":[{"name":"secret","in":"query","required":true,"description":"Base32 secret","schema":{"type":"string"},"example":"GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ"},{"name":"code","in":"query","required":true,"description":"Code to verify","schema":{"type":"string"},"example":"94287082"},{"name":"digits","in":"query","required":false,"description":"6, 7 or 8","schema":{"type":"string"},"example":"8"},{"name":"period","in":"query","required":false,"description":"Seconds","schema":{"type":"string"},"example":"30"},{"name":"window","in":"query","required":false,"description":"Drift window 0-10 (default 1)","schema":{"type":"string"},"example":"1"},{"name":"timestamp","in":"query","required":false,"description":"Unix time (default now)","schema":{"type":"string"},"example":"59"}],"security":[{"oanorKey":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"data":{"delta":0,"valid":true,"digits":8,"period":30,"window":1,"algorithm":"SHA1"},"meta":{"timestamp":"2026-05-30T18:16:48.162Z","request_id":"73e92b67-5a1e-4088-95cf-38a3c18ea107"},"status":"ok","message":"OK","success":true}}}},"401":{"description":"Missing or invalid x-oanor-key header"},"402":{"description":"Active subscription required"},"429":{"description":"Rate-limit or monthly quota reached"},"502":{"description":"Upstream did not respond"}}}}},"x-oanor-pricing":[{"slug":"free","name":"Free","price_cents_month":0,"monthly_call_quota":1500,"rps_limit":3,"hard_limit":true},{"slug":"basic","name":"Basic","price_cents_month":500,"monthly_call_quota":30000,"rps_limit":10,"hard_limit":true},{"slug":"pro","name":"Pro","price_cents_month":1700,"monthly_call_quota":250000,"rps_limit":30,"hard_limit":true},{"slug":"mega","name":"Mega","price_cents_month":4600,"monthly_call_quota":1500000,"rps_limit":80,"hard_limit":true}],"x-oanor-marketplace-url":"https://www.oanor.com/api/totp-api"}