Run the directory sync now (admin-only)
const url = 'https://example.com/api/admin/ldap/sync';const options = { method: 'POST', headers: { 'X-Ssoossh-Key-Secret': '<X-Ssoossh-Key-Secret>', 'Content-Type': 'application/json' }, body: '{}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://example.com/api/admin/ldap/sync \ --header 'Content-Type: application/json' \ --header 'X-Ssoossh-Key-Secret: <X-Ssoossh-Key-Secret>' \ --data '{}'Runs the same pass the scheduler runs, on this instance, and returns what it concluded. One at a time: a pass already in progress makes this a 409 rather than stacking a second one over the same users. With dry_run the pass reads the directory and changes nothing, reporting the disables and re-enables it would have performed — which is what makes it safe to press during an incident.
With nss.enabled on, a pass that is not a dry run also runs the NSS directory’s full sync on this instance afterwards and reports it under nss: the POSIX accounts and groups the filters select, with each group’s members limited to the accounts stored. The NSS sync has no dry run.
Authorizations
Section titled “Authorizations”Request Body
Section titled “Request Body”Sync options
Responses
Section titled “Responses”What the pass concluded
LastRun is the most recent pass on any instance, absent when none has ever run.
object
ActorUsername is the admin who triggered it, absent for a scheduled pass. The username rather than the id, since it is displayed.
Error is why the pass could not run — an unreachable directory, a failed bind. Empty for a pass that completed, whatever it concluded about individual users.
FinishedAt is absent while the pass runs, which is also how a pass that died with its process reads afterwards.
Instance is the host that ran it. Jobs are not leader-elected, so every instance runs its own pass and this says whose log to read.
NSS is what the NSS directory’s full sync concluded when an admin ran this pass by hand with nss.enabled on: POST /api/admin/ldap/sync runs both, except on a dry run. Absent otherwise, and on every scheduled pass, which the NSS sync does not ride on.
object
object
Failed is the entries that could not be checked or written.
Missing is the rows marked missing for the first time; Tombstoned the rows missing for nss.tombstone_after and now deleted.
Refused is the new entries not stored because another row, a tombstone included, holds their number or name.
Seen is the entries the directory returned.
Skipped is the entries rejected because a value did not parse (a name the POSIX rules refuse, a uid that is not a number, a relative home); each is logged with its DN.
Error is why the run stopped short: the directory could not be reached or searched, or another run was in progress on this instance. Nothing is marked missing by a run that stopped short.
FinishedAt is absent when the run stopped on an error.
Full is true for a full run, which is the only kind that marks entries missing; the admin trigger always runs one.
object
Failed is the entries that could not be checked or written.
Missing is the rows marked missing for the first time; Tombstoned the rows missing for nss.tombstone_after and now deleted.
Refused is the new entries not stored because another row, a tombstone included, holds their number or name.
Seen is the entries the directory returned.
Skipped is the entries rejected because a value did not parse (a name the POSIX rules refuse, a uid that is not a number, a relative home); each is logged with its DN.
Trigger is “schedule” or “manual”.
Example generated
{ "actor_username": "example", "disabled": 1, "dry_run": true, "error": "example", "failed": 1, "finished_at": "example", "found": 1, "id": "example", "instance": "example", "missing": 1, "nss": { "accounts": { "created": 1, "failed": 1, "missing": 1, "refused": 1, "seen": 1, "skipped": 1, "tombstoned": 1, "updated": 1 }, "error": "example", "finished_at": "example", "full": true, "groups": { "created": 1, "failed": 1, "missing": 1, "refused": 1, "seen": 1, "skipped": 1, "tombstoned": 1, "updated": 1 }, "started_at": "example" }, "reenabled": 1, "started_at": "example", "trigger": "example", "users_seen": 1}Invalid request body
object
Data is always null on an error response.
Error is a human-readable message. Branch on the HTTP status rather than this string; it is for humans and logs.
ErrorCode is a machine-readable error classifier. One of the error_code constants from internal/apitypes; use this to decide whether to retry or branch on the failure mode.
Example
{ "error": "certificate request \"9f1c…\" not found", "error_code": "not_found"}Not authenticated
object
Data is always null on an error response.
Error is a human-readable message. Branch on the HTTP status rather than this string; it is for humans and logs.
ErrorCode is a machine-readable error classifier. One of the error_code constants from internal/apitypes; use this to decide whether to retry or branch on the failure mode.
Example
{ "error": "certificate request \"9f1c…\" not found", "error_code": "not_found"}Not authorized as admin
object
Data is always null on an error response.
Error is a human-readable message. Branch on the HTTP status rather than this string; it is for humans and logs.
ErrorCode is a machine-readable error classifier. One of the error_code constants from internal/apitypes; use this to decide whether to retry or branch on the failure mode.
Example
{ "error": "certificate request \"9f1c…\" not found", "error_code": "not_found"}A sync is already running
object
Data is always null on an error response.
Error is a human-readable message. Branch on the HTTP status rather than this string; it is for humans and logs.
ErrorCode is a machine-readable error classifier. One of the error_code constants from internal/apitypes; use this to decide whether to retry or branch on the failure mode.
Example
{ "error": "certificate request \"9f1c…\" not found", "error_code": "not_found"}The directory could not be reached
object
Data is always null on an error response.
Error is a human-readable message. Branch on the HTTP status rather than this string; it is for humans and logs.
ErrorCode is a machine-readable error classifier. One of the error_code constants from internal/apitypes; use this to decide whether to retry or branch on the failure mode.
Example
{ "error": "certificate request \"9f1c…\" not found", "error_code": "not_found"}