8 October 2026. Administrative API for eEKAS-to-eEKAS sync, other S3 destinations, backup/recovery, customers, billing and logging. Requests require an API key; mutating object-storage requests require admin or s3-admin. These endpoints are not a customer self-service portal.
Use HTTPS and the X-API-Key header. Send credentials, passphrases, invitation bundles and encoded credentials in an application/json body. Base64 values are not encrypted. URL secrets are rejected. Use an Idempotency-Key to replay identical mutating requests safely. A 202 response contains an API job ID and status URL; poll GET /api/v1/jobs?job_id=... until complete or failed. Cancellation uses DELETE /api/v1/jobs?job_id=....
An API job ID differs from a restore-worker job ID. Setup and recovery-bundle export/import run as API jobs. Restore previews return a restore-worker job ID; use backup status and backup control for that job. Configuration apply queues an API job which submits configuration recovery to the restore worker; then monitor backup status.
GET /api/v1/object-storage/replication lists relationships. Add relationship_id for status. Views are invitations, audit, buckets, backfill and destinations. Bucket metrics accept marker, query and limit (1–50); follow the backend continuation marker rather than loading every bucket into a browser. The destinations view discovers local service instances.
POST /api/v1/object-storage/replication accepts the following actions and their OpenAPI parameters: enable; pause/resume; set_mode; set_policy; set_advanced_policy; refresh_topology; promote; dr_test; recover_gateway; remove_site; decommission_local; credential rotation/adoption/activation/finalization; backfill start/pause/resume/cancel; recovery_validate; compliance_report; orchestrate_recovery; run_archive; revoke_invitation; purge_invitations. Selected native buckets and backfill buckets accept JSON arrays or semicolon-separated strings. Existing fencing, conflict acknowledgements and deletion confirmations are enforced by the backend.
{"action":"set_policy","relationship_id":"RELATIONSHIP_ID","bucket_scope":"all","rpo_seconds":300,"allow_untrusted":false}Invitation endpoints are /replication/invitations and /replication/invitations/redeem. Joining uses POST /replication/join; validate_only:true performs preflight. Supply a public ca_pem certificate, a server-local ca_file, or an explicitly chosen allow_untrusted exception. Uploaded certificates are validated and held in private temporary files until the request finishes. Invitation and passphrase values preserve commas and Unicode.
A scheduled external mirror is configured by set_advanced_policy using config_b64 and started by run_archive. This workflow follows the mirror/deletion policy. A generation-preserving backup has its own catalogue, checkpoints and recovery bundle; use the backup endpoints below when independent disaster recovery is required. Direct mode reads completed object generations from the source. History mode uses an intermediate archive zone to retain generations. Direct mode cannot retrieve a generation overwritten or deleted before capture.
All backup operations are exposed at /api/v1/object-storage/replication/backups. POST bodies contain action and a structured request. The worker retains the same validation and protection rules as the GUI. Successful synchronous responses contain status and data.
| Action | Request / behaviour |
|---|---|
| backup_discover | {}; discovers local realms, zones and worker hosts. |
| backup_bucket_search | realm, source_zone, query, cursor, limit. Maximum 100 results per page; follow next_cursor. An index may initially report building. |
| backup_list | {}; returns saved configurations with credentials removed. |
| backup_save | id; new configurations also require mode, realm, zonegroup, source_zone, host, source_endpoint, endpoint, bucket and destination access_key/secret_key. Whole-zone scope uses bucket_scope=zone and includes future buckets. Individual scope uses bucket_scope=selected and a buckets array. History mode additionally needs archive_zone, archive_endpoint, gateway_certificate and gateway_private_key. Editing retains omitted settings and secrets; changing storage identity requires a new ID. |
| backup_setup | id. Queued API job; applies settings on the selected worker host and starts the worker. |
| backup_status | id. Includes worker activity, progress, scans, jobs, checkpoint, event queue and protection-check state. |
| backup_checkpoints | id and optional continuation_token. Returns bounded items, display_name (UTC date plus original ID in brackets), and another continuation_token when present. |
| backup_preview | id, checkpoint, target_endpoint, target_access_key/target_secret_key. Optional source_bucket, object_key, prefix or object_id narrows selection. target_prefix defaults to recovery-. target_bucket requires a source_bucket. Returns a worker job_id; wait for preview_ready and review the preview. |
| backup_control | id and control. Without job_id: pause/resume backup. With job_id: start/pause/resume/cancel recovery. Starting recovery requires confirm=job_id after review. |
| backup_bundle_export | id, bundle_password (at least 16 characters). Queued API job. Download the encrypted result from /replication/backups/bundle?job_id=API_JOB_ID after completion. |
| backup_bundle_import | id, bundle_b64, bundle_password. Queued API job. Use an unused archive ID on a replacement node; imports a recovery-only configuration. |
| backup_configuration_preview | id, job_id. Reviews owner and bucket configuration recovery from the imported bundle. |
| backup_configuration_apply | id, job_id, confirm=job_id, target_realm, target_zone. Queued API job; monitor the restore worker for configuration_complete. |
Optional backup settings include concurrency (1–8), interval (10–3600 seconds), catalog_interval (minimum 60 seconds, default 3600), staging_limit, recall_timeout, scale_enabled, protection_concurrency and lock_check_interval. source_ca_pem supplies the source CA; destination_ca_pem supplies a private destination CA without disabling certificate verification. target_ca_pem supplies a recovery-destination CA. Passphrases and all private keys stay in JSON bodies.
{
"action": "backup_save",
"request": {
"id": "offsite-backup", "mode": "direct",
"realm": "REALM", "zonegroup": "ZONEGROUP", "source_zone": "SOURCE_ZONE",
"host": "WORKER_HOST", "source_endpoint": "https://source.example:8443",
"endpoint": "https://backup.example", "bucket": "archive-target",
"access_key": "DESTINATION_ACCESS_KEY", "secret_key": "DESTINATION_SECRET_KEY",
"bucket_scope": "zone", "catalog_interval": 3600, "scale_enabled": true
}
}
The worker host is the server running transfer, catalogue and recovery jobs. Send configuration/start requests to that host. The backups route accepts a bounded 24 MiB JSON body, enough for the worker's 16 MiB encrypted recovery-bundle limit after base64 encoding. Ordinary routes retain the configured body limit, normally 1 MiB. Bundle export uses background work and a separate download endpoint, so job output truncation cannot corrupt the downloaded bundle.
WORM sources remain protected. A WORM or unclassified backup cannot overwrite an existing recovery bucket; verified protection metadata is required and protected content uses new recovery buckets. Recovery retains active retention and legal holds according to backend checks. Configuration recovery needs a separate reviewed confirmation, and automatic lifecycle expiration stays disabled. External target tape completion remains unknown to eEKAS.
/api/v1/object-storage/customers supports GET/POST/PATCH/DELETE for customer metadata, quota and storage/upload/download prices. POST /customers/usage samples storage and collects traffic. Schedule storage sampling separately; the five-minute traffic collector does not sample storage peaks. Inspect error_count, errors and traffic_error even when HTTP status is 200.
POST /customers/adopt registers an existing replicated or recovered user/bucket without recreating data, keys or quotas. Supply customer_id, customer_name, quota_gb, site, bucket and uid; the existing bucket owner must match uid. Use primary metadata including prices, generation_id and created_at when appropriate. quota_gb records the existing agreed quota; adoption does not enforce or change it. PATCH can explicitly change quota later. Adopted registrations default to registration-only deletion when purge_data is omitted; explicit purge_data=true remains destructive. Existing customer creation retains its existing deletion behaviour.
GET /billing, /billing/users and /billing/export accept inclusive UTC period_start/period_end, with customer_id or uid filters where supported. GB means GiB (1073741824 bytes). A selected range has one sampled storage peak and minimum charge. Reports use current prices/status; keep approved exports because this is not an immutable issued-invoice ledger. suspended remains billable and does not revoke S3 access.
GET /billing/federation reads the explicit billing configuration. POST /billing/federation configures HTTPS peers and ownership groups using a body-only request object. Each group maps a single logical realm/user/bucket across distinct accounting zones and identifies one pricing owner. Use customer adoption on replicas first. Peer API keys are stored privately and removed from responses. Omitting a key preserves it only for an unchanged peer ID and origin. TLS verification is mandatory; supply ca_pem for private CAs. Redirects are rejected.
{"request":{
"peers":[{"id":"site-b","url":"https://site-b.example:18443","api_key":"PEER_API_KEY","ca_pem":"PUBLIC_CA_PEM"}],
"groups":[{"id":"customer-a","owner":{"peer":"local","customer_id":"customer-a"},
"members":[{"peer":"local","customer_id":"customer-a"},{"peer":"site-b","customer_id":"customer-a"}]}]
}}POST /billing/federation/report takes {"request":{"period_start":"2026-09-01","period_end":"2026-09-30"}}. It charges the maximum logical storage peak once, adds traffic from distinct zones, and uses the pricing owner's tariffs/status. Totals remain separated by currency. Missing counters produce null amounts, provisional/incomplete coverage remains visible, and unavailable peers or duplicate accounting zone IDs fail the report. Reaching a peer does not make its recent traffic final.
Consolidation is opt-in. Customer registries, tariff changes and historical ledgers are not silently copied by object replication. Retain customer exports and approved reports off the primary installation. Changing billing ownership after a disaster requires review; recovery of object content does not reconstruct a lost billing ledger. There is no automatic accounting failover or automatic invoice finalization.
GET /traffic reads tracking status; POST /traffic enables a selected site; POST /traffic/collect collects counters. Enabling tracking may restart gateways. Accounting begins at a full UTC-hour boundary; recently flushed hours remain provisional. Amounts measure gateway S3 bytes, not all network/WAN bytes. Managed archive source reads use dedicated system accounts and are excluded from gateway customer usage logs. Caller-supplied source credentials must be system credentials; customer keys are rejected to prevent internal archive reads being charged to customers. Native synchronization already uses system requests.
External destination uploads and recovery requests are accounted by their destination. If an eEKAS destination bucket is registered for billing and ordinary customer credentials write or restore into it, those destination transfers can be billable. Source-read exclusion does not disable destination accounting.
| Endpoint | Operation |
|---|---|
| GET /access-logs | Logging level, retention and service state; optional site for applicable providers. |
| POST /access-logs | level=off/standard/detailed; retention_days; optional site. Uses the GUI backend and can restart gateways. Provider-specific restrictions apply. |
| GET /access-logs/export | days=0/1/7/30/90/365 (default 7); optional site. Returns JSON log contents with filename and MIME type. |
| POST /access-logs/clear | confirm=clear-access-logs; optional site. Existing traffic-billing protections prevent erasing required accounting logs. |
| GET /usage | Legacy raw usage view with uid, start, end and show_entries; use traffic/billing APIs for coverage-aware accounting. |
Endpoint prefixes above are /api/v1/object-storage. OpenAPI JSON/YAML and the generated Python SDK include the new routes and replication parameters.