Node SDK reference
Pair this with the Node.js setup tutorial. The SDK exposes a typed LinkMeClient for creating and managing links programmatically.
Package: @li-nk.me/node-sdk
Installation
npm install @li-nk.me/node-sdk
import LinkMeClient from '@li-nk.me/node-sdk';
CommonJS usage
const LinkMeClient = require('@li-nk.me/node-sdk').default;
Client options
const linkme = new LinkMeClient({
apiKey: process.env.LINKME_SERVER_KEY, // Optional for read-only usage
fetch: customFetchImplementation, // Required only in Node < 18
});
| Option | Type | Description |
|---|---|---|
apiKey |
string |
Server/API key with can_write scope for link management. |
fetch |
typeof fetch |
Provide your own fetch when running on Node versions without global fetch. |
Models
The package re-exports its TypeScript models:
Link— the full link entity returned by the API.CreateLinkInput— camelCase input for creating links.UpdateLinkInput— snake_case partial update payload matching the API schema.NodeSDKOptions— constructor options forLinkMeClient.
Link
interface Link {
id: string;
app_id: string;
domain_id?: string | null;
slug: string;
deep_link_path?: string | null;
deep_link_params?: string | null;
ios_custom_url?: string | null;
android_custom_url?: string | null;
web_fallback_url?: string | null;
allow_param_passthrough: 0 | 1;
force_redirect_web: 0 | 1;
og_title?: string | null;
og_description?: string | null;
og_image_url?: string | null;
utm?: string | null;
utm_override?: string | null;
internal?: 0 | 1;
enabled: 0 | 1;
click_count: number;
last_click_at?: string | null;
created_at?: string;
}
CreateLinkInput
type CreateLinkInput = {
appId: string;
slug?: string;
deepLink?: string | null;
redirects?: {
ios?: string | null;
android?: string | null;
web?: string | null;
forceWeb?: boolean;
};
utm?: Partial<Record<UTMField, string>>;
utmPresetId?: string;
utmOverrides?: Partial<Record<UTMField, boolean>>;
allowParamPassthrough?: boolean;
displayInPortal?: boolean;
customData?: Record<string, string | number | boolean | null | undefined>;
og?: { title?: string; description?: string; imageUrl?: string };
};
Where UTMField is 'utm_source' | 'utm_medium' | 'utm_campaign' | 'utm_term' | 'utm_content' | 'utm_id' | 'utm_source_platform' | 'utm_creative_format' | 'utm_marketing_tactic' | 'tags'.
UpdateLinkInput
Uses snake_case field names and 0 | 1 for boolean flags, matching the API schema directly:
type UpdateLinkInput = Partial<Pick<Link,
'deep_link_path' | 'ios_custom_url' | 'android_custom_url' | 'web_fallback_url' |
'allow_param_passthrough' | 'force_redirect_web' | 'og_title' | 'og_description' |
'og_image_url' | 'utm' | 'utm_override' | 'enabled'
>>;
Zod Schemas
The SDK also exports Zod schemas and their inferred types for runtime validation:
| Schema | Inferred type | Description |
|---|---|---|
LinkSchema |
LinkParsed |
Core link entity. |
ExtendedLinkSchema |
ExtendedLinkParsed |
Link with computed fields (hostname, idUrl, slugUrl, clicks, installs). |
CreateLinkInputSchema |
CreateLinkInputParsed |
Validates createLink input. |
UpdateLinkInputSchema |
UpdateLinkInputParsed |
Validates updateLink payload. |
CreateLinkResponseSchema |
CreateLinkResponseParsed |
Shape returned by createLink. |
LinkMeWebhookEnvelopeSchema |
LinkMeWebhookEnvelopeParsed |
Webhook envelope structure. |
import { LinkSchema, CreateLinkInputSchema } from '@li-nk.me/node-sdk';
Webhook Helper Functions
The SDK includes generic helper functions for webhook receivers:
parseLinkMeWebhookEnvelope(payload)— validates the webhook JSON envelope usingLinkMeWebhookEnvelopeSchema.verifyLinkMeWebhookSignature(rawBody, signatureHeader, secret)— verifiesX-LinkMe-Signatureusing HMAC-SHA256.
import {
parseLinkMeWebhookEnvelope,
verifyLinkMeWebhookSignature,
} from '@li-nk.me/node-sdk';
const rawBody = req.rawBody.toString('utf8');
if (!verifyLinkMeWebhookSignature(rawBody, req.get('X-LinkMe-Signature'), process.env.LINKME_WEBHOOK_SIGNING_SECRET!)) {
res.status(401).json({ ok: false, error: 'Invalid signature' });
return;
}
const envelope = parseLinkMeWebhookEnvelope(JSON.parse(rawBody));
// forward `envelope` to your own destination (queue, analytics provider, warehouse, etc.)
Methods
createLink(input: CreateLinkInput)
Creates a new short link under an app.
displayInPortal behavior:
falsehides the link from/portal/app/<appId>/links(still works as a universal link).truekeeps it visible in the portal list.- In current Node SDK versions, if omitted,
displayInPortaldefaults tofalse. - For older SDK/API clients that omit this field, server compatibility keeps links visible.
Returns: Promise<{ id: string; app_id: string; domain_id: string | null; slug: string; slugUrl: string }>
await linkme.createLink({
appId: 'app_123',
slug: 'spring',
displayInPortal: true,
redirects: {
ios: 'https://apps.apple.com/...',
android: 'https://play.google.com/...',
web: 'https://example.com/spring',
},
});
getLink(id: string)
Fetches a single link by slug or ID.
Returns: Promise<Link>
listLinks(appId: string)
Returns every link under the given app with computed extras.
Returns: Promise<Array<Link & { hostname?: string | null; idUrl?: string; slugUrl?: string; clicks?: number; installs?: number }>>
updateLink(id: string, updates: UpdateLinkInput)
Applies a partial update using snake_case field names and 0 | 1 for boolean flags.
Returns: Promise<Link>
await linkme.updateLink('spring', {
web_fallback_url: 'https://example.com/spring-2025',
force_redirect_web: 1,
});
deleteLink(id: string)
Deletes a link. Use with caution—deletions are permanent.
await linkme.deleteLink('spring');
HTTP behavior
LinkMeClientusesfetchunder the hood. Supply your own implementation if you run on Node < 18.- Requests are sent to
/api/...onhttps://li-nk.meand automatically includeAuthorization: Bearer <apiKey>when provided. - Input/output payloads are validated with Zod before being returned, so runtime errors surface early when a shape is wrong.
For lower-level access (custom routes beyond link management) call the REST endpoints directly using the REST Endpoints & OpenAPI reference as a guide.