SenviokSenviok
v1.0.2 · Stable
All systems operational

Senviok SDK

Senviok provides official SDKs that wrap our REST API, giving you a type-safe, idiomatic way to send emails, SMS, and WhatsApp messages. SDKs handle authentication, error handling, and serialization — so you can focus on building.


Quick Start

Send your first email in under 30 seconds.

1Install the SDK

bash
npm install senviok

2Initialize the client

ts
import { Senviok } from 'senviok';

const senviok = new Senviok('svk_live_your_api_key');

3Send an email

ts
const { id } = await senviok.emails.send({
  from: 'hello@yourdomain.com',
  to: 'user@example.com',
  subject: 'Hello from Senviok',
  html: '<h1>Welcome!</h1><p>You\'re all set.</p>'
});

console.log('Sent!', id); // msg_01HZ8...

Official SDKs

We're building SDKs for every popular language. Install the one for your stack and start sending in minutes.

Node.js / TypeScript
Available
npm install senviok
Python
Available
pip install senviok
Go
Available
go get github.com/senviok/senviok
PHP
Available
composer require senviok/senviok-php
Ruby
Coming Soon
gem install senviok
Java
Coming Soon
implementation 'com.senviok:senviok-java'
C# / .NET
Coming Soon
dotnet add package Senviok

Authentication

All requests are authenticated with a Bearer API key. Generate keys from your Dashboard under Settings → API Keys. Keys are prefixed with svk_live_.

Your API Key

svk_live_your_api_key

ts
import { Senviok } from 'senviok';

// Initialize with your API key
const senviok = new Senviok('svk_live_your_api_key');

// Or with a custom base URL
const senviok = new Senviok('svk_live_your_api_key', {
  BASE: 'https://your-custom-api.example.com'
});

Send Email

Send transactional emails with HTML/text body, templates, CC/BCC, and unsubscribe headers. Every send returns a unique message ID for tracking.

Default Sender: If you haven't verified a custom domain, use onboarding@senviok.live as your from address to get started.

Basic Email

ts
await senviok.emails.send({
  from: 'hello@yourdomain.com',
  to: 'user@example.com',
  subject: 'Welcome to Acme!',
  html: '<h1>Hello!</h1><p>Welcome aboard.</p>',
  text: 'Hello! Welcome aboard.'
});

Expected Response

json
{
  "id": "msg_01HZ8a3b4c5d6e7f"
}

Asynchronous Delivery Pipeline

An HTTP 200 OK response with a message ID confirms that your email was validated and accepted into Senviok's high-speed dispatch queue.

Because email delivery over SMTP involves remote receiving mail servers, final delivery status (e.g. delivered, rejected, bounced, opened) is handled asynchronously. To track delivery confirmations and handle bounces programmatically in real time, configure or check .

With Template

ts
await senviok.emails.send({
  from: 'hello@yourdomain.com',
  to: 'user@example.com',
  subject: 'Welcome {{name}}!',
  templateId: 'tmpl_welcome',
  templateData: { name: 'John', company: 'Acme' }
});

With CC, BCC, Reply-To

ts
await senviok.emails.send({
  from: 'hello@yourdomain.com',
  fromName: 'Acme Support',
  to: 'user@example.com',
  subject: 'Your Invoice',
  html: '<p>Please find your invoice attached.</p>',
  cc: 'manager@acme.com',
  bcc: 'records@acme.com',
  replyTo: 'support@acme.com',
  addUnsubscribeFooter: true,
  addListUnsubscribeHeader: true
});

Parameters

FieldTypeRequiredDescription
fromstringYesSender email address
tostringYesRecipient email address
subjectstringYesEmail subject line
htmlstringNo*HTML body content
textstringNo*Plain text body content
fromNamestringNoSender display name
ccstringNoCC recipient(s)
bccstringNoBCC recipient(s)
replyTostringNoReply-to address
templateIdstringNoID of a saved template
templateDataobjectNoKey-value pairs for template variables
addUnsubscribeFooterbooleanNoAppend unsubscribe link to email body
addListUnsubscribeHeaderbooleanNoAdd List-Unsubscribe header

* Either html, text, or templateId must be provided.


Send SMS

Deliver OTPs, alerts, and notifications globally via SMS with sender ID control.

DND Routes: For Nigerian numbers registered on the Do-Not-Disturb list, messages are automatically routed through DND-capable channels.

ts
await senviok.sms.send({
  from: 'Acme',
  to: '+2348012345678',
  text: 'Your verification code is 4829. Valid for 10 minutes.'
});

Expected Response

json
{
  "id": "msg_01HZ8a3b4c5d6e7f"
}

Parameters

FieldTypeDescription
fromstringSender ID (up to 11 alphanumeric characters)
tostringRecipient phone number in E.164 format
textstringMessage content

WhatsApp

Beta

Send WhatsApp messages for order confirmations, shipping notifications, and alerts. Contact support to enable WhatsApp for your account.

