Skip to content

Authenticate users with the Hoody API, manage sessions, verify email addresses, and configure two-factor authentication. This page covers email/password flows, OAuth (GitHub and Google), PKCE-protected popup handoffs, email verification, password recovery, and TOTP-based 2FA.

Returns regions where free-tier servers exist, with boolean availability. This endpoint is public and requires no authentication.

Terminal window
curl https://api.hoody.com/api/v1/auth/available-regions

Returns the ED25519 public keys used by Hoody to sign API responses (X-Hoody-Signature header), identity claims issued at login, and container authorization claims. No authentication required.

Verification flow:

  1. Fetch this endpoint once and cache the result for at least 24 hours.
  2. Locate the key by kid from the keys[] array.
  3. For response signatures, parse X-Hoody-Signature: t=<ts>,kid=<id>,path=<url>,sig=<hex> and verify sig against t + "." + responseBody.
  4. For identity and container claims, verify claim.signature_hex against the UTF-8 bytes of claim.payload_b64.
  5. If a signature references a kid not present in your cached keys, re-fetch this endpoint.
Terminal window
curl https://api.hoody.com/api/v1/meta/public-key

All OAuth redirect endpoints use PKCE. The code_challenge (base64url SHA-256 of code_verifier) is required.

Redirects the browser to GitHub for OAuth authentication. Browser-only endpoint.

NameInTypeRequiredDescription
intentquerystringNoOAuth intent: login (default) or star_check (check for star credit). Allowed values: login, star_check.
redirect_uriquerystringNoFrontend URL to redirect to after OAuth completes (must be on allowed domain)
code_challengequerystringYesPKCE code_challenge (base64url SHA-256 of code_verifier). Required — all OAuth flows must use PKCE post-migration.
Terminal window
curl -L "https://api.hoody.com/api/v1/auth/github?intent=login&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM"

Handles the GitHub OAuth callback. Browser-only endpoint.

NameInTypeRequiredDescription
codequerystringYesOAuth code returned by GitHub
statequerystringYesState value for CSRF protection
Terminal window
curl -L "https://api.hoody.com/api/v1/auth/github/callback?code=acf4d2e9&state=xyz123"

Redirects the browser to Google for OAuth authentication. Browser-only endpoint.

NameInTypeRequiredDescription
redirect_uriquerystringNoFrontend URL to redirect to after OAuth completes
code_challengequerystringYesPKCE code_challenge (base64url SHA-256 of code_verifier). Required — all OAuth flows must use PKCE post-migration.
Terminal window
curl -L "https://api.hoody.com/api/v1/auth/google?code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM"

Handles the Google OAuth callback. Browser-only endpoint.

NameInTypeRequiredDescription
codequerystringYesOAuth code returned by Google
statequerystringYesState value for CSRF protection
Terminal window
curl -L "https://api.hoody.com/api/v1/auth/google/callback?code=4/0AY0e-g7X&state=xyz123"

Issues a one-shot launch ticket bound to the request Origin header. The frontend navigates the popup to the returned launch_url, which consumes the ticket and runs the existing PKCE-protected OAuth flow with state_id and opener_origin plumbed through.

NameTypeRequiredDescription
providerstringYesOAuth provider. Allowed values: github, google.
code_challengestringYesPKCE code_challenge (base64url SHA-256 of code_verifier, 43–128 chars)
state_idstringYesPer-attempt UUID v4 — plumbed through state JWT, cookie name, fragment, message filter
Terminal window
curl -X POST https://api.hoody.com/api/v1/auth/launch/initiate \
-H "Content-Type: application/json" \
-d '{
"provider": "github",
"code_challenge": "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM",
"state_id": "f7a3b1c9-4d2e-4a8b-9f0c-1e2d3a4b5c6d"
}'

GET endpoint the popup navigates to. Consumes the launch ticket atomically and runs the existing OAuth redirect flow. Sets Referrer-Policy: no-referrer.

NameInTypeRequiredDescription
ticketquerystringYesOne-shot ticket from /launch/initiate response
Terminal window
curl -L "https://api.hoody.com/api/v1/auth/launch/start?ticket=tkt_8d7f6e5c4b3a2918"

