Integration patterns
Practical guidance for retries, idempotency, server-side calling, and bulk import automation.
Integration patterns
This guide focuses on safe automation patterns for Nimriz: server-side calls, retries, idempotency, and import workflows.
Call Nimriz from your server
Recommended architecture:
- Authenticate your user in your own backend or trusted runtime.
- Call Nimriz from that trusted backend.
- Store Nimriz identifiers such as
url_idandshort_urlin your system.
Do not call control-plane endpoints directly from browsers with privileged credentials.
Prefer stable identifiers
Use:
url_idas the durable link identifierdomain_idas the durable domain identifier
Do not key your system only by slug. Slugs can change.
Retry rules
Retry these classes of failures:
429with backoff- transient
5xxerrors such as502,503, or504 - network timeouts and temporary upstream failures
Do not blindly retry:
- validation failures
- authorization failures
- policy-driven rejections such as reserved slugs or blocked destinations
Exponential backoff example
async function callWithBackoff(run: () => Promise<Response>) {
let delayMs = 500;
for (let attempt = 0; attempt < 4; attempt += 1) {
const response = await run();
if (response.ok) return response;
if (![429, 502, 503, 504].includes(response.status)) return response;
if (attempt === 3) return response;
await new Promise((resolve) => setTimeout(resolve, delayMs));
delayMs *= 2;
}
throw new Error('unreachable');
}
Idempotency for imports
For job-style creation, prefer POST /api/shorten/bulk.
Each row should include:
client_row_id: your stable row identifier inside the batchidempotency_key: a deterministic key for that exact intended mutation
If the same bulk request is replayed, Nimriz returns the stored per-row result with idempotent: true instead of creating a duplicate link.
Good idempotency-key inputs
Build the key from stable fields such as:
- import session ID
- row number or source record ID
domain_idlong_urlcustom_slugexpires_at
If any of those inputs change, generate a new key.
Bulk import recommendations
- Keep batches small and ordered.
- Store per-row outcomes in your own job log.
- Continue processing valid rows even when some rows fail validation.
- Re-run only the failed or interrupted rows using the same idempotency keys.
Protected-link handling
If you use password-protected links:
- only send plaintext passwords from a trusted backend
- do not log plaintext passwords in your own request logs
- treat password updates as sensitive mutations, not general-purpose retries
Trusted actor headers
The Nimriz first-party app forwards trusted actor headers for provenance and role-aware enforcement. Third-party integrations usually do not need these headers unless they are part of a tightly controlled internal environment.
If you do use them, send them only from trusted infrastructure and only together with valid control-plane authentication.
Conversion callback pattern
Phase 1 conversion tracking is a signed callback flow, not a browser pixel.
Recommended pattern:
- User clicks a short link.
- If the destination is safe, Nimriz appends
nim_ctto the landing URL. - Your application stores that token on the session, lead, cart, checkout, or order record.
- When your backend confirms the real business event, it sends a signed callback to Nimriz.
Use the workspace callback secret from the dashboard integrations screen. Do not use CONTROL_PLANE_API_KEY for conversion events.
Recommended storage points
- lead forms: save
nim_cton the pending lead or CRM contact - checkout flows: save
nim_cton the cart, order, or payment metadata - later lifecycle events: reuse your own
external_id,order_id, andrelated_order_id
Event recipes
form submit -> lead- read
nim_ctfrom the landing URL - store it with the pending signup or CRM record
- after the lead or account is created, send
event_name: "lead"
- read
checkout success -> sale- store
nim_cton the order before payment - after payment succeeds, send
event_name: "sale"withcustom_data.order_id,custom_data.value, andcustom_data.currency
- store
billing webhook -> refund- receive the refund or cancellation webhook in your backend
- look up the original order or transaction
- send
event_name: "refund"orevent_name: "cancellation"withcustom_data.related_order_id
Retry guidance for conversions
- Retry transient
429and5xxfailures with backoff. - Reuse the same idempotency key for true retries of the same business event.
- Generate a new idempotency key when the underlying business event changes.
Current best practice summary
- Single create: use
POST /api/shorten - Imports and replay-safe jobs: use
POST /api/shorten/bulk - Slug preflight: use
POST /api/check-slug - Link edits: use the specific update endpoints instead of recreating links
- Conversion callbacks: capture
nim_ct, persist it in your system, and send signed server-to-server callbacks from your backend
Roadmap note
Webhook delivery is available for plans with webhook access. Review Webhooks and keep consumers idempotent from the start.
Conversion tracking is available as an opt-in, signed callback flow on supported plans. Review Conversion tracking before building post-click attribution or revenue callbacks.