SFTP v1.0.0
On visitor action (such as click on a button, scoring, input...) Screeb can upload a JSON file to an external SFTP server containing the response data.
Entitiesโ
- Organization: A Screeb account, shared by many Screeb users of your company
- Channel: A distribution channel for your survey (Javascript SDK, Android SDK, iOS SDK...)
- Survey
- Survey scenario: A versioned survey: on survey update, your flow is saved in a new scenario. New users will see the last scenario.
- User: Information about the visitor
- Response: A response is a chain of question+answers. A user sometimes has many responses to a single survey.
- Question
- Answer: An answer is part of a response. Each answer is associated with a question.
- Field: An answer may have many fields (eg: multiple choices question)
Hook typesโ
You can trigger SFTP uploads on 3 different events:
- On survey display: a survey is shown to visitors, but no question is replied. You will get notified even if no response is given.
- On question answered: a question has been replied. This webhook will be triggered for each question of a single survey.
- On response end: a survey has been closed or fully replied to by the user.
Configurationโ
To configure your SFTP integration, you need to provide:
- Host: The SFTP server hostname or IP address
- Port: The SFTP connection port. If empty, Screeb uses
22. - Username: Your SFTP account username
- Authentication: Either a password, or an SSH key generated by Screeb (see below). Exactly one of the two is required.
- Path: Optional base directory on the SFTP server. If provided, Screeb trims leading and trailing slashes and appends its own folder structure below it.
Authenticationโ
Two authentication methods are supported:
- Username and password: the traditional method, unchanged.
- Username and SSH key: from the integration settings, generate a key pair. Screeb creates an ed25519 key pair on its servers and returns the public key for you to install in the
authorized_keysfile of the corresponding user on your SFTP server. The private key is stored server-side and is never returned by the API again; there is no way to download or display it after generation.
Host key pinningโ
The integration settings screen has a Test connection button that validates the host, port, username, and credentials against your server. On a successful test, Screeb captures your server's host key and pins its OpenSSH SHA256 fingerprint (SHA256:...) to the integration once you save it. From then on, every export verifies the server presents that same host key and fails if it does not, protecting against a compromised or spoofed server after the initial setup. Integrations set up before this pinning feature keep working without a pinned fingerprint until you run Test connection and save.
If you have configured a base path, running Test connection creates that directory on your server if it does not already exist: it is not a purely read-only check.
Network accessโ
If your SFTP server restricts inbound connections by IP, whitelist Screeb's egress IP addresses on your firewall. The current list is shown on the integration settings screen and depends on your Screeb environment.
Remote file structureโ
Screeb always uploads JSON files in a deterministic directory layout:
- Survey display events:
/workspaces/<workspace_id>/surveys/<survey_id>/displays/<response_id>.json - Question answered events:
/workspaces/<workspace_id>/surveys/<survey_id>/responses/<response_id>.json - Response ended events:
/workspaces/<workspace_id>/surveys/<survey_id>/responses/<response_id>.json
If you configure a custom base path, it is prepended to the structure above. For example:
- Configured path:
/exports/screeb - Final upload path:
/exports/screeb/workspaces/<workspace_id>/surveys/<survey_id>/responses/<response_id>.json
Because response.answered and response.ended use the same destination path for a given response, later uploads replace the previous file for that response.
Uploads are atomic: Screeb writes the file under a temporary name and renames it into its final path only once the write is complete. A process polling the directory never sees a partially written file; it either finds the previous version or the complete new one.
Payload formatโ
The SFTP integration uploads survey data in JSON format. The filename is the response identifier:
<response_id>.json
Payload structureโ
{
"event_id": "64c7ea3b-827b-4679-b25d-7fd61f6c3d33",
"event_type": "response.ended",
"version": "1.0.0",
"time": "2021-07-29T13:45:09.325344042Z",
"time_ms": 1627566309325,
"payload": {
"organization": {
"id": "b5969d13-5e5e-4648-9806-5339ddafd984",
"name": "ACME"
},
"channel": {
"id": "411ee7c3-7e64-409f-9d75-c782b3f73aa4",
"type": "android"
},
"survey": {
"id": "9b913c69-3daf-4a6e-a26d-042004fc7881",
"name": "Measure NPS",
"scenario_id": "cc4a3710-e8ee-4672-a35c-5c17485ec441",
"scenario_version": 9,
"scenario_time": "2021-07-29T00:08:31.069497Z",
"scenario_time_ms": 1627517311069
},
"user": {
"anonymous_id": "2eb83fb4-b1b3-4e48-be48-a8fd9c4e5a7d",
"user_id": "support@screeb.app",
"name": "John Doe",
"email": "support@screeb.app",
"group_names": ["Screeb", "10-100-companies", "plan-enterprise"],
"properties": {
"firstname": "John",
"lastname": "Doe",
"email": "support@screeb.app",
"plan": "free"
}
},
"response": {
"id": "5854a797-628c-4906-bb4c-da03e418cf47",
"locale": "en-US",
"time": "2021-07-29T13:44:59.831Z",
"time_ms": 1627918228831,
"time_to_complete_second": 34,
"completion": "fully_completed",
"hidden_fields": {
"variable-from-crm": "blablabla"
},
"context": {
"active_page": {
"url": "https://screeb.app/solutions/product-analytics?utm_medium=email"
},
"locale": "en-GB"
},
"question": {
"id": "a44252c3-ef3d-4156-90d6-a3d6364516c0",
"correlation_id": "c6d4d007-879f-43fe-b4cf-d58e1f8ed1f8",
"type": "input",
"title": "How can we improve your experience?"
},
"answer": {
"field": {
"id": "c71dfe9d-6b47-452f-bda2-6091c13561b0",
"correlation_id": "eb398cc0-1223-4590-bb60-e41ac8dfb0f6",
"type": "string",
"value": "The new dashboard is buggy.",
"text": "The new dashboard is buggy."
},
"fields": [
{
"id": "c71dfe9d-6b47-452f-bda2-6091c13561b0",
"correlation_id": "eb398cc0-1223-4590-bb60-e41ac8dfb0f6",
"type": "string",
"value": "The new dashboard is buggy.",
"text": "The new dashboard is buggy."
}
],
"replied_at": "2021-07-29T13:45:09.286Z",
"replied_at_ms": 1627566309286,
"tags": ["screeb", "feedback"]
},
"tags": ["screeb", "feedback"],
"items": [
{
"question": {
"id": "a44252c3-ef3d-4156-90d6-a3d6364516c0",
"correlation_id": "c6d4d007-879f-43fe-b4cf-d58e1f8ed1f8",
"type": "input",
"title": "How can we improve your experience?"
},
"answer": {
"fields": []
}
}
]
}
}
}
Payload notesโ
- The top-level JSON contains
event_id,event_type,version,time,time_ms, andpayload. payload.user.properties,payload.response.context, andpayload.response.hidden_fieldsare free-form nested objects.payload.response.questionandpayload.response.answerare mainly useful forresponse.answeredevents.payload.response.itemscontains the ordered list of answered questions available at the time the file is generated.payload.response.answer.fieldis kept for backward compatibility, whilepayload.response.answer.fieldsis the complete list.- Question and answer fields include both
idandcorrelation_id.
Event-specific behaviorโ
response.displayeduploads to thedisplaysfolder and uses the response creation time as event time.response.answereduploads to theresponsesfolder and includesquestion,answer,items,tags, and a computedcompletionstatus.response.endeduploads to theresponsesfolder and includes the finalitems,tags,completion, andtime_to_complete_second.
Best practicesโ
- Use a dedicated SFTP directory for Screeb exports.
- Expect files to be overwritten for the same response in the
responsesfolder. - Restrict the SFTP account to write access on the export directory only.
- Consume files by parsing JSON content rather than relying on filename patterns.
- If needed, archive files after ingestion on your side.
- Prefer SSH key authentication over a password, and run Test connection to pin the server's host key fingerprint once your server is reachable.
Troubleshootingโ
Connection failedโ
- Verify that the SFTP server is reachable
- Check firewall rules allow outbound connections to the SFTP port
- Verify credentials are correct
Authentication errorโ
- Ensure username and password are correct, or that the installed SSH public key matches the key pair generated for this integration
- Check if the SFTP account has the necessary permissions
- Check that the public key is present in the correct user's
authorized_keysfile on the server
Host key mismatchโ
- This means the server's host key no longer matches the fingerprint pinned when you last ran Test connection. This can happen after a legitimate server migration or key rotation, or it can indicate the connection is being intercepted.
- Confirm with your infrastructure team that the server's host key changed for a legitimate reason before proceeding.
- Once confirmed, run Test connection again and save the integration to pin the new fingerprint.
Upload failedโ
- Verify the remote path exists and the account has write permissions
- Check available disk space on the SFTP server
Compatibility notesโ
- Authentication supports username/password or username/SSH key.
- If no port is configured, Screeb connects on port
22. - Screeb creates missing directories automatically before uploading the file.
- Host key pinning is opt-in: integrations without a pinned fingerprint keep the previous behavior of accepting the server's key without verification. Run Test connection and save to start pinning.
Supportโ
For additional help with your SFTP integration, please contact our support team or refer to the main API documentation.