SDK method reference
Main TxnShield SDK and HTTP methods, expected inputs, return values, and where they should run.
createTxnShieldNode
Creates a server-side client for protected transaction evaluation. Use it only in trusted backend code, route handlers, workers, or server actions.
| Field | Type | Required | Description | Example |
|---|---|---|---|---|
| secretKey | string | Yes | Server-only secret key from the TxnShield environment. Must start with txn_sec_. | process.env.TXNSHIELD_SECRET_KEY |
| apiBaseUrl | string | Yes | Base URL for the Control Plane API, without a trailing endpoint path. | "https://txnshield.com" |
| evaluatePath | string | No | Optional override for the evaluate endpoint path. | "/api/evaluate" |
| fetchImpl | typeof fetch | No | Optional fetch implementation for tests or custom runtimes. | fetch |
import { createTxnShieldNode } from "@txnshield/sdk-node";
const txnShield = createTxnShieldNode({
secretKey: process.env.TXNSHIELD_SECRET_KEY!,
apiBaseUrl: process.env.TXNSHIELD_API_BASE_URL!,
});txnShield.evaluate
Evaluates one protected transaction and stores the event evidence when the hosted /api/evaluate endpoint succeeds. This is the primary method for enforcing protected operation policies.
| Field | Type | Required | Description | Example |
|---|---|---|---|---|
| operationKey | string | Yes | Stable key for the concrete protected operation. It must match a Protected Operation configured in the TxnShield environment, such as customer.create, invoice.export, bank_account.update, or payment_transaction.create. | "payment_transaction.create" |
| actor | object | Yes | The user, service, or principal attempting the protected action. Send stable identifiers and role context, not raw authentication tokens. | { id, authenticated, roles } |
| actor.id | string | Yes | Stable actor identifier from your application or identity provider. Use the same value you would use in audit logs. | "user_123" |
| actor.authenticated | boolean | No | Whether your application considers the actor signed in for this transaction. | true |
| actor.role | string | No | Single role for applications that do not use role arrays. TxnShield checks both actor.role and actor.roles when enforcing requireRoles. | "support" |
| actor.roles | string[] | No | List of roles or grants the actor has for this request. Policies can require at least one matching role. | ["support", "billing_admin"] |
| actor.trusted | boolean | No | Optional application-side trust flag for the actor. Use it only if your app has a meaningful trusted-user concept. | false |
| actor.sessionAgeMinutes | number | No | Age of the actor session in minutes. Useful when your app wants policies to distinguish fresh and old sessions. | 42 |
| resource | object | Yes | The object being read, changed, exported, approved, or deleted. | { type: "customer", id: "cus_456" } |
| resource.type | string | Yes | Stable resource category, such as customer, account, invoice, payment_method, admin_user, or report. | "customer" |
| resource.id | string | Yes | Stable resource identifier. Avoid sending full records when an id is enough. | "cus_456" |
| resource.ownerId | string | No | Application owner identifier when ownership matters for policy or review. | "user_789" |
| resource.classification | string | No | Data classification or sensitivity label from your app, such as public, internal, PII, restricted, or critical. | "PII" |
| requestData | object | No | Security-relevant shape of the request. Include counts, field lists, and operation metadata, not raw secrets or unnecessary PII. | { requestedCount: 1 } |
| requestData.requestedCount | number | No | Number of records, resources, or items affected by the action. The risk engine uses this for volume-sensitive actions. | 25 |
| session | object | No | Browser or server continuity context. The web SDK can prepare these values from client-side signals. | { sessionId, tabId, continuityStrength } |
| session.sessionId | string | No | Stable browser or app session identifier for continuity analysis. | "sess_abc" |
| session.tabId | string | No | Browser tab identifier produced by the web SDK. | "tab_abc" |
| session.isNewDevice | boolean | No | Whether the current browser/device appears new for this publishable key. | false |
| session.continuityStrength | number | No | Continuity confidence from 0 to 1. Lower values raise weak_session_continuity risk. | 0.95 |
| session.recentHumanSignalAt | string | No | ISO timestamp for recent pointer, keyboard, or touch activity captured by the web SDK. | "2026-05-19T01:22:00.000Z" |
| session.recentHumanSignalAgeSeconds | number | No | Age in seconds of the latest human signal. Policies can require a recent signal before allowing an action. | 12 |
| session.geoChanged | boolean | No | Whether your app detected a geography change for the session. | false |
| session.networkChanged | boolean | No | Whether your app detected a network change for the session. | false |
| session.ipAddress | string | No | IP address observed by your server, if you choose to send it. | "203.0.113.10" |
| session.userAgent | string | No | User-Agent observed by your server, if useful for investigation. | "Mozilla/5.0 ..." |
| metadata | object | No | Normalized risk metadata used by the risk engine and policy engine. | { changedFields: [] } |
| metadata.requestedCount | number | No | Canonical count used by policy rules. If omitted, TxnShield falls back to requestData.requestedCount or 1. | 1 |
| metadata.velocityWindowCount | number | No | Number of similar actions observed in your chosen velocity window. | 8 |
| metadata.changedFields | string[] | No | Field names changed by this action. Non-empty arrays increase privileged_write risk and help audits explain what changed. | ["routingNumber", "accountNumber"] |
| metadata.resourceCount | number | No | Number of resources included in the action, often the same as requestedCount for exports and bulk operations. | 250 |
| metadata.abnormalSequence | boolean | No | Whether your app detected an unusual workflow sequence before this action. | false |
| metadata.objectAccessRare | boolean | No | Whether this actor rarely accesses this resource or resource class. | true |
| metadata.suspiciousTimeWindow | boolean | No | Whether your app considers the local time or operating window suspicious. | false |
| metadata.localHour | number | No | Local hour from 0 to 23. The risk engine treats late-night hours as a possible signal. | 23 |
| metadata.proofToken | string | No | Application proof token used when retrying after a challenge flow. | "proof_abc" |
| metadata.notes | string | No | Short operational context for review. Do not include secrets or full protected records. | "support escalation SUP-123" |
| challengeResult | object | No | Result of a completed step-up challenge when retrying an action. | { type: "proof_token", passed: true } |
| challengeResult.type | "passkey" | "proof_token" | No | Challenge mechanism completed by the app. | "proof_token" |
| challengeResult.passed | boolean | No | Whether the challenge was successfully completed. | true |
| rawSignals | Record<string, boolean | number> | No | Optional raw signal map for advanced integrations. Supported values are booleans and numbers. | { "new_device": true } |
const result = await txnShield.evaluate({
operationKey: "invoice.export",
actor: { id: user.id, authenticated: true, roles: user.roles },
resource: { type: "customer", id: customerId },
requestData: { requestedCount: 25 },
metadata: { changedFields: [] },
});txnShield.protect
Express middleware helper that evaluates a protected route and blocks, challenges, throttles, or continues based on the decision. It reads browser continuity headers when they are present.
| Field | Type | Required | Description | Example |
|---|---|---|---|---|
| operationKey | string | Yes | Operation key protected by this route. | "invoice.export" |
| actor(req) | (req) => object | Yes | Function that returns actor context for the current request. | ({ id: req.user.id, roles: req.user.roles }) |
| resource(req) | (req) => object | Yes | Function that returns resource context for the current request. | ({ type: "customer", id: req.params.id }) |
| requestData(req) | (req) => object | No | Function that returns request shape, counts, and relevant field data. | ({ requestedCount: 1 }) |
| session(req) | (req) => object | No | Optional function that overrides session context. If omitted, middleware reads TxnShield continuity headers. | ({ continuityStrength: 0.95 }) |
| metadata(req) | (req) => object | No | Optional function that returns normalized metadata such as changedFields or velocityWindowCount. | ({ changedFields: ["email"] }) |
| challenge.verifyProofToken | (token: string) => boolean | Promise<boolean> | No | Optional verifier for proof-token step-up retries. | async (token) => verifyToken(token) |
| challenge.verifyPasskeyAssertion | (assertion: string) => boolean | Promise<boolean> | No | Optional verifier for passkey/WebAuthn assertion retries. | async (assertion) => verifyPasskey(assertion) |
app.post("/customers/:id/export", txnShield.protect({
operationKey: "invoice.export",
actor: (req) => ({ id: req.user?.id ?? "anonymous", authenticated: Boolean(req.user), roles: ["support"] }),
resource: (req) => ({ type: "customer", id: req.params.id }),
requestData: (req) => ({ requestedCount: Number(req.body.requestedCount ?? 1) }),
}), async (_req, res) => {
res.json({ ok: true });
});createTxnShieldWeb
Creates a browser-side client for continuity and human-signal capture. It does not evaluate protected actions with a secret key. Use its output as context for your server-side evaluate call.
| Field | Type | Required | Description | Example |
|---|---|---|---|---|
| publishableKey | string | Yes | Client-safe publishable key from the same environment as the server secret key. Must start with txn_pub_. | process.env.NEXT_PUBLIC_TXNSHIELD_PUBLISHABLE_KEY |
| apiBaseUrl | string | Yes | Control Plane base URL used by browser preparation flows. | "http://localhost:3000" |
| captureHumanSignals | boolean | No | Whether the SDK should capture pointer, keyboard, and touch activity timestamps. | true |
import { createTxnShieldWeb } from "@txnshield/sdk-web";
const txnShieldWeb = createTxnShieldWeb({
publishableKey: process.env.NEXT_PUBLIC_TXNSHIELD_PUBLISHABLE_KEY!,
apiBaseUrl: process.env.NEXT_PUBLIC_TXNSHIELD_API_BASE_URL!,
captureHumanSignals: true,
});txnShieldWeb.prepareTransaction
Prepares client-side continuity context and headers for a protected transaction. Send the session object or headers to your backend, then evaluate on the server with the secret key.
| Field | Type | Required | Description | Example |
|---|---|---|---|---|
| operationKey | string | Yes | Same protected operation key your server will evaluate. | "invoice.export" |
| resource.type | string | Yes | Resource type for browser-side preparation. | "customer_export" |
| resource.id | string | Yes | Resource or batch identifier for correlation. | "batch_123" |
| metadata | Record<string, unknown> | No | Client-safe metadata that helps prepare the transaction. Do not put secrets here. | { requestedCount: 25 } |
| returns.session | object | Yes | Session context including sessionId, tabId, isNewDevice, continuityStrength, and recentHumanSignalAt. | { continuityStrength: 0.95 } |
| returns.headers | Record<string, string> | Yes | Headers such as x-txnshield-session-id, x-txnshield-tab-id, x-txnshield-operation-key, and x-txnshield-recent-human-signal. | { "x-txnshield-operation-key": "invoice.export" } |
const prepared = await txnShieldWeb.prepareTransaction({
operationKey: "invoice.export",
resource: { type: "customer_export", id: "batch_123" },
metadata: { requestedCount: 25 },
});HTTP POST /api/evaluate
Direct HTTP equivalent of txnShield.evaluate for stacks that do not use the Node SDK. This endpoint applies policies and records events automatically.
| Field | Type | Required | Description | Example |
|---|---|---|---|---|
| operationKey | string | Yes | Stable key for the concrete protected operation. It must match a Protected Operation configured in the TxnShield environment, such as customer.create, invoice.export, bank_account.update, or payment_transaction.create. | "payment_transaction.create" |
| actor | object | Yes | The user, service, or principal attempting the protected action. Send stable identifiers and role context, not raw authentication tokens. | { id, authenticated, roles } |
| actor.id | string | Yes | Stable actor identifier from your application or identity provider. Use the same value you would use in audit logs. | "user_123" |
| actor.authenticated | boolean | No | Whether your application considers the actor signed in for this transaction. | true |
| actor.role | string | No | Single role for applications that do not use role arrays. TxnShield checks both actor.role and actor.roles when enforcing requireRoles. | "support" |
| actor.roles | string[] | No | List of roles or grants the actor has for this request. Policies can require at least one matching role. | ["support", "billing_admin"] |
| actor.trusted | boolean | No | Optional application-side trust flag for the actor. Use it only if your app has a meaningful trusted-user concept. | false |
| actor.sessionAgeMinutes | number | No | Age of the actor session in minutes. Useful when your app wants policies to distinguish fresh and old sessions. | 42 |
| resource | object | Yes | The object being read, changed, exported, approved, or deleted. | { type: "customer", id: "cus_456" } |
| resource.type | string | Yes | Stable resource category, such as customer, account, invoice, payment_method, admin_user, or report. | "customer" |
| resource.id | string | Yes | Stable resource identifier. Avoid sending full records when an id is enough. | "cus_456" |
| resource.ownerId | string | No | Application owner identifier when ownership matters for policy or review. | "user_789" |
| resource.classification | string | No | Data classification or sensitivity label from your app, such as public, internal, PII, restricted, or critical. | "PII" |
| requestData | object | No | Security-relevant shape of the request. Include counts, field lists, and operation metadata, not raw secrets or unnecessary PII. | { requestedCount: 1 } |
| requestData.requestedCount | number | No | Number of records, resources, or items affected by the action. The risk engine uses this for volume-sensitive actions. | 25 |
| session | object | No | Browser or server continuity context. The web SDK can prepare these values from client-side signals. | { sessionId, tabId, continuityStrength } |
| session.sessionId | string | No | Stable browser or app session identifier for continuity analysis. | "sess_abc" |
| session.tabId | string | No | Browser tab identifier produced by the web SDK. | "tab_abc" |
| session.isNewDevice | boolean | No | Whether the current browser/device appears new for this publishable key. | false |
| session.continuityStrength | number | No | Continuity confidence from 0 to 1. Lower values raise weak_session_continuity risk. | 0.95 |
| session.recentHumanSignalAt | string | No | ISO timestamp for recent pointer, keyboard, or touch activity captured by the web SDK. | "2026-05-19T01:22:00.000Z" |
| session.recentHumanSignalAgeSeconds | number | No | Age in seconds of the latest human signal. Policies can require a recent signal before allowing an action. | 12 |
| session.geoChanged | boolean | No | Whether your app detected a geography change for the session. | false |
| session.networkChanged | boolean | No | Whether your app detected a network change for the session. | false |
| session.ipAddress | string | No | IP address observed by your server, if you choose to send it. | "203.0.113.10" |
| session.userAgent | string | No | User-Agent observed by your server, if useful for investigation. | "Mozilla/5.0 ..." |
| metadata | object | No | Normalized risk metadata used by the risk engine and policy engine. | { changedFields: [] } |
| metadata.requestedCount | number | No | Canonical count used by policy rules. If omitted, TxnShield falls back to requestData.requestedCount or 1. | 1 |
| metadata.velocityWindowCount | number | No | Number of similar actions observed in your chosen velocity window. | 8 |
| metadata.changedFields | string[] | No | Field names changed by this action. Non-empty arrays increase privileged_write risk and help audits explain what changed. | ["routingNumber", "accountNumber"] |
| metadata.resourceCount | number | No | Number of resources included in the action, often the same as requestedCount for exports and bulk operations. | 250 |
| metadata.abnormalSequence | boolean | No | Whether your app detected an unusual workflow sequence before this action. | false |
| metadata.objectAccessRare | boolean | No | Whether this actor rarely accesses this resource or resource class. | true |
| metadata.suspiciousTimeWindow | boolean | No | Whether your app considers the local time or operating window suspicious. | false |
| metadata.localHour | number | No | Local hour from 0 to 23. The risk engine treats late-night hours as a possible signal. | 23 |
| metadata.proofToken | string | No | Application proof token used when retrying after a challenge flow. | "proof_abc" |
| metadata.notes | string | No | Short operational context for review. Do not include secrets or full protected records. | "support escalation SUP-123" |
| challengeResult | object | No | Result of a completed step-up challenge when retrying an action. | { type: "proof_token", passed: true } |
| challengeResult.type | "passkey" | "proof_token" | No | Challenge mechanism completed by the app. | "proof_token" |
| challengeResult.passed | boolean | No | Whether the challenge was successfully completed. | true |
| rawSignals | Record<string, boolean | number> | No | Optional raw signal map for advanced integrations. Supported values are booleans and numbers. | { "new_device": true } |
curl -X POST "$TXNSHIELD_API_BASE_URL/api/evaluate" \
-H "authorization: Bearer $TXNSHIELD_SECRET_KEY" \
-H "content-type: application/json" \
--data '{
"operationKey": "customer.read_pii",
"actor": { "id": "user_123", "authenticated": true, "roles": ["support"] },
"resource": { "type": "customer", "id": "cus_456" },
"requestData": { "requestedCount": 1 }
}'HTTP POST /api/events/ingest
Direct event ingestion is for publishing an already-known decision and evidence payload. It does not calculate policy outcomes. Use /api/evaluate when you want TxnShield to apply protected operations, policies, risk scoring, step-up, redaction, throttle, or deny.
| Field | Type | Required | Description | Example |
|---|---|---|---|---|
| operationKey | string | Yes | Operation key for the event being recorded. | "invoice.export" |
| actorId | string | Yes | Actor identifier for the event. | "user_123" |
| resourceType | string | Yes | Resource category for the event. | "customer" |
| resourceId | string | Yes | Resource identifier for the event. | "cus_456" |
| telemetryId | string | Yes | Unique event identifier generated by your app or SDK. | "evt_123" |
| requestSummary | object | Yes | Summary of request shape, such as requestedCount and changedFields. | { requestedCount: 1 } |
| decision | "allow" | "allow_redacted" | "step_up_required" | "throttle" | "deny" | Yes | Decision already produced by your app or evaluator. | "allow" |
| score | number | Yes | Risk score already produced by your app or evaluator. | 12 |
| reasons | string[] | Yes | Reason codes for the decision. | ["activation_test"] |
| normalizedSignals | Record<string, number> | Yes | Normalized risk signals from 0 to 1. | { missing_recent_human_signal: 0.5 } |
Next steps