comfyauthDOCS
COMFYAUTH / GETTING STARTED

One API.
Any stack.

Build the interface your users deserve. Connect it to the same small set of HTTPS endpoints.

Open the complete OpenAPI contract ↗

Your first connection

  1. Create a developer workspace.

    Sign up, verify your email, then sign in. Hostinger email is connected for verification and password-reset messages.

  2. Create your application project.

    Add a name and the verification and password-reset page URLs you own. Production callbacks require HTTPS. Copy the public project ID.

  3. Make an HTTP request.

    Send JSON with X-Project-ID to identify your application. No language-specific SDK is required.

    POST /v1/auth/signup
    Content-Type: application/json
    X-Project-ID: YOUR_PROJECT_ID
    
    {
      "email": "person@example.com",
      "password": "a long unique password phrase",
      "username": "Taylor"
    }

    A 202 response is intentionally generic. It does not directly reveal whether an account already exists. The signup password is provisional; login is blocked until verification.

  4. Complete verification, then sign in.

    The email link opens your verification URL with #token=…. Read the fragment, remove it from the URL, then ask the email owner to choose their final password. POST both values to /v1/auth/email/verify. This replaces the provisional password and cancels sessions and outstanding action links in the same transaction.

    POST /v1/auth/email/verify
    Content-Type: application/json
    X-Project-ID: YOUR_PROJECT_ID
    
    {
      "token": "TOKEN_FROM_THE_EMAIL_FRAGMENT",
      "password": "FINAL_PASSWORD_CHOSEN_BY_THE_EMAIL_OWNER"
    }

    Success returns {"email_verified":true}. A token without a password is rejected.

  5. Log in and check the session.

    POST email and the final password to /v1/auth/login. The response has this shape; these are example values:

    {
      "session_token": "ca_s_RANDOM_PRIVATE_TOKEN",
      "token_type": "Bearer",
      "expires_at": "2030-01-02T12:00:00Z",
      "user": {
        "id": "11111111-1111-4111-8111-111111111111",
        "email": "person@example.com",
        "username": "Taylor",
        "email_verified": true,
        "created_at": "2030-01-01T12:00:00Z"
      }
    }

    GET /v1/me with X-Project-ID and Authorization: Bearer SESSION_TOKEN to validate the session. It returns the user object directly, without a user wrapper. On 401, renewable clients may refresh once as described below; otherwise require login. If validation is unavailable, fail closed.

Stay signed in, using the same API

Add "renewable": true to the login JSON. Omit it to keep the existing fixed 24-hour session. Renewable login returns the normal user/access fields plus refresh_token, refresh_expires_at and session_expires_at.

POST /v1/auth/refresh
Content-Type: application/json
X-Project-ID: YOUR_PROJECT_ID

{"refresh_token":"CURRENT_PRIVATE_REFRESH_TOKEN"}

Use the current refresh token once, then replace both saved tokens and expiry values atomically. No access token or server API key is needed for this request. The session ID stays the same, and the old access token immediately stops working. Only one refresh may run per session, including across tabs or backend replicas.

SHORT PASS EXPIRES↓ Send current renewal tokenCOMFYAUTH CHECKS & ROTATES↓ Save both new tokens togetherCONTINUE USING YOUR APP

Default limits are 15-minute access, seven days without renewal and 30 days total from login. In Project Settings, choose access of 5–60 minutes, inactivity of 1–90 days and total lifetime of 1–365 days. Inactivity cannot exceed total lifetime. Settings apply to new logins and future refresh checks; they never extend a family’s original absolute maximum.

A consumed refresh token cannot be used again: replay cancels the whole session family. If the refresh response is lost or times out, require login instead of automatically trying the old token again. A refresh 401 also requires login. Logout, password recovery and account disabling cancel access and renewal together.

For browser apps, your backend keeps both secrets. Native apps use Keychain/Keystore or equivalent secure storage. The ComfyAuth portal uses HttpOnly cookies with cross-tab Web Locks; without Web Locks it requires login again after access expiry. This is a custom HTTPS/JSON API, not OAuth/OIDC.

A clear path from UI to identity

