Server SDK — API/SDK advanced
Use the API/SDK advanced path from Node.js for custom attribution, billing and non-native integration workflows.
Updated August 3, 2026
Use API/SDK advanced when you need custom Checkout, non-Stripe billing, custom pre-Checkout attribution, custom discounts, trials or onboarding, or non-financial events. If Stripe is your payment source and a supported Payment Link fits your flow, use Stripe automatic instead.
@affihq/sdk works with Node.js 20 or later and does not depend on a specific framework. AffiHQ provides it as a compiled archive that you can keep in your private dependency workflow.
Install the SDK
Install the archive supplied by AffiHQ from your project directory:
pnpm add ./affihq-sdk-0.1.0.tgz
Create the client
import { createAffiHQ } from '@affihq/sdk/server'
const affihq = createAffiHQ({
apiKey: process.env.AFFIHQ_API_KEY!,
fingerprintKey: process.env.AFFIHQ_FINGERPRINT_KEY!,
baseUrl: process.env.AFFIHQ_BASE_URL,
timeoutMs: 1500,
})
Product API and fingerprint keys belong only in your server secret store for API/SDK advanced requests. Never use either key in browser code. Stripe automatic does not need these keys or this SDK; its connected Stripe deliveries are handled by AffiHQ. The default base URL is https://affihq.com and the default timeout is 2500 ms.
Fingerprint the customer
const customerFingerprint = affihq.customers.fingerprint(customerEmail)
The SDK normalizes the email and computes a product-scoped HMAC-SHA-256 digest locally. Send the digest; never put the email in an API payload, outbox message, exception or log.
Handle typed results
const result = await affihq.attributions.create(input)
if (result.status === 'accepted') {
// Continue with result.data.
} else if (result.status === 'retryable_error') {
// Keep the original message in the API/SDK advanced outbox for retry.
} else {
// Record result.error.code for review without logging the payload.
}
Timeouts, network failures, 429 and 5xx responses are retryable. Stable business rejections are invalid. Bad local configuration throws before a request is sent.
Available clients
integration.get()checks credentials and capabilities;references.validate(input)previews a reference;attributions.create(input)locks the first qualified attribution;attributions.discount(publicId, billingCycle)reads the frozen discount;billingEvents.send(input)submits verified financial facts;delivery.*creates and flushes API/SDK advanced outbox messages.