Skip to main content
POST
Copy through the Byteport Transfer API. The source is left untouched; the destination receives a new copy. The request is accepted asynchronously — a 202 means accepted, not done — and comes in two flavors:
  • Single objectfrom and to each name one object. The response is {id, status: "queued"}; poll GET /v1/transfers/{id} (statuses queued, running, complete, failed).
  • Bulk job — both paths end in / (a prefix copy), or a manifest lists the keys to copy. The response is {job_id, status: "planning"}; poll GET /v1/jobs/{id} for status and per-object counts (statuses planning, running, complete, partial, failed, canceled). Failed objects are listed under GET /v1/jobs/{id}/failures and can be re-planned with POST /v1/jobs/{id}/retry; POST /v1/jobs/{id}/cancel stops the job.

Targets

Each side addresses a location the same way as List Objects — by name or id (a non-unique name returns 409 with the candidates) — plus a path within it. Two equivalent shapes are accepted:
The compact string splits on the first :; a UUID before the colon addresses by id, anything else by name. Arrays are not accepted — to copy many objects, use a prefix or manifest bulk copy.

Paths are exact bytes

Paths are stored and executed verbatim, never normalized — providers treat object keys as exact bytes, so a “cleaned up” path would name a different object. A single-object path must be bucket/object-key: no leading or trailing /, no :, no .. segment, and it may not start with -. A bulk prefix is bucket/ or bucket/dir/.../ — always slash-terminated, on both sides. Copying an object or prefix onto itself is rejected.
Both locations must be active to accept a copy; a location whose single-use access token is expired (or about to) returns 409 — refresh it via POST /v1/locations/refresh and retry. Copy accepts are limited to 30 per account per minute; the body is capped at 8 MiB (sized for manifests of up to 100,000 keys).

Examples

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Body

application/json
from
required

Source target: location (name or id) plus path. A trailing / on the path makes this a bulk prefix copy (then to must be a prefix as well).

Example:

"prod-backups:archives/2026-04-21/data.bin"

to
required

Destination target: location (name or id) plus path.

Example:

"prod-backups:archives/2026-04-21/data.bin"

manifest
string[]

Bulk only: an explicit list of object keys to copy, each relative to the from prefix (both paths must be slash-terminated prefixes). At most 100,000 keys; each key at most 4096 bytes, with no leading or trailing / and no ... The whole body is capped at 8 MiB.

Maximum array length: 100000
Example:
overwrite
enum<string>
default:always

Bulk only (a 400 on single-object copies): always replaces existing destination objects; if-missing skips objects that already exist at the destination.

Available options:
always,
if-missing

Response

Copy accepted. Single-object copies return a transfer ({id, status: "queued"} — poll GET /v1/transfers/{id}); bulk copies return a job ({job_id, status: "planning"} — poll GET /v1/jobs/{id}).

A single-object copy was accepted. Poll GET /v1/transfers/{id} for progress.

id
string

The transfer's UUID.

Example:

"7c1f4b0e-9a2d-4d1c-8b3f-2e6a5d90c417"

status
enum<string>

Always queued on accept. Later polls report queued, running, complete, or failed.

Available options:
queued
Example:

"queued"