Platform
ScaiWave ScaiGrid ScaiCore ScaiBot ScaiDrive ScaiKey Models Tools & Services
Solutions
Organisations Developers Internet Service Providers Managed Service Providers AI-in-a-Box
Resources
Support Documentation Blog Downloads
Company
About Research Careers Investment Opportunities Contact
Log in

SMB Connector

Keep a ScaiDrive share in step with an SMB (Windows / Samba) file share. The connector logs in with a service account, walks the SMB tree, mirrors the structure into ScaiDrive, and schedules recurring syncs. Changes on either side propagate.

Base path: /api/v1/smb-connectors/

Why#

Organizations with existing SMB shares want their content available through modern sync and sharing without migrating it. Install the connector, point it at an SMB share, and that content becomes accessible through the ScaiDrive web client, desktop client, and API.

The connector is not an SMB frontend for ScaiDrive — clients don't connect to ScaiDrive over SMB. The connector bridges SMB content into ScaiDrive's native sync model.

Sync directions#

Mode Behavior
bidirectional Changes on either side replicate. Conflicts resolved per configured strategy
smb_to_scaidrive SMB is authoritative. Changes in ScaiDrive are overwritten on next sync
scaidrive_to_smb ScaiDrive is authoritative. SMB changes are overwritten

Use bidirectional for active collaboration. Use the unidirectional modes when one side is the system of record (e.g., a legacy scanner that writes to SMB) and the other is the view layer.

Creating a connector#

bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
curl -X POST $SCAIDRIVE_URL/api/v1/smb-connectors \
  -H "Authorization: Bearer $SCAIDRIVE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Finance Fileserver",
    "description": "Legacy Windows share — finance department",
    "server_host": "fs01.corp.example.com",
    "server_port": 445,
    "share_name": "Finance",
    "base_path": "2026",
    "domain": "CORP",
    "username": "scaidrive-svc",
    "password": "<secret>",
    "target_share_id": "shr_01J3H",
    "target_path": "/From Fileserver",
    "sync_direction": "bidirectional",
    "sync_permissions": true,
    "include_patterns": {"extensions": ["pdf", "docx", "xlsx"]},
    "exclude_patterns": {"patterns": ["~$*", ".DS_Store", "Thumbs.db"]},
    "conflict_resolution": "LAST_WRITER_WINS",
    "sync_interval_minutes": 15
  }'
python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
resp = httpx.post(
    f"{url}/api/v1/smb-connectors",
    headers={"Authorization": f"Bearer {token}"},
    json={
        "name": "Finance Fileserver",
        "server_host": "fs01.corp.example.com",
        "server_port": 445,
        "share_name": "Finance",
        "base_path": "2026",
        "domain": "CORP",
        "username": "scaidrive-svc",
        "password": os.environ["SMB_PASS"],
        "target_share_id": "shr_01J3H",
        "target_path": "/From Fileserver",
        "sync_direction": "bidirectional",
        "sync_interval_minutes": 15,
    },
)
connector = resp.json()
typescript
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
const resp = await fetch(`${url}/api/v1/smb-connectors`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${token}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    name: "Finance Fileserver",
    server_host: "fs01.corp.example.com",
    server_port: 445,
    share_name: "Finance",
    base_path: "2026",
    domain: "CORP",
    username: "scaidrive-svc",
    password: process.env.SMB_PASS,
    target_share_id: "shr_01J3H",
    target_path: "/From Fileserver",
    sync_direction: "bidirectional",
    sync_interval_minutes: 15,
  }),
});
const connector = await resp.json();

Credentials are encrypted at rest. The password field is write-only — reads never return it. Requires MANAGE_PERMISSIONS on the target share.

All configuration fields#

Field Notes
name, description Display
server_host, server_port SMB server, usually port 445
share_name SMB share root
base_path Subpath inside the SMB share (optional)
domain NT domain / workgroup
username, password Service account
target_share_id ScaiDrive share to mirror into
target_path Path inside the target share (created if missing)
sync_direction bidirectional, smb_to_scaidrive, scaidrive_to_smb
sync_permissions Replicate SMB ACLs to ScaiDrive ACLs (requires identity mappings)
sync_hidden_files Default false
sync_system_files Default false
include_patterns {"extensions": [...], "patterns": [...]} — whitelist
exclude_patterns Same shape — blacklist
conflict_resolution One of the sync strategies
sync_interval_minutes Recurring sync schedule; 0 disables scheduled runs

Testing connectivity#

Before your first sync, test the connection:

bash
1
2
curl -X POST $SCAIDRIVE_URL/api/v1/smb-connectors/cnn_01J5X/test \
  -H "Authorization: Bearer $SCAIDRIVE_TOKEN"

Response:

json
1
2
3
4
5
{
  "success": true,
  "message": "Connected to fs01.corp.example.com\\Finance as CORP\\scaidrive-svc",
  "error": null
}

