Project

onetime

0.01
No release in over 3 years
Low commit activity in last 3 years
Command-line tool and library for onetimesecret.com API
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Runtime

>= 0.6.9
>= 0.7.7
>= 1.6.8
 Project Readme

OnetimeSecret Ruby Client

The official Ruby client for the OnetimeSecret API. Share sensitive information through a link that can only be viewed once.

  • Zero runtime dependencies — built entirely on the Ruby standard library (net/http, uri, json), so it drops into any environment without pulling transitive gems.
  • Supports API v1 and v2 — pick a version per client. The same resource methods exist for both, but each version returns its own response shape (they are different APIs; the client does not normalize them). v1 is deprecated and included only because the service still serves it — use v2 for new work.
  • Ruby 3.1+.

The onetime command-line tool has moved to a separate onetime-cli gem so that this library stays dependency-free.

Installation

gem install onetime

Or in a Gemfile:

gem "onetime"

Quick start

require "onetime"

client = Onetime::Client.new(
  base_url:     "https://us.onetimesecret.com", # your region's API host (required)
  organization: "on1abc...",                    # organization extid (see below)
  api_token:    ENV["ONETIME_API_TOKEN"],       # API token from your account page
  api_version:  :v2,                            # :v1 or :v2 (default :v2)
)

# Conceal a secret you already have
res = client.secrets.conceal(secret: "hunter2", ttl: 3600, passphrase: "pw")
res.dig("record", "receipt", "identifier")  # the receipt (creator) key
res.dig("record", "secret", "identifier")   # the secret (recipient) key

# Generate a random secret server-side
client.secrets.generate(ttl: 86_400)

# Reveal (consume) a secret — one-time only
secret = client.secrets.reveal("abc123secretkey", passphrase: "pw")
secret.dig("record", "secret_value")

# Service status (works on v1 and v2)
client.status

Authentication

Authentication uses HTTP Basic, where the organization extid is the username and your API token is the password.

The organization extid is the identifier beginning with on shown (with a copy button) at the bottom of the user menu when you are signed in. It is no longer your email address.

Base URL (required)

base_url must be the API host for your region, your self-hosted domain, or your custom domain. There is no default: deployments are region-isolated for data sovereignty, so the client cannot guess one for you.

Regional API hosts:

Region Host
United States https://us.onetimesecret.com
Europe https://eu.onetimesecret.com
United Kingdom https://uk.onetimesecret.com
Canada https://ca.onetimesecret.com
Aotearoa New Zealand https://nz.onetimesecret.com

The apex onetimesecret.com is the company website, not an API host, and is rejected with a helpful error.

Configuration

Option Default Notes
base_url — (required) Region/self-hosted/custom domain
api_version :v2 :v1 or :v2
organization ENV["ONETIME_ORG_EXTID"] Organization extid (on...)
api_token ENV["ONETIME_API_TOKEN"] API token
timeout 30 Read timeout (seconds)
open_timeout 10 Connect timeout (seconds)
max_retries 2 Retries for idempotent (GET) requests

Environment fallbacks: base_urlONETIME_BASE_URL; organizationONETIME_ORG_EXTID; api_tokenONETIME_API_TOKEN.

Clients are thread-safe: they hold only configuration and a stateless transport, opening a fresh connection per request.

Anonymous and guest usage

A client created without credentials is anonymous and can use public and guest endpoints:

guest = Onetime::Client.new(base_url: "https://us.onetimesecret.com")  # no credentials
guest.secrets.conceal(secret: "no account needed", guest: true)

Resources

client.secrets

Method v1 v2
conceal(secret:, ttl:, passphrase:, recipient:, share_domain:) yes yes
generate(ttl:, passphrase:, recipient:, share_domain:) yes yes
reveal(key, passphrase:, continue:) yes yes
show(key) yes
status(key) yes
status_list(keys) yes

conceal is also available as share. reveal/show accept either a bare key or a full secret URL.

client.receipts

Method v1 v2
show(key) yes yes
recent yes yes
burn(key, passphrase:, continue:) yes yes
update(key, memo:) yes

Meta

client.status (v1 & v2), client.version / client.supported_locales (v2 only), client.authcheck (v1 only).

Responses

Resource methods return an Onetime::Response with indifferent (String or Symbol) key access:

res = client.secrets.conceal(secret: "hi")
res["record"]                                   # Hash
res.dig(:record, :secret, :secret_value)        # deep access
res.success?                                     # 2xx?
res.http_status                                  # Integer
res.to_h                                         # the parsed body

The response shape is the API's, unchanged. v1 and v2 differ on purpose — v1 returns flat, all-string fields; v2 nests data under record/details with richer typing — and the client does not reconcile them. Read the API docs for the shape of the version you target.

Errors

HTTP errors (status >= 400) raise typed exceptions following the API's ADR-013 error contract ({ error:, error_type:, ... }):

begin
  client.secrets.reveal("missing")
rescue Onetime::NotFoundError => e
  e.message      # human-readable message ("error" field)
  e.error_type   # machine-readable type ("RecordNotFound")
  e.http_status  # 404
rescue Onetime::RateLimitError => e
  e.retry_after
rescue Onetime::APIError => e
  # any other API error
end
Exception When
Onetime::BadRequestError 400 / FormError (see #field)
Onetime::AuthenticationError 401
Onetime::ForbiddenError 403 / Forbidden, GuestRoutesDisabled
Onetime::EntitlementError EntitlementRequired (see #entitlement)
Onetime::NotFoundError 404 / RecordNotFound
Onetime::RateLimitError 429 / LimitExceeded (see #retry_after)
Onetime::ServerError 5xx
Onetime::TransportError / TimeoutError network failures

All inherit from Onetime::Error.

Development

bundle install
rake test

License

See LICENSE.txt.