Skip to main content
Storage provider endpoints let you configure where NekoHub stores uploaded assets. You can maintain multiple profiles and designate one as the default. All endpoints require authentication via JWT Bearer token or API key. Supported provider types:
  • local — local filesystem storage
  • s3 — S3-compatible object storage (AWS S3, MinIO, R2, etc.)
  • github-repo — GitHub repository storage

Get storage providers overview

GET /api/v1/system/storage/providers
Returns all configured storage profiles, the active default profile, and runtime information about the currently active storage backend. Required permission: providers.read

Response

data
object

Example

curl http://localhost:5121/api/v1/system/storage/providers \
  -H "Authorization: Bearer <token>"

Create a storage profile

POST /api/v1/system/storage/providers
Creates a new storage provider profile. Required permission: providers.create

Request body

name
string
required
Unique internal name for the profile (e.g. my-s3-bucket).
displayName
string
required
Human-readable name shown in the UI.
providerType
string
required
Provider type. One of: local, s3, github-repo.
isEnabled
boolean
Whether the profile is enabled. Defaults to true.
isDefault
boolean
Whether to set this as the default profile. Defaults to false.
configuration
object
Provider-specific non-sensitive configuration (e.g. bucket name, region, root path, repository owner/name).
secretConfiguration
object
Provider-specific sensitive configuration (e.g. access key, secret key, GitHub token). Values in this object are stored encrypted and are not returned in GET responses.

Response — 201 Created

Returns the created storage profile object.

Example — create an S3 profile

curl -X POST http://localhost:5121/api/v1/system/storage/providers \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-s3",
    "displayName": "My S3 Bucket",
    "providerType": "s3",
    "isEnabled": true,
    "isDefault": false,
    "configuration": {
      "bucketOrContainer": "nekohub-assets",
      "region": "us-east-1",
      "publicBaseUrl": "https://cdn.example.com"
    },
    "secretConfiguration": {
      "accessKey": "AKIAIOSFODNN7EXAMPLE",
      "secretKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
    }
  }'

Update a storage profile

PATCH /api/v1/system/storage/providers/{id}
Updates an existing storage provider profile. Only fields you include are changed. Required permission: providers.update

Path parameters

id
string (uuid)
required
The unique identifier of the profile to update.

Request body

name
string
New internal name. Omit to leave unchanged.
displayName
string
New display name. Omit to leave unchanged.
isEnabled
boolean
New enabled state. Omit to leave unchanged.
configuration
object
Updated non-sensitive configuration. Omit to leave unchanged.
secretConfiguration
object
Updated sensitive configuration. Omit to leave unchanged.

Response — 200 OK

Returns the updated storage profile object.

Example

curl -X PATCH http://localhost:5121/api/v1/system/storage/providers/01956f8d-0000-0000-0000-000000000010 \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"displayName": "Primary S3 Bucket", "isEnabled": true}'

Delete a storage profile

DELETE /api/v1/system/storage/providers/{id}
Deletes a storage provider profile. Existing assets stored under this profile are not automatically migrated or deleted. Required permission: providers.delete

Path parameters

id
string (uuid)
required
The unique identifier of the profile to delete.

Response

data
object

Example

curl -X DELETE http://localhost:5121/api/v1/system/storage/providers/01956f8d-0000-0000-0000-000000000010 \
  -H "Authorization: Bearer <token>"

Set default storage profile

POST /api/v1/system/storage/providers/{id}/set-default
Marks the specified profile as the default storage profile for new asset uploads. Required permission: settings.update

Path parameters

id
string (uuid)
required
The unique identifier of the profile to set as default.

Response — 200 OK

Returns the updated storage profile object.

Example

curl -X POST http://localhost:5121/api/v1/system/storage/providers/01956f8d-0000-0000-0000-000000000010/set-default \
  -H "Authorization: Bearer <token>"

Browse a GitHub Repo directory

GET /api/v1/system/storage/providers/{id}/github-repo/browse
Lists files and directories within a GitHub-based storage profile. Only available for profiles with providerType: github-repo. Required permission: providers.read

Path parameters

id
string (uuid)
required
The unique identifier of a github-repo storage profile.

Query parameters

path
string
Directory path to browse. Defaults to the repository root.
recursive
boolean
Whether to list contents recursively.
maxDepth
integer
Maximum recursion depth when recursive is true.
type
string
Filter by entry type: file, dir, or omit for all.
keyword
string
Filter entries by name keyword.
page
integer
Page number. Defaults to 1.
pageSize
integer
Results per page.

Response

data
object

Example

curl "http://localhost:5121/api/v1/system/storage/providers/01956f8d-0000-0000-0000-000000000010/github-repo/browse?path=images&page=1&pageSize=20" \
  -H "Authorization: Bearer <token>"

Upsert a file in a GitHub Repo

POST /api/v1/system/storage/providers/{id}/github-repo/upsert
Creates or updates a single file in a GitHub-based storage profile. Required permission: providers.update

Path parameters

id
string (uuid)
required
The unique identifier of a github-repo storage profile.

Request body

path
string
required
Path within the repository where the file should be written (e.g. images/2026/photo.png).
contentBase64
string
required
Base64-encoded content of the file to write.
commitMessage
string
Optional commit message. Defaults to a generated message if omitted.
expectedSha
string
For updates: the current file’s Git blob SHA. Required when updating an existing file to prevent conflicts. Omit when creating a new file.

Response

data
object
Returns 409 Conflict if the expectedSha does not match the current file SHA.

Example

curl -X POST http://localhost:5121/api/v1/system/storage/providers/01956f8d-0000-0000-0000-000000000010/github-repo/upsert \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "path": "images/hello.txt",
    "contentBase64": "SGVsbG8sIHdvcmxkIQ==",
    "commitMessage": "Add hello.txt"
  }'