
Product
PHP and Composer Support Is Now in Beta
Socket’s PHP and Composer support is now in Beta for all customers, with PHP reachability analysis generally available.
@apiosk/sdk
Advanced tools
Official JavaScript SDK for Apiosk — call and pay for APIs through the gateway, or get paid for your own API on your own URL.
Both sides of a paid API call, in one package.
npm i @apiosk/sdk
| Buy | ApioskClient | Call APIs through the Apiosk gateway and pay their 402s automatically. |
| Sell | @apiosk/sdk/express (and /fastify, /next, /hono) | Charge for an API you host, on your URL. |
They ship together because the same team that sells one API usually calls three
others. The sell side carries no dependencies of its own — if you only ever
import @apiosk/sdk/express, no crypto library is loaded at runtime.
import { ApioskClient } from "@apiosk/sdk"
const apiosk = new ApioskClient({
authorization: `Bearer ${process.env.APIOSK_API_KEY}`,
})
// USDC in, euros to your bank. One paid call.
const data = await apiosk.execute("openweather", { q: "Amsterdam" })
Pass a privateKey and 402s are signed, paid and retried for you:
const apiosk = new ApioskClient({
authorization: `Bearer ${process.env.APIOSK_API_KEY}`,
privateKey: process.env.WALLET_PRIVATE_KEY,
})
Without one, an unpaid call throws ApioskPaymentRequiredError carrying the
challenge, so you can decide what to do with it.
| Method | |
|---|---|
listApis(params?) | Browse the catalog. |
getApi(slug) / getMetadata(slug) | Describe one listing. |
execute(slug, input?, options?) | Run the listing's default operation. |
executeOperation(slug, operation, input?) | Run a named operation. |
passthrough(slug, path?, options?) | Call an arbitrary path on the upstream. |
api.yourcompany.com/v1/todos stays api.yourcompany.com/v1/todos. The
middleware sits in front of handlers you already run. A request carrying one of
your existing customers' API keys falls through untouched. A request without one
gets an x402 402 Payment Required, and once the payment
verifies, the same handler runs.
POST api.yourcompany.com/v1/todos
API key valid → your customer → normal flow, handler runs untouched
no API key → an agent → 402 payment required
→ payment verified through Apiosk
→ same handler
Create an integration at Apiosk → Integrations → New integration. The wizard
registers your URL, generates the sk_live_… key, and hands you the snippet
below with both already filled in.
import express from "express"
import { apiosk } from "@apiosk/sdk/express"
const app = express()
app.use(
apiosk({
apiKey: process.env.APIOSK_API_KEY,
baseUrl: "https://api.yourcompany.com",
// Your existing customers never see a 402: if your own auth recognises the
// request, the middleware calls next() and the handler runs as it does today.
isExistingCustomer: (req) => Boolean(req.header("x-api-key")),
}),
)
// Unchanged. Same route, same handler — only the paywall in front of it is new.
app.post("/v1/todos", createTodo)
import { apioskPlugin } from "@apiosk/sdk/fastify"
await app.register(apioskPlugin, {
apiKey: process.env.APIOSK_API_KEY,
baseUrl: "https://api.yourcompany.com",
isExistingCustomer: (req) => Boolean(req.headers["x-api-key"]),
})
// middleware.ts
import { apioskMiddleware } from "@apiosk/sdk/next"
export const middleware = apioskMiddleware({
apiKey: process.env.APIOSK_API_KEY,
baseUrl: "https://api.yourcompany.com",
isExistingCustomer: (req) => Boolean(req.headers.get("x-api-key")),
// Next has no router table to read, so list what you want priced.
routes: [{ method: "POST", path: "/api/todos" }],
})
export const config = { matcher: "/api/:path*" }
import { apiosk } from "@apiosk/sdk/hono"
app.use(
"*",
apiosk({
apiKey: process.env.APIOSK_API_KEY,
baseUrl: "https://api.yourcompany.com",
isExistingCustomer: (c) => Boolean(c.req.header("x-api-key")),
app, // optional, gives accurate route discovery
}),
)
| Option | Required | Description |
|---|---|---|
apiKey | yes | sk_live_… from Settings → SDK & API keys. |
baseUrl | yes | This deployment's public origin. Must match what you registered, exactly — it is the identity of the integration. |
isExistingCustomer | no | Recognise one of your own customers. Default: nobody, so every caller is treated as an agent. |
routes | no | Routes to report to the dashboard. Discovered automatically on Express, Fastify and Hono; required on Next.js. |
apiUrl | no | Override the Apiosk endpoint (staging, self-hosted). |
pollIntervalMs | no | Config poll interval. Min 5s, default 30s. |
logger | no | (level, message, meta) => void. Defaults to console. |
Installing a paywall in front of a working API is only safe if it fails toward "free". Each of these serves the request free, and they are all checked before the one condition that charges:
authFallback is passthrough (the default).Only then does an unpaid caller get a 402. And only an affirmatively verified payment reaches your handler: an unreachable verifier, a rejected proof, or an ambiguous response all re-issue the challenge. Delivering on an unverified proof would hand your product away while telling you it was sold.
A discovered route is reported to Apiosk unpriced and switched off. Installing the middleware never starts charging for anything — that is always a decision you make in the dashboard.
/.well-known/apioskThe middleware serves a small public document at {baseUrl}/.well-known/apiosk,
which is what the dashboard's Test connection button reads. It names the
middleware and the origin it believes it serves — never your API key, your
account, your routes or your prices.
The adapters are thin, and the decision core is exported:
import { ApioskProvider, decide } from "@apiosk/sdk/server"
const provider = new ApioskProvider({ apiKey, baseUrl })
await provider.start(routes)
const decision = await decide({
client: provider,
method: request.method,
path: new URL(request.url).pathname,
isExistingCustomer: Boolean(request.headers.get("x-api-key")),
getHeader: (name) => request.headers.get(name),
})
if (decision.action === "challenge") {
return new Response(JSON.stringify(decision.challenge.body), {
status: 402,
headers: decision.challenge.headers,
})
}
// "passthrough" | "free" | "paid" -> run your handler
Nothing breaks. ApioskClient and everything around it is unchanged — 0.2.0 only
adds the sell side under new subpath exports.
One naming note if you use both halves: the sell side's client is
ApioskProvider, not ApioskClient. They are opposite ends of the same
protocol (one pays 402s, the other issues them), and giving them the same name
would make every import a coin flip.
The buy side is stable. On the sell side, registration, configuration and the
402 challenge are complete and tested against Apiosk — but settlement for
SDK-mode integrations is not live yet: the gateway endpoint that verifies an
integration's payment proof and records it in the revenue ledger is still being
built. Until it ships, verifyPayment fails closed, so a priced route issues a
correct 402 and then declines to deliver.
In practice: install it, connect it, price your routes, watch the dashboard go green — but leave x402 switched off on routes you depend on until settlement is announced.
MIT
FAQs
Official JavaScript SDK for the Apiosk gateway
The npm package @apiosk/sdk receives a total of 59 weekly downloads. As such, @apiosk/sdk popularity was classified as not popular.
We found that @apiosk/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.

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.

Research
/Security News
Three compromised Rust crates pulled in a malicious dependency that downloaded and executed cross-platform malware during Cargo builds.