Overview
The Nectifi Global API lets you integrate guest CRM, promotions, loyalty, wallet, email, Wi‑Fi, and analytics into your POS, mobile app, or data warehouse — with scoped API keys and signed webhooks.
https://nectifi.com/api/v1/external/v1All paths below are relative to /api/v1/external/v1. Interactive OpenAPI schema: openapi.json · Swagger UI (/docs)
Sign in to your Nectifi workspace to create tenant-scoped API keys.
Authentication
Every request must include a Bearer token in the Authorization header:
Authorization: Bearer nk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxTokens are shown once when created. Store them securely — Nectifi stores only a SHA-256 hash. Revoke compromised keys immediately from the workspace API settings page.
curl -sS -X GET \
"https://nectifi.com/api/v1/external/v1/crm/guests?search=alex&limit=50&offset=0" \
-H "Authorization: Bearer nk_your_api_key" \
-H "Accept: application/json"API keys
- Prefix
nk_— tenant-scoped, never share across workspaces - Assign only the scopes your integration needs (principle of least privilege)
- Optional IP allowlist — CIDR blocks or single IPs per key
- Per-key rate limit — default 60 requests/minute, configurable up to 10,000
- Monthly quota enforced by plan tier — watch for
X-API-Usage-Warningheader
Scopes
Scopes gate access per module. Write scopes imply read for the same module. Wildcards * and module:* are supported when creating keys.
| Scope | Module |
|---|---|
| crm.read | CRM Public API |
| crm.write | CRM Public API |
| guests.read | CRM Public API |
| guests.write | CRM Public API |
| tags.write | CRM Public API |
| notes.write | CRM Public API |
| events.read | CRM Public API |
| webhooks.read | CRM Public API |
| webhooks.write | CRM Public API |
| crm:read | CRM (legacy scopes) |
| crm:write | CRM (legacy scopes) |
| promotions:read | Promotions |
| promotions:write | Promotions |
| promotions.grant | Promotions |
| loyalty:read | Loyalty |
| loyalty:write | Loyalty |
| loyalty.adjust | Loyalty |
| wallet:read | Wallet |
| wallet:write | Wallet |
| communication:read | Communication |
| communication:write | Communication |
| communication.send | Communication |
| wifi:read | WiFi |
| analytics:read | Analytics |
Rate limits
- Per-key: sliding window per minute — HTTP 429 with
Rate limit exceeded for this API key - Monthly quota: plan-based — HTTP 429 with
api_monthly_quota_exceededwhen blocked - Response headers:
X-Request-Id,X-API-Usage-Warning,X-API-Usage-Percent
Errors
Errors return JSON with a detail field (string or validation object).
| Status | Meaning |
|---|---|
| 401 | Missing, invalid, or revoked Bearer token |
| 403 | Missing scope, IP blocked, or entitlement required |
| 404 | Resource not found (wrong ID or other tenant) |
| 429 | Rate limit or monthly quota exceeded |
| 502 | Upstream failure (e.g. email provider) |
Pagination
List endpoints use limit and offset query parameters. Default limit is 50; maximum is 200 unless noted otherwise.
GET /api/v1/external/v1/crm/guests?limit=50&offset=0&search=alexThere is no cursor-based pagination in V1 — use offset paging and stable sort order (newest first).
Webhooks
Subscribe to outbound HTTPS events from your workspace. Payloads are JSON POST requests signed with HMAC-SHA256.
Example payload
{
"event": "guest.created",
"tenant_id": 1,
"payload": {
"guest_id": 42
},
"timestamp": "2026-06-20T12:00:00+00:00"
}Verify signature (JavaScript)
import crypto from "node:crypto";
export function verifyNectifiWebhook(
secret: string,
rawBody: Buffer | string,
signatureHeader: string | null,
): boolean {
if (!secret || !signatureHeader) return false;
const body = typeof rawBody === "string" ? Buffer.from(rawBody, "utf8") : rawBody;
const expected =
"sha256=" + crypto.createHmac("sha256", secret).update(body).digest("hex");
const provided = signatureHeader.trim().startsWith("sha256=")
? signatureHeader.trim()
: `sha256=${signatureHeader.trim()}`;
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(provided));
}Verify signature (Python)
import hmac
import hashlib
def verify_nectifi_webhook(secret: str, body: bytes, signature_header: str | None) -> bool:
if not secret or not signature_header:
return False
expected = "sha256=" + hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
provided = signature_header.strip()
if not provided.startswith("sha256="):
provided = f"sha256={provided}"
return hmac.compare_digest(expected, provided)Events: guest.created, guest.updated, promotion.granted, promotion.redeemed, loyalty.points_added, loyalty.points_redeemed, wallet.redeemed, visit.started, visit.ended
CRM API
Manage guest profiles, timeline events, tags, and staff notes.
Required scopes: crm:read (read) · crm:write (write)
/api/v1/external/v1/crm/guestscrm:readList guests
curl -sS -X GET \
"https://nectifi.com/api/v1/external/v1/crm/guests?search=alex&limit=50&offset=0" \
-H "Authorization: Bearer nk_your_api_key" \
-H "Accept: application/json"/api/v1/external/v1/crm/guestscrm:writeCreate guest
curl -sS -X POST \
"https://nectifi.com/api/v1/external/v1/crm/guests" \
-H "Authorization: Bearer nk_your_api_key" \
-H "Accept: application/json"
-H "Content-Type: application/json" \
-d '{ "location_id": 1, "portal_id": 1, "name": "Alex", "email": "alex@example.com", "marketing_consent": true}'/api/v1/external/v1/crm/guests/{guest_id}crm:readGet guest by ID
curl -sS -X GET \
"https://nectifi.com/api/v1/external/v1/crm/guests/42" \
-H "Authorization: Bearer nk_your_api_key" \
-H "Accept: application/json"/api/v1/external/v1/crm/guests/{guest_id}crm:writeUpdate guest
curl -sS -X PATCH \
"https://nectifi.com/api/v1/external/v1/crm/guests/42" \
-H "Authorization: Bearer nk_your_api_key" \
-H "Accept: application/json"
-H "Content-Type: application/json" \
-d '{ "name": "Alex M.", "is_vip": true, "tags": [ "vip" ]}'/api/v1/external/v1/crm/guests/{guest_id}/timelinecrm:readGuest activity timeline
curl -sS -X GET \
"https://nectifi.com/api/v1/external/v1/crm/guests/42/timeline" \
-H "Authorization: Bearer nk_your_api_key" \
-H "Accept: application/json"/api/v1/external/v1/crm/tagscrm:readList tag definitions
curl -sS -X GET \
"https://nectifi.com/api/v1/external/v1/crm/tags" \
-H "Authorization: Bearer nk_your_api_key" \
-H "Accept: application/json"/api/v1/external/v1/crm/tagscrm:writeCreate tag
curl -sS -X POST \
"https://nectifi.com/api/v1/external/v1/crm/tags" \
-H "Authorization: Bearer nk_your_api_key" \
-H "Accept: application/json"
-H "Content-Type: application/json" \
-d '{ "slug": "vip", "label": "VIP", "color": "#6366f1"}'/api/v1/external/v1/crm/guests/{guest_id}/notescrm:readList staff notes
curl -sS -X GET \
"https://nectifi.com/api/v1/external/v1/crm/guests/42/notes" \
-H "Authorization: Bearer nk_your_api_key" \
-H "Accept: application/json"/api/v1/external/v1/crm/guests/{guest_id}/notescrm:writeAdd staff note
curl -sS -X POST \
"https://nectifi.com/api/v1/external/v1/crm/guests/42/notes" \
-H "Authorization: Bearer nk_your_api_key" \
-H "Accept: application/json"
-H "Content-Type: application/json" \
-d '{ "text": "Prefers window seat."}'Promotion API
List active promotions, grant offers to guests, and redeem at a location.
Required scopes: promotions:read (read) · promotions:write (write)
/api/v1/external/v1/promotionspromotions:readList promotions
curl -sS -X GET \
"https://nectifi.com/api/v1/external/v1/promotions?limit=50" \
-H "Authorization: Bearer nk_your_api_key" \
-H "Accept: application/json"/api/v1/external/v1/promotions/{promotion_id}/grantpromotions:writeGrant promotion to guest
curl -sS -X POST \
"https://nectifi.com/api/v1/external/v1/promotions/7/grant" \
-H "Authorization: Bearer nk_your_api_key" \
-H "Accept: application/json"
-H "Content-Type: application/json" \
-d '{ "guest_id": 42, "location_id": 1}'/api/v1/external/v1/promotions/redeempromotions:writeRedeem grant at POS
curl -sS -X POST \
"https://nectifi.com/api/v1/external/v1/promotions/redeem" \
-H "Authorization: Bearer nk_your_api_key" \
-H "Accept: application/json"
-H "Content-Type: application/json" \
-d '{ "grant_id": 100, "location_id": 1, "idempotency_key": "pos-001"}'Loyalty API
Read and adjust loyalty points, check tier status, and redeem points.
Required scopes: loyalty:read (read) · loyalty:write (write)
/api/v1/external/v1/loyalty/guests/{guest_id}/pointsloyalty:readPoints balance
curl -sS -X GET \
"https://nectifi.com/api/v1/external/v1/loyalty/guests/42/points" \
-H "Authorization: Bearer nk_your_api_key" \
-H "Accept: application/json"/api/v1/external/v1/loyalty/guests/{guest_id}/tierloyalty:readCurrent tier
curl -sS -X GET \
"https://nectifi.com/api/v1/external/v1/loyalty/guests/42/tier" \
-H "Authorization: Bearer nk_your_api_key" \
-H "Accept: application/json"/api/v1/external/v1/loyalty/guests/{guest_id}/pointsloyalty:writeAdd points
curl -sS -X POST \
"https://nectifi.com/api/v1/external/v1/loyalty/guests/42/points" \
-H "Authorization: Bearer nk_your_api_key" \
-H "Accept: application/json"
-H "Content-Type: application/json" \
-d '{ "guest_id": 42, "points": 50, "note": "Birthday bonus", "idempotency_key": "adj-001"}'/api/v1/external/v1/loyalty/guests/{guest_id}/redeemloyalty:writeRedeem points
curl -sS -X POST \
"https://nectifi.com/api/v1/external/v1/loyalty/guests/42/redeem" \
-H "Authorization: Bearer nk_your_api_key" \
-H "Accept: application/json"
-H "Content-Type: application/json" \
-d '{ "guest_id": 42, "points": 100, "idempotency_key": "rdm-001"}'Wallet API
Fetch guest wallet payloads, issue signed wallet links, and redeem QR rewards.
Required scopes: wallet:read (read) · wallet:write (write)
/api/v1/external/v1/wallet/guests/{guest_id}wallet:readFull wallet payload
curl -sS -X GET \
"https://nectifi.com/api/v1/external/v1/wallet/guests/42" \
-H "Authorization: Bearer nk_your_api_key" \
-H "Accept: application/json"/api/v1/external/v1/wallet/linkwallet:writeIssue wallet URL
curl -sS -X POST \
"https://nectifi.com/api/v1/external/v1/wallet/link" \
-H "Authorization: Bearer nk_your_api_key" \
-H "Accept: application/json"
-H "Content-Type: application/json" \
-d '{ "guest_id": 42, "portal_id": 1, "ttl_days": 14}'/api/v1/external/v1/wallet/redeemwallet:writeRedeem wallet reward
curl -sS -X POST \
"https://nectifi.com/api/v1/external/v1/wallet/redeem" \
-H "Authorization: Bearer nk_your_api_key" \
-H "Accept: application/json"
-H "Content-Type: application/json" \
-d '{ "guest_id": 42, "reward_id": 3, "location_id": 1}'Communication API
Send template emails to guests and poll delivery status.
Required scopes: communication:read (read) · communication:write (write)
/api/v1/external/v1/communication/email/sendcommunication:writeSend template email
curl -sS -X POST \
"https://nectifi.com/api/v1/external/v1/communication/email/send" \
-H "Authorization: Bearer nk_your_api_key" \
-H "Accept: application/json"
-H "Content-Type: application/json" \
-d '{ "guest_id": 42, "template_slug": "welcome_email", "variables": { "guest_name": "Alex" }}'/api/v1/external/v1/communication/deliveries/{request_id}communication:readDelivery status
curl -sS -X GET \
"https://nectifi.com/api/v1/external/v1/communication/deliveries/1001" \
-H "Authorization: Bearer nk_your_api_key" \
-H "Accept: application/json"WiFi API
Read locations, captive portals, Wi‑Fi sessions, and live connected guests.
Required scopes: wifi:read
/api/v1/external/v1/wifi/locationswifi:readList locations
curl -sS -X GET \
"https://nectifi.com/api/v1/external/v1/wifi/locations" \
-H "Authorization: Bearer nk_your_api_key" \
-H "Accept: application/json"/api/v1/external/v1/wifi/portalswifi:readList portals
curl -sS -X GET \
"https://nectifi.com/api/v1/external/v1/wifi/portals?location_id=1" \
-H "Authorization: Bearer nk_your_api_key" \
-H "Accept: application/json"/api/v1/external/v1/wifi/sessionswifi:readList sessions
curl -sS -X GET \
"https://nectifi.com/api/v1/external/v1/wifi/sessions?location_id=1&active_only=true&limit=50" \
-H "Authorization: Bearer nk_your_api_key" \
-H "Accept: application/json"/api/v1/external/v1/wifi/live-guestswifi:readCurrently connected guests
curl -sS -X GET \
"https://nectifi.com/api/v1/external/v1/wifi/live-guests?location_id=1" \
-H "Authorization: Bearer nk_your_api_key" \
-H "Accept: application/json"Analytics API
Overview KPIs, guest metrics, and promotion performance.
Required scopes: analytics:read
/api/v1/external/v1/analytics/overviewanalytics:readOverview KPIs
curl -sS -X GET \
"https://nectifi.com/api/v1/external/v1/analytics/overview?location_id=1" \
-H "Authorization: Bearer nk_your_api_key" \
-H "Accept: application/json"/api/v1/external/v1/analytics/guestsanalytics:readGuest KPIs + 30-day series
curl -sS -X GET \
"https://nectifi.com/api/v1/external/v1/analytics/guests" \
-H "Authorization: Bearer nk_your_api_key" \
-H "Accept: application/json"/api/v1/external/v1/analytics/promotionsanalytics:readPromotion grants and redemptions
curl -sS -X GET \
"https://nectifi.com/api/v1/external/v1/analytics/promotions" \
-H "Authorization: Bearer nk_your_api_key" \
-H "Accept: application/json"