API

基本

ベースURL
https://getotp.cc/api/v1
メソッド
すべてPOST
APIキー
Authorization: Bearer gk_…(またはX-Api-Key)。/developerで発行。/totpは不要
受信箱
毎回addressとpasswordを本文で指定。キーには紐づかない
本文
JSONまたはapplication/x-www-form-urlencoded。4KBまで
応答
JSON。失敗時は{"error": "...", "message": "..."}
日時
ISO 8601(UTC)
CORS
許可。公開ページのJavaScriptにキーやパスワードを置かない
OpenAPI
/docs/openapi.json

アドレス

ログイン画面と同じ。mail7z.net / mailcab.win / mailgz.dev などの受信ドメインと、irith / firstmail / mail.tm。GmailやYahooなどの個人向けメールは不可。

エンドポイント

POST /otp

コード入りの一番新しいメール。無ければotpとmailはnull。

本文

名前型必須説明
addressstring必須メールアドレス
passwordstring必須メールボックスのパスワード
afterstringこの日時(ISO 8601)より後の受信だけ見る。firstmailには効かない

応答

名前型説明
addressstring照合したアドレス
otpstring | null認証コード
mailobject | nullid / sender / subject / receivedAt
リクエスト
curl -X POST https://getotp.cc/api/v1/otp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer gk_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
  -d '{"address": "xxxx@mail7z.net", "password": "パスワード", "after": "2026-10-12T03:20:00Z"}'
200
{
  "address": "xxxx@mail7z.net",
  "otp": "482913",
  "mail": {
    "id": 1203,
    "sender": "info@x.com",
    "subject": "Your X confirmation code is 482913",
    "receivedAt": "2026-10-12T03:21:45.000Z"
  }
}
200(未着)
{"address": "xxxx@mail7z.net", "otp": null, "mail": null}

POST /mails

受信箱。新しい順。firstmailは最新の1通のみ(idは1)。

本文

名前型必須説明
addressstring必須メールアドレス
passwordstring必須メールボックスのパスワード

応答

名前型説明
addressstring照合したアドレス
mailsarray次の要素の配列

mails[]

名前型説明
idinteger/mails/{id}に渡すID
senderstring | null差出人
subjectstring | null件名
otpstring | null本文から抜き出した認証コード
receivedAtstring受信日時(ISO 8601、UTC)。firstmailは空文字
リクエスト
curl -X POST https://getotp.cc/api/v1/mails \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer gk_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
  -d '{"address": "xxxx@mail7z.net", "password": "パスワード"}'
200
{
  "address": "xxxx@mail7z.net",
  "mails": [
    {
      "id": 1203,
      "sender": "info@x.com",
      "subject": "Your X confirmation code is 482913",
      "otp": "482913",
      "receivedAt": "2026-10-12T03:21:45.000Z"
    },
    {
      "id": 1198,
      "sender": "noreply@example.com",
      "subject": "お知らせ",
      "otp": null,
      "receivedAt": "2026-10-12T02:10:03.000Z"
    }
  ]
}

POST /mails/{id}

1通の本文。他人宛・無いIDは404。

パス

名前型必須説明
idinteger必須/mailsのid

本文

名前型必須説明
addressstring必須メールアドレス
passwordstring必須メールボックスのパスワード

応答

名前型説明
addressstring照合したアドレス
mailobjectmails[]の項目に加えて次の2つ
mail.bodystring本文(テキスト)
mail.replyTostring | nullReply-To
リクエスト
curl -X POST https://getotp.cc/api/v1/mails/1203 \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer gk_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
  -d '{"address": "xxxx@mail7z.net", "password": "パスワード"}'
200
{
  "address": "xxxx@mail7z.net",
  "mail": {
    "id": 1203,
    "sender": "info@x.com",
    "subject": "Your X confirmation code is 482913",
    "otp": "482913",
    "receivedAt": "2026-10-12T03:21:45.000Z",
    "body": "Your X confirmation code is 482913.\n...",
    "replyTo": null
  }
}

POST /totp

base32の秘密キーから現在のコード。SHA-1 / 6桁 / 30秒。キーは保存しない。APIキー不要。

本文

名前型必須説明
secretstring必須base32。空白とハイフンは無視

応答

名前型説明
codestring6桁
expiresIninteger切り替わるまでの秒数
periodinteger30
digitsinteger6
リクエスト
curl -X POST https://getotp.cc/api/v1/totp \
  -H "Content-Type: application/json" \
  -d '{"secret": "JBSWY3DPEHPK3PXP"}'
200
{"code": "287082", "expiresIn": 17, "period": 30, "digits": 6}

回数制限

超過は429とRetry-After。ポーリングは3〜5秒間隔。

対象上限
/otp・/mails・/mails/{id}キーごと60回/分、1,000回/時
同じアドレス30回/分(キー横断)
照合の失敗キーごと10回/分、60回/時
パスワードの連続ミス同じアドレスで5回続くと5分ロック
キー無し・無効なキーIPごと30回/分
/totpIPごと60回/分

エラー

HTTPerror意味
400invalid_request必須項目が無い、または形式が違う
400invalid_jsonJSONとして読めない
400invalid_secretsecretがbase32でない
401invalid_api_keyAPIキーが無い・無効・停止中
401invalid_credentialsアドレスまたはパスワードが違う
404not_foundエンドポイントまたはメールが無い
413payload_too_large本文が4KBを超えている
429rate_limited回数制限。retryAfter秒後に再試行
502upstreamメールサービスに接続できない

サンプル

Python
import time, requests

API_KEY = "gk_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

def wait_for_otp(address, password, timeout=120):
    after = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
    # ここでコードを送らせる
    deadline = time.time() + timeout
    while time.time() < deadline:
        res = requests.post("https://getotp.cc/api/v1/otp",
                            headers={"Authorization": "Bearer " + API_KEY},
                            json={"address": address, "password": password, "after": after}).json()
        if res.get("otp"):
            return res["otp"]
        if res.get("error") in ("invalid_api_key", "invalid_credentials", "rate_limited"):
            raise RuntimeError(res["message"])
        time.sleep(4)
    raise TimeoutError("timeout")

print(wait_for_otp("xxxx@mail7z.net", "パスワード"))
JavaScript
const API_KEY = "gk_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";

async function waitForOtp(address, password, timeoutMs = 120000) {
  const after = new Date().toISOString();
  const deadline = Date.now() + timeoutMs;
  while (Date.now() < deadline) {
    const res = await fetch("https://getotp.cc/api/v1/otp", {
      method: "POST",
      headers: { "Content-Type": "application/json", Authorization: "Bearer " + API_KEY },
      body: JSON.stringify({ address, password, after }),
    }).then((r) => r.json());
    if (res.otp) return res.otp;
    if (["invalid_api_key", "invalid_credentials", "rate_limited"].includes(res.error)) throw new Error(res.message);
    await new Promise((r) => setTimeout(r, 4000));
  }
  throw new Error("timeout");
}
シェル
curl -s -X POST https://getotp.cc/api/v1/otp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer gk_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
  -d '{"address": "xxxx@mail7z.net", "password": "パスワード"}' | jq -r .otp