Authentication
Peako Studio supports two authentication methods: Google OAuth 2.0 for users, and API Keys for service-to-service integrations.
Google OAuth 2.0 Flow (PKCE)
For browser-based applications and user sessions.
Step 1: Initiate OAuth
Start the Google OAuth 2.0 PKCE flow.
GET /auth/google
Response: 302 redirect to Google's consent screen.
Example:
curl -L https://peako.shin0x.space/auth/google
# Redirects to: https://accounts.google.com/o/oauth2/v2/auth?client_id=...&redirect_uri=...
Step 2: Handle Callback
After the user consents, Google redirects back to your application with an authorization code.
GET /auth/google/callback?code=CODE&state=STATE
Query Parameters:
code(string) — Authorization code from Googlestate(string) — PKCE state parameter (matches what was sent in step 1)
Response: 302 redirect to https://studio.shin0x.space/dashboard
Sets Cookie:
peako_session— JWT session token (httpOnly, Secure, SameSite=Lax)- Max-Age: 7 days
- Domain: peako.shin0x.space
Example:
curl -L "https://peako.shin0x.space/auth/google/callback?code=4%2F0AY0e-g...&state=abcd1234ef..."
# Sets peako_session cookie
# Redirects to dashboard
PKCE Details
Why PKCE? PKCE (Proof Key for Code Exchange) protects against authorization code interception attacks — essential for public clients like SPAs and mobile apps.
Flow:
- Client generates
code_verifier(random string, 43–128 chars) - Client creates
code_challenge = base64url(sha256(code_verifier)) - Client sends
code_challengein authorization request - Google returns
code - Client exchanges
code+code_verifierfor tokens (already handled by our backend)
The Peako backend handles the exchange; your frontend just needs to redirect to /auth/google.
Logout
Clear the session cookie.
POST /auth/logout
Headers:
Cookie: peako_session=<token>(sent by browser, or include manually)
Response: 302 redirect to /login
Example:
curl -X POST -b "peako_session=$TOKEN" https://peako.shin0x.space/auth/logout
# Clears peako_session cookie
# Redirects to /login
Get Current User
Retrieve the authenticated user's profile.
GET /auth/me
Headers:
X-API-Key: <your-api-key>(for service calls) ORCookie: peako_session=<token>(for browser sessions)
Response:
{
"id": "user-uuid",
"email": "user@example.com",
"name": "John Doe",
"picture": "https://lh3.googleusercontent.com/...",
"createdAt": 1709767500000,
"plan": "pro",
"apiQuota": {
"requestsPerMinute": 100,
"storageGb": 100
}
}
Response Fields:
| Field | Type | Description |
|---|---|---|
id | string | Unique user ID |
email | string | User's email address |
name | string | User's display name |
picture | string | Avatar URL (from Google) |
createdAt | number | Account creation time (Unix ms) |
plan | string | Subscription plan (e.g., "free", "pro", "enterprise") |
apiQuota | object | Rate limits and storage allocations |
Error Codes:
200— Success401— Unauthorized (missing/invalid credentials)
Example:
curl -H "X-API-Key: YOUR_KEY" https://peako.shin0x.space/auth/me
# Response:
# {
# "id": "user-550e8400-e29b-41d4",
# "email": "user@example.com",
# "name": "John Doe",
# ...
# }
API Key Management
API Keys are for service-to-service calls (not browser-based). They grant full access to your account.
Rotate API Key
Generate a new API key and invalidate the old one.
POST /auth/api-key/rotate
Headers:
X-API-Key: <current-api-key>(required to rotate)
Response:
{
"apiKey": "peako_sk_abc123def456...",
"createdAt": 1709767500000,
"rotatedPreviousKeyAt": 1709767400000
}
Important:
- Old API key is immediately invalidated
- Store the new key in a secure location
- There is no way to recover the old key
Example:
curl -X POST \
-H "X-API-Key: $OLD_KEY" \
https://peako.shin0x.space/auth/api-key/rotate
# Response:
# {
# "apiKey": "peako_sk_abc123def456...",
# "createdAt": 1709767500000,
# "rotatedPreviousKeyAt": 1709767400000
# }
# Store this key immediately:
export PEAKO_API_KEY="peako_sk_abc123def456..."
Security Best Practices
- Never commit API keys — use environment variables or secret management
- Rotate keys regularly — especially if you suspect compromise
- Use HTTPS only — all requests must be over TLS
- For session cookies — browser cookies are httpOnly and Secure, no JavaScript access
- For OAuth — use PKCE for public clients; the Peako backend handles this automatically
If you expose an API key, rotate it immediately via POST /auth/api-key/rotate.
Error Codes
| Code | HTTP | Meaning |
|---|---|---|
UNAUTHORIZED | 401 | Missing or invalid credentials |
INVALID_STATE | 400 | OAuth state mismatch (PKCE validation failed) |
OAUTH_ERROR | 400 | Google OAuth returned an error |
SESSION_EXPIRED | 401 | Session token expired (>7 days old) |
RATE_LIMITED | 429 | Too many auth attempts |
Complete OAuth Flow Example
For a Browser/SPA Application
1. User clicks "Sign In with Google"
<a href="https://peako.shin0x.space/auth/google">Sign In</a>
2. Redirect to auth endpoint
window.location.href = 'https://peako.shin0x.space/auth/google';
3. User logs in at Google (Google's UI)
4. Google redirects back to callback
https://peako.shin0x.space/auth/google/callback?code=...&state=...
5. Backend validates and sets cookie
// Cookie is automatically set by the response
// Frontend can now make authenticated requests
fetch('https://peako.shin0x.space/api/templates', {
credentials: 'include' // Include cookies
});
6. Logout
await fetch('https://peako.shin0x.space/auth/logout', {
method: 'POST',
credentials: 'include'
});
// Redirects to /login
For a Service/Server Application
Use API Keys instead:
# Create template
curl -X POST \
-H "X-API-Key: $PEAKO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"My Template","composition":{...}}' \
https://peako.shin0x.space/api/templates
# Get user info
curl -H "X-API-Key: $PEAKO_API_KEY" \
https://peako.shin0x.space/auth/me
Next: Assets — Upload media files to the CDN.