Skip to content

Auth (Reference)

For most clients the login + refresh pair in Getting Started → Authentication is all you need. This page documents the endpoints that aren’t strictly part of the daily loop but are useful for programmatic onboarding (signup) and profile management (me).


Create a new account. Optional profile fields are stored on the account and applied on the first authenticated request.

Auth: None

Only email and password are required. Every profile field below is optional and can be set (or changed) later via PATCH /auth/me.

Terminal window
curl -X POST https://api.hungrymachines.io/auth/signup \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "securepassword",
"location_zip": "92101",
"home_size_sqft": 2000,
"pricing_location": 1
}'
FieldTypeRequiredNotes
emailstringYesMust be unique
passwordstringYesSubject to the account password policy
location_zipstringNoUS zip code, used for weather forecasts
home_size_sqftintegerNoUsed to estimate appliance power draw
pricing_locationintegerNoRate-catalog id (see available_pricing_zones from GET /api/v1/rates; default 1)
newsletter_opt_inbooleanNoNewsletter checkbox state. Omitted means opted in.

When the account doesn’t require email confirmation, the response is a full session:

{
"access_token": "eyJhbGciOi...",
"refresh_token": "JKLrM3...",
"expires_in": 3600,
"expires_at": 1762450800,
"token_type": "bearer",
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@example.com"
}
}

Response (200) — email confirmation pending

Section titled “Response (200) — email confirmation pending”

When email confirmation is required, the session fields (access_token, refresh_token, expires_in, expires_at, token_type) may be absent and the body contains only the pending user row:

{
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@example.com"
}
}

Clients must handle both shapes — typically by treating the absence of access_token as “show a confirm-your-email screen.”

StatusDetailCause
400"User already registered"Email is already in use (or another signup failure message)
422"Password should be at least 6 characters"Password policy rejection
502"Auth service unreachable"Identity provider upstream failure
503"Auth not configured"Auth not configured on the API

Get the current user’s profile and subscription tier. Creates the profile row on first call.

Auth: Required (Bearer JWT)

Terminal window
curl https://api.hungrymachines.io/auth/me \
-H "Authorization: Bearer YOUR_TOKEN"
{
"user_id": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@example.com",
"location_zip": "92101",
"home_size_sqft": 2000,
"pricing_location": 1,
"timezone": "America/New_York",
"subscription_tier": "free",
"weather_entity_id": "weather.home"
}
FieldTypeNotes
user_idstring (UUID)Account id (matches the JWT subject)
emailstring
location_zipstringMay be empty
home_size_sqftintegerMay be 0
pricing_locationintegerRate-catalog id (see available_pricing_zones)
timezonestringIANA timezone
subscription_tierstring"free" or "premium". Defaults to "free".
weather_entity_idstringThe Home Assistant weather.* entity the user picked for forecasts. Empty when unset (a fallback weather source is then used).
StatusDetailCause
401"Not authenticated" / "Invalid token" / "Token expired"Missing, malformed, or expired token
503"Database unavailable" / "Auth not configured"Backend dependency unavailable

Update the profile row. Send only the fields you want to change.

Auth: Required (Bearer JWT)

All fields are optional — include only what you want to change. Sending null clears the value.

Terminal window
curl -X PATCH https://api.hungrymachines.io/auth/me \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"location_zip": "94110",
"home_size_sqft": 1800,
"pricing_location": 3,
"timezone": "America/Los_Angeles"
}'
{
"location_zip": "94110",
"home_size_sqft": 1800,
"pricing_location": 3,
"timezone": "America/Los_Angeles",
"weather_entity_id": "weather.home"
}
FieldTypeValidation
location_zipstring | nullUS zip code
home_size_sqftinteger | null
pricing_locationinteger | nullRate-catalog id (see available_pricing_zones)
timezonestring | nullIANA timezone
weather_entity_idstring | nullHA weather.* entity id. The nightly forecast resolver prefers a pushed forecast from this entity over the fallback source.

Returns the full profile object after the update — same shape as GET /auth/me.

StatusDetailCause
401"Not authenticated"Missing or invalid token
503"Database unavailable"Database not configured or write failed