picko-sdk
v1.2.2
Published
TypeScript SDK for the Picko Bear API – typed HTTP client for domain monitoring integrations
Maintainers
Readme
picko-sdk
TypeScript SDK for the Picko Bear API – a typed, ergonomic client for domain monitoring integrations.
Features
- TypeScript-first – fully typed inputs, outputs, and errors
- All Bear API routes – domains (CRUD + stats + webhooks) and quota
- Robust error handling – typed error subclasses for every HTTP failure mode
- Retries & timeouts – configurable, with exponential back-off
- Response-signature verification – optional HMAC-SHA256 check on every response
- ESM + CJS – works in Node.js 18+ with either module system
- Tree-shakeable – import only what you use
Installation
npm install picko-sdk
# or
yarn add picko-sdkRequires Node.js ≥ 18 (uses the native
fetchAPI).
Quick start
import { PickoClient } from "picko-sdk";
const picko = new PickoClient({
baseUrl: "https://api.picko.jeremiemeunier.dev",
apiToken: "your-api-token",
});
// List all domains
const domains = await picko.domains.list();
console.log(domains);
// Get API quota
const quota = await picko.quota.get();
console.log(`Remaining: ${quota.rateLimit.remaining}/${quota.rateLimit.limit}`);Authentication
All Bear API endpoints require an Authorization header:
Authorization: Bearer <api_token>The SDK handles this automatically. Pass apiToken to PickoClient:
Legacy public/secret authentication is still accepted for migration, but deprecated.
const picko = new PickoClient({
baseUrl: "https://api.picko.jeremiemeunier.dev",
apiToken: process.env.PICKO_API_TOKEN!,
});Configuration
const picko = new PickoClient({
// Required
baseUrl: "https://api.picko.jeremiemeunier.dev",
apiToken: "your-api-token",
// Optional
timeout: 10_000, // ms before a request times out (default: 10 000)
retries: 2, // retry attempts on network errors / 5xx (default: 2)
retryDelay: 300, // ms before the first retry; doubles each attempt (default: 300)
headers: {
// extra headers sent with every request
"X-Custom-Header": "value",
},
// Response-signature verification (Pro)
verifySignature: true,
signingSecret: process.env.PICKO_SIGNING_SECRET,
});API Reference
Domains – picko.domains
list(): Promise<BearDomain[]>
List all domains accessible to the authenticated user.
const domains = await picko.domains.list();get(id: string): Promise<BearDomain>
Fetch a single domain by ID.
const domain = await picko.domains.get("64a1b2c3d4e5f6a7b8c9d0e1");getStats(domainIds: string[], format: StatsFormat): Promise<BearDomainStats[]>
Get statistics for one or more domains. format controls the shape of stats:
The SDK sends one domain query parameter per ID (for example:
?domain=id1&domain=id2&format=history).
| format | stats shape | Description |
| ---------- | ---------------------------- | ------------------------------------ |
| complete | { history, live, tracker } | All three datasets combined |
| history | StatsHistory[] | Daily uptime % (up to 30 or 90 days) |
| live | StatsSpark[] | Current-day ping-by-ping results |
| tracker | StatsTracker[] | Colour-coded status indicators |
const stats = await picko.domains.getStats(
["64a1b2c3d4e5f6a7b8c9d0e1"],
"complete",
);create(input: CreateDomainInput): Promise<CreateDomainResponse>
Create a new monitored domain. Free accounts are limited to 3 domains.
const result = await picko.domains.create({
name: "My API",
endpoint: "https://api.example.com/health",
mail: ["[email protected]"], // optional
});
console.log(result.data._id); // new domain ID
console.log(result.init_ping); // initial health-check resultupdate(id: string, input: UpdateDomainInput): Promise<BearDomain>
Update a domain's name, endpoint URL, or notification emails (owner only).
const updated = await picko.domains.update("64a1b2c3d4e5f6a7b8c9d0e1", {
name: "Renamed API",
endpoint: "https://api.example.com/v2/health",
});setState(id: string, state: "active" | "inactive"): Promise<BearDomain>
Enable or disable monitoring for a domain (owner only).
await picko.domains.setState("64a1b2c3d4e5f6a7b8c9d0e1", "inactive");setDiscordWebhook(id: string, discord: string | null): Promise<BearDomain>
Set or remove the Discord webhook URL for a domain (owner only).
// Set
await picko.domains.setDiscordWebhook(
"64a1b2c3d4e5f6a7b8c9d0e1",
"https://discord.com/api/webhooks/123/token",
);
// Remove
await picko.domains.setDiscordWebhook("64a1b2c3d4e5f6a7b8c9d0e1", null);setWebhook(id: string, url: string | null): Promise<void> (Pro)
Set or remove an external webhook URL for a domain (owner only, Pro subscription required). The API sends a verification POST to the URL before saving it.
await picko.domains.setWebhook(
"64a1b2c3d4e5f6a7b8c9d0e1",
"https://example.com/picko-hook",
);delete(id: string): Promise<void>
Permanently delete a domain (owner only).
await picko.domains.delete("64a1b2c3d4e5f6a7b8c9d0e1");Quota – picko.quota
get(): Promise<BearQuota>
Get the current API rate-limit quota and usage.
const quota = await picko.quota.get();
console.log(quota.rateLimit);
// { limit: 100, remaining: 87, resetAt: "2024-01-15T10:30:00.000Z" }Rate limits: 100 req/min (free) · 600 req/min (Pro).
Error handling
Every error thrown by the SDK is an instance of PickoError (or a subclass).
Catch the base class to handle all SDK errors, or use subclasses for specific cases:
import {
PickoClient,
PickoAuthError,
PickoNotFoundError,
PickoRateLimitError,
PickoValidationError,
PickoServerError,
PickoNetworkError,
} from "picko-sdk";
try {
const domains = await picko.domains.list();
} catch (err) {
if (err instanceof PickoAuthError) {
console.error("Invalid or missing API credentials");
} else if (err instanceof PickoRateLimitError) {
console.error("Rate limit hit – back off and retry");
} else if (err instanceof PickoNotFoundError) {
console.error("Domain not found");
} else if (err instanceof PickoValidationError) {
console.error("Bad request:", err.fields);
} else if (err instanceof PickoServerError) {
console.error(`Server error ${err.statusCode}`);
} else if (err instanceof PickoNetworkError) {
console.error("Network problem:", err.cause);
}
}All error classes expose:
message– human-readable descriptionstatusCode– HTTP status code (where applicable)body– raw parsed response body (where applicable)
PickoValidationError additionally exposes fields – the array of field-level
validation details returned by the API.
Response signature verification
When verifySignature: true is set, the client checks the X-Signature
(HMAC-SHA256) header on every response against your signingSecret.
A PickoSignatureError is thrown if the signature does not match.
import { PickoClient, PickoSignatureError } from "picko-sdk";
const picko = new PickoClient({
baseUrl: "https://api.picko.jeremiemeunier.dev",
apiToken: process.env.PICKO_API_TOKEN!,
verifySignature: true,
signingSecret: process.env.PICKO_SIGNING_SECRET,
});TypeScript types
All public types are exported from the package root:
import type {
// Domain
BearDomain,
BearDomainStats,
StatsComplete,
StatsHistory,
StatsSpark,
StatsTracker,
CreateDomainInput,
UpdateDomainInput,
CreateDomainResponse,
StatsFormat,
DomainActiveState,
// Quota
BearQuota,
RateLimitInfo,
// Primitives
PickoAPIState,
TrackerColor,
TrackerTooltip,
// Config
PickoClientConfig,
} from "picko-sdk";Advanced usage
Tree-shaking – use route modules directly
import { PickoHttpClient, DomainRoutes } from "picko-sdk";
const http = new PickoHttpClient({
baseUrl: "https://api.picko.jeremiemeunier.dev",
apiToken: process.env.PICKO_API_TOKEN!,
});
const domains = new DomainRoutes(http);
const list = await domains.list();Custom fetch (e.g. for testing or proxying)
The PickoClient constructor accepts an optional second argument – a fetch-compatible
function. Use this to inject a mock in tests or route requests through a proxy:
import { PickoClient } from "picko-sdk";
const picko = new PickoClient(
{ baseUrl: "...", apiToken: process.env.PICKO_API_TOKEN! },
myCustomFetch,
);Release plan
| Version | Contents |
| ------- | ------------------------------------------------- |
| 1.0.0 | All Bear API routes, full TypeScript types, tests |
Versioning follows Semantic Versioning.
Changelogs are maintained in Git tags and GitHub Releases.
To publish:
cd sdk
npm run build
npm publish --access publicDevelopment
# Install dependencies
npm install
# Run tests
npm test
# Run tests in watch mode
npm run test:watch
# Build (ESM + CJS + type declarations)
npm run build
# Coverage report
npm run test:coverageLicense
MIT © Jeremie Meunier
