Authentication

Stashly uses a centralized authentication service. There are two authentication methods: JWT tokens for interactive user sessions and API keys for programmatic access.

ℹ

No passwords

Stashly uses OTP-based authentication. There are no passwords — users sign in via a one-time code sent to their email.

JWT Authentication#

Login Flow (OTP)

1

Request an OTP

curl -X POST https://auth.stashly.io/auth/send-otp \
  -H "Content-Type: application/json" \
  -d '{"email": "you@example.com"}'
2

Verify the OTP

curl -X POST https://auth.stashly.io/auth/verify-otp \
  -H "Content-Type: application/json" \
  -d '{"email": "you@example.com", "otp": "123456"}'

Response:

{
  "success": true,
  "data": {
    "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "user": { "id": "usr_01j9", "email": "you@example.com", "role": "admin" }
  }
}

A refreshToken is also set as an HTTP-only cookie on .stashly.io.

3

Use the access token

Include it in the Authorization header:

curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Token Lifetimes

TokenLifetimeStorage
Access token15 minutesIn-memory / localStorage
Refresh token7–30 daysHTTP-only cookie on .stashly.io

Refreshing Tokens

When the access token expires, use the refresh endpoint:

curl -X POST https://auth.stashly.io/auth/refresh \
  --cookie "refreshToken=<value>"

Response returns a new accessToken.

Get Current User

curl -X GET https://auth.stashly.io/auth/me \
  -H "Authorization: Bearer <token>"
{
  "success": true,
  "data": {
    "id": "usr_01j9",
    "email": "you@example.com",
    "role": "admin",
    "tenantId": "ten_abc123"
  }
}

Logout

curl -X POST https://auth.stashly.io/auth/logout \
  -H "Authorization: Bearer <token>"

Clears the refresh token cookie.


API Key Authentication#

API keys are ideal for server-to-server calls where interactive login is not appropriate.

Creating an API Key

Log into your dashboard → Settings → API Keys → Create Key.

Select the permission scopes you need:

Permission Scopes

NameTypeDescription
viewbooleanList buckets, objects, and download files
addbooleanUpload files, create buckets and directories
editbooleanRename, move, and copy files and buckets
deletebooleanDelete files, directories, and buckets

Using an API Key

Pass the key in the X-API-Key header:

curl -X GET https://api.stashly.io/api/buckets \
  -H "X-API-Key: sk_live_01j9xk2m..."
⚠

API keys cannot manage other API keys

For security, API keys cannot be used to create, list, or revoke other API keys. Use a JWT for those operations.


Rate Limits#

Rate Limits

NameTypeDescription
send-otpendpoint5 requests per 15 minutes per IP
verify-otpendpoint10 attempts per OTP before lockout
API (general)global1,000 requests per minute per tenant
Upload sessionendpoint60 file uploads per session per hour

When rate-limited, you receive a 429 Too Many Requests response.