If success: false, error carries the SMB error (auth failure, DNS, firewall).

Triggering a sync#

bash
1
2
curl -X POST $SCAIDRIVE_URL/api/v1/smb-connectors/cnn_01J5X/sync \
  -H "Authorization: Bearer $SCAIDRIVE_TOKEN"

Returns 202 Accepted with a job ID. List jobs:

bash
1
2
curl -H "Authorization: Bearer $SCAIDRIVE_TOKEN" \
     $SCAIDRIVE_URL/api/v1/smb-connectors/cnn_01J5X/jobs
json
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
{
  "jobs": [
    {
      "id": "job_01J6A",
      "status": "completed",
      "started_at": "2026-04-23T10:00:00Z",
      "finished_at": "2026-04-23T10:07:33Z",
      "files_scanned": 8420,
      "files_synced": 42,
      "bytes_transferred": 98765432,
      "error_count": 0
    }
  ]
}

Scheduled syncs run on the sync_interval_minutes cadence. You can force a manual sync at any time.

Identity mapping#

By default, files synced from SMB are owned by the connector's service account in ScaiDrive. To preserve original ownership — so Alice who created a file in SMB is shown as the owner in ScaiDrive — configure identity mappings.

Map an SMB principal to a ScaiDrive user or group:

bash
1
2
3
4
5
6
7
8
curl -X POST $SCAIDRIVE_URL/api/v1/smb-connectors/cnn_01J5X/identity-mappings \
  -H "Authorization: Bearer $SCAIDRIVE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "identity_type": "user",
    "smb_principal": "CORP\\alice",
    "scaidrive_principal_id": "usr_01J4M"
  }'

With sync_permissions: true on the connector and identity mappings in place, SMB ACLs are translated to ScaiDrive ACEs automatically. Unmapped SMB principals generate a warning in the job log and fall back to the connector service account.

List mappings:

bash
1
2
curl -H "Authorization: Bearer $SCAIDRIVE_TOKEN" \
     $SCAIDRIVE_URL/api/v1/smb-connectors/cnn_01J5X/identity-mappings

Remove a mapping:

bash
1
2
curl -X DELETE $SCAIDRIVE_URL/api/v1/smb-connectors/cnn_01J5X/identity-mappings/map_01J6B \
  -H "Authorization: Bearer $SCAIDRIVE_TOKEN"

File-state inspection#

To see which files the connector is tracking and their sync status:

bash
1
2
curl -H "Authorization: Bearer $SCAIDRIVE_TOKEN" \
     $SCAIDRIVE_URL/api/v1/smb-connectors/cnn_01J5X/file-states

Useful for debugging — shows per-file last-sync time, last error, and current checksum on both sides.

Conflict handling#

In bidirectional mode, conflicts arise when both SMB and ScaiDrive change the same file between syncs. conflict_resolution controls:

  • LAST_WRITER_WINS — newest modification time wins.
  • KEEP_BOTH — server (ScaiDrive) side gets a (conflict) suffix; SMB side stays.
  • SCAIDRIVE_WINS — ScaiDrive always wins.
  • SMB_WINS — SMB always wins.

For safety during initial onboarding, consider starting in smb_to_scaidrive mode for a few cycles (SMB is authoritative, nothing in ScaiDrive can damage the original), then switch to bidirectional once you trust the flow.

Updating a connector#

bash
1
2
3
4
curl -X PATCH $SCAIDRIVE_URL/api/v1/smb-connectors/cnn_01J5X \
  -H "Authorization: Bearer $SCAIDRIVE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"sync_interval_minutes": 60}'

Any field except immutable ones (target_share_id) can be updated. Rotating credentials:

bash
1
2
3
4
curl -X PATCH $SCAIDRIVE_URL/api/v1/smb-connectors/cnn_01J5X \
  -H "Authorization: Bearer $SCAIDRIVE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"username": "new-svc", "password": "<new-secret>"}'

Deleting a connector#

bash
1
2
curl -X DELETE $SCAIDRIVE_URL/api/v1/smb-connectors/cnn_01J5X \
  -H "Authorization: Bearer $SCAIDRIVE_TOKEN"

Deletes the connector and identity mappings. Content already synced into ScaiDrive stays. SMB content is untouched.

Troubleshooting#

CONNECTOR_AUTH_FAILED — SMB rejected credentials. Check domain, username, password. Check whether the account is locked or disabled.

CONNECTOR_UNREACHABLE — Network failure. Check DNS, firewall on port 445, SMB service on the server.

Errors on individual files — Show up in job error_count. Common causes: locked files (Office temp files ~$* — exclude them), permission denied in SMB (service account needs read/write), symlinks (not followed).

Partial syncs — If a connector's job takes longer than the sync interval, the next scheduled run is skipped rather than overlapping. GET /jobs shows the schedule decisions.

What's next#

Updated 2026-05-18 15:04:14 View source (.md) rev 2