Persistent Sync Issue: Unable to delete/overwrite Keypad entry (Error 204 but entry remains)

Hi everyone,

I’m bringing this issue back to your attention because it’s still causing significant friction in managing access codes. It appears there is a synchronization gap between the Nuki servers/API and the physical Smart Lock that remains unresolved. Sorry if there is already a solution.

The Problem

I recently created a keypad code via the app, but it never successfully synced to the Smart Lock. This has led to a “ghost entry” situation:

  1. Ghost Entry: When I call /smartlock/[lock id]/auth, the code is listed.
  2. Failed Deletion: When I attempt to delete this code, the API returns a 204 No Content (indicating success). However, when I refresh the list, the code is still there.
  3. Conflict: I cannot re-create the code because the system throws an error stating the PIN already exists.

Effectively, I am stuck with a non-functional code that I cannot remove or overwrite.

Suggested Improvements

To prevent these deadlocks, I’d like to propose two logic changes:

  • Forced Deletion: The API should always prioritize the deletion of a record in the database, even if the physical lock is temporarily unreachable, to allow for a “clean slate” retry.
  • Sync Logic & Error Handling: Implement a periodic synchronization (e.g., a daily heartbeat at 00:00) between the server and the lock. Alternatively, provide a Webhook notification or a specific error state if a code fails to commit to the hardware, rather than returning a false-positive 204.

Workarounds?

Has anyone found a solid code-based workaround for forced-clearing the auth list when the server and lock are out of sync?

I look forward to hearing your thoughts or if there’s a fix in the pipeline.

Hi Almer,

Welcome to the forums :wave:

When you call the /smartlock/{id}/auth endpoint, the data will be fetched from the server. If the authorisation is present there, it means your locally (via smartphone) created authorisation has been synced to the server. Can you explain what you mean by “ghost entry” in this case? Do you not see the authorisation where you expect it to be?

Regarding the delete request, please note that our API is asynchronous. A 204 response implies the request was accepted by the server, but it doesn’t necessarily mean that the request was then executed on the smart lock (more about this handling of asynchronous API requests can be found in our API documentation). To determine what the error is when attempting to delete the authorisation, you can use the webhook functionality that’s included in our Advanced API. A detailed error message will be contained in the webhook payload.

Hope that helps.

Kind regards,

Andrew

1 Like

Hi Andrew,

Thanks for the quick response and the welcome!

I understand that the API is asynchronous and that 204 signifies acceptance rather than completion. However, the issue I’m highlighting is that this asynchronous process never completes, leading to what I call a “ghost entry.”

To clarify:

  • The “Ghost Entry”: The authorization exists on the server (it shows up in the /auth call), but it does not work on the physical Keypad (when checking the Nuki app). Because the server thinks it exists, I cannot recreate it.
  • The Deadlock: When I try to delete it, the server accepts the command (204), but the change never reaches the lock. Because the server waits for the lock to confirm the deletion before actually removing it from the database, and that confirmation never comes, I can delete it time after time, the entry stays on the server forever.

The problem with the Webhook suggestion: While a webhook can tell me that it failed, it doesn’t solve the fact that I am now blocked. I cannot delete the code (it stays in the system) and I cannot add it (it already exists).

My question to you is: How can I force-delete an authorization from the server when the physical lock is unable to confirm the deletion? Is there a way to break this deadlock without a full factory reset of the hardware?

Kind regards,

Almer

Hi Almer,

Thanks for the detailed feedback. Our smart locks work on the principle that the smart lock itself is the source of truth. That means the authorisations will remain on the server until they are deleted from the device. The question here would then be why the device is not reachable for your delete requests (e.g. presumably due to a lost network connection). GET requests will read directly from the server, which may give the false impression that the device is obtainable.

If you are within bluetooth range of the smart lock, you can also delete the authorisations via the smart phone app. After the next successful sync with the server, the authorisation should disappear.

Hi Almer,

I’m observing the same failure mode, although with a different type of authorisation object.

In my case, the authorisation no longer exists on the physical lock (verified locally via Bluetooth), yet it remains present on the server and continues to appear in /auth. Delete requests return 204 (accepted), but the server-side state never changes because the expected device confirmation never arrives.

The issue is not the asynchronous model itself, but the absence of a deterministic recovery path when confirmation never occurs. If the backend refuses to remove an entry without device acknowledgement, a deadlock can arise and persist indefinitely.

From a distributed systems perspective, this resembles a two-phase commit without a reconciliation mechanism.

Is there any backend-side timeout or reconciliation process for stuck authorisations?

Curious whether others have encountered similar permanently “stuck” states.

Hi Andrew,

I’m jumping into this thread because I am experiencing the exact same issue as José. After attempting to delete or overwrite a keypad entry, the system returns a success message (or a 204 No Content), but a subsequent GET request shows that the entry is still there. It simply won’t disappear.

You mentioned that the Keypad is the “Source of Truth,” but based on this behavior, I have my doubts. It feels like we are dealing with two separate “truths” (the Cloud/Bridge and the Keypad) that have stopped syncing.

Crucially: because the entry does not actually exist on the physical Keypad, I cannot delete it from the hardware side either. The Cloud thinks it’s there, the Keypad knows it’s not. This creates a deadlock where it’s impossible to make these entries disappear.

If the Keypad were the absolute source of truth, a successful deletion command should either:

  1. Fail immediately if the Keypad cannot be reached or refuses the command.
  2. Be reflected accurately in the next GET call once the Cloud registers the change.

Currently, we are in a limbo state where the API claims the job is done, but the data persists in your database. This suggests a sync-logic failure between the server-side credential storage and the hardware. Is there a way to force a deep sync or a manual “pruning” of the database on the Nuki side to match the actual state of the Keypad?

Looking forward to your insights. Thanks already.

Hi José and Almer,

Thanks for your detailed inputs. I understand where you are coming from with your concerns.

Could you both please send me a direct message via this forum with the request URL are sending (so I can also see your smart lock ID), as well as the timestamp (UTC) of when you sent these requests? I’ll have a look in our logs to see how these cases are being handled and can give you more input.

Thanks,

Andrew