Skip to content

Storage API ​

S3-compatible object storage

Endpoints ​

MethodPathDescription
GET/v1/storage/bucketsList buckets
POST/v1/storage/bucketsCreate bucket
GET/v1/storage/buckets/{bucket_name}Get bucket
DELETE/v1/storage/buckets/{bucket_name}Delete bucket
PATCH/v1/storage/buckets/{bucket_name}/visibilitySet bucket visibility
GET/v1/storage/buckets/{bucket_name}/keysList bucket keys
POST/v1/storage/buckets/{bucket_name}/keysCreate bucket key
PATCH/v1/storage/buckets/{bucket_name}/keys/{key_id}Update bucket key
DELETE/v1/storage/buckets/{bucket_name}/keys/{key_id}Delete bucket key
GET/v1/storage/buckets/{bucket_name}/corsGet bucket CORS
PUT/v1/storage/buckets/{bucket_name}/corsSet bucket CORS
DELETE/v1/storage/buckets/{bucket_name}/corsDelete bucket CORS
GET/v1/storage/buckets/{bucket_name}/lifecycleGet bucket lifecycle
PUT/v1/storage/buckets/{bucket_name}/lifecycleSet bucket lifecycle
DELETE/v1/storage/buckets/{bucket_name}/lifecycleDelete bucket lifecycle
GET/v1/storage/buckets/{bucket_name}/versioningGet bucket versioning
GET/v1/storage/buckets/{bucket_name}/object-lockGet bucket Object Lock
GET/v1/storage/actionsList storage actions
GET/v1/storage/keysList access keys
POST/v1/storage/keysCreate access key
GET/v1/storage/keys/{key_id}Get access key
PATCH/v1/storage/keys/{key_id}Update access key
DELETE/v1/storage/keys/{key_id}Delete access key
GET/v1/storage/tiersList storage tiers
GET/storage/s3S3 protocol guide

GET /v1/storage/buckets ​

List buckets

Get all storage buckets with name, creation date, and usage statistics. The response is an array; it is empty when you have no buckets.

Response example:

json
[
  {
    "bucket_name": "company-assets",
    "storage_tier": "standard",
    "region": "no",
    "created_at": "2024-01-20T09:00:00Z",
    "is_active": true,
    "is_public": false,
    "total_storage_gb": 50.0,
    "total_objects": 12458
  }
]

Example:

bash
curl https://api.wayscloud.services/v1/storage/buckets \
  -H "X-API-Key: wayscloud_s3_abc12_YOUR_SECRET"

Response:

json
[
  {
    "bucket_name": "company-assets",
    "storage_tier": "standard",
    "region": "no",
    "created_at": "2024-01-20T09:00:00Z",
    "is_active": true,
    "is_public": false,
    "total_storage_gb": 50.0,
    "total_objects": 12458
  }
]

POST /v1/storage/buckets ​

Create bucket

Create a new bucket. Names: 3-63 chars, lowercase/numbers/hyphens, globally unique, cannot be reused after deletion.

Storage Tiers:

  • standard (default): Reliable storage for general use
  • enterprise: High-performance storage with dedicated infrastructure and enhanced durability

Request Body:

FieldTypeDescription
bucket_namestringRequired. Unique bucket name (lowercase, numbers, hyphens)
tierstringStorage tier: standard (general use) or enterprise (dedicated infrastructure, enhanced performance) Values: standard, enterprise
regionstringRegion code from GET /v1/regions. Object Storage is available in region no (Norway) only; the legacy no-oslo-1 spelling is accepted and reported as no.
is_publicbooleanWhether anonymous clients can read objects

Response:

FieldTypeDescription
successboolean
bucket_namestring
messagestring
endpointstringS3 endpoint URL
regionstringStorage region code (no).
tierstringstandard or enterprise
access_keystringS3 access key for this bucket
secret_keystringS3 secret key for this bucket. Shown only once.

Example:

bash
curl -X POST https://api.wayscloud.services/v1/storage/buckets \
  -H "X-API-Key: wayscloud_s3_abc12_YOUR_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
  "bucket_name": "my-app-uploads",
  "tier": "standard"
}'

