Use this for the main programmatic download route.
Documentation
Use Invisible Folder from your app without guessing.
This page only covers the routes you would call from software. Browser account flows, dashboard endpoints, account linking, and internal service-to-service hooks are intentionally left out.
Use this when you want the shortest possible download URL.
This is the route intended for software-driven downloads.
There is no migrated API-key upload endpoint yet, so this page focuses on download access.
Start here
- Primary domain:
https://invisiblefolder.net. - Short domain:
https://invis.zipfor the short download URL format. - For software integrations, use
POST /a/{reference_id}. The matchingGETroute is for browser-style access and is intentionally not documented here. - This page only covers software-facing access. Account pages, browser session endpoints, System Locker linking, and service-token webhook routes are intentionally omitted.
All examples below assume you are using libcurl from C++ and want predictable non-browser behavior.
Access quick reference
| File access mode | What you send | Notes |
|---|---|---|
| Public or hidden | No extra credential | The route can stream the file immediately when the file is allowed to be shared without extra protection. |
| Password-protected | password |
Send the file password as a form field in the same POST request. |
| System Locker Simple | systemlocker_key or systemlocker_username + systemlocker_password |
Use either the single key form or the username/password form. |
| System Locker Advanced | invisiblefolder_token field or X-Invisiblefolder-Token header |
The token must match the required System Locker system and the file owner's Invisible Folder account. |
Programmatic download route
| Method + path | Purpose | Result shape |
|---|---|---|
POST /a/{reference_id}POST https://invis.zip/{reference_id} |
Programmatic download endpoint (recommended for apps). | Success: raw file bytes (download attachment). Failure: JSON with error and error_human. |
Private-or-higher files are not exposed through this software-facing route. Denied access is intentionally returned as the same not-found response shape used for missing references.
Credential fields
- Password-protected files:
password. - System Locker Simple:
systemlocker_keyorsystemlocker_username+systemlocker_password. - System Locker Advanced:
invisiblefolder_tokenfield orX-Invisiblefolder-Tokenheader.
System Locker access
| Mode | What to send | Notes |
|---|---|---|
| Simple with key | systemlocker_key |
Useful when your client already has the System Locker key and does not want to prompt for username/password. |
| Simple with username/password | systemlocker_username and systemlocker_password |
Use this when you need a traditional credential prompt. |
| Advanced token | invisiblefolder_token or X-Invisiblefolder-Token |
The token must still match the required System Locker system and the owning Invisible Folder account. |
The System Locker linking flow and webhook endpoints exist for partner systems, not for end-user integrations, so they are deliberately not documented on this page.
libcurl C++ examples
1) Programmatic download with an Advanced token
CURL* curl = curl_easy_init();
if (curl) {
FILE* out = fopen("download.bin", "wb");
struct curl_slist* headers = nullptr;
headers = curl_slist_append(headers, "X-Invisiblefolder-Token: YOUR_IF_TOKEN");
curl_easy_setopt(curl, CURLOPT_URL, "https://invisiblefolder.net/a/abc123def456");
curl_easy_setopt(curl, CURLOPT_POST, 1L);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, out);
CURLcode rc = curl_easy_perform(curl);
long status = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
if (rc == CURLE_OK && status == 200) {
// Success: file bytes were written to download.bin
} else {
// Failure: non-200 responses return JSON with error and error_human
}
fclose(out);
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}
2) System Locker Simple download with username and password
CURL* curl = curl_easy_init();
if (curl) {
curl_mime* form = curl_mime_init(curl);
curl_mimepart* part = nullptr;
part = curl_mime_addpart(form);
curl_mime_name(part, "systemlocker_username");
curl_mime_data(part, "YOUR_SYSTEMLOCKER_USERNAME", CURL_ZERO_TERMINATED);
part = curl_mime_addpart(form);
curl_mime_name(part, "systemlocker_password");
curl_mime_data(part, "YOUR_SYSTEMLOCKER_PASSWORD", CURL_ZERO_TERMINATED);
FILE* out = fopen("download.bin", "wb");
curl_easy_setopt(curl, CURLOPT_URL, "https://invisiblefolder.net/a/abc123def456");
curl_easy_setopt(curl, CURLOPT_POST, 1L);
curl_easy_setopt(curl, CURLOPT_MIMEPOST, form);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, out);
CURLcode rc = curl_easy_perform(curl);
long status = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
if (rc == CURLE_OK && status == 200) {
// Success: file bytes were written to download.bin
} else {
// Failure: non-200 responses return JSON with error and error_human
}
fclose(out);
curl_easy_cleanup(curl);
curl_mime_free(form);
}
Things to plan around
- There is no migrated API-key upload endpoint yet, so software-facing integrations are currently download-focused.
- Private-or-higher files are not exposed through this route; denied access uses the same not-found error shape as missing references.
- Non-200 responses from the programmatic download route are JSON, even though successful responses are raw file bytes.
- If you automate against exact response fields, keep integration tests around the routes you use most.