TypeScript SDK
Install and authenticate
npm install @surgeapi/nodeSet your API key as an environment variable:
export SURGE_API_KEY=sk_live_your_key_hereimport Surge from "@surgeapi/node";
const surge = new Surge();Your first request
const message = await surge.messages.create("acct_01jrzhe8d9enptypyx360pcmxj", {
to: "+18015551234",
body: "Your appointment is confirmed for Friday at 2pm.",
});
console.log(message.id); // msg_01j...Type imports
Every resource and parameter has a corresponding TypeScript type:
import type { Message, MessageCreateParams } from "@surgeapi/node";
const params: MessageCreateParams = {
to: "+18015551234",
body: "Hello",
};
const message: Message = await surge.messages.create("acct_01j...", params);Pagination
The SDK returns auto-paginating iterators using async iteration:
// Iterates through all messages
for await (const message of surge.messages.list("acct_01j...")) {
console.log(message.id);
}Page manually when you need cursor control:
const page = await surge.messages.list("acct_01j...", { limit: 25 });
console.log(page.data);
console.log(page.pagination.next_cursor);Retries and timeouts
The SDK retries transient failures automatically. Configure on the client:
const surge = new Surge({
maxRetries: 5,
timeout: 30_000, // milliseconds
});Error handling
Errors are typed exceptions:
import { APIError, AuthenticationError } from "@surgeapi/node";
try {
await surge.messages.create("acct_01j...", { to: "+18015551234", body: "Hello" });
} catch (error) {
if (error instanceof APIError) {
console.log(error.status); // e.g. 422
console.log(error.error.error.type); // e.g. "opted_out"
console.log(error.error.error.message);
}
}Webhooks
Use the SDK's built-in webhook helper to verify signatures and parse events:
// Express example:
const surge = new Surge({ webhookSigningSecret: process.env.SURGE_WEBHOOK_SECRET });
app.post("/webhooks/surge", express.raw({ type: "application/json" }), (req, res) => {
let event;
try {
event = surge.webhooks.unwrap(req.body.toString(), { headers: req.headers });
} catch {
return res.status(400).end();
}
switch (event.type) {
case "message.received":
handleInbound(event.data);
break;
case "contact.opted_out":
handleOptOut(event.data);
break;
}
res.status(200).end();
});Note: Pass the raw request body (string) to surge.webhooks.unwrap, not the parsed JSON. Signature verification requires the exact byte sequence that was signed. Use express.raw() or your framework's equivalent. The webhook secret is passed to the Surge client constructor as webhookSigningSecret, or it can be passed per-call as the key option.