Authentication
Sign up and sign in through Better Auth, then issue API tokens for SDKs and agents.
- Better Auth serves the /api/auth/* routes. Browser clients receive an httpOnly session cookie; API clients send the session token in the Authorization: Bearer header.
- Sign-up sends a verification email. Sign-in works after the address is verified.
- OAuth sign-in with Google or GitHub uses /api/auth/sign-in/social.
- POST /v1/auth/register and POST /v1/auth/login remain for SDK password sign-in and are deprecated.
Sign Up with Email
POST
/api/auth/sign-up/email
Create a user account and send a verification email.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Display name |
| string | Yes | Email address | |
| password | string | Yes | Password (minimum 8 characters) |
Example Request
bash
curl -X POST https://api.elydora.com/api/auth/sign-up/email \
-H "Content-Type: application/json" \
-d '{
"name": "Admin User",
"email": "[email protected]",
"password": "s3cureP@ssw0rd"
}'Response
The user carries org_id null, role org_owner, and onboarding_completed 0 until onboarding creates a workspace.
json
{
"token": null,
"user": {
"id": "0195a0b1-c2d3-7e4f-a5b6-c7d8e9f0a1b2",
"email": "[email protected]",
"name": "Admin User",
"emailVerified": false,
"image": null,
"createdAt": "2026-02-28T14:00:00.000Z",
"updatedAt": "2026-02-28T14:00:00.000Z",
"org_id": null,
"role": "org_owner",
"status": "active",
"onboarding_completed": 0
}
}Sign In with Email
POST
/api/auth/sign-in/email
Authenticate with email and password and receive a session token.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| string | Yes | Email address | |
| password | string | Yes | Password |
Example Request
bash
curl -X POST https://api.elydora.com/api/auth/sign-in/email \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"password": "s3cureP@ssw0rd"
}'Response
json
{
"redirect": false,
"token": "<session-token>",
"user": {
"id": "0195a0b1-c2d3-7e4f-a5b6-c7d8e9f0a1b2",
"email": "[email protected]",
"name": "Admin User",
"emailVerified": true,
"image": null,
"createdAt": "2026-02-28T14:00:00.000Z",
"updatedAt": "2026-02-28T14:00:00.000Z",
"org_id": null,
"role": "org_owner",
"status": "active",
"onboarding_completed": 0
}
}Sign In with OAuth
POST
/api/auth/sign-in/social
Start an OAuth sign-in with Google or GitHub. Better Auth handles the redirect and callback.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| provider | string | Yes | OAuth provider: "google" or "github" |
| callbackURL | string | Yes | URL to redirect to after authentication |
Example Request
bash
curl -X POST https://api.elydora.com/api/auth/sign-in/social \
-H "Content-Type: application/json" \
-d '{
"provider": "github",
"callbackURL": "https://console.elydora.com/"
}'Response
json
{
"url": "https://github.com/login/oauth/authorize?client_id=...&redirect_uri=...",
"redirect": true
}Get Session
GET
/api/auth/get-session
Return the Better Auth session and user for the current cookie or bearer token. Without a session the response is HTTP 200 with null.
Auth: Optional
Example Request
bash
curl https://api.elydora.com/api/auth/get-session \
-H "Authorization: Bearer <session-token>"Response
json
{
"session": {
"id": "<session-id>",
"userId": "0195a0b1-c2d3-7e4f-a5b6-c7d8e9f0a1b2",
"expiresAt": "2026-03-07T14:00:00.000Z"
},
"user": {
"id": "0195a0b1-c2d3-7e4f-a5b6-c7d8e9f0a1b2",
"email": "[email protected]",
"name": "Admin User",
"emailVerified": true,
"image": null,
"createdAt": "2026-02-28T14:00:00.000Z",
"updatedAt": "2026-02-28T14:00:00.000Z",
"org_id": null,
"role": "org_owner",
"status": "active",
"onboarding_completed": 0
}
}Response without a session:
json
nullGet Current User
GET
/v1/auth/me
Return the user profile and the current organization context.
Auth: Any authenticated user
Example Request
bash
curl https://api.elydora.com/v1/auth/me \
-H "Authorization: Bearer <token>"Response
json
{
"user": {
"user_id": "0195a0b1-c2d3-7e4f-a5b6-c7d8e9f0a1b2",
"org_id": "0195a0b1-c2d3-7e4f-a5b6-c7d8e9f0a1b3",
"email": "[email protected]",
"display_name": "Admin User",
"role": "org_owner",
"status": "active",
"created_at": 1772287200000,
"updated_at": 1772287200000,
"onboarding_completed": true
},
"current_organization": {
"org_id": "0195a0b1-c2d3-7e4f-a5b6-c7d8e9f0a1b3",
"ba_org_id": "<better-auth-organization-id>",
"role": "org_owner"
}
}Refresh Session
POST
/v1/auth/refresh
Issue a new session token. Requires a session credential.
Auth: Session token
Example Request
bash
curl -X POST https://api.elydora.com/v1/auth/refresh \
-H "Authorization: Bearer <session-token>"Response
json
{
"token": "<session-token>"
}Issue API Token
POST
/v1/auth/token
Issue an API token for SDKs and agents. Requires a session credential and a current organization.
Auth: Session token
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| ttl_seconds | number | null | No | Lifetime in seconds, from 1 to 31536000. null or omitted issues a token without expiry. |
Example Request
bash
# Issue a 90-day token
curl -X POST https://api.elydora.com/v1/auth/token \
-H "Authorization: Bearer <session-token>" \
-H "Content-Type: application/json" \
-d '{"ttl_seconds": 7776000}'
# Issue a token without expiry
curl -X POST https://api.elydora.com/v1/auth/token \
-H "Authorization: Bearer <session-token>" \
-H "Content-Type: application/json" \
-d '{"ttl_seconds": null}'Response
json
{
"token": "<api-token>",
"token_id": "0195a5f6-a7b8-7c9d-e0f1-a2b3c4d5e6f7",
"expires_at": 1780063200
}expires_at is a Unix timestamp in seconds, or null.
Rotate API Token
POST
/v1/auth/rotate
Replace the current API token. Requires the API token itself; the previous token stays valid until previous_token_grace_until.
Auth: API token
Example Request
bash
curl -X POST https://api.elydora.com/v1/auth/rotate \
-H "Authorization: Bearer <api-token>"Response
json
{
"token": "<api-token>",
"token_id": "0195a6a7-b8c9-7d0e-f1a2-b3c4d5e6f7a8",
"expires_at": 1780063200,
"previous_token_grace_until": 1772290800
}