> ## Documentation Index
> Fetch the complete documentation index at: https://docs.motioness.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 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

```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/google
GET 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](/guides/webhooks) for the verify recipe.