Skip to content

About

Strait Node.js SDK (@straitlink/node): create deep links, send events and verify webhooks from your server.

Topics

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Strait

Strait SDK for Node.js

Straight to the screen. On the record.
A tap opens the exact screen, and every link open and install is recorded in your Strait dashboard.

Latest version SDK: Beta CI Licence: MIT

Docs · Platform status · Changelog · Talk to the Strait team

@straitlink/node

Server SDK for Strait: create and manage links and send conversion events from your backend. Zero dependencies; uses your tenant API key.

Quick start (60 seconds)

1. Install.

npm install @straitlink/node

2. Make a link from your server. Save this as quickstart.mjs. The secret key (st_live_…) is in Dashboard → Settings → Secret keys; keep it on servers only.

import { StraitClient } from '@straitlink/node';

const strait = new StraitClient({ apiKey: process.env.STRAIT_API_KEY, baseUrl: 'https://strait.link' });
const link = await strait.createLink({ slug: 'hello', longUrl: 'https://shop.example.com/product/42' });
console.log(link.shortUrl);
STRAIT_API_KEY=st_live_… node quickstart.mjs

You should see: https://<your-handle>.strait.link/hello, and the same link in Dashboard → Links. Run it twice and the second run throws a StraitError with status 409, because the path is taken.

Platform features

Feature Status Notes
Create, list, update and delete links ◐ Beta StraitClient, with your tenant API key.
Conversion events from your backend (sendEvent) ◐ Beta Pass the clickId from the app to tie an event to its tap.
iPhone install matching Opt-in Off until you choose it. Happens in your app (the mobile SDKs), not on the server. Your choice in Dashboard → Settings → iPhone installs: device matching, paste handoff, both or neither, read from Strait at runtime. Device matching is off by default. iPhone matches are labelled Estimated until measured.
Published on npm ● Live npm install @straitlink/node

● Live · ◐ Beta · ○ Planned · – Not yet · Opt-in: off until you switch it on. The same words as the platform status page.

Install

Don't install other names that look similar (strait on npm is someone else's package).

npm install @straitlink/node

Use

import { StraitClient } from '@straitlink/node';

const strait = new StraitClient({
  apiKey: process.env.STRAIT_API_KEY!,   // st_live_… from the dashboard
  baseUrl: 'https://strait.link',        // must be https (http only for localhost)
});

// Create a link
const link = await strait.createLink({
  slug: 'launch',
  longUrl: 'https://yourapp.com/launch',
  tags: ['campaign'],
});

// List / update / pause
await strait.listLinks();                                   // every active link
await strait.listLinks({ limit: 100, status: 'paused' });   // one page: { links, nextCursor }
await strait.updateLink('launch', { longUrl: 'https://yourapp.com/launch-v2' });
await strait.deactivateLink('launch');                      // paused, not deleted

// Send a conversion / revenue event (ties revenue to the funnel)
// Authenticated with your secret key — no publishable key needed server-side.
await strait.sendEvent({ event: 'purchase', value: 49.99, currency: 'USD' });
// Optional: the tap it came from (B15), e.g. forwarded by your app, so the
// dashboard places the revenue on that tap's channel / A/B variant.
await strait.sendEvent({ event: 'purchase', value: 49.99, currency: 'USD', clickId });
// Your order id as eventId: stored once, so a retry never counts twice.
await strait.sendEvent({ event: 'purchase', value: 49.99, currency: 'USD', eventId: order.id });

Failures throw a StraitError with .status and the parsed .body (the raw text when the reply is not JSON, such as a proxy's HTML 502 page).

API

Every secret-key operation of the API has a method named after its OpenAPI operationId (openapi.json, pinned in this repo; test/openapi-coverage.test.ts checks each one's HTTP method and path, and a daily job compares the pin with the live file).

method endpoint
createLink(input) POST /v1/links
batchCreateLinks(links) POST /v1/links/batch (up to 500)
getLink(slug) GET /v1/links/:slug
listLinks() / listLinks({ limit, cursor, status }) GET /v1/links
updateLink(slug, fields) PATCH /v1/links/:slug
deactivateLink(slug) (deleteLink still works) DELETE /v1/links/:slug (pauses it)
getLinkQr(slug, { format, size, … }) GET /v1/links/:slug/qr → { contentType, body }
getAnalytics({ from, to, link, group }) GET /v1/analytics
getUsage() GET /v1/usage
getReferrals({ from, to }) GET /v1/referrals
simulateTap({ url, ua, country }) GET /v1/simulate
exportData({ part, from, to }) GET /v1/export → { contentType, body }
createExportToken({ part, from, to }) POST /v1/export/token
testWebhook(id) POST /v1/webhooks/:id/test
listWebhookDeliveries(id, { limit, cursor }) GET /v1/webhooks/:id/deliveries
redeliverWebhookDelivery(id) POST /v1/webhook-deliveries/:id/redeliver
listDomains() / addDomain(hostname) / removeDomain(hostname) /v1/domains
recordEvent(input) (sendEvent returns nothing) POST /v1/event
verifyWebhook(rawBody, headers, secret, { toleranceSeconds }) checks a webhook delivery (no request)

Verify a webhook

Pass the raw body (before JSON parsing), the headers and your webhook's signing secret. It checks the X-Strait-Signature HMAC in constant time and refuses deliveries more than 5 minutes old.

import express from 'express';
import { verifyWebhook } from '@straitlink/node';

const app = express();
app.post('/webhooks/strait', express.raw({ type: 'application/json' }), (req, res) => {
  if (!verifyWebhook(req.body, req.headers, process.env.STRAIT_WEBHOOK_SECRET!)) return res.status(401).end();
  const delivery = JSON.parse(req.body.toString('utf8')); // { id, event, createdAt, data }
  res.status(204).end();
});

Size and speed

Measured 25 Oct 2026 on 0.7.0.

What Size or time How it was measured
npm package 9.5 KB download, 30 KB unpacked, no dependencies npm pack --dry-run
Start-up 5.9 ms to load the module (most of it is node:crypto, for webhook signatures) + 0.05 ms for new StraitClient(...) fresh Node 26 process on an M-series Mac, median of 25

Example app

examples/node creates a link, sends a purchase event and deletes the link, built against this repo's source (CI builds it on every PR).

  1. npm ci here, then cd examples/node && npm ci.
  2. cp .env.example .env and set your secret key (st_live_…, a test workspace).
  3. npm start

Docs and support

About

Strait Node.js SDK (@straitlink/node): create deep links, send events and verify webhooks from your server.

Topics

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages