{"openapi":"3.0.3","info":{"title":"getotp API","version":"1.1.0","description":"メールの受信箱・認証コードの取得・2FAコード生成のHTTP API。API キー（/developer で発行）を Authorization: Bearer に、受信箱の address と password を本文に入れる。人が読む説明は https://getotp.cc/docs"},"servers":[{"url":"https://getotp.cc/api/v1"}],"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"https://getotp.cc/developer で発行した API キー（gk_…）。X-Api-Key ヘッダーでも可"}},"schemas":{"Credentials":{"type":"object","required":["address","password"],"properties":{"address":{"type":"string","format":"email"},"password":{"type":"string"}}},"MailSummary":{"type":"object","required":["id","sender","subject","otp","receivedAt"],"properties":{"id":{"type":"integer"},"sender":{"type":"string","nullable":true},"subject":{"type":"string","nullable":true},"otp":{"type":"string","nullable":true,"description":"本文から抜き出した認証コード。無ければnull"},"receivedAt":{"type":"string","description":"ISO 8601（UTC）。firstmail は受信時刻が取れないので空文字"}}},"MailDetail":{"allOf":[{"type":"object","required":["id","sender","subject","otp","receivedAt"],"properties":{"id":{"type":"integer"},"sender":{"type":"string","nullable":true},"subject":{"type":"string","nullable":true},"otp":{"type":"string","nullable":true,"description":"本文から抜き出した認証コード。無ければnull"},"receivedAt":{"type":"string","description":"ISO 8601（UTC）。firstmail は受信時刻が取れないので空文字"}}},{"type":"object","required":["body","replyTo"],"properties":{"body":{"type":"string","description":"本文（テキスト）"},"replyTo":{"type":"string","nullable":true}}}]},"Error":{"type":"object","required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"integer","description":"429のときだけ。待つ秒数"}}}}},"paths":{"/otp":{"post":{"summary":"最新の認証コード（コード入りの一番新しいメール）","security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Credentials"},{"type":"object","properties":{"after":{"type":"string","format":"date-time","description":"この日時（ISO 8601）より後に届いたメールだけを見る。受信時刻が取れないメール（firstmail）には効かない"}}}]}},"application/x-www-form-urlencoded":{"schema":{"allOf":[{"$ref":"#/components/schemas/Credentials"},{"type":"object","properties":{"after":{"type":"string","format":"date-time","description":"この日時（ISO 8601）より後に届いたメールだけを見る。受信時刻が取れないメール（firstmail）には効かない"}}}]}}}},"responses":{"200":{"description":"最新の認証コード。無ければotpとmailがnull","content":{"application/json":{"schema":{"type":"object","required":["address","otp","mail"],"properties":{"address":{"type":"string"},"otp":{"type":"string","nullable":true},"mail":{"nullable":true,"type":"object","properties":{"id":{"type":"integer"},"sender":{"type":"string","nullable":true},"subject":{"type":"string","nullable":true},"receivedAt":{"type":"string","format":"date-time"}}}}}}}},"400":{"description":"入力の形式が違う","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"API キーが無効（invalid_api_key）、またはアドレス・パスワードが違う（invalid_credentials）","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"本文が4KBを超えている","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"回数制限","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"メールサービス側に接続できない","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/mails":{"post":{"summary":"受信箱（新しい順）","security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Credentials"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Credentials"}}}},"responses":{"200":{"description":"一覧","content":{"application/json":{"schema":{"type":"object","required":["address","mails"],"properties":{"address":{"type":"string"},"mails":{"type":"array","items":{"$ref":"#/components/schemas/MailSummary"}}}}}}},"400":{"description":"入力の形式が違う","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"API キーが無効（invalid_api_key）、またはアドレス・パスワードが違う（invalid_credentials）","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"本文が4KBを超えている","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"回数制限","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"メールサービス側に接続できない","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/mails/{id}":{"post":{"summary":"1通の本文","security":[{"apiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Credentials"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Credentials"}}}},"responses":{"200":{"description":"1通","content":{"application/json":{"schema":{"type":"object","required":["address","mail"],"properties":{"address":{"type":"string"},"mail":{"$ref":"#/components/schemas/MailDetail"}}}}}},"400":{"description":"入力の形式が違う","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"API キーが無効（invalid_api_key）、またはアドレス・パスワードが違う（invalid_credentials）","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"無い","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"本文が4KBを超えている","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"回数制限","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"メールサービス側に接続できない","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/totp":{"post":{"summary":"2FAコード生成（SHA-1 / 6桁 / 30秒）","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["secret"],"properties":{"secret":{"type":"string","description":"base32の秘密キー"}}}}}},"responses":{"200":{"description":"今のコード","content":{"application/json":{"schema":{"type":"object","required":["code","expiresIn","period","digits"],"properties":{"code":{"type":"string"},"expiresIn":{"type":"integer","description":"切り替わるまでの秒数"},"period":{"type":"integer"},"digits":{"type":"integer"}}}}}},"400":{"description":"入力の形式が違う","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"回数制限","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}