Organization API: Customer Portal: Import
The 5 Organization API operations for import.
Part of Customer Portal.
Operations
Section titled Operations| Method | Path | Summary |
|---|---|---|
| GET | /api/v1/orgs/{org_slug}/portal/servers/{uuid}/import/current |
Get the current server import |
| POST | /api/v1/orgs/{org_slug}/portal/servers/{uuid}/import/start |
Start a server import |
| GET | /api/v1/orgs/{org_slug}/portal/servers/{uuid}/import/status/{import_id} |
Get the status of a server import |
| POST | /api/v1/orgs/{org_slug}/portal/servers/{uuid}/import/test-connection |
Test the connection to another host |
| DELETE | /api/v1/orgs/{org_slug}/portal/servers/{uuid}/import/{import_id} |
Stop a server import |
Get the current server import
Section titled Get the current server importGET /api/v1/orgs/{org_slug}/portal/servers/{uuid}/import/current
Find the import to show when a page opens.
Answers with the import that is pending, running or stopping on this server. When there is
none, it answers with the latest import that ended in the last 24 hours. import is null
when there is neither, so a page can tell that nothing has run lately.
Needs the file.read permission on the server. The server's owner holds every
permission, and a customer the owner shared the server with holds the ones the owner
granted. Without it the answer is 403 with Insufficient permissions.
Answers 404 when the server is not found.
Parameters
Section titled Parameters| Name | In | Type | Required | Description |
|---|---|---|---|---|
uuid |
path | string | yes | The server's UUID. |
org_slug |
path | string | yes |
Responses
Section titled Responses| Status | Meaning |
|---|---|
200 |
Success. |
403 |
The caller does not hold the permission this needs on the server. |
404 |
The server does not exist, or the caller cannot reach it. |
409 |
The server is being deleted. |
422 |
The request is not valid. detail lists each problem. |
Fields of a 200 response:
| Field | Type | Description |
|---|---|---|
import |
ImportStatusResponse or null | The running import, or the latest one that ended in the last 24 hours. Null when there is none. |
import.import_id |
string or null | The import's ID. Use it with the status and cancel routes. |
import.status |
string, one of pending, in_progress, cancelling, completed, failed, cancelled |
Where the import is. pending: waiting for a free place to start. in_progress: copying files. cancelling: a stop was asked for, and the import is finishing its current file. completed: the copy ended, and errors lists any files that could not be copied. failed: the import stopped before it finished, and the last entry of errors says why. cancelled: the import was stopped, and the files already copied stay on the server. The first three are active: the server has no other import until they end. |
import.files_transferred |
integer | How many files have been copied so far. |
import.total_files |
integer | How many files the import will copy. It is 0 until the other host's listing ends. |
import.bytes_transferred |
integer | How many bytes have been copied so far. |
import.total_bytes |
integer | How many bytes the import will copy. It is 0 until the other host's listing ends. |
import.current_file |
string or null | The file being copied now, or null when none is. |
import.errors |
array of ImportErrorItem | Files that could not be copied, and the reason the import failed when it did. The import fails once 200 files could not be copied. |
import.skipped |
array of ImportSkippedItem | Entries left out on purpose, up to 200. They do not count as errors, and the import still completes. |
import.cancel_requested |
boolean | Whether someone asked to stop this import. |
import.truncate |
boolean | Whether the import empties the server's main folder first. |
import.stopped_server |
boolean | Whether the import stopped a running server to copy the files. The server stays stopped afterwards, so start it when the import ends. |
Start a server import
Section titled Start a server importPOST /api/v1/orgs/{org_slug}/portal/servers/{uuid}/import/start
Copy the files of another host into this server.
Signs in to the host in the body once to check the details, queues the copy and answers with
the new import's status, which starts as pending. Read its progress from the status route
with the import_id it returns. A running server is stopped for the copy and stays stopped. A
file with the same path as one on the server replaces it, and files that exist only on the
server stay. With truncate set to true, the server's main folder is emptied first, except
for entries whose name starts with a dot or with backups. With skip_existing set to
true, a file already on the server with the same size is left alone, so an import that
stopped can run again without copying everything twice.
Over SFTP, send the fingerprint the connection test showed as host_key_fingerprint. Every
connection of the import must show that key, and a host that shows another one is refused with
400 before any password is sent. Without a fingerprint, the first key the start shows is saved
and used for the whole import.
Needs the file.create permission on the server, and the file.delete permission as
well when truncate is true. confirm_server_name must then name the server, in any
capitals. A server whose install never finished needs no name. The server's owner holds
every permission, and a customer the owner shared the server with holds the ones the owner
granted. Without them the answer is 403 with Insufficient permissions.
Answers 400 when a detail is not valid, the host is refused or does not accept the sign-in,
the server is suspended, installing or moving to another machine, or the name is missing or
wrong. The name is checked before the rate limit, so a refused request does not use up the
budget. Answers 404 when the server is not found, 409 while another import is pending, running
or stopping on this server, and 429 above 12 test and start requests in 5 minutes for the
account and server. Test and start share that limit. A 409 with the message Please try again in a moment. means the database stayed busy through every retry and no import was
created, so send the request again.
Parameters
Section titled Parameters| Name | In | Type | Required | Description |
|---|---|---|---|---|
uuid |
path | string | yes | The server's UUID. |
org_slug |
path | string | yes |
Request body
Section titled Request bodyapplication/json (required)
| Field | Type | Required | Description |
|---|---|---|---|
type |
string, one of sftp, ftp |
yes | How to connect to the other host: sftp or ftp. Capital letters and spaces around the word are accepted. FTPS is not supported, so ftps is refused with 422. |
remote_host |
string | yes | The other host's name or address, up to 255 characters. A prefix such as sftp:// and anything after the address, such as a path, is dropped. A port typed after the address, as in files.example.com:2022, is used when remote_port is empty. An address that starts with ftps:// or ftpes:// is refused with 400. A private or local address is refused with 400 too, and so is any host of this platform, except on port 2022, the SFTP port of a server. |
remote_port |
integer or null | no | The port to connect to, from 1 to 65535. When empty, the port typed after remote_host is used, and without one the usual port: 22 for sftp and 21 for ftp. A value outside the range is refused with 400. |
username |
string | yes | The user name for the other host, up to 255 characters. Required. |
password |
string | yes | The password for the other host, up to 4096 characters. Required. We keep it encrypted while the import runs, then delete it when the import ends. It never appears in a response. |
base_path |
string | no | The folder on the other host whose contents land in this server's main folder, up to 1024 characters. The default / copies everything the account can see. With /minecraft, the file /minecraft/world/level.dat lands at /world/level.dat. An address such as sftp://user@host:2022/minecraft is read as the folder after the host, here /minecraft, and / when nothing follows it. A path that contains .. is refused with 400. A folder the other host has not got, or will not list, fails the import at once. |
truncate |
boolean | no | Set to true to empty this server's main folder before copying. The default is false. Entries whose name starts with a dot and entries whose name starts with backups stay, and so does the executable a free server keeps. A wipe cannot be undone. It needs the file.delete permission as well as file.create, and confirm_server_name. Ignored by the connection test. |
host_key_fingerprint |
string or null | no | The fingerprint of the other host's key, as the connection test showed it: SHA256: followed by 43 base64 characters. Every connection of the import must show this key, so someone between us and the other host cannot read the password. Ignored for ftp, which has no host key. When empty, the first key the start shows is saved and used for the whole import. Any other text is refused with 400. |
skip_existing |
boolean | no | Set to true to leave out a file that is already on this server with the same size, so an import that stopped can run again without copying everything twice. The default is false. Ignored when truncate is true, because the wipe leaves nothing to compare. Ignored by the connection test. |
confirm_server_name |
string or null | no | The server's name, in any capitals. Required when truncate is true, and a missing or wrong name is refused with 400 before the rate limit counts the request. A server whose install never finished needs no name. Ignored when truncate is false, and by the connection test. |
Responses
Section titled Responses| Status | Meaning |
|---|---|
200 |
Success. |
400 |
The details are not valid, the host is refused or does not accept the sign-in, the server is suspended, installing or moving to another machine, or truncate is set without the server's name in confirm_server_name. |
403 |
The caller does not hold the permission this needs on the server. |
404 |
The server does not exist, or the caller cannot reach it. |
409 |
An import is already running on this server, and the body names it in import_id and status. Or the server is being deleted. Or the database stayed busy through every retry, and message says Please try again in a moment. Send the request again. |
429 |
More than 12 test and start requests in 5 minutes for this account and server. The Retry-After header says how many seconds to wait. |
422 |
The request is not valid. detail lists each problem. |
Fields of a 200 response:
| Field | Type | Description |
|---|---|---|
import_id |
string or null | The import's ID. Use it with the status and cancel routes. |
status |
string, one of pending, in_progress, cancelling, completed, failed, cancelled |
Where the import is. pending: waiting for a free place to start. in_progress: copying files. cancelling: a stop was asked for, and the import is finishing its current file. completed: the copy ended, and errors lists any files that could not be copied. failed: the import stopped before it finished, and the last entry of errors says why. cancelled: the import was stopped, and the files already copied stay on the server. The first three are active: the server has no other import until they end. |
files_transferred |
integer | How many files have been copied so far. |
total_files |
integer | How many files the import will copy. It is 0 until the other host's listing ends. |
bytes_transferred |
integer | How many bytes have been copied so far. |
total_bytes |
integer | How many bytes the import will copy. It is 0 until the other host's listing ends. |
current_file |
string or null | The file being copied now, or null when none is. |
errors |
array of ImportErrorItem | Files that could not be copied, and the reason the import failed when it did. The import fails once 200 files could not be copied. |
errors[].file |
string | The path of the file, as it is on the other host. Empty when the entry is the reason the whole import stopped. |
errors[].error |
string | What went wrong, in a sentence. |
skipped |
array of ImportSkippedItem | Entries left out on purpose, up to 200. They do not count as errors, and the import still completes. |
skipped[].file |
string | The path of the entry, as it is on the other host. |
skipped[].reason |
string | Why the entry was left out, for example a symbolic link, a device, a socket or a pipe, or the executable a free server keeps. |
cancel_requested |
boolean | Whether someone asked to stop this import. |
truncate |
boolean | Whether the import empties the server's main folder first. |
stopped_server |
boolean | Whether the import stopped a running server to copy the files. The server stays stopped afterwards, so start it when the import ends. |
Get the status of a server import
Section titled Get the status of a server importGET /api/v1/orgs/{org_slug}/portal/servers/{uuid}/import/status/{import_id}
Read the progress of one import on this server.
Anyone who may read files on the server can poll any import on it, whoever started it. The
import's status says where it is, the counters say how much is copied, errors lists the
files that could not be copied and skipped the entries left out on purpose.
Needs the file.read permission on the server. The server's owner holds every
permission, and a customer the owner shared the server with holds the ones the owner
granted. Without it the answer is 403 with Insufficient permissions.
Answers 404 when the server is not found, or when the ID is not an import of this server.
Parameters
Section titled Parameters| Name | In | Type | Required | Description |
|---|---|---|---|---|
uuid |
path | string | yes | The server's UUID. |
import_id |
path | string | yes | The import's ID, as the start request returned it. |
org_slug |
path | string | yes |
Responses
Section titled Responses| Status | Meaning |
|---|---|
200 |
Success. |
403 |
The caller does not hold the permission this needs on the server. |
404 |
The server does not exist, the caller cannot reach it, or the ID is not an import of this server. |
409 |
The server is being deleted. Or the database stayed busy through every retry, and message says Please try again in a moment. Nothing changed, so send the request again. |
422 |
The request is not valid. detail lists each problem. |
Fields of a 200 response:
| Field | Type | Description |
|---|---|---|
import_id |
string or null | The import's ID. Use it with the status and cancel routes. |
status |
string, one of pending, in_progress, cancelling, completed, failed, cancelled |
Where the import is. pending: waiting for a free place to start. in_progress: copying files. cancelling: a stop was asked for, and the import is finishing its current file. completed: the copy ended, and errors lists any files that could not be copied. failed: the import stopped before it finished, and the last entry of errors says why. cancelled: the import was stopped, and the files already copied stay on the server. The first three are active: the server has no other import until they end. |
files_transferred |
integer | How many files have been copied so far. |
total_files |
integer | How many files the import will copy. It is 0 until the other host's listing ends. |
bytes_transferred |
integer | How many bytes have been copied so far. |
total_bytes |
integer | How many bytes the import will copy. It is 0 until the other host's listing ends. |
current_file |
string or null | The file being copied now, or null when none is. |
errors |
array of ImportErrorItem | Files that could not be copied, and the reason the import failed when it did. The import fails once 200 files could not be copied. |
errors[].file |
string | The path of the file, as it is on the other host. Empty when the entry is the reason the whole import stopped. |
errors[].error |
string | What went wrong, in a sentence. |
skipped |
array of ImportSkippedItem | Entries left out on purpose, up to 200. They do not count as errors, and the import still completes. |
skipped[].file |
string | The path of the entry, as it is on the other host. |
skipped[].reason |
string | Why the entry was left out, for example a symbolic link, a device, a socket or a pipe, or the executable a free server keeps. |
cancel_requested |
boolean | Whether someone asked to stop this import. |
truncate |
boolean | Whether the import empties the server's main folder first. |
stopped_server |
boolean | Whether the import stopped a running server to copy the files. The server stays stopped afterwards, so start it when the import ends. |
Test the connection to another host
Section titled Test the connection to another hostPOST /api/v1/orgs/{org_slug}/portal/servers/{uuid}/import/test-connection
Check that we can sign in to another host, and count what an import would copy.
Signs in to the host in the body over SFTP or FTP, lists the folder in base_path and
answers with the number of files and folders in it. Nothing is written on this server or on
the other host. A sign-in that fails, or a listing that takes longer than 60 seconds, answers
200 with success set to false and the reason in message. truncate and
confirm_server_name are ignored here. Over SFTP the answer also holds the key the host
showed in host_key, with its algorithm and its SHA256: fingerprint. Check it, then send
the fingerprint as host_key_fingerprint when you start the import.
Needs the file.read permission on the server. The server's owner holds every
permission, and a customer the owner shared the server with holds the ones the owner
granted. Without it the answer is 403 with Insufficient permissions.
Answers 400 when a detail is not valid or the host is refused, 404 when the server is not found, and 429 above 12 test and start requests in 5 minutes for the account and server. Test and start share that limit.
Parameters
Section titled Parameters| Name | In | Type | Required | Description |
|---|---|---|---|---|
uuid |
path | string | yes | The server's UUID. |
org_slug |
path | string | yes |
Request body
Section titled Request bodyapplication/json (required)
| Field | Type | Required | Description |
|---|---|---|---|
type |
string, one of sftp, ftp |
yes | How to connect to the other host: sftp or ftp. Capital letters and spaces around the word are accepted. FTPS is not supported, so ftps is refused with 422. |
remote_host |
string | yes | The other host's name or address, up to 255 characters. A prefix such as sftp:// and anything after the address, such as a path, is dropped. A port typed after the address, as in files.example.com:2022, is used when remote_port is empty. An address that starts with ftps:// or ftpes:// is refused with 400. A private or local address is refused with 400 too, and so is any host of this platform, except on port 2022, the SFTP port of a server. |
remote_port |
integer or null | no | The port to connect to, from 1 to 65535. When empty, the port typed after remote_host is used, and without one the usual port: 22 for sftp and 21 for ftp. A value outside the range is refused with 400. |
username |
string | yes | The user name for the other host, up to 255 characters. Required. |
password |
string | yes | The password for the other host, up to 4096 characters. Required. We keep it encrypted while the import runs, then delete it when the import ends. It never appears in a response. |
base_path |
string | no | The folder on the other host whose contents land in this server's main folder, up to 1024 characters. The default / copies everything the account can see. With /minecraft, the file /minecraft/world/level.dat lands at /world/level.dat. An address such as sftp://user@host:2022/minecraft is read as the folder after the host, here /minecraft, and / when nothing follows it. A path that contains .. is refused with 400. A folder the other host has not got, or will not list, fails the import at once. |
truncate |
boolean | no | Set to true to empty this server's main folder before copying. The default is false. Entries whose name starts with a dot and entries whose name starts with backups stay, and so does the executable a free server keeps. A wipe cannot be undone. It needs the file.delete permission as well as file.create, and confirm_server_name. Ignored by the connection test. |
host_key_fingerprint |
string or null | no | The fingerprint of the other host's key, as the connection test showed it: SHA256: followed by 43 base64 characters. Every connection of the import must show this key, so someone between us and the other host cannot read the password. Ignored for ftp, which has no host key. When empty, the first key the start shows is saved and used for the whole import. Any other text is refused with 400. |
skip_existing |
boolean | no | Set to true to leave out a file that is already on this server with the same size, so an import that stopped can run again without copying everything twice. The default is false. Ignored when truncate is true, because the wipe leaves nothing to compare. Ignored by the connection test. |
confirm_server_name |
string or null | no | The server's name, in any capitals. Required when truncate is true, and a missing or wrong name is refused with 400 before the rate limit counts the request. A server whose install never finished needs no name. Ignored when truncate is false, and by the connection test. |
Responses
Section titled Responses| Status | Meaning |
|---|---|
200 |
Success. |
400 |
The details are not valid, the host does not resolve, or the host is private, local or one of this platform's own hosts on a port other than 2022. |
403 |
The caller does not hold the permission this needs on the server. |
404 |
The server does not exist, or the caller cannot reach it. |
409 |
The server is being deleted. |
429 |
More than 12 test and start requests in 5 minutes for this account and server. The Retry-After header says how many seconds to wait. |
422 |
The request is not valid. detail lists each problem. |
Fields of a 200 response:
| Field | Type | Description |
|---|---|---|
success |
boolean | Whether we signed in and listed the folder. |
files |
integer | How many files the folder holds. 0 when success is false. |
directories |
integer | How many folders the folder holds. 0 when success is false. |
message |
string or null | Why the test failed. Not in the response when success is true. |
host_key |
ImportHostKey or null | The key the other host showed. Only for sftp when success is true. Check that it is the key you expect, then send its fingerprint as host_key_fingerprint when you start the import. |
host_key.algorithm |
string | The key type, for example ssh-ed25519 or ssh-rsa. |
host_key.fingerprint |
string | The key's fingerprint: SHA256: followed by 43 base64 characters. Send it as host_key_fingerprint when you start the import. |
Stop a server import
Section titled Stop a server importDELETE /api/v1/orgs/{org_slug}/portal/servers/{uuid}/import/{import_id}
Stop an import that is pending, running or already stopping.
Anyone who may create files on the server can stop any import on it, whoever started it. A
pending import is cancelled at once. A running one moves to cancelling and halts after the
file it is copying, and a file that was half copied is deleted. Files the import already
copied stay on the server. The answer is the import's status. An import that has already
ended is returned as it is, with no change.
Needs the file.create permission on the server. The server's owner holds every
permission, and a customer the owner shared the server with holds the ones the owner
granted. Without it the answer is 403 with Insufficient permissions.
Answers 404 when the server is not found, or when the ID is not an import of this server.
Answers 409 with the message Please try again in a moment. when the database stayed busy
through every retry. The stop was not applied, so send it again.
Parameters
Section titled Parameters| Name | In | Type | Required | Description |
|---|---|---|---|---|
uuid |
path | string | yes | The server's UUID. |
import_id |
path | string | yes | The import's ID, as the start request returned it. |
org_slug |
path | string | yes |
Responses
Section titled Responses| Status | Meaning |
|---|---|
200 |
Success. |
403 |
The caller does not hold the permission this needs on the server. |
404 |
The server does not exist, the caller cannot reach it, or the ID is not an import of this server. |
409 |
The server is being deleted. Or the database stayed busy through every retry, and message says Please try again in a moment. Nothing changed, so send the request again. |
422 |
The request is not valid. detail lists each problem. |
Fields of a 200 response:
| Field | Type | Description |
|---|---|---|
import_id |
string or null | The import's ID. Use it with the status and cancel routes. |
status |
string, one of pending, in_progress, cancelling, completed, failed, cancelled |
Where the import is. pending: waiting for a free place to start. in_progress: copying files. cancelling: a stop was asked for, and the import is finishing its current file. completed: the copy ended, and errors lists any files that could not be copied. failed: the import stopped before it finished, and the last entry of errors says why. cancelled: the import was stopped, and the files already copied stay on the server. The first three are active: the server has no other import until they end. |
files_transferred |
integer | How many files have been copied so far. |
total_files |
integer | How many files the import will copy. It is 0 until the other host's listing ends. |
bytes_transferred |
integer | How many bytes have been copied so far. |
total_bytes |
integer | How many bytes the import will copy. It is 0 until the other host's listing ends. |
current_file |
string or null | The file being copied now, or null when none is. |
errors |
array of ImportErrorItem | Files that could not be copied, and the reason the import failed when it did. The import fails once 200 files could not be copied. |
errors[].file |
string | The path of the file, as it is on the other host. Empty when the entry is the reason the whole import stopped. |
errors[].error |
string | What went wrong, in a sentence. |
skipped |
array of ImportSkippedItem | Entries left out on purpose, up to 200. They do not count as errors, and the import still completes. |
skipped[].file |
string | The path of the entry, as it is on the other host. |
skipped[].reason |
string | Why the entry was left out, for example a symbolic link, a device, a socket or a pipe, or the executable a free server keeps. |
cancel_requested |
boolean | Whether someone asked to stop this import. |
truncate |
boolean | Whether the import empties the server's main folder first. |
stopped_server |
boolean | Whether the import stopped a running server to copy the files. The server stays stopped afterwards, so start it when the import ends. |