@saperly/sdk
v0.1.0
Published
Typed TypeScript client for the [Saperly](https://saperly.com) API. Give any AI agent a phone number with compliance built in.
Downloads
106
Readme
@saperly/sdk
Typed TypeScript client for the Saperly API. Give any AI agent a phone number with compliance built in.
Install
npm install @saperly/sdkRequires Node.js 18+ (uses global fetch). Zero runtime dependencies.
Quick start
import { Saperly } from "@saperly/sdk";
const client = new Saperly({ apiKey: "sk_live_..." });
// Provision a phone line
const line = await client.lines.create({
name: "support bot",
mode: "text",
webhookUrl: "https://myapp.com/calls",
});
console.log(line.phoneNumber); // +14155550123
// Make an outbound call
const call = await client.calls.create({
lineId: line.id,
toNumber: "+14155551234",
});
// List all lines
const lines = await client.lines.list();Resources
Lines
client.lines.create({ name, mode, webhookUrl?, audioHandlerUrl?, statusCallbackUrl? })
client.lines.list()
client.lines.get(lineId)
client.lines.delete(lineId)Calls
client.calls.create({ lineId, toNumber })
client.calls.list({ lineId?, status?, limit?, offset? })
client.calls.get(callId)
client.calls.hangup(callId)Consent
client.consent.grant({ lineId, phoneNumber, consentType, source })
client.consent.check({ phoneNumber, lineId? })
client.consent.revoke({ phoneNumber, lineId? })Compliance
client.compliance.audit({ lineId?, phoneNumber?, eventType?, from?, to?, limit?, offset? })Disclosures
client.disclosures.create({ message, language? })
client.disclosures.list()Billing
client.billing.balance()Note: The billing balance endpoint is not yet available (ships in Phase 5). Calling
billing.balance()will throw aNotFoundErroruntil then.
Error handling
All API errors are mapped to typed exceptions:
import { Saperly, ConsentRequiredError } from "@saperly/sdk";
const client = new Saperly({ apiKey: "sk_live_..." });
try {
await client.calls.create({ lineId: "...", toNumber: "+14155551234" });
} catch (err) {
if (err instanceof ConsentRequiredError) {
// Grant consent first, then retry
await client.consent.grant({
lineId: "...",
phoneNumber: "+14155551234",
consentType: "explicit_outbound",
source: "api",
});
}
}Error classes: ValidationError, AuthenticationError, ForbiddenError, NotFoundError, ConsentRequiredError, ConsentAlreadyGrantedError, CallInProgressError, CallNotActiveError, InsufficientCreditsError, NumberOptedOutError, EmailTakenError.
Programmatic signup
Create an account without an existing API key:
import { Saperly } from "@saperly/sdk";
const { user } = await Saperly.register({
email: "[email protected]",
password: "secure-password",
name: "My Agent",
});Configuration
const client = new Saperly({
apiKey: "sk_live_...",
baseUrl: "http://localhost:3000", // optional, for local dev
});License
MIT
