
Security News
Open VSX Unblocks Extension IDs Used in Malware Campaign
Open VSX has removed three extension IDs from its malicious-extension list as the legitimate publishers they impersonated move to claim the names for themselves.
@getbioflow/sdk
Advanced tools
Official TypeScript SDK for the BioFlow public API (https://app.getbioflow.com/v1)
The official TypeScript SDK for the BioFlow public
API (https://app.getbioflow.com/v1) — typed access to pages, blocks,
publishing, contacts, files, analytics, usage, and outbound webhooks, plus a
Standard Webhooks signature verifier.
bf_ API keys are secrets; the client refuses to
construct in a browser.fetch); Bun and
nodejs_compat worker runtimes work too.npm install @getbioflow/sdk
Create an API key in BioFlow → Settings (Creator or Pro plan), then:
import BioFlow from "@getbioflow/sdk";
const bioflow = new BioFlow({ apiKey: process.env.BIOFLOW_API_KEY! });
// List pages — one page of results…
const pages = await bioflow.pages.list({ limit: 20 });
console.log(pages.data.map((page) => page.slug));
// …or auto-paginate the whole collection.
for await (const contact of await bioflow.contacts.list()) {
console.log(contact);
}
// Create, edit, publish.
const page = await bioflow.pages.create({ title: "Launch page" });
await bioflow.pages.addBlock(page.id, { kind: "LINK" });
await bioflow.pages.publish(page.id);
Failures throw a typed hierarchy mirroring the API's RFC 9457 problem codes.
Branch on the class or on error.code — never parse messages.
import {
NotFoundError,
QuotaExhaustedError,
RateLimitError,
} from "@getbioflow/sdk";
try {
await bioflow.pages.get("pg_missing");
} catch (error) {
if (error instanceof NotFoundError) {
console.log(error.code, error.requestId); // "resource_not_found", "req_…"
}
}
| class | codes (status) |
|---|---|
BadRequestError | invalid_request (400) — error.errors holds JSON-Pointer field errors |
AuthenticationError | invalid_api_key (401) |
PermissionDeniedError | insufficient_scope, feature_not_enabled, test_key_read_only (403) |
NotFoundError | resource_not_found (404) |
ConflictError | stale_snapshot, idempotency_in_progress (409) |
UnprocessableEntityError | idempotency_key_reused, endpoint_verification_failed, endpoint_limit_reached (422) |
RateLimitError | rate_limited (429, per-key burst) |
QuotaExhaustedError | quota_exhausted (429, monthly plan quota — subclass of RateLimitError) |
InternalServerError | internal_error (5xx) |
Unknown future codes stay forward-compatible: the class follows the HTTP
status family and error.code carries the new value verbatim.
POST automatically gets an Idempotency-Key
(sdk_<uuid>), reused across retries — the server dedupes instead of
double-executing. Pass { idempotencyKey } to control it, or
autoIdempotencyKeys: false to opt out (which also disables POST retries).maxRetries: 2): 429 rate_limited for any method;
network errors, timeouts, 408 and 5xx for GETs and keyed POSTs.quota_exhausted (waits until your monthly reset —
handle it), PATCH/DELETE on ambiguous failures, and anything after your
own AbortSignal fires.Retry-After is honored exactly; waits longer than maxRetryAfterMs
(default 60 s) abandon the retry instead of sleeping.await bioflow.pages.create(
{ title: "Exactly once" },
{ idempotencyKey: "order-1234", timeoutMs: 10_000 },
);
Verify BEFORE parsing, against the raw request bytes — any re-serialize breaks the signature. Rotation overlap (two signatures) is handled.
import { verifyWebhook, WebhookVerificationError } from "@getbioflow/sdk";
app.post("/bioflow-webhooks", express.raw({ type: "*/*" }), (req, res) => {
let event;
try {
event = verifyWebhook({
payload: req.body, // Buffer — the raw bytes
headers: req.headers,
secret: process.env.BIOFLOW_WEBHOOK_SECRET!, // whsec_… shown at endpoint creation
});
} catch (error) {
if (error instanceof WebhookVerificationError) return res.status(400).end();
throw error;
}
// event.id (whmsg_…) is stable across retries — use it as your dedup key.
switch (event.type) {
case "contact.created":
console.log(event.data.contact.email);
break;
case "page.published":
case "sale.paid":
case "sale.refunded":
break;
default: // new event types may appear — always keep a default branch
}
res.status(200).end();
});
// Raw request through the same auth/retry/error pipeline:
const { data, response, requestId } = await bioflow.request({
method: "GET",
path: "/v1/usage",
});
// Page-level pagination:
const first = await bioflow.pages.list({ limit: 50 });
if (first.hasNextPage()) {
const second = await first.nextPage();
}
new BioFlow({
apiKey: "bf_live_…", // required
baseUrl: "https://app.getbioflow.com",
timeoutMs: 30_000,
maxRetries: 2,
authStyle: "bearer", // or "x-api-key"
autoIdempotencyKeys: true,
maxRetryAfterMs: 60_000,
defaultHeaders: {},
debug: false, // true | (line) => void — secrets are redacted
fetch: globalThis.fetch,
dangerouslyAllowBrowser: false,
});
This package is developed in the private BioFlow monorepo and mirrored to DevinoSolutions/bioflow-sdk; issues and PRs are welcome on the mirror. Docs: getbioflow.com/developers.
MIT © Devino Solutions Inc.
FAQs
Official TypeScript SDK for the BioFlow public API (https://app.getbioflow.com/v1)
The npm package @getbioflow/sdk receives a total of 0 weekly downloads. As such, @getbioflow/sdk popularity was classified as not popular.
We found that @getbioflow/sdk demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
Open VSX has removed three extension IDs from its malicious-extension list as the legitimate publishers they impersonated move to claim the names for themselves.

Product
Socket’s PHP and Composer support is now in Beta for all customers, with PHP reachability analysis generally available.

Product
Socket is bringing experimental protection to Firefox, scanning 97,000+ extensions in Mozilla's official directory for malware and risky updates.