Response:

json
{
  "success": true,
  "bucket_name": "my-app-uploads",
  "message": "Bucket 'my-app-uploads' created successfully",
  "endpoint": "https://storage.wayscloud.services",
  "region": "no",
  "tier": "standard",
  "access_key": "AKWC3XJQK7HMNTUVWXYZ",
  "secret_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
}

GET /v1/storage/buckets/ ​

Get bucket

Get bucket details: name, creation date, object count, and storage used.

Response:

FieldTypeDescription
bucket_namestring
storage_tierstringstandard or enterprise
regionstringStorage region code (no).
created_atstring
is_activeboolean
is_publicbooleanWhether anonymous clients can read objects
total_storage_gbnumberStorage used, in GB
total_objectsinteger

Example:

bash
curl https://api.wayscloud.services/v1/storage/buckets/{bucket_name} \
  -H "X-API-Key: wayscloud_s3_abc12_YOUR_SECRET"

Response:

json
{
  "bucket_name": "company-assets",
  "storage_tier": "standard",
  "region": "no",
  "created_at": "2024-01-20T09:00:00Z",
  "is_active": true,
  "is_public": false,
  "total_storage_gb": 50.0,
  "total_objects": 12458
}

DELETE /v1/storage/buckets/ ​

Delete bucket

Delete a bucket permanently. Must be empty first. Deleted names cannot be reused.

Response:

FieldTypeDescription
successboolean
messagestring

Example:

bash
curl -X DELETE https://api.wayscloud.services/v1/storage/buckets/{bucket_name} \
  -H "X-API-Key: wayscloud_s3_abc12_YOUR_SECRET"

Response:

json
{
  "success": true,
  "message": "Resource deleted successfully"
}

PATCH /v1/storage/buckets/{bucket_name}/visibility ​

Set bucket visibility

Toggle a bucket between public (anonymous reads) and private. Public buckets serve every object under the bucket anonymously through the gateway.

Request Body:

FieldTypeDescription
is_publicbooleanRequired. True for public read access, false for private

Response:

FieldTypeDescription
successboolean
bucket_namestring
is_publicbooleanThe visibility now in force
messagestring

Example:

bash
curl -X PATCH https://api.wayscloud.services/v1/storage/buckets/{bucket_name}/visibility \
  -H "X-API-Key: wayscloud_s3_abc12_YOUR_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
  "is_public": true
}'

Response:

json
{
  "success": true,
  "bucket_name": "company-assets",
  "is_public": true,
  "message": "Bucket is now public"
}

GET /v1/storage/buckets/{bucket_name}/keys ​

List bucket keys

List the access keys that can reach this bucket. Secrets are never returned.

Response example:

json
[
  {
    "id": "f4b0a76e-0425-44cc-bad0-0ca7fccd8b61",
    "name": "Backup Script Key",
    "description": "Daily backup to the NAS",
    "access_key": "wayscloud_s3_company-assets_ab12cd34",
    "actions": [
      "s3:GetObject",
      "s3:PutObject"
    ],
    "full_access": false,
    "is_default": false,
    "created_at": "2025-11-24T10:00:00Z",
    "last_used_at": null
  }
]

Example:

bash
curl https://api.wayscloud.services/v1/storage/buckets/{bucket_name}/keys \
  -H "X-API-Key: wayscloud_s3_abc12_YOUR_SECRET"

Response:

json
[
  {
    "id": "f4b0a76e-0425-44cc-bad0-0ca7fccd8b61",
    "name": "Backup Script Key",
    "description": "Daily backup to the NAS",
    "access_key": "wayscloud_s3_company-assets_ab12cd34",
    "actions": [
      "s3:GetObject",
      "s3:PutObject"
    ],
    "full_access": false,
    "is_default": false,
    "created_at": "2025-11-24T10:00:00Z",
    "last_used_at": null
  }
]

POST /v1/storage/buckets/{bucket_name}/keys ​

Create bucket key

