Authentication
Session cookies, OAuth, and project keys — when to use each.
Authentication
Motioness has two auth surfaces:
| Surface | Token | When |
|---|---|---|
REST API (/api/...) | Session cookie (better-auth.session_token) | Dashboard, user-scoped operations |
Public proxy (/v1/...) | Project key + (allowlist OR signed URL) | Browser embeds, server-to-server |
Session cookie auth
Sign up
bashcurl -X POST https://motioness.com/api/user/signup \ -H 'Content-Type: application/json' \ -c cookie.txt \ -d '{"email":"you@example.com","password":"hunter2","name":"You"}'# 201 Created → Set-Cookie: better-auth.session_token=...
Password rules: 8-128 characters. Email validated, max 255 chars.
Sign in
bashcurl -X POST https://motioness.com/api/user/signin \ -H 'Content-Type: application/json' \ -c cookie.txt \ -d '{"email":"you@example.com","password":"hunter2"}'
Sign out
bashcurl -X POST https://motioness.com/api/user/signout -b cookie.txt
Destroys the session in D1 and clears the cookie.
Inspect current session
bashcurl https://motioness.com/api/user/session -b cookie.txt# → { "user": { "id": "...", "email": "...", "name": "..." } }# or { "user": null } if not signed in
For full profile + usage stats:
bashcurl https://motioness.com/api/user/me -b cookie.txt# → {# "id": "...", "email": "...", "plan": "free",# "aiGenerationsUsed": 3, "aiGenerationsResetAt": "...",# "compositionCount": 7, "themeCount": 0, "createdAt": "..."# }
OAuth
Two providers: Google and GitHub. Browser-only flow (redirect-based).
Initiate
textGET https://motioness.com/api/user/oauth/googleGET https://motioness.com/api/user/oauth/github
Redirects to the provider with a CSRF state cookie. The callback URL is fixed:
texthttps://motioness.com/api/user/oauth/callback/{provider}
After the user grants consent, the callback creates or links the account, sets the session cookie, and redirects to /dashboard.
Linking an existing account
If the OAuth email matches an existing email/password user, the OAuth identity is linked to that user (not duplicated). Subsequent sign-ins via either method log into the same account.
Project keys
Project keys (pk_…) authorize the public proxy. They're public — safe to embed in HTML — but scoped to a single project + the project's allowlist or signing config.
Create
Project keys are generated lazily on first save of proxy config:
bashcurl -X PUT https://motioness.com/api/projects/$PROJECT_ID/proxy-config \ -H 'Content-Type: application/json' -b cookie.txt \ -d '{ "allowed_origins": ["https://acme.com"] }'# Response includes project.proxy_key
Rotate
bashcurl -X POST "https://motioness.com/api/projects/$PROJECT_ID/keys/rotate?which=proxy" \ -b cookie.txt# → { "proxy_key": "pk_..." }
Old key invalidates immediately. Update embedded URLs before rotating, or use signing mode for scheduled rotation.
Signing secrets
Signing secrets are secret — server-only. Generated when you enable signing, returned once:
bashcurl -X PUT https://motioness.com/api/projects/$PROJECT_ID/proxy-config \ -H 'Content-Type: application/json' -b cookie.txt \ -d '{ "enable_signing": true }'# Response includes project.signing_secret (shown once)
To rotate:
bashcurl -X POST "https://motioness.com/api/projects/$PROJECT_ID/keys/rotate?which=signing" \ -b cookie.txt
Old secret invalidates immediately. Outstanding signed URLs that haven't expired yet still verify against the new secret only — plan rotations during low-traffic windows.
Webhook secrets
Webhook secrets are signing secrets for outbound deliveries (Standard Webhooks scheme). Set on first webhook config save, rotatable via:
bashcurl -X POST https://motioness.com/api/projects/$PROJECT_ID/webhooks/rotate-secret \ -b cookie.txt# → { "webhook_secret": "whsec_..." }
See webhooks guide for the verify recipe.