Cancel a pending OAuth AuthIntent or 2FA temp_token. Idempotent. Used by the handoff page when the user dismisses the confirmation. Send the token as Authorization: Bearer <intent or temp_token>.

Terminal window
curl -X POST https://api.hoody.com/api/v1/auth/intent/cancel \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Create a new account with email and password. A verification email is sent. The account is not active until the email is verified.

NameTypeRequiredDescription
emailstringYesEmail address for the new account
passwordstringYesPassword (min 12 chars, must include uppercase, lowercase, number, and special char)
regionstringNoOptional preferred server region (e.g. eu-west). If omitted, auto-assigned by GeoIP proximity.
Terminal window
curl -X POST https://api.hoody.com/api/v1/auth/signup \
-H "Content-Type: application/json" \
-d '{
"email": "john.doe@example.com",
"password": "SecurePassword123!"
}'

Authenticate with username and password to receive a JWT access token (expires in 1 day) and refresh token (expires in 7 days). Use the access token in the Authorization header for subsequent requests: Authorization: Bearer {token}.

NameTypeRequiredDescription
usernamestringNoUsername (alphanumeric, underscores, hyphens). Provide username or email.
emailstringNoEmail address (alternative to username)
passwordstringYesAccount password. Must be at least 8 characters with uppercase, lowercase, and number.
response_modestringNoResponse shape. tokens (default) returns access/refresh tokens. intent returns an opaque auth_intent_token for PKCE exchange. Allowed values: intent, tokens.
code_challengestringNoPKCE code_challenge (base64url SHA-256 of code_verifier). Required when response_mode=intent.
Terminal window
curl -X POST https://api.hoody.com/api/v1/users/auth/login \
-H "Content-Type: application/json" \
-d '{
"username": "john_doe",
"password": "SecurePassword123!"
}'

Log out the current user. Creates an audit log entry. In a stateless JWT setup, the client should also discard the token. This endpoint works even for banned users.

Terminal window
curl -X POST https://api.hoody.com/api/v1/users/auth/logout \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Exchange a valid refresh token for a new access token and new refresh token. Send the refresh token in the Authorization header: Authorization: Bearer {refreshToken}.

NameTypeRequiredDescription
refreshTokenstringYesValid refresh token from previous login/refresh
Terminal window
curl -X POST https://api.hoody.com/api/v1/users/auth/refresh \
-H "Content-Type: application/json" \
-d '{
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}'

Retrieve the profile of the currently authenticated user. Works with JWT, auth token, or Basic authentication. When authenticated with an auth token, the response includes data.auth_token introspection details (permissions and realm restrictions). This endpoint works even for banned users (read-only access).

Terminal window
curl https://api.hoody.com/api/v1/users/auth/me \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Verify the email address using the token from the verification email. The default response returns full login credentials. When response_mode=intent + code_challenge are provided, returns an opaque auth_intent_token for PKCE exchange (hosted auth UI flow). If 2FA is enabled on the account, returns requires_2fa + temp_token instead.

NameTypeRequiredDescription
tokenstringYesVerification token from the email link (64 characters)
response_modestringNoResponse shape. tokens (default) returns access/refresh tokens. intent returns an opaque auth_intent_token for PKCE exchange. Allowed values: intent, tokens.
code_challengestringNoPKCE code_challenge (base64url SHA-256 of code_verifier). Required when response_mode=intent.
Terminal window
curl -X POST https://api.hoody.com/api/v1/auth/verify-email \
-H "Content-Type: application/json" \
-d '{
"token": "a1b2c3d4e5f6789012345678901234567890abcdefabcdefabcdefabcdef1234"
}'

Resend the email verification link. Always returns success to prevent email enumeration.

NameTypeRequiredDescription
emailstringYesEmail address to resend verification to
Terminal window
curl -X POST https://api.hoody.com/api/v1/auth/resend-verification \
-H "Content-Type: application/json" \
-d '{
"email": "john.doe@example.com"
}'

Send a password reset email. Always returns success to prevent email enumeration.

