Authentication
How to authenticate requests from your server.
Every request to Easy Labs is authenticated with a single secret API key
sent in the X-Easy-Api-Key header. The SDK attaches it for you on every
call, so you never construct headers by hand.
Two key prefixes exist:
| Prefix | Environment | Base URL |
|---|---|---|
sk_test_… | Sandbox | https://sandbox-api.itseasy.co/v1/api |
sk_live_… | Live | https://api.itseasy.co/v1/api |
The SDK resolves the base URL from the key prefix — pass a sk_test_…
key and you're on sandbox, no flag required. Keys are server-side
secrets; never ship them to a browser or mobile app.
Initializing with an API key
require "easy_sdk"
client = EasyLabs::Client.new(api_key: ENV.fetch("EASY_API_KEY"))The constructor calls GET /validate-key and raises
EasyLabs::AuthenticationError if the key is rejected. It also caches the
returned BasisTheory public key on client.basis_theory_public_api_key
for tokenisation flows.
Overriding the base URL
For internal testing against a custom deployment you can override the
resolved URL with internal_api_url: — this skips the prefix-based
routing entirely:
EasyLabs::Client.new(
api_key: ENV.fetch("EASY_API_KEY"),
internal_api_url: "https://api.staging.example.com/v1/api"
)Use this only when you need it; the default resolution is correct for sandbox and live.
Rotating keys
Easy Labs API keys can be rotated without downtime. The recommended flow:
- Issue a new key in the dashboard. The old key keeps working.
- Deploy a new build that reads the new key from
EASY_API_KEY(or whatever env var you use). NewEasyLabs::Clientinstances will validate against the new key. - Once the rollout is complete, revoke the old key in the dashboard.
Because EasyLabs::Client is a plain object, no global state needs to be
flushed — replacing the env var and restarting the process is enough.
Multi-tenant authentication
There is no global state in this SDK — EasyLabs::Client holds the API
key as instance state. Build one client per tenant and dispatch on it:
class TenantClients
def self.for(tenant)
@clients ||= {}
@clients[tenant.id] ||= EasyLabs::Client.new(api_key: tenant.easy_api_key)
end
end
TenantClients.for(tenant).customers.create(email: "...")Clients are cheap to keep around (a single HTTP wrapper plus lazily
constructed resource objects), but the constructor does make one
/validate-key call. Cache the instance per tenant rather than building
a new one on every request.
Idempotency keys
For mutation endpoints, pass an Idempotency-Key header by setting it on
the underlying HTTP layer. See Error handling › Idempotency keys.