YOUR LOGIN PAGE↓ Same-origin requestYOUR APPLICATION SERVER↓ HTTPS + project IDCOMFYAUTH API↓ Verified sessionYOUR APPLICATION

For browsers, keep the ComfyAuth bearer token on your server and use a secure, HttpOnly session cookie for your own UI. Native apps can use secure operating-system storage. Never store an administrative API key in browser or mobile code.

Direct browser API calls require an exact allowed origin. Include ?project_id=YOUR_PROJECT_ID as well as the matching header for CORS preflight routing. Browser token storage remains your responsibility; a server-backed integration is recommended.

Use the same requests on every platform. Browser backends keep the bearer token private; native apps keep it in secure OS storage. Allow a bounded 60-second client timeout for the Vercel deployment: email requests can include delivery attempts. Do not automatically retry single-use token actions after an uncertain timeout.

The API surface

All routes are relative to this deployment. Requests use Content-Type: application/json and X-Project-ID. Authenticated calls also send Authorization: Bearer SESSION_TOKEN.

Method Endpoint Body / purpose
POST /v1/auth/signup email, password, optional username
POST /v1/auth/login email, password
POST /v1/auth/refresh Rotate renewable access and refresh credentials
POST /v1/auth/email/verification-request email
POST /v1/auth/email/verify token, final password chosen by the email owner
POST /v1/auth/password/reset-request email
POST /v1/auth/password/reset token, password
POST /v1/auth/password/change current_password, new_password
GET /v1/me Current verified user
GET /v1/sessions Active account sessions
DELETE /v1/sessions/{id} Revoke one session
POST /v1/auth/logout Revoke current session
POST /v1/auth/logout-all Revoke all account sessions
POST /v1/admin/users/{id}/disable Server API key required

Handling responses

400 invalid input or link · 401 invalid credentials or session · 404 missing resource · 429 rate limited · 503 temporarily unavailable. Respect Retry-After when provided. Errors contain error.code and error.message.

Several users may share one application backend. Public traffic has project capacity budgets and per-account controls, without an extra login key or arbitrary forwarded-IP headers. Defaults include 1,200 requests/minute per project/source IP and 10 login attempts per account per 15 minutes. These are ceilings, not guaranteed throughput. X-Request-ID helps investigate failures.

Security you can inspect

Passwords use Argon2id. Opaque session tokens and single-use action tokens are stored as hashes. Email payloads are encrypted with AES-256-GCM. Production connections use HTTPS and verified PostgreSQL TLS.

Fixed sessions expire after 24 hours; opted-in renewable sessions follow the project’s access, inactivity and absolute limits. Verification links expire after one hour; password reset links after 20 minutes. Password reset, password change, and disabling an account revoke its sessions. Passwords require 15–128 characters and at most 512 bytes.

Portal access is separate from your application users. Ownership is checked on every project operation; mutations also recheck the developer session inside the database transaction. Portal sessions use HttpOnly, Secure, SameSite=Strict cookies and exact-origin checks.

These controls are informed by the OWASP CSRF guidance and browser cookie rules. This early release has not had an independent security audit.

What is available today

Email/password authentication, project management, user access controls, keys, and session revocation are implemented. Hostinger email is connected with a verified sender domain. Developer and customer verification and password-reset flows have passed real email tests in our Hostinger inbox.

Phone, Google, Apple, passkeys, MFA, team roles, billing, and OAuth/OIDC interoperability are not implemented yet. This is a custom HTTPS authentication API. Existing CLI projects are not automatically assigned to a developer.

Workspaces support up to 100 projects and 20 active server keys per project. Key lists include every active key and up to 80 recent revoked keys. User lists are paginated; activity shows the latest 100 events, retained for 90 days. Vercel Hobby runs daily cleanup; reliable idle email retries require an external scheduler.

Before public production use, test delivery to external email providers, configure reliable idle retries, complete a backup restore drill and workload tests, and arrange maintained common/compromised-password screening and an independent security review. The current small password denylist needs a maintenance and coverage policy; see NIST password guidance. The successful Hostinger inbox tests do not complete these release checks.

Future Google/Apple identities will link to the same user ID using project, provider, and provider subject. Matching email text will not automatically join accounts. Phone-only login first requires a schema and verification-rule migration because email is required today.

Go to your workspace ↗