Authentication

Motioness has two auth surfaces:

SurfaceTokenWhen
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

Sign up

bash
curl -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

bash
curl -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

bash
curl -X POST https://motioness.com/api/user/signout -b cookie.txt

Destroys the session in D1 and clears the cookie.

Inspect current session

bash
curl 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:

bash
curl 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

text
GET 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:

text
https://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:

bash
curl -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

bash
curl -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:

bash
curl -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:

bash
curl -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:

bash
curl -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.

Ask a question... ⌘I