Client SDKs
Typed clients with idempotency, retries, and webhook verification built in.
Every Atlas SDK is built on top of the same REST and WebSocket surface you'd hit with raw HTTP, but it ships with the production-grade defaults baked in: automatic Idempotency-Key generation, retry with exponential backoff, webhook signature verification, and typed request/response models generated from the OpenAPI spec.
Available clients
@atlas-softpos/sdkNode 18+, Deno, Bun, Cloudflare WorkersGAatlas-softposPython 3.10+ (sync + async)GAcom.atlas-softpos:sdkAndroid, JVM (bundled with Local Embedded kernel)BETAAtlasSoftPOSiOS 16+, macOS 13+COMING SOONatlas-softpos-goGo 1.22+COMING SOONatlas_softposRuby 3.2+COMING SOONAtlasSoftPOS.SDK.NET 8+ (many POS systems)COMING SOONSDKs marked Coming Soon are in development. Request early access from your account manager or email [email protected].
TypeScript
npm install @atlas-softpos/sdk
# or
pnpm add @atlas-softpos/sdk
# or
yarn add @atlas-softpos/sdkThe TypeScript client is fully typed end-to-end. Every request and response comes straight from the OpenAPI spec, and the client handles idempotency, retries, and request IDs for you.
import { Atlas } from "@atlas-softpos/sdk";
const atlas = new Atlas({
apiKey: process.env.ATLAS_API_KEY!,
baseUrl: process.env.BASE_URL, // defaults to https://api.atlas-softpos.com
apiVersion: "2026-04-09", // pin your integration
timeout: 90_000, // 90s — orchestrated sales block
maxRetries: 3, // automatic retry with same Idempotency-Key
});
// Orchestrated sale. Idempotency-Key is generated for you and reused across retries.
const result = await atlas.transactions.sale({
amount: 2500,
currency: "NZD",
referenceId: "POS-INV-20260409-001",
metadata: { cashier: "Jane", register: "REG-02" },
});
if (result.status === "APPROVED") {
console.log("Auth code:", result.authorizationCode);
}Granular mode feels the same — just a second call:
// Granular mode — POS routes the auth itself.
const initiated = await atlas.granular.initiate({
amount: 5000,
currency: "NZD",
});
// Route to your own acquirer...
const issuerResponse = await myAcquirer.authorize(initiated.chipData);
// Hand the issuer response back to the terminal.
const final = await atlas.granular.complete({
transactionId: initiated.transactionId,
responseCode: issuerResponse.code,
authorizationCode: issuerResponse.authCode,
issuerAuthData: issuerResponse.authData,
});Webhook signature verification is a one-liner. The helper throws if the signature is invalid or the timestamp is outside the replay window:
import express from "express";
import { Atlas } from "@atlas-softpos/sdk";
const app = express();
app.use(express.raw({ type: "application/json" }));
app.post("/atlas-webhook", (req, res) => {
try {
const event = Atlas.webhooks.constructEvent(
req.body,
req.headers["atlas-signature"] as string,
process.env.ATLAS_WEBHOOK_SECRET!,
);
switch (event.type) {
case "transaction.settled":
// ... reconcile in your system
break;
case "dispute.opened":
// ... notify the merchant
break;
}
res.status(200).end();
} catch {
res.status(401).end();
}
});Python
pip install atlas-softpos
# or
poetry add atlas-softpos
# or
uv add atlas-softposThe Python client targets Python 3.10+ and supports both sync and async usage (atlas_softpos.aio). Same idempotency and retry defaults as TypeScript.
from atlas_softpos import Atlas
atlas = Atlas(
api_key=os.environ["ATLAS_API_KEY"],
base_url=os.environ.get("BASE_URL"),
api_version="2026-04-09",
timeout=90,
max_retries=3,
)
# Orchestrated sale with automatic idempotency + retry.
result = atlas.transactions.sale(
amount=2500,
currency="NZD",
reference_id="POS-INV-20260409-001",
metadata={"cashier": "Jane", "register": "REG-02"},
)
if result.status == "APPROVED":
print(f"Auth code: {result.authorization_code}")from flask import Flask, request, abort
from atlas_softpos import Atlas, SignatureVerificationError
app = Flask(__name__)
ATLAS_WEBHOOK_SECRET = os.environ["ATLAS_WEBHOOK_SECRET"]
@app.post("/atlas-webhook")
def atlas_webhook():
try:
event = Atlas.webhooks.construct_event(
payload=request.get_data(),
signature=request.headers["Atlas-Signature"],
secret=ATLAS_WEBHOOK_SECRET,
)
except SignatureVerificationError:
abort(401)
if event.type == "transaction.settled":
... # reconcile
elif event.type == "dispute.opened":
... # notify merchant
return ("", 200)Kotlin (Local Embedded)
The Kotlin SDK is different from the others — it includes the EMV kernel itself. Use it when you want the terminal to run inside your merchant app process rather than as a separate REST surface. See Connectivity & Flows for when to choose Local Embedded over Local Connected or Cloud.
Design principles
- Zero boilerplate for the common path. If you can call raw HTTP, you can call the SDK. The defaults are production-grade.
- Idempotency and retries on by default. Turn them off explicitly if you need to — never the other way around.
- Generated from the OpenAPI spec. Every SDK is regenerated on every API release. Your types always match the server.
- Typed webhook events. Discriminated unions on event.type so your switch statement is exhaustive at compile time.
- Thin surface. SDKs don't add concepts, routing, or caching. They're a transport, not a framework.