TypeScript SDK
The official TypeScript client — fully typed against the OpenAPI document, for Node.js and edge runtimes, with a webhook signature verifier.
Getting it
npm i @403ent/transmute
The package version tracks the API release: @403ent/transmute@X.Y.Z is generated from API release vX.Y.Z and published with npm provenance, which you can check with npm audit signatures. Requires Node.js 20+.
First publish pending. Until the first release appears on npm, access is provided during onboarding (contact support).
Convert a message
import { createClient, convert } from "@403ent/transmute";
const client = createClient({
baseUrl: "https://api.transmute.403fin.io",
apiKey: process.env.TRANSMUTE_KEY!,
});
// raw MT; `from` omitted → auto-detect
const res = await convert(client, mt940Text, { to: "camt.053" });
if (!res.ok) {
console.error(res.problem.type, res.problem.detail); // RFC 9457 problem
} else {
console.log(res.data.meta.detectedType); // "mt940"
for (const w of res.data.warnings) {
console.log(`${w.code} (${w.severity})`);
}
}
The helpers convert, normalize, validate, and enrich take the client as their first argument and return { ok: true, data } or { ok: false, problem }, plus the raw response for headers such as X-Request-Id. Every other route is on the client itself, fully typed: client.POST("/v1/diff", { body }), client.GET("/v1/jobs/{id}/items", { params: { path: { id } } }), client.GET("/v1/samples", ...), and so on. All request and response shapes — ConvertRequest, ConvertResponse, Problem, Warning, and the rest — are exported types generated from the OpenAPI document.
Pin the API version
New in this release: pass apiVersion: "2026-06-01" to createClient and every request sends X-Api-Version, pinning date-versioned behaviour (today, the default Standards Release). Leave it out to follow your API key's pin, else the current version. See Migrating from SR2025 to SR2026.
createClient also accepts accessToken (an OAuth access token) instead of apiKey, and a custom fetch.
Verify a webhook delivery
import { verifyWebhookSignature } from "@403ent/transmute";
// In your handler — use the RAW body bytes, before any JSON parsing:
const valid = verifyWebhookSignature(
endpointSecret, // "whsec_..." — the full string
req.headers["x-transmute-signature"], // "t=...,v1=..."
rawBody,
300, // tolerance in seconds (the default)
);
if (!valid) {
// respond 400
}
It returns false (never throws) for a malformed header, a mismatched signature, or a timestamp outside the tolerance.
See Webhooks for the delivery contract (retries, dedupe, auto-disable).
Notes
- Amounts are strings in every type — use a decimal library (
big.js,decimal.js); JavaScript numbers corrupt money. - API errors come back as the parsed RFC 9457 problem (
res.problem), including thetypeslug from the error catalog. - The portal endpoints are intentionally absent from the SDK — they are the web dashboard's internal surface.