Skip to main content

Hosting Providers – Customers, Services and Billing

The hosting API helps providers offer managed S3 storage with customer and reseller access, versioned plans, service operations and monthly usage statements. This guide describes the 23 October 2026 edition. Confirm that the installed eEKAS release supports these operations and that hosting, metering and monitoring have been activated before onboarding customers. API usage is at your own responsibility and is not covered by support.

Choose the appropriate workflow

Use /api/v1/object-storage/ for administrator-managed S3 users, buckets and existing customer billing reports. Use /api/v1/hosting/ for plan-based subscriptions and scoped customer/reseller automation. Hosting creates dedicated users and buckets per service; existing S3 users, buckets and billing registrations are not automatically adopted. The S3 Browser provides object access and branding; a subscription or billing portal requires a separate integration.

Accounts and permissions

Send X-API-Key over the configured HTTPS API, normally port 18443. GUI login accounts, management API credentials, hosting customer records and S3 access keys serve different purposes. Creating an account does not automatically issue an API token or grant administrator permissions.

Identity Use
Provider staff: admin or s3-admin Manage locations, plans, resellers and services. Inspect provider-wide status, monitoring and backup metadata.
Hosting reseller Create customers and manage services within assigned plans and allocation limits.
Hosting customer Read owned services, usage, operations, statements and events; retrieve active-service credentials and manage own tokens/webhooks.

Hosting customer/reseller tokens cannot access global administrative endpoints or global jobs. Provider-wide status, monitoring and backup reads also exclude read-only staff keys. Use GET /api/v1/hosting/me to inspect the authenticated identity.

POST /tokens selects exactly one customer_id or reseller_id, with a label and optional expires_days (1–366; default 90). Save the returned token securely: it is shown once. Up to 20 active tokens are allowed per identity. Revoke an unused token with DELETE /tokens and a JSON token_id.

Prepare plans and customers

Paths below are relative to /api/v1/hosting. Send mutations as JSON objects with Content-Type: application/json. List endpoints support limit (1–200) and cursor.

  1. Register an existing S3 location with POST /locations: id, name, site and capacity_gib. A location does not create a new S3 site. Its site cannot later be changed.
  2. Publish a plan with POST /plans: id, name, quota_gib, allowed locations and currency. Configure object limits, retention, versioning/WORM, rate limits and prices as needed. Publishing the same plan ID creates a new immutable version.
  3. Optionally create a reseller with id, name, quota_gib and allowed_plans. Create the customer with id, name and optional email, external_id and reseller_id.
  4. Verify storage sampling and S3 traffic collection before the billable period begins. Enabling collection later does not reconstruct missing history.

Location and reseller limits reserve logical GiB allocations. Failed and cancelled services continue to reserve their quota until purged. These allocations do not guarantee physical Ceph capacity. Rate limits apply per minute per RGW daemon; they are not a strict cluster-wide bandwidth cap.

Provision and hand over a service

Send POST /services with a unique Idempotency-Key (8–200 allowed characters) and a body such as:

{"customer_id":"customer01","plan_id":"standard","plan_version":1,"external_id":"subscription-123","location_id":"eu-central"}

Repeat the same request with the same key after a connection failure. Conflicting plan or location references return 409. HTTP 202 means accepted: poll the returned status_url until state=complete or state=failed. Hosting operations use /hosting/operations, not the global jobs endpoint. Only hand over access after verified completion.

For an active owned service, POST /credentials with service_id explicitly retrieves S3 credentials. Deliver them securely and use the separate S3 endpoint for object access. rotate=true adds a second key and leaves the old key active. At most two keys are allowed; a provider administrator must revoke an unused key through S3 administration. Verify bucket access and quotas before handover.

Manage the service lifecycle

POST /services/actions requires service_id, action and an Idempotency-Key; expected_revision can protect against concurrent changes. Only one queued/running operation is allowed per service.