Create an additional access key scoped to this bucket. Without actions the key keeps full access to the bucket (legacy default); with actions it is limited to the fine-grained S3 actions listed by GET /v1/storage/actions.

Note: secret_key is only returned once. Save it immediately!

Request Body:

FieldTypeDescription
namestringRequired. User-friendly key name
descriptionstring
actionsarrayFine-grained S3 actions (see GET /v1/storage/actions). Omit for full access.

Example:

json
{
  "name": "Backup Script Key",
  "actions": [
    "s3:GetObject",
    "s3:PutObject"
  ]
}

Response:

FieldTypeDescription
idstring
namestring
descriptionstring
access_keystring
secret_keystringS3 secret key. Shown only once.
actionsarray
full_accessboolean
endpointstring
created_atstring

Example:

bash
curl -X POST https://api.wayscloud.services/v1/storage/buckets/{bucket_name}/keys \
  -H "X-API-Key: wayscloud_s3_abc12_YOUR_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Backup Script Key",
  "actions": [
    "s3:GetObject",
    "s3:PutObject"
  ]
}'

Response:

json
{
  "id": "f4b0a76e-0425-44cc-bad0-0ca7fccd8b61",
  "name": "Backup Script Key",
  "description": null,
  "access_key": "wayscloud_s3_company-assets_ab12cd34",
  "secret_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
  "actions": [
    "s3:GetObject",
    "s3:PutObject"
  ],
  "full_access": false,
  "endpoint": "https://storage.wayscloud.services",
  "created_at": "2025-11-24T10:00:00Z"
}

PATCH /v1/storage/buckets/{bucket_name}/keys/ ​

Update bucket key

Update a key's name, description and/or fine-grained actions. Sending actions replaces the key's grants on this bucket.

Request Body:

FieldTypeDescription
namestringRequired. User-friendly key name
descriptionstring
actionsarrayFine-grained S3 actions (see GET /v1/storage/actions). Omit for full access.

Example:

json
{
  "name": "Backup Script Key",
  "actions": [
    "s3:GetObject",
    "s3:PutObject"
  ]
}

Response:

FieldTypeDescription
idstring
namestring
descriptionstring
access_keystringS3 access key; the secret is never listed
actionsarrayFine-grained S3 actions granted on this bucket
full_accessbooleanTrue when the key keeps the legacy coarse grants
is_defaultbooleanTrue for the key created with the bucket
created_atstring
last_used_atstring

Example:

bash
curl -X PATCH https://api.wayscloud.services/v1/storage/buckets/{bucket_name}/keys/{key_id} \
  -H "X-API-Key: wayscloud_s3_abc12_YOUR_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
  "actions": [
    "s3:GetObject"
  ]
}'

Response:

json
{
  "id": "f4b0a76e-0425-44cc-bad0-0ca7fccd8b61",
  "name": "Backup Script Key",
  "description": "Daily backup to the NAS",
  "access_key": "wayscloud_s3_company-assets_ab12cd34",
  "actions": [
    "s3:GetObject",
    "s3:PutObject"
  ],
  "full_access": false,
  "is_default": false,
  "created_at": "2025-11-24T10:00:00Z",
  "last_used_at": null
}

DELETE /v1/storage/buckets/{bucket_name}/keys/ ​

Delete bucket key

Delete an additional key for this bucket. The default key created with the bucket cannot be deleted.

Response:

FieldTypeDescription
successboolean
messagestring

Example:

bash
curl -X DELETE https://api.wayscloud.services/v1/storage/buckets/{bucket_name}/keys/{key_id} \
  -H "X-API-Key: wayscloud_s3_abc12_YOUR_SECRET"

Response:

json
{
  "success": true,
  "message": "Resource deleted successfully"
}

GET /v1/storage/buckets/{bucket_name}/cors ​

Get bucket CORS

Get the CORS document the gateway enforces for this bucket. Returns 404 when no CORS configuration is set.

Response:

FieldTypeDescription
rulesarrayAt most 100 rules

Example:

bash
curl https://api.wayscloud.services/v1/storage/buckets/{bucket_name}/cors \
  -H "X-API-Key: wayscloud_s3_abc12_YOUR_SECRET"