NameTypeRequiredDescription
emailstringYesEmail address associated with the account
Terminal window
curl -X POST https://api.hoody.com/api/v1/auth/forgot-password \
-H "Content-Type: application/json" \
-d '{
"email": "john.doe@example.com"
}'

Set a new password using the reset token from the password reset email.

NameTypeRequiredDescription
tokenstringYesPassword reset token from the email link (64 characters)
passwordstringYesNew password (min 12 chars)
Terminal window
curl -X POST https://api.hoody.com/api/v1/auth/reset-password \
-H "Content-Type: application/json" \
-d '{
"token": "a1b2c3d4e5f6789012345678901234567890abcdefabcdefabcdefabcdef1234",
"password": "NewSecurePassword123!"
}'

Check the current 2FA status for the authenticated user, including whether it is enabled and how many backup codes remain.

Terminal window
curl https://api.hoody.com/api/v1/users/auth/2fa/status \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Begin 2FA setup. Requires the current password for verification. Returns a QR code for the authenticator app and backup codes. Save backup codes securely — they are shown only once.

NameTypeRequiredDescription
passwordstringYesCurrent account password for verification (8–128 characters)
Terminal window
curl -X POST https://api.hoody.com/api/v1/users/auth/2fa/setup \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
-H "Content-Type: application/json" \
-d '{
"password": "SecurePassword123!"
}'

Verify and complete 2FA setup by providing the first code from the authenticator app. This confirms the setup is working correctly.

NameTypeRequiredDescription
codestringYes6-digit code from the authenticator app
Terminal window
curl -X POST https://api.hoody.com/api/v1/users/auth/2fa/verify-setup \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
-H "Content-Type: application/json" \
-d '{
"code": "482915"
}'

Complete login by verifying the 2FA code. Use the temp_token from the login response and provide either a 6-digit OTP code or a backup code.

NameTypeRequiredDescription
temp_tokenstringNoTemporary token from login response (valid for 5 minutes). Alternatively pass it as Authorization: Bearer header.
codestringYes6-digit OTP code from the authenticator app OR 10-character backup code
response_modestringNoResponse shape. tokens (default) returns access/refresh tokens. intent returns an opaque auth_intent_token for PKCE exchange. Allowed values: intent, tokens.
Terminal window
curl -X POST https://api.hoody.com/api/v1/users/auth/2fa/verify \
-H "Content-Type: application/json" \
-d '{
"temp_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"code": "482915"
}'

POST /api/v1/users/auth/2fa/backup-codes/regenerate

Section titled “POST /api/v1/users/auth/2fa/backup-codes/regenerate”

Generate new backup codes (invalidates all existing ones). Requires password and current OTP code for security. Save the new codes securely.

NameTypeRequiredDescription
passwordstringYesCurrent account password (8–128 characters)
codestringYes6-digit OTP code from the authenticator app
Terminal window
curl -X POST https://api.hoody.com/api/v1/users/auth/2fa/backup-codes/regenerate \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
-H "Content-Type: application/json" \
-d '{
"password": "SecurePassword123!",
"code": "482915"
}'

Enable or disable the OTP requirement for token mutation operations. Disabling requires both password and OTP.

NameTypeRequiredDescription
enabledbooleanYestrue = require OTP for token mutations (default), false = skip OTP gate
passwordstringNoRequired when setting enabled=false (security downgrade requires primary-factor reauth)
otp_codestringNoTOTP code or backup code. Required when setting enabled=false.
Terminal window
curl -X PATCH https://api.hoody.com/api/v1/users/auth/2fa/token-gate \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
-H "Content-Type: application/json" \
-d '{
"enabled": false,
"password": "SecurePassword123!",
"otp_code": "482915"
}'

Disable 2FA for the account. Requires both the current password and a valid OTP code (or backup code) for security.

NameTypeRequiredDescription
passwordstringYesCurrent account password (8–128 characters)
codestringYes6-digit OTP code from the authenticator app OR backup code
Terminal window
curl -X DELETE https://api.hoody.com/api/v1/users/auth/2fa \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
-H "Content-Type: application/json" \
-d '{
"password": "SecurePassword123!",
"code": "482915"
}'