POST /api/unpair
Endpoint:
POST /api/unpair
Auth Scope: Profile Protected (verify_profile_access)
Target Service: Local DaemonX Bridge Daemon (127.0.0.1:9123)
Introduced In: v1.0.0
Last Updated: v1.0.0
1. Description & Purpose
POST /api/unpair securely de-registers an active counter from the workstation.
Note on Pairing:
Workstation pairing is performed directly inside the DaemonX Windows Desktop App using a 6-character pairing code generated by the Web POS. The desktop app communicates directly with Nyxzie Core over HTTPS. There is no unauthenticated/api/pairloopback endpoint on the bridge.
POST /api/unpair is available to trusted local callers that already possess the counter profile secret. This includes a separated business/developer dashboard where an authorized operator can view or copy the profile secret for that counter. Do not bake the secret into public POS bundles.
Use it when:
- Decommissioning or replacing a register workstation.
- Re-allocating a counter to a different store or site.
- Clearing local hardware credentials.
2. Authentication & Request Headers
POST /api/unpair requires valid counter credentials to prevent unauthorized local profile deletion:
| Header Name | Type | Required | Description |
|---|---|---|---|
Content-Type | string | Yes | application/json |
Origin | string | Conditional | Browser origin. Required for browser calls and validated against the counter's allowed origins; direct trusted local tooling may omit it. |
X-Bridge-Counter-Id | string (UUID) | Yes | Counter ID being unpaired. |
X-Bridge-Profile-Secret | string | Yes | Counter profile secret (dxp_...). |
3. TypeScript Contracts
export interface LocalUnpairResponse {
success: boolean;
counter_id: string;
core_unpair_status: 'confirmed' | 'already_missing';
message: string;
}
export interface DaemonXErrorResponse {
detail: {
error: string;
message: string;
counter_id?: string;
};
}
4. Request Payload
Empty JSON body {} or no body required. The target counter is identified by the X-Bridge-Counter-Id header.
5. Successful Response (200 OK)
{
"success": true,
"counter_id": "d402ddec-ecf7-4b39-b57a-86ce6008df05",
"core_unpair_status": "confirmed",
"message": "Counter d402ddec-ecf7-4b39-b57a-86ce6008df05 unpaired successfully."
}
Post-Unpair State Machine Transitions:
- Local Storage Cleanup: The counter profile is purged from local encrypted storage.
- Tray Menu Update: The Windows System Tray immediately switches status to
"○ Not Paired". - Core Quota Release: Nyxzie Core frees the counter slot under the merchant's plan quota.
- Subsequent Calls: Future hardware commands using the old credentials return
401 Unauthorized.
6. Integration Snippets
Trusted Local Unpairing Function
This is safe for trusted admin/developer tooling where the authorized user supplies or reveals the secret. Do not place profileSecret in public browser bundles, NEXT_PUBLIC_* variables, or generic long-lived browser storage.
export async function unpairDaemonXTerminal(
counterId: string,
profileSecret: string
): Promise<LocalUnpairResponse> {
const res = await fetch('http://127.0.0.1:9123/api/unpair', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Bridge-Counter-Id': counterId,
'X-Bridge-Profile-Secret': profileSecret,
},
});
if (!res.ok) {
const err = await res.json().catch(() => null);
throw new Error(err?.detail?.message || err?.detail || `Unpairing failed (HTTP ${res.status})`);
}
return (await res.json()) as LocalUnpairResponse;
}
cURL
curl -X POST "http://127.0.0.1:9123/api/unpair" \
-H "Content-Type: application/json" \
-H "X-Bridge-Counter-Id: d402ddec-ecf7-4b39-b57a-86ce6008df05" \
-H "X-Bridge-Profile-Secret: dxp_202b541b2a72ecc32867e0f62b26b07be38024210e30af90" \
-H "Origin: https://pos.yourdomain.com"