Response:

json
{
  "rules": [
    {
      "id": "web-app",
      "allowed_origins": [
        "https://app.example.com"
      ],
      "allowed_methods": [
        "GET",
        "PUT"
      ],
      "allowed_headers": [
        "content-type"
      ],
      "expose_headers": [
        "etag"
      ],
      "max_age_seconds": 3000
    }
  ]
}

PUT /v1/storage/buckets/{bucket_name}/cors ​

Set bucket CORS

Replace the whole CORS document. Rules: at most 100; origins are * or scheme://host[:port] with no path; methods are GET, PUT, HEAD, POST, DELETE, OPTIONS; max_age_seconds is 0-86400.

Request Body:

FieldTypeDescription
rulesarrayAt most 100 rules

Example:

json
{
  "rules": [
    {
      "id": "web-app",
      "allowed_origins": [
        "https://app.example.com"
      ],
      "allowed_methods": [
        "GET",
        "PUT"
      ],
      "allowed_headers": [
        "content-type"
      ],
      "expose_headers": [
        "etag"
      ],
      "max_age_seconds": 3000
    }
  ]
}

Response:

FieldTypeDescription
rulesarrayAt most 100 rules

Example:

bash
curl -X PUT https://api.wayscloud.services/v1/storage/buckets/{bucket_name}/cors \
  -H "X-API-Key: wayscloud_s3_abc12_YOUR_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
  "rules": [
    {
      "id": "web-app",
      "allowed_origins": [
        "https://app.example.com"
      ],
      "allowed_methods": [
        "GET",
        "PUT"
      ],
      "allowed_headers": [
        "content-type"
      ],
      "expose_headers": [
        "etag"
      ],
      "max_age_seconds": 3000
    }
  ]
}'

Response:

json
{
  "rules": [
    {
      "id": "web-app",
      "allowed_origins": [
        "https://app.example.com"
      ],
      "allowed_methods": [
        "GET",
        "PUT"
      ],
      "allowed_headers": [
        "content-type"
      ],
      "expose_headers": [
        "etag"
      ],
      "max_age_seconds": 3000
    }
  ]
}

DELETE /v1/storage/buckets/{bucket_name}/cors ​

Delete bucket CORS

Remove the CORS configuration. Idempotent: deleting when none is set also succeeds.

Example:

bash
curl -X DELETE https://api.wayscloud.services/v1/storage/buckets/{bucket_name}/cors \
  -H "X-API-Key: wayscloud_s3_abc12_YOUR_SECRET"

GET /v1/storage/buckets/{bucket_name}/lifecycle ​

Get bucket lifecycle

Get the lifecycle rules the gateway enforces for this bucket. Returns 404 when no lifecycle configuration is set.

Response:

FieldTypeDescription
rulesarrayAt most 1000 rules

Example:

bash
curl https://api.wayscloud.services/v1/storage/buckets/{bucket_name}/lifecycle \
  -H "X-API-Key: wayscloud_s3_abc12_YOUR_SECRET"

Response:

json
{
  "rules": [
    {
      "id": "expire-logs",
      "status": "Enabled",
      "prefix": "logs/",
      "expiration_days": 30,
      "expiration_date": null,
      "noncurrent_days": null
    }
  ]
}

PUT /v1/storage/buckets/{bucket_name}/lifecycle ​

Set bucket lifecycle

Replace the whole lifecycle document. Rules: at most 1000; each needs a status and at least one of expiration_days, expiration_date or noncurrent_days; expiration_days and expiration_date are mutually exclusive. Transitions, tag filters and AbortIncompleteMultipartUpload are rejected.

Request Body:

FieldTypeDescription
rulesarrayAt most 1000 rules

Example:

json
{
  "rules": [
    {
      "id": "expire-logs",
      "status": "Enabled",
      "prefix": "logs/",
      "expiration_days": 30,
      "expiration_date": null,
      "noncurrent_days": null
    }
  ]
}

Response:

FieldTypeDescription
rulesarrayAt most 1000 rules

Example:

bash
curl -X PUT https://api.wayscloud.services/v1/storage/buckets/{bucket_name}/lifecycle \
  -H "X-API-Key: wayscloud_s3_abc12_YOUR_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
  "rules": [
    {
      "id": "expire-logs",
      "status": "Enabled",
      "prefix": "logs/",
      "expiration_days": 30,
      "expiration_date": null,
      "noncurrent_days": null
    }
  ]
}'

Response:

json
{
  "rules": [
    {
      "id": "expire-logs",
      "status": "Enabled",
      "prefix": "logs/",
      "expiration_days": 30,
      "expiration_date": null,
      "noncurrent_days": null
    }
  ]
}

DELETE /v1/storage/buckets/{bucket_name}/lifecycle ​

Delete bucket lifecycle

Remove the lifecycle configuration. Idempotent: deleting when none is set also succeeds.

Example:

bash
curl -X DELETE https://api.wayscloud.services/v1/storage/buckets/{bucket_name}/lifecycle \
  -H "X-API-Key: wayscloud_s3_abc12_YOUR_SECRET"

GET /v1/storage/buckets/{bucket_name}/versioning ​

Get bucket versioning

Report the versioning status. Norway (no) buckets are platform-managed and always Enabled.

Response:

FieldTypeDescription
statusstringEnabled, Suspended or Unknown
platform_managedbooleanTrue when the platform owns the setting
editablebooleanTrue when a client may still change it

Example:

bash
curl https://api.wayscloud.services/v1/storage/buckets/{bucket_name}/versioning \
  -H "X-API-Key: wayscloud_s3_abc12_YOUR_SECRET"

Response:

json
{
  "status": "Enabled",
  "platform_managed": true,
  "editable": false
}

GET /v1/storage/buckets/{bucket_name}/object-lock ​

Get bucket Object Lock

Report the Object Lock status. Norway (no) buckets use platform-managed GOVERNANCE mode with a default retention period.

Response:

FieldTypeDescription
enabledboolean
modestringGOVERNANCE or null
default_retention_daysinteger
platform_managedboolean

Example:

bash
curl https://api.wayscloud.services/v1/storage/buckets/{bucket_name}/object-lock \
  -H "X-API-Key: wayscloud_s3_abc12_YOUR_SECRET"

Response:

json
{
  "enabled": true,
  "mode": "GOVERNANCE",
  "default_retention_days": 1,
  "platform_managed": true
}

GET /v1/storage/actions ​

List storage actions

List the fine-grained S3 actions a storage key can be granted.

Response example:

json
[
  {
    "code": "s3:GetObject",
    "group": "List og les",
    "description": "Read and download the contents of objects (files) in the bucket."
  }
]

Example:

bash
curl https://api.wayscloud.services/v1/storage/actions \
  -H "X-API-Key: wayscloud_s3_abc12_YOUR_SECRET"

Response:

json
[
  {
    "code": "s3:GetObject",
    "group": "List og les",
    "description": "Read and download the contents of objects (files) in the bucket."
  }
]

GET /v1/storage/keys ​

List access keys

List every storage access key on the account with its policy document.

Response example:

json
[
  {
    "id": "8a1c2e30-9b47-4d51-8e2a-16c9b0d5f4a1",
    "name": "backup-script",
    "description": "Daily backup to the NAS",
    "access_key": "wayscloud_s3_backup-script_ab12cd34",
    "grants": [
      {
        "bucket": "company-assets",
        "actions": [
          "s3:GetObject",
          "s3:ListBucket"
        ]
      }
    ],
    "full_access": false,
    "is_default_for_bucket": null,
    "created_at": "2025-11-24T10:00:00Z",
    "last_used_at": null
  }
]

Example:

bash
curl https://api.wayscloud.services/v1/storage/keys \
  -H "X-API-Key: wayscloud_s3_abc12_YOUR_SECRET"

Response:

