Authentication
API keys for servers and agents, session tokens for browsers.
Every call to the Senddy API is authenticated. There are two kinds of credential, and which one you use depends on where your code runs.
| Where your code runs | Use | Why |
|---|---|---|
| Your server, a script, an agent | API key | Simple, long-lived, kept secret on your side |
| A user's browser or phone | Session token | Short-lived, per user, safe to ship to the client |
API keys#
Create keys in the Developer Dashboard. Pass one to the client as apiKey, and the client sends it as X-API-Key on every request.
const senddy = createSenddyClient({
// …chain config
apiKey: process.env.SENDDY_API_KEY,
});Never put an API key in browser code. Anyone can read it from your bundle, and every user would share one rate limit.
Session tokens#
In a browser, your server mints a short-lived token for each signed-in user, and the client uses that instead of a key.
On your server, after you've verified the user is signed in:
const res = await fetch(`${SENDDY_API_URL}/session`, {
method: 'POST',
headers: { 'content-type': 'application/json', 'x-api-key': process.env.SENDDY_API_KEY! },
body: JSON.stringify({ sub: user.id, perms: ['read', 'write'], ttl_secs: 900 }),
});
const { token, exp } = await res.json(); // token starts with "sst_"Require an explicit Authorization header on that route, not just a cookie, so another site can't mint tokens for a signed-in user. Throttle it per user.
In the browser, give the client a provider function. It's called when a token is needed, and again if one expires, after which the request is retried once.
const senddy = createSenddyClient({
// …chain config
sessionToken: async () => {
const res = await fetch('/api/session-token', { method: 'POST', headers: { authorization: `Bearer ${userAuthToken}` } });
return (await res.json()).token;
},
});Cache the token in the provider and refresh it shortly before it expires. When sessionToken is set, the client doesn't send apiKey.
Using Privy#
If your app signs users in with Privy, you can skip the server route. Register your Privy app with us at developers@senddy.com, and the browser can exchange the user's Privy access token for a session directly at POST /session/exchange.
Rate limits#
| Limit | |
|---|---|
| Per signed-in user, with a session token | 120 requests a minute |
| Per developer | 60 requests a minute and 10,000 a day by default. Ask us for more |
Requests over a limit get a 429. A request with an expired session token gets 401 SESSION_EXPIRED, which the client handles for you.