Get started
Authentication
Two kinds of key, and the one rule that matters about where each belongs.
Trovy issues two kinds of key, and they are not interchangeable.
| Key | Looks like | Lives | Can |
|---|---|---|---|
| Secret | trv_live_… / trv_test_… (64 hex) | Your server, only | Earn, redeem, refund, read customers |
| Publishable | trv_pk_live_… / trv_pk_test_… (32 hex) | Your web page | Open the sign-up widget. Nothing else. |
You create both kinds yourself, in your dashboard under Integrations → Developer API. Test keys come from your sandbox, which you make in a click; live keys from your real business, once its owner has switched the Developer API on there.
Secret keys
Send a secret key as a bearer token on every /v1 call:
curl https://api.sandbox.trovy.ca/v1/business \
-H "Authorization: Bearer $TROVY_SECRET_KEY"Never put a secret key in a browser, a mobile app bundle, or anything a customer can read. It can move money on your customers' behalf, and it is shown to you once, when you create it. If one leaks, revoke it in your dashboard — revocation is immediate, because the key row is read on every request and nothing is cached.
The key decides which environment you reach. With the SDK there is no base URL to configure, because it picks the host from the key. Calling the API directly, use the host that matches your key:
| Key prefix | Reaches |
|---|---|
trv_test_ | https://api.sandbox.trovy.ca |
trv_live_ | https://api.trovy.ca |
There is no way to cross over. Each host refuses the other's keys before it looks
anything up, so a test key sent to api.trovy.ca (or a live key sent to the sandbox)
is answered API_KEY_INVALID, not "wrong environment". That is on purpose: the
error should not confirm which keys exist where.
Publishable keys
A publishable key ships in the page that embeds the widget, so treat it as public. What protects your customers is not the key but how little it reaches: it can create a membership and hand back a one-time token, and that is all. It cannot read a customer, move money, or tell anyone whether a phone number is already a member.
Each publishable key carries a list of allowed origins — the websites you may
embed the widget on. The frame is served with a Content-Security-Policy built from
that list, so an unauthorized site cannot embed your sign-up form at all. Set them
under the key's Websites this key may load on, then press Save websites; a key
with none is refused. A sandbox key may also list a http://localhost address to
develop against. A live key may not.
See Customers and the widget for the flow.
Getting it wrong
| Mistake | What happens |
|---|---|
No Authorization header | 401 API_KEY_MISSING |
A publishable key on /v1 | 403 API_KEY_WRONG_TYPE |
| A secret key in the widget | 403 API_KEY_WRONG_TYPE — and our SDK and loader both throw before sending it |
| A revoked key | 401 API_KEY_REVOKED |
| A key Trovy disabled | 403 API_KEY_DISABLED — rotating will not help; email developers@trovy.ca |
| The Developer API is not switched on for your business | 403 API_NOT_ENABLED. Your organization's owner switches it on in the dashboard. If Trovy switched it off, the dashboard says so: email developers@trovy.ca |
Keys in the SDK
import { Trovy } from "@trovy/sdk";
const trovy = new Trovy({ apiKey: process.env.TROVY_SECRET_KEY! });The SDK infers the base URL from the key and throws a TypeError on a malformed or
publishable key, before any request leaves your process. A mistake becomes a
start-up failure instead of 403s at checkout.