ts
await senviok.whatsapp.send({
  from: '+14155238886',
  to: '+2348012345678',
  text: 'Your order #1234 has been shipped! Track at https://acme.com/track/1234'
});

Expected Response

json
{
  "id": "msg_01HZ8a3b4c5d6e7f"
}

Templates

Create reusable email templates with {{variable}} placeholders. Pass data at send time to personalize each message.

ts
// Create a template
const template = await senviok.templates.create({
  name: 'Welcome Email',
  subject: 'Welcome {{name}}!',
  htmlContent: '<h1>Hello {{name}}</h1><p>Welcome to {{company}}.</p>'
});

// List all templates
const templates = await senviok.templates.list();

// Get a single template
const tmpl = await senviok.templates.get('tmpl_abc123');

// Update a template
await senviok.templates.update('tmpl_abc123', {
  name: 'Updated Welcome',
  subject: 'Hey {{name}}!',
  htmlContent: '<h1>Hey {{name}}</h1><p>Great to have you.</p>'
});

// Delete a template
await senviok.templates.delete('tmpl_abc123');

Expected Response

json
{
  "id": "tmpl_abc123",
  "name": "Welcome Email",
  "subject": "Welcome {{name}}!",
  "htmlContent": "<h1>Hello {{name}}</h1><p>Welcome to {{company}}.</p>",
  "createdAt": "2024-01-15T10:30:00Z",
  "updatedAt": "2024-01-15T10:30:00Z"
}

Using Templates When Sending

ts
await senviok.emails.send({
  from: 'hello@yourdomain.com',
  to: 'user@example.com',
  subject: 'Welcome {{name}}!',
  templateId: template.id,
  templateData: {
    name: 'Sarah',
    company: 'Acme Inc'
  }
});

Domains

Add custom sending domains and configure DKIM authentication to improve deliverability and send from your own addresses.

ts
// Add a domain
const domain = await senviok.domains.create({ name: 'yourdomain.com' });

// List all domains
const domains = await senviok.domains.list();

// Get DKIM DNS records (add these to your DNS provider)
const dkim = await senviok.domains.getDkim('dom_abc123');
// Returns: { tokens: [...] } — add these as CNAME records

// Verify domain after adding DNS records
const result = await senviok.domains.verify('dom_abc123');
// Returns: { verified: true }

Expected Response

json
{
  "id": "dom_abc123",
  "name": "yourdomain.com",
  "status": "pending",
  "createdAt": "2024-01-15T10:30:00Z"
}

DNS Record Configuration Tips

  • DKIM Records: Add the generated CNAME records to authenticate outgoing mail signatures for your domain.
  • Domain Ownership Verification Record: The verification code provided for your domain is an independent TXT record.
  • Important: Do not merge or append your domain verification code into your SPF (v=spf1...) record. It must be added as its own standalone TXT record on your DNS host. Merging verification codes into SPF records invalidates SPF syntax and will hurt email deliverability.

Audiences

Organize your recipients into audiences (mailing lists). Each audience can contain multiple contacts.

ts
// Create an audience
const audience = await senviok.audiences.create({
  name: 'Newsletter Subscribers'
});

// List all audiences
const audiences = await senviok.audiences.list();

// Delete an audience
await senviok.audiences.delete('aud_abc123');

Expected Response

json
{
  "id": "aud_abc123",
  "name": "Newsletter Subscribers",
  "createdAt": "2024-01-15T10:30:00Z"
}

Contacts

Add and manage contacts within an audience. Contacts are scoped to a specific audience.

ts
// Add a contact to an audience
const contact = await senviok.contacts.create('aud_abc123', {
  email: 'john@example.com',
  firstName: 'John',
  lastName: 'Doe',
  unsubscribed: false
});

// List contacts in an audience
const contacts = await senviok.contacts.list('aud_abc123');

// Remove a contact from an audience
await senviok.contacts.delete('aud_abc123', 'ct_xyz789');

Expected Response

json
{
  "id": "ct_xyz789",
  "audienceId": "aud_abc123",
  "email": "john@example.com",
  "firstName": "John",
  "lastName": "Doe",
  "unsubscribed": false,
  "createdAt": "2024-01-15T10:30:00Z"
}

Suppressions

Manage your suppression list to prevent sending to addresses that have bounced, complained, or unsubscribed. Senviok automatically adds hard bounces.

ts
// Add an address to the suppression list
await senviok.suppressions.create({
  email: 'bounced@example.com',
  reason: 'hard_bounce'
});

// List all suppressed addresses
const suppressions = await senviok.suppressions.list();

// Remove from suppression list (re-enable sending)
await senviok.suppressions.delete('sup_abc123');

Expected Response

json
{
  "id": "sup_abc123",
  "email": "bounced@example.com",
  "reason": "hard_bounce",
  "createdAt": "2024-01-15T10:30:00Z"
}

Message Logs

Query your sending history with powerful filters. View delivery status, timestamps, and metadata for every message.

ts
// Get recent messages
const logs = await senviok.messages.list({
  take: 50,
  sortOrder: 'desc'
});

