Surge

TypeScript SDK

Install and authenticate

npm install @surgeapi/node

Set your API key as an environment variable:

export SURGE_API_KEY=sk_live_your_key_here
import 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.