Action Result
suspend / resume Disable or enable S3 access. Suspension continues base and storage billing.
change-plan Supply plan_id and optionally plan_version. Quota must accommodate stored data and the current location must remain allowed. Currency and protection constraints remain enforced. Technical limits change after verification; the new tariff starts next UTC calendar month.
cancel Suspend access and end future billable time. Retain data and quota allocation for the plan retention period.
purge After cancellation retention, require confirm="purge:<service_id>". Only empty owned buckets/users are removed. Protected or nonempty content is not force-deleted. Allocation is released after verified deletion.
retry After inspecting a failed operation, explicitly retry with a new idempotency key. A failed operation can have partially changed storage.

Usage and monthly statements

GET /usage?service_id=... returns sampled storage, object count, quota, collection time and traffic coverage. Missing values are unavailable, not zero. management_check_ms measures the management query, not S3 client latency.

Plan prices use nonnegative decimal strings: monthly_base, included_storage_gib, storage_price_per_gib, included_upload_gib, upload_price_per_gib, included_download_gib and download_price_per_gib. Unspecified monetary values default to zero. One GiB is 1,073,741,824 bytes.

  1. After a UTC month closes, request GET /billing/preview?customer_id=customer01&period=2026-09.
  2. Review service line items, effective tariffs, storage/traffic coverage and currency totals. The monthly base is prorated by billable active seconds. Storage overage uses the sampled monthly peak above the allowance; traffic overage uses measured counters. Allowances and storage overage are not prorated. Suspension continues billing; cancellation ends billable time.
  3. Finalize with POST /billing/statements and {"customer_id":"customer01","period":"2026-09"}. Incomplete required coverage returns 409 and blocks finalization.
  4. Read the statement with GET /billing/statements and export using GET /billing/export?statement_id=.... Preserve the statement and its digest with your billing records.

Storage requires samples within 300 seconds of both active-period boundaries and no adjacent gap above 600 seconds. Priced traffic requires complete coverage and known counters. Free traffic can remain explicitly unknown while known base/storage charges finalize. Do not replace missing measurements with estimates. Amounts round half-up to three decimals and currencies remain separate.

Final statements are immutable and unique per customer/month. Repeating finalization returns the same statement. They freeze tariffs, line items and coverage evidence and include a SHA-256 digest. Unlike existing S3 reports, later price edits do not recalculate finalized statements. Tax, legal invoices, payments and credit notes remain the responsibility of the billing system. Import external-reference CSV fields as text.

Events, webhooks and billing integration

GET /events?after=0 returns scoped events; continue with next_after. Events cover lifecycle results, failures, quota thresholds, unavailable meters and finalized statements. POST /webhooks registers an HTTPS url and event names (or *). Save the signing secret returned once.

Verify X-Euronas-Signature as HMAC-SHA256 using the hexadecimal-decoded signing secret over X-Euronas-Timestamp + "." + exact request body. Enforce a short timestamp window and deduplicate X-Euronas-Event-ID. Delivery is at least once; inspect retries and dead letters with GET /webhooks/deliveries. Removing a webhook disables future deliveries.

The optional WHMCS bridge reconciles explicitly enrolled services and configured product-to-plan mappings. Preview changes before applying them. It supports provisioning, suspension, resumption, plan changes and cancellation. It does not accept orders, create invoices, collect payments, purge customer data or deliver S3 secrets. Export finalized statements for your billing-system integration.

Monitoring and recovery

Provider staff use GET /status, GET /monitoring and GET /backups. HTTP 200 can still contain health=degraded. Review stale samples, coverage gaps, failed or delayed operations, webhook failures and backup freshness. Backup reads return metadata, not downloadable customer data.

Once scheduled backups are activated, the default registry backup interval is six hours with 30-day retention. Administrators can configure the interval, retention and destination. These backups protect hosting records and statements; they do not back up Ceph objects or the separate traffic history. Arrange object protection and off-appliance copies separately.

Restore requires maintenance, backup verification and an explicit choice to revoke or preserve restored tokens/webhooks. Preserving them may revive access revoked since the backup and replay deliveries. Review storage discrepancies and interrupted operations before resuming. Restore does not automatically replay storage changes or recreate missing measurements. The hosting coordinator has no automatic failover; confirm its recovery procedure before production use.