// Filter by channel and status
const emailLogs = await senviok.messages.list({
  channel: 'email',
  status: 'sent',
  take: 100
});

// Filter by date range and recipient
const filtered = await senviok.messages.list({
  startDate: '2024-01-01',
  endDate: '2024-01-31',
  toAddress: 'user@example.com'
});

// Filter by sender and subject
const specific = await senviok.messages.list({
  fromAddress: 'hello@yourdomain.com',
  subject: 'Welcome',
  skip: 0,
  take: 20
});

Expected Response

json
[
  {
    "id": "msg_abc123",
    "channel": "email",
    "status": "sent",
    "toAddress": "user@example.com",
    "fromAddress": "hello@yourdomain.com",
    "subject": "Welcome",
    "htmlBody": "<p>Hello</p>",
    "textBody": "Hello",
    "providerMessageId": "0107017a",
    "createdAt": "2024-01-15T10:30:00Z"
  }
]

Webhooks

Receive real-time delivery notifications via HTTPS POST. Subscribe to events like message.sent, message.failed, message.delivered, and message.bounced.

Manage Webhooks

ts
// Create a webhook
const webhook = await senviok.webhooks.create({
  url: 'https://your-app.com/webhooks/senviok',
  events: ['message.sent', 'message.failed', 'message.delivered', 'message.bounced']
});
console.log(webhook.secret); // Save this for signature verification

// List all webhooks
const webhooks = await senviok.webhooks.list();

// Get delivery logs for a webhook
const deliveries = await senviok.webhooks.logs('wh_abc123');

// Delete a webhook
await senviok.webhooks.delete('wh_abc123');

Expected Response

json
{
  "id": "wh_abc123",
  "url": "https://your-app.com/webhooks/senviok",
  "secret": "whsec_2f5a0c1b9e3d4f",
  "events": ["message.sent", "message.failed", "message.delivered", "message.bounced"],
  "createdAt": "2024-01-15T10:30:00Z"
}

Webhook Headers

HeaderDescription
svk-signatureHMAC-SHA256 signature of the request body
svk-event-idUnique ID for this webhook delivery
svk-timestampISO 8601 timestamp of the event

Example Payload

json
{
  "event": "message.sent",
  "messageId": "msg_01HZ8a3b4c5d",
  "to": "user@example.com",
  "channel": "email",
  "timestamp": "2024-01-15T10:30:00Z",
  "metadata": { "user_id": "usr_001" }
}

Verify Signatures

Always verify the svk-signature header before processing to prevent spoofed requests.

ts
// Built into the SDK — no extra code needed
const isValid = senviok.webhooks.verifySignature(
  rawRequestBody,    // The raw JSON string from the request
  req.headers['svk-signature'],
  webhook.secret     // The secret from when you created the webhook
);

if (!isValid) {
  return res.status(401).send('Invalid signature');
}

Error Handling

The SDK throws typed errors that you can catch and inspect. All errors include the HTTP status code, a human-readable message, and the full response body.

ts
import { Senviok, ApiError } from 'senviok';

try {
  await senviok.emails.send({
    from: 'hello@yourdomain.com',
    to: 'user@example.com',
    subject: 'Hello!',
    html: '<p>Hi there</p>'
  });
} catch (error) {
  if (error instanceof ApiError) {
    console.error('Status:', error.status);   // 400, 401, 403, 429, 500
    console.error('Message:', error.message); // Human-readable error
    console.error('Body:', error.body);       // Full error response
  }
}

Error Codes

StatusMeaningWhat To Do
400
Bad Request — Invalid or missing fieldsCheck your request parameters
401
Unauthorized — Missing or invalid API keyVerify your API key is correct
403
Forbidden — Insufficient permissions or suspendedCheck your account status
429
Rate Limited — Too many requestsRetry with exponential backoff
500
Server Error — Something went wrongRetry after a brief delay

Rate Limits & Headers

All Senviok API requests are rate-limited to ensure system stability and fair resource usage. Standard accounts are allocated 100 requests per minute per API key.

You can monitor your current consumption in real time using the HTTP headers returned with every API response:

HeaderDescription
X-RateLimit-LimitThe maximum number of requests allowed in the current 60-second window (default: 100).
X-RateLimit-RemainingThe number of requests remaining in the current window.
X-RateLimit-ResetUnix timestamp (in seconds) when the current rate limit quota resets.

Handling Rate Limits (HTTP 429)

If you exceed the rate limit, the API returns an HTTP 429 Too Many Requests response with a Retry-After header indicating how many seconds to wait. Official Senviok SDKs handle rate limiting with automatic exponential backoff retries.


SMTP Relay

Prefer SMTP over the SDK? Configure frameworks like Laravel, Rails, WordPress, or any SMTP client to send through Senviok using your API key as the password.

Host / Server

mail.senviok.live

Port

2525 (Recommended) or 587

Username

api

Password

[Your Senviok API Key]

Encryption: STARTTLS is required. Most SMTP clients enable this by default. If you see connection errors, ensure TLS is enabled in your SMTP configuration.