/developers
Developer docsAtom Files ↗
← API referenceWrite & track · API access unavailable
API REFERENCE / UPLOADS

POST /v1/uploads

Create an upload intent for a folder. Requires a future folder-scoped write credential. Returns an operation and a destination-specific transfer plan; it does not mean file bytes have been committed.

Request fields

LocationFieldTypeRequiredDescription
HeaderAuthorizationstringYesCredential scoped to the authorized resource.
HeaderContent-Typestring (media type)Yesapplication/json.
HeaderIdempotency-KeystringYesStable retry identity for this upload intent.
Bodyparent_idstringYesDestination folder.
BodynamestringYesNew file name.
Bodysize_bytesinteger (bytes)YesExpected byte size.
Bodysha256stringYesWhole-file digest.
Bodyreplace_version_idstring | nullNoExpected current version when replacing.

Request example

Example request
POST /v1/uploads
Authorization: Bearer <scoped token>
Idempotency-Key: invoice-8427
Content-Type: application/json

{
  "parent_id": "folder_123",
  "name": "invoice.pdf",
  "size_bytes": 4194304,
  "sha256": "<whole-file digest>",
  "replace_version_id": null
}

HTTP status codes

StatusMeaning
202 AcceptedSuccess response shown below.
400 Bad RequestInvalid upload intent or file metadata.
401 UnauthorizedMissing, expired, or invalid credential.
403 ForbiddenCredential is valid but lacks the required scope or role.
409 ConflictIdempotency key reused with different input, or expected version changed.
429 Too Many RequestsRate limit reached; honor Retry-After when provided.
503 Service UnavailableService temporarily unavailable; retry safely.

Response fields

FieldTypeExample
operation_idstringop_456
file_idstringfile_789
statusstringready_to_transfer
transferobject{…}
transfer.methodstringdirect
transfer.capabilitystring<short-lived, destination-scoped capability>

Response example

Example response
202 Accepted
Content-Type: application/json

{
  "operation_id": "op_456",
  "file_id": "file_789",
  "status": "ready_to_transfer",
  "transfer": {
    "method": "direct",
    "capability": "<short-lived, destination-scoped capability>"
  }
}

How it works

An app declares the destination, size, content hash, and retry identity. Atom decides whether the bytes can go directly to the destination or need an explicitly permitted staging route.

The transfer plan would be short-lived and destination-scoped. A client would refresh an expired plan using the same operation ID; it must not create another file to resume. A future SDK could hide transport details.

Mac offline?

A local-only folder returns waiting_for_device. The sender retains the bytes. Temporary cloud staging is a separate, owner-approved folder policy—not a silent fallback.