Skip to main content
This page describes how teams usually build against the API. It focuses on decisions that affect reliability, not on product features.

Separate human actions from automated actions

Everabyte deliberately splits responsibilities: Do not design around an API-key route for key creation or bucket creation. Those routes are session-only and are rejected for API keys.

Use one key per integration

Create a distinct key for each deployed service, and at least one for local development. A useful naming scheme is:
This makes revocation precise. If a key leaks, you revoke one integration instead of rotating every credential in the company.

Choose scopes before writing code

Start from the operations you actually need: Bucket scopes are the ceiling. A key with files:write but only buckets:read cannot perform writes. See Scopes and permissions.

Build for these realities

The server validates quota, plan limits, folder ownership, and encryption-key state while the multipart body is streaming. A rejection can arrive mid-upload. Your client must handle a non-2xx response even after it has sent bytes, and must not assume a file exists until it has a fileId.
trash=soft moves a file to trash and keeps it restorable during the display window. trash=hard permanently deletes it. Retention and legal hold can block either mode. Model deletion as a state transition, not an immediate cleanup.
An active retention policy makes a file immutable until it expires. Bucket-level retention can also block per-file changes and deletion. Read the retention state before offering destructive actions in your UI.
The default limit is 600 requests per minute per key. The limiter is per key, not per endpoint. Batch work should be paced, and retries should use exponential backoff with jitter.
This reference documents one production base URL. If you need isolated testing, use a separate company workspace and separate keys rather than assuming a sandbox domain exists.

Handle responses consistently

Success and error envelopes are not identical:
Controller-level errors may use error instead of code:
Write one decoder that:
  1. Checks response.ok.
  2. Parses JSON only when the content type is JSON.
  3. Reads code when present.
  4. Falls back to message for display, never for branching.
  5. Treats an unknown 5xx body as opaque.
See Error handling.

Treat downloads as streams

Files can be large. Do not buffer a download into memory just to save it. Stream to disk, a pipe, or your own object storage. Pass through Range when you need partial reads, and preserve the server’s Content-Range and 206 status when you proxy the response.

Observe your integration

At minimum, log:
  • the HTTP method and route template, not the full URL with identifiers,
  • the response status,
  • the stable code when present,
  • your own request ID,
  • latency and bytes transferred.
Never log X-Secret-Key, full X-Public-Key values, file contents, or signed download URLs.

Ship checklist

Secrets live in a secret manager, not in source control.
Each service has its own key with the narrowest scopes and bucket scope.
Uploads handle mid-stream rejection and quota exhaustion.
Deletes distinguish soft and hard behavior, and respect retention.
Downloads stream and support resumption or range where needed.
Retries use backoff and are idempotent at the application level.
Error handling branches on HTTP status and stable code, not message text.