OTPBase

API quickstart

OTPBase exposes the codes you collect through a small read-only HTTP API. Issue a token, send it as a Bearer header, and read the newest code as JSON. This page gets you from zero to a working request.

Create a read-only token

Go to Settings → API (/settings/api) and create a token. It carries the codes:read scope and nothing else — it can read codes, never send or delete them.

A read token looks like otpb_…. A few things to know:

  • It is shown exactly once, at creation. Copy it immediately and store it somewhere safe.
  • You can hold up to 10 tokens at a time.
  • You can revoke any token from the same page. Revocation takes effect immediately.

Don't confuse this with the device token (dvt_) your phone uses to push codes in. Scripts read with otpb_; phones ingest with dvt_.

Fetch the latest code

GET /api/v1/codes/latest returns the newest active code. Pass your token as a Bearer header.

curl -s https://otpbase.com/api/v1/codes/latest \
  -H "Authorization: Bearer otpb_your_token_here"

A successful call returns 200 with the code and its timing:

{
  "id": 123,
  "code": "482913",
  "service": "GitHub",
  "sender": "noreply@github.com",
  "received_at": "2026-06-23T10:21:07+00:00",
  "expires_at": "2026-06-23T10:36:07+00:00",
  "seconds_remaining": 838
}

The field you usually want is code. Use seconds_remaining to decide whether it's still fresh enough to submit.

List active codes

GET /api/v1/codes returns every code that's currently active, newest first.

curl -s https://otpbase.com/api/v1/codes \
  -H "Authorization: Bearer otpb_your_token_here"
{
  "codes": [
    {
      "id": 123,
      "code": "482913",
      "service": "GitHub",
      "sender": "noreply@github.com",
      "received_at": "2026-06-23T10:21:07+00:00",
      "expires_at": "2026-06-23T10:36:07+00:00",
      "seconds_remaining": 838
    }
  ],
  "count": 2,
  "now": "2026-06-23T10:21:40+00:00"
}

count is how many codes matched, and now is the server's clock so you can compute remaining time yourself if you prefer.

Query parameters

Both endpoints accept filters. Narrow the result by service so you don't read someone else's code, and bound it by age so you never act on a stale one.

Parameter Endpoint Meaning
service both Only codes from this service, e.g. service=GitHub.
max_age_seconds /codes/latest Ignore codes older than this many seconds.
limit /codes How many to return. Default 20, max 100.
curl -s "https://otpbase.com/api/v1/codes/latest?service=GitHub&max_age_seconds=120" \
  -H "Authorization: Bearer otpb_your_token_here"

When there's nothing to read

If no code matches — none have arrived, or everything is older than your max_age_seconds, or no code matches the service filter — /codes/latest returns 404:

{ "error": "no_active_code" }

Treat this as "not yet," not as an error. Poll again after a short delay rather than failing the run.

Rate limiting and read-only behaviour

The API is read-only by design: you can fetch codes, but you can never send or delete them through it. Requests are rate-limited under the standard API throttle, so back off and retry instead of hammering latest in a tight loop. A short poll interval — a second or two between tries — is plenty.

Treat tokens like passwords

A read token is a live credential. Anyone holding it can read your incoming codes until you revoke it.

  • Don't commit tokens to a repo or paste them into chat logs.
  • Keep them in a secret store or environment variable, not in source.
  • Rotate periodically, and revoke immediately at /settings/api if one leaks.

Codes don't stick around

Whatever you read is short-lived. A code is visible for 15 minutes, then hidden from this API, and the underlying row is physically deleted within an hour of arrival — no backup keeps it past that. Build your scripts to fetch on demand, right when you need the code, rather than caching it for later.

To wire a token into an AI agent or CI job, see "Let an AI agent read codes."

Hat das Ihre Frage beantwortet? Support per E-Mail