Sftp
Optional filter: pending, processed, or error.
File list returned.
One file sitting in the tenant's SFTP inbox.
Original file name (stripped of any internal timestamp prefix).
One of pending, processed, or error.
File size in bytes.
When the file was last written, in UTC.
Stable identifier for this specific file run. Pass this to the import-log endpoint. Unlike Neo.Web.Api.Admin.Controllers.Sftp.SftpController.SftpFileResponse.FileName, this is unique even when the same file name is re-imported multiple times: each run produces a distinct blob path.
Invalid status filter.
Not authorized.
GET /api/{tenantId}/admin/sftp/files HTTP/1.1
Host: app.neostore.cloud
Authorization: Bearer YOUR_OAUTH2_TOKEN
Accept: */*
[
{
"fileName": "text",
"status": "text",
"sizeInBytes": 1,
"lastModified": "2026-01-01T00:00:00.000Z",
"blobPath": "text"
}
]Streams the file exactly as the customer dropped it — no parsing, no reformatting — as an attachment named after the file itself.
The body is gzip-compressed on the fly whenever the caller advertises Accept-Encoding: gzip, which every browser does: these drops are overwhelmingly CSV, where gzip cuts the transfer by roughly an order of magnitude. This is transport compression, not a different artifact — the client decompresses transparently and ends up with the original file, byte for byte, under its original name. A caller that does not advertise gzip gets the bytes uncompressed.
Authorization
Requires tenant.sftp:download scope — deliberately separate from tenant.sftp:read, which exposes file names, row counts and pass identifiers but never the customer data in the file.
Blob path, exactly as returned by the blobPath field in the files list endpoint.
File content returned as an attachment.
Not authorized.
No file with this blob path was found in the tenant's SFTP inbox.
GET /api/{tenantId}/admin/sftp/files/content HTTP/1.1
Host: app.neostore.cloud
Authorization: Bearer YOUR_OAUTH2_TOKEN
Accept: */*
binaryBlob path, exactly as returned by the blobPath field in the files list endpoint. Uniquely identifies one file run even when the same file name is re-imported multiple times.
Import log returned.
Full story of what happened when one SFTP-dropped file was imported.
Current status of the file: pending, processed, or error.
Whether a matching import run was found in the log store. false while the file is pending.
Whether the import function itself completed successfully. null when not found.
Number of batches sent to the wallet update pipeline.
Total rows read from the file.
Rows that resolved to at least one pass and were queued for update.
Rows whose identifiers matched no pass at all — a data-quality signal, not a technical failure.
Rows that threw while being transformed.
Not authorized.
No file with this blob path was found in the tenant's SFTP inbox.
GET /api/{tenantId}/admin/sftp/files/log HTTP/1.1
Host: app.neostore.cloud
Authorization: Bearer YOUR_OAUTH2_TOKEN
Accept: */*
{
"status": "text",
"fileRunFound": true,
"fileRunSuccess": null,
"batchCount": null,
"rowCount": null,
"successCount": null,
"noMatchCount": null,
"errorCount": null,
"passOutcomes": [
{
"passId": null,
"success": true,
"errorMessage": null
}
]
}Status returned.
Quick-glance SFTP activity summary for a tenant.
false when the tenant has no SFTP inbox at all — the normal case for most tenants, not an error. Every other field is null in that case.
Files dropped but not yet processed.
Files successfully processed.
Files that failed processing.
Timestamp of the most recently modified file across all folders.
Not authorized.
GET /api/{tenantId}/admin/sftp/status HTTP/1.1
Host: app.neostore.cloud
Authorization: Bearer YOUR_OAUTH2_TOKEN
Accept: */*
{
"sftpEnabled": true,
"pendingCount": null,
"processedCount": null,
"errorCount": null,
"lastActivity": null
}Last updated

