hyreflow-ai Auth API
The Auth API from hyreflow-ai — 13 operation(s) for auth.
The Auth API from hyreflow-ai — 13 operation(s) for auth.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/hyreflow-ai:hyreflow-ai-auth-api"
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: hyreflow engine (local) Auth API
version: 0.1.0
tags:
- name: Auth
paths:
/api/v2/auth/cli/start:
post:
summary: Auth Cli Start
description: 'CLI kicks off a claim → gets a claim_id + the approval/poll URLs. No auth (bootstrap).
Rate-limited per IP (anti credit-farming) when HYREFLOW_START_RATE_LIMIT > 0.'
operationId: auth_cli_start_api_v2_auth_cli_start_post
requestBody:
content:
application/json:
schema:
additionalProperties: true
type: object
title: Body
default: {}
responses:
'200':
description: Successful Response
content:
application/json:
schema: {}
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
tags:
- Auth
/api/v2/auth/cli/claim/{claim_id}:
get:
summary: Auth Cli Claim Page
description: 'Browser entry (the CLI opens this). Redirect to the sign-in page on the same origin
carrying the cli_token. Sign-in → magic-link → finalize approves THIS claim in-process — no
webengine secret. (POST below still approves directly for the legacy dashboard path.)'
operationId: auth_cli_claim_page_api_v2_auth_cli_claim__claim_id__get
parameters:
- name: claim_id
in: path
required: true
schema:
type: string
title: Claim Id
- name: ref
in: query
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: Ref
responses:
'200':
description: Successful Response
content:
application/json:
schema: {}
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
tags:
- Auth
post:
summary: Auth Cli Claim Approve
description: 'Legacy ANONYMOUS approve (kept for dev / back-compat). Identity binding happens exclusively via
the magic-link verify endpoint, which approves in-process after proving email control — so this
public endpoint ignores any identity in the body (no claim forgery surface, no shared secret).'
operationId: auth_cli_claim_approve_api_v2_auth_cli_claim__claim_id__post
parameters:
- name: claim_id
in: path
required: true
schema:
type: string
title: Claim Id
requestBody:
content:
application/json:
schema:
type: object
additionalProperties: true
default: {}
title: Body
responses:
'200':
description: Successful Response
content:
application/json:
schema: {}
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
tags:
- Auth
/api/v2/auth/cli/approve:
post:
summary: Auth Cli Approve Signed In
description: 'Instant approve for an ALREADY signed-in browser: the bearer (hf_session) is
the identity proof, so a waiting CLI claim binds to its user without a second magic-link email.
Anonymous/legacy bearers (no bound user) are refused — they prove nothing about an email.
`invite_code` (optional) binds this CLI claim to the invited TEAM workspace — an explicit "join my
waiting CLI into a team" action, so it deliberately differs from the magic-link CLI leg
(`signin.complete`), which binds the CLI to the user''s HOME workspace (personal, or their team if
they own none). Without an invite, approve_claim ensures that home workspace. (Threading an
invite through the magic-link EMAIL round-trip is deferred until the invite UX exists: invites are
single-use, and verify approves two claims, so blind forwarding would consume the invite on one and
split the keys across workspaces.)'
operationId: auth_cli_approve_signed_in_api_v2_auth_cli_approve_post
requestBody:
content:
application/json:
schema:
additionalProperties: true
type: object
title: Body
default: {}
responses:
'200':
description: Successful Response
content:
application/json:
schema: {}
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
security:
- HTTPBearer: []
tags:
- Auth
/api/v2/auth/cli/poll/{claim_id}:
get:
summary: Auth Cli Poll
description: CLI polls here until status=approved, then receives its bearer token. No auth (bootstrap).
operationId: auth_cli_poll_api_v2_auth_cli_poll__claim_id__get
parameters:
- name: claim_id
in: path
required: true
schema:
type: string
title: Claim Id
responses:
'200':
description: Successful Response
content:
application/json:
schema: {}
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
tags:
- Auth
/api/v2/auth/logout:
post:
summary: Auth Logout
description: 'Revoke the caller''s bearer token server-side (dashboard / CLI). Revoked by token hash, NOT by the
resolved workspace — under an `X-Workspace-Id` switch that isn''t the key''s own workspace.'
operationId: auth_logout_api_v2_auth_logout_post
responses:
'200':
description: Successful Response
content:
application/json:
schema: {}
security:
- HTTPBearer: []
tags:
- Auth
/api/v2/auth/magic-link:
post:
summary: Auth Magic Link
description: 'Issue a single-use magic sign-in link and email it. No auth (bootstrap).
`cli_token` (the waiting CLI claim_id) threads the link''s callbackURL so the click finalizes that
claim; absent ⇒ `next` (allowlisted, see `_safe_next`) or a plain dashboard sign-in. The engine
verifies the token itself at /verify — no webengine secret. Delivery failures (incl. a missing
RESEND_API_KEY without the explicit HYREFLOW_DEV_MAIL_LOG=1 dev opt-in) surface as 502.'
operationId: auth_magic_link_api_v2_auth_magic_link_post
requestBody:
content:
application/json:
schema:
additionalProperties: true
type: object
title: Body
required: true
responses:
'200':
description: Successful Response
content:
application/json:
schema: {}
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
tags:
- Auth
/api/v2/auth/magic-link/verify:
post:
summary: Auth Magic Link Verify
description: 'Verify a magic token (single-use) and bind its email to a user. Then either approve the waiting
CLI claim in-process (kind=cli) or mint a fresh dashboard session (kind=session). The token is the
proof of email control — this is what replaces the old X-Hyreflow-Internal handshake.
If the existing user is an unverified password account (legacy takeover target), we instead return
kind=''set_password'' so the real owner can set a fresh password before being signed in.
On failure the 400''s `detail` is a dict carrying a machine-readable `reason`
({"expired","used","unknown","missing"}) alongside the human `message`, so a caller can tell a
genuinely aged-out link apart from a double-click replay or a garbage token — FastAPI renders it as
`{"detail": {...}}`.'
operationId: auth_magic_link_verify_api_v2_auth_magic_link_verify_post
requestBody:
content:
application/json:
schema:
additionalProperties: true
type: object
title: Body
required: true
responses:
'200':
description: Successful Response
content:
application/json:
schema: {}
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
tags:
- Auth
/api/v2/auth/magic-link/verify-code:
post:
summary: Auth Magic Link Verify Code
description: 'Verify the 6-digit code from the sign-in email — the code-first path that keeps an OAuth resume
in the tab that started it. Binds identity exactly like /verify (same _finish_magic tail), so a
code and the link on its row spend each other.
On failure the 400''s `detail` carries a machine-readable `reason` ({"wrong","expired","locked",
"unknown","invalid"}) the sign-in form maps to copy. The per-email guess cap lives in
magic.consume_code (checked before the compare, summed across resends); this route adds a
request cap keyed by the normalized email, since browser requests share the BFF''s source IP.'
operationId: auth_magic_link_verify_code_api_v2_auth_magic_link_verify_code_post
requestBody:
content:
application/json:
schema:
additionalProperties: true
type: object
title: Body
required: true
responses:
'200':
description: Successful Response
content:
application/json:
schema: {}
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
tags:
- Auth
/api/v2/auth/oauth/google/start:
get:
summary: Auth Oauth Google Start
description: 'Kick off Google sign-in: mint a single-use state (bound to any waiting CLI claim, the post-auth
callback, and the invite the sign-in started from) and 302 to Google''s consent screen. 404 when
GOOGLE_CLIENT_ID/SECRET aren''t configured (UI hides the button).'
operationId: auth_oauth_google_start_api_v2_auth_oauth_google_start_get
parameters:
- name: cli_token
in: query
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: Cli Token
- name: next
in: query
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: Next
- name: invite_code
in: query
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: Invite Code
responses:
'200':
description: Successful Response
content:
application/json:
schema: {}
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
tags:
- Auth
/api/v2/auth/oauth/google/callback:
get:
summary: Auth Oauth Google Callback
description: 'Google redirects here. Verify our state, exchange the code for the user''s email, bind identity,
approve any waiting CLI claim, and set the dashboard session cookie — then 302 to the finalize page
(CLI connect) or the dashboard. Any failure bounces to /sign-in?error=connect.'
operationId: auth_oauth_google_callback_api_v2_auth_oauth_google_callback_get
parameters:
- name: state
in: query
required: false
schema:
type: string
default: ''
title: State
- name: code
in: query
required: false
schema:
type: string
default: ''
title: Code
- name: error
in: query
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: Error
responses:
'200':
description: Successful Response
content:
application/json:
schema: {}
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
tags:
- Auth
/api/v2/auth/password/signup:
post:
summary: Auth Password Signup
description: 'Start password sign-up OR reset: create a pending verification row and email a set-password link.
The user chooses their password only after proving email control, so an existing account is not a
refusal — the same link resets it. That also means the response never reveals whether the address is
registered. Returns {ok, pending, email}.'
operationId: auth_password_signup_api_v2_auth_password_signup_post
requestBody:
content:
application/json:
schema:
additionalProperties: true
type: object
title: Body
required: true
responses:
'200':
description: Successful Response
content:
application/json:
schema: {}
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
tags:
- Auth
/api/v2/auth/password/signup/complete:
post:
summary: Auth Password Signup Complete
description: 'Complete password sign-up: consume the pending verification token, set the password, and sign in.
Returns the same {ok, kind, cli_token?, session, next_url?} shape as magic verify, with the
hf_session cookie set by the engine.'
operationId: auth_password_signup_complete_api_v2_auth_password_signup_complete_post
requestBody:
content:
application/json:
schema:
additionalProperties: true
type: object
title: Body
required: true
responses:
'200':
description: Successful Response
content:
application/json:
schema: {}
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
tags:
- Auth
/api/v2/auth/password/login:
post:
summary: Auth Password Login
description: 'Sign in with email/password. 401 on any mismatch (no user / no password set / wrong password / email
not verified — not distinguished, to avoid account enumeration). The engine sets the hf_session cookie.'
operationId: auth_password_login_api_v2_auth_password_login_post
requestBody:
content:
application/json:
schema:
additionalProperties: true
type: object
title: Body
required: true
responses:
'200':
description: Successful Response
content:
application/json:
schema: {}
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
tags:
- Auth
components:
schemas:
HTTPValidationError:
properties:
detail:
items:
$ref: '#/components/schemas/ValidationError'
type: array
title: Detail
type: object
title: HTTPValidationError
ValidationError:
properties:
loc:
items:
anyOf:
- type: string
- type: integer
type: array
title: Location
msg:
type: string
title: Message
type:
type: string
title: Error Type
input:
title: Input
ctx:
type: object
title: Context
type: object
required:
- loc
- msg
- type
title: ValidationError
securitySchemes:
HTTPBearer:
type: http
scheme: bearer