json
[
  {
    "id": "8a1c2e30-9b47-4d51-8e2a-16c9b0d5f4a1",
    "name": "backup-script",
    "description": "Daily backup to the NAS",
    "access_key": "wayscloud_s3_backup-script_ab12cd34",
    "grants": [
      {
        "bucket": "company-assets",
        "actions": [
          "s3:GetObject",
          "s3:ListBucket"
        ]
      }
    ],
    "full_access": false,
    "is_default_for_bucket": null,
    "created_at": "2025-11-24T10:00:00Z",
    "last_used_at": null
  }
]

POST /v1/storage/keys ​

Create access key

Create an account-level key from a policy document. Each grant names a bucket (or *) and the fine-grained S3 actions on it.

Note: secret_key is only returned once. Save it immediately!

Request Body:

FieldTypeDescription
namestringRequired.
descriptionstring
grantsarrayRequired. Policy document; replaces every grant

Example:

json
{
  "name": "backup-script",
  "grants": [
    {
      "bucket": "company-assets",
      "actions": [
        "s3:GetObject"
      ]
    }
  ]
}

Response:

FieldTypeDescription
idstring
namestring
descriptionstring
access_keystring
grantsarray
full_accessboolean
is_default_for_bucketstring
created_atstring
last_used_atstring
secret_keystringS3 secret key. Shown only once.
endpointstring
warningstring

Example:

bash
curl -X POST https://api.wayscloud.services/v1/storage/keys \
  -H "X-API-Key: wayscloud_s3_abc12_YOUR_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "backup-script",
  "grants": [
    {
      "bucket": "company-assets",
      "actions": [
        "s3:GetObject"
      ]
    }
  ]
}'

Response:

json
{
  "id": "8a1c2e30-9b47-4d51-8e2a-16c9b0d5f4a1",
  "name": "backup-script",
  "description": null,
  "access_key": "wayscloud_s3_backup-script_ab12cd34",
  "grants": [
    {
      "bucket": "company-assets",
      "actions": [
        "s3:GetObject"
      ]
    }
  ],
  "full_access": false,
  "is_default_for_bucket": null,
  "created_at": "2025-11-24T10:00:00Z",
  "last_used_at": null,
  "secret_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
  "endpoint": "https://storage.wayscloud.services",
  "warning": "Save the secret key now. You won't be able to see it again."
}

GET /v1/storage/keys/ ​

Get access key

Get one access key and its policy document.

Response:

FieldTypeDescription
idstring
namestring
descriptionstring
access_keystring
grantsarray
full_accessbooleanTrue for legacy keys with coarse full-access grants
is_default_for_bucketstringSet when this key is the default key of a bucket (cannot be deleted directly)
created_atstring
last_used_atstring

Example:

bash
curl https://api.wayscloud.services/v1/storage/keys/{key_id} \
  -H "X-API-Key: wayscloud_s3_abc12_YOUR_SECRET"

Response:

json
{
  "id": "8a1c2e30-9b47-4d51-8e2a-16c9b0d5f4a1",
  "name": "backup-script",
  "description": "Daily backup to the NAS",
  "access_key": "wayscloud_s3_backup-script_ab12cd34",
  "grants": [
    {
      "bucket": "company-assets",
      "actions": [
        "s3:GetObject",
        "s3:ListBucket"
      ]
    }
  ],
  "full_access": false,
  "is_default_for_bucket": null,
  "created_at": "2025-11-24T10:00:00Z",
  "last_used_at": null
}

PATCH /v1/storage/keys/ ​

Update access key

Update a key. Sending grants replaces the whole policy document.

Request Body:

FieldTypeDescription
namestring
descriptionstring
grantsarrayReplaces the whole policy document

Example:

json
{
  "grants": [
    {
      "bucket": "company-assets",
      "actions": [
        "s3:GetObject"
      ]
    }
  ]
}

Response:

FieldTypeDescription
idstring
namestring
descriptionstring
access_keystring
grantsarray
full_accessbooleanTrue for legacy keys with coarse full-access grants
is_default_for_bucketstringSet when this key is the default key of a bucket (cannot be deleted directly)
created_atstring
last_used_atstring

Example:

bash
curl -X PATCH https://api.wayscloud.services/v1/storage/keys/{key_id} \
  -H "X-API-Key: wayscloud_s3_abc12_YOUR_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
  "grants": [
    {
      "bucket": "company-assets",
      "actions": [
        "s3:GetObject"
      ]
    }
  ]
}'

Response:

json
{
  "id": "8a1c2e30-9b47-4d51-8e2a-16c9b0d5f4a1",
  "name": "backup-script",
  "description": "Daily backup to the NAS",
  "access_key": "wayscloud_s3_backup-script_ab12cd34",
  "grants": [
    {
      "bucket": "company-assets",
      "actions": [
        "s3:GetObject",
        "s3:ListBucket"
      ]
    }
  ],
  "full_access": false,
  "is_default_for_bucket": null,
  "created_at": "2025-11-24T10:00:00Z",
  "last_used_at": null
}

DELETE /v1/storage/keys/ ​

Delete access key

Delete an account-level key. A bucket's default key cannot be deleted directly.

Response:

FieldTypeDescription
successboolean
messagestring

Example:

bash
curl -X DELETE https://api.wayscloud.services/v1/storage/keys/{key_id} \
  -H "X-API-Key: wayscloud_s3_abc12_YOUR_SECRET"

Response:

json
{
  "success": true,
  "message": "Resource deleted successfully"
}

GET /v1/storage/tiers ​

List storage tiers

List available storage tiers for bucket creation, with the price per GB in the account currency.

Response example:

json
[
  {
    "id": "standard",
    "name": "Standard",
    "description": "Reliable storage for general use",
    "features": [
      "Object storage",
      "Per-bucket access keys"
    ],
    "price_per_gb": 0.79,
    "currency": "NOK"
  }
]

Example:

bash
curl https://api.wayscloud.services/v1/storage/tiers \
  -H "X-API-Key: wayscloud_s3_abc12_YOUR_SECRET"

GET /storage/s3 ​

S3 protocol guide

WAYSCloud Storage is fully AWS S3 compatible. Use any AWS SDK or S3 client.

Endpoint: https://storage.wayscloud.services | Signing region: no (an S3 client setting; the bucket's location is its region in GET /v1/storage/buckets)

AWS CLI

bash
# Configure
aws configure set default.s3.endpoint_url https://storage.wayscloud.services

# List buckets
aws s3 ls

# Upload file
aws s3 cp local.txt s3://your-bucket/remote.txt

# Download file
aws s3 cp s3://your-bucket/remote.txt local.txt

Python (boto3)

python
import boto3

s3 = boto3.client('s3',
    endpoint_url='https://storage.wayscloud.services',
    aws_access_key_id='YOUR_ACCESS_KEY',
    aws_secret_access_key='YOUR_SECRET_KEY',
    region_name='no'
)

# List objects
response = s3.list_objects_v2(Bucket='your-bucket')
for obj in response.get('Contents', []):
    print(obj['Key'])

# Upload file
s3.upload_file('local.txt', 'your-bucket', 'remote.txt')

# Download file
s3.download_file('your-bucket', 'remote.txt', 'local.txt')

JavaScript (AWS SDK v3)

javascript
import { S3Client, ListObjectsV2Command } from "@aws-sdk/client-s3";

const s3 = new S3Client({
  endpoint: "https://storage.wayscloud.services",
  region: "no",
  credentials: {
    accessKeyId: "YOUR_ACCESS_KEY",
    secretAccessKey: "YOUR_SECRET_KEY"
  }
});

const response = await s3.send(new ListObjectsV2Command({
  Bucket: "your-bucket"
}));

Get your Access Key and Secret Key in your dashboard under Storage → Access keys (account-level keys, not scoped to one bucket). Per-bucket keys are the legacy default and are still issued on each bucket.

Example:

bash
curl https://api.wayscloud.services/storage/s3 \
  -H "X-API-Key: wayscloud_s3_abc12_YOUR_SECRET"

Response:

json
[
  {
    "id": "standard",
    "name": "Standard",
    "description": "Reliable storage for general use",
    "features": [
      "Object storage",
      "Per-bucket access keys"
    ],
    "price_per_gb": 0.79,
    "currency": "NOK"
  }
]