Skip to main content
The official JavaScript / TypeScript SDK wraps the REST API with a typed client, automatic retries, a resolve-and-wait helper, typed error classes, and webhook verification.

npm

@linkskipper/sdk · v0.2.1

GitHub

Source, issues, and changelog.

Install

Requires Node 18+ (for global fetch), a modern browser, or a custom fetch passed in. Ships ESM with TypeScript types.
Use the SDK from a server, not the browser, so your API key stays secret. See Authentication.

Initialize

Client options

string
required
Your sk_live_… key. Throws LinkSkipperError if missing.
string
default:"https://api.linkskipper.app"
Override the API base URL.
number
default:"30000"
Per-request timeout in milliseconds.
number
default:"2000"
Default poll interval for resolveAndWait.
number
default:"120000"
Default overall deadline for resolveAndWait.
Partial<RetryConfig>
Retry tuning: { maxAttempts: 3, initialDelayMs: 500, maxDelayMs: 8000, backoffFactor: 2 }. Retries 429 and 5xx, honoring Retry-After, with exponential backoff and jitter.
typeof fetch
Custom fetch implementation (for older Node or testing).
string
Override the default User-Agent.

Methods

resolve

resolve(url, options?) => Promise<ResolveResult> Submits a URL to POST /v1/resolve. Returns immediately — a cached link comes back with status: "done", a new one with status: "queued" and a jobId.
string
required
The shortener URL to resolve.
string
Sent as the Idempotency-Key header to de-duplicate retries.
The ResolveResult exposes jobId, status, url, targetUrl, provider, tier, creditsCharged, cached, balance, queuePosition, and pollUrl (camelCase mappings of the resolve response).

resolveAndWait

resolveAndWait(url, options?) => Promise<ResolvedLink> The high-level helper: submits the resolve, then polls the job until it is terminal and returns the resolved link. A cached hit returns without polling.
string
required
The shortener URL to resolve.
string
De-duplicate retries.
number
default:"2000"
How often to poll the job.
number
default:"120000"
Overall deadline. Exceeding it throws TimeoutError.
AbortSignal
Cancel the wait loop.
The ResolvedLink has a guaranteed targetUrl plus jobId, provider, tier, creditsCharged, balance, and cached.

getJob

getJob(jobId, signal?) => Promise<Job> Reads GET /v1/jobs/{jobId} once. Use it to poll manually or check a job from a webhook.

account

account() => Promise<Account> Reads GET /v1/account: telegramId, balance, subscriptionUntil, and providers.

providers

providers() => Promise<ProviderEntry[]> Reads GET /v1/providers. Each entry has provider, label, hosts, tier, and latency.

Errors

Every failed API call rejects with an ApiError subclass keyed to the response error code. JobFailedError, TimeoutError, NetworkError, and WebhookVerificationError cover the non-HTTP cases. All extend LinkSkipperError. Every ApiError carries status, code, title, detail, type, balance, retryAfter, and the raw problem object.

Webhook verification

verifyWebhook(payload, signatureHeader, secret, toleranceSeconds?) checks the X-LinkSkipper-Signature header, the timestamp tolerance (default 300s), and the HMAC, then returns the typed WebhookEvent. It throws WebhookVerificationError on any failure.
Pass the raw request body (e.g. via express.raw), not a re-serialized object, or the signature won’t match. See Webhooks.

Exported types

The package exports Account, AccountProvider, Job, JobStatus, ProviderEntry, ProviderTier, ResolveResult, ResolveStatus, ResolvedLink, ProblemDetails, WebhookEvent/WebhookPayload, WebhookEventName, ClientOptions, ResolveOptions, ResolveAndWaitOptions, RetryConfig, ErrorCode, and the ERROR_CODES constant.