For Developers

API Documentation

Integrate HaoChi into your applications. Authentication, profile management and more.

Overview

Base URL

https://haochi.it/api

Required headers

All requests must include the following headers:

Content-Type: application/json
Accept: application/json

Response format

All responses are in JSON format with the following structure:

Example response 200

{
  "success": true,
  "message": "...",
  "data": { ... }
}

Example response 201

{
  "success": true,
  "message": "...",
  "data": { ... }
}

Authentication

User endpoints require a Bearer token in the Authorization header:

Authorization: Bearer <token>

API Key

Product endpoints require a static API key in the X-Api-Key header:

X-Api-Key: <api_key>

Rate Limiting

Authentication endpoints are limited to 5 requests per minute per IP. Product endpoints are limited to 30 requests per minute per IP.

Error responses

Error responses 401

{
  "success": false,
  "message": "Invalid credentials."
}

Error responses 422

{
  "message": "The email field is required.",
  "errors": {
    "email": [
      "The email field is required."
    ]
  }
}
POST /api/auth/register

Register

Create a new user account with email and password.

Parameters

name
string Required

User's first name

surname
string Required

User's last name

email
string Required

Email address

password
string Required

Password (minimum 8 characters)

password_confirmation
string Required

Password confirmation

Example response 201

{
  "success": true,
  "message": "Registration successful.",
  "data": {
    "user": {
      "id": 1,
      "name": "Marco",
      "surname": "Rossi",
      "full_name": "Marco Rossi",
      "email": "marco@example.com",
      "email_verified": false,
      "avatar": null,
      "google_linked": false,
      "google_locale": null,
      "created_at": "2025-01-15T10:30:00+00:00",
      "updated_at": "2025-01-15T10:30:00+00:00"
    },
    "token": "1|abc123..."
  }
}
POST /api/auth/login

Login

Authenticate an existing user with email and password.

Note: If the user registered via Google and has no password, the response will be a 401 with the message: "Invalid credentials. If you signed up with Google, please use Google Sign-In."

Parameters

email
string Required

Email address

password
string Required

Password (minimum 8 characters)

Example response 200

{
  "success": true,
  "message": "Login successful.",
  "data": {
    "user": {
      "id": 1,
      "name": "Marco",
      "surname": "Rossi",
      "full_name": "Marco Rossi",
      "email": "marco@example.com",
      "email_verified": false,
      "avatar": null,
      "google_linked": false,
      "google_locale": null,
      "created_at": "2025-01-15T10:30:00+00:00",
      "updated_at": "2025-01-15T10:30:00+00:00"
    },
    "token": "2|def456..."
  }
}
POST /api/auth/google

Google Sign-In

Authenticate or register a user via Google ID token. If the account does not exist, it will be created automatically.

Parameters

id_token
string Required

ID token obtained from Google Sign-In

Example response 200

{
  "success": true,
  "message": "Login via Google successful.",
  "data": {
    "user": {
      "id": 2,
      "name": "Laura",
      "surname": "Bianchi",
      "full_name": "Laura Bianchi",
      "email": "laura@gmail.com",
      "email_verified": true,
      "avatar": "https://lh3.googleusercontent.com/...",
      "google_linked": true,
      "google_locale": "it",
      "created_at": "2025-01-15T10:30:00+00:00",
      "updated_at": "2025-01-15T10:30:00+00:00"
    },
    "token": "3|ghi789...",
    "is_new": false
  }
}
GET /api/user Requires authentication

User profile

Retrieve the authenticated user's profile.

Example response 200

{
  "success": true,
  "message": "User profile retrieved.",
  "data": {
    "id": 1,
    "name": "Marco",
    "surname": "Rossi",
    "full_name": "Marco Rossi",
    "email": "marco@example.com",
    "email_verified": false,
    "avatar": null,
    "google_linked": false,
    "google_locale": null,
    "created_at": "2025-01-15T10:30:00+00:00",
    "updated_at": "2025-01-15T10:30:00+00:00"
  }
}
PUT /api/user Requires authentication

Update profile

Update the authenticated user's profile data. Only send the fields you want to change.

Parameters

name
string Optional

User's first name

surname
string Optional

User's last name

email
string Optional

Email address

Example response 200

{
  "success": true,
  "message": "Profile updated.",
  "data": {
    "id": 1,
    "name": "Marco",
    "surname": "Verdi",
    "full_name": "Marco Verdi",
    "email": "marco@example.com",
    "email_verified": false,
    "avatar": null,
    "google_linked": false,
    "google_locale": null,
    "created_at": "2025-01-15T10:30:00+00:00",
    "updated_at": "2025-01-15T11:00:00+00:00"
  }
}
POST /api/auth/logout Requires authentication

Logout

Revoke the current access token of the authenticated user.

Example response 200

{
  "success": true,
  "message": "Logged out successfully.",
  "data": null
}

User resource

All endpoints that return user data use the following structure:

id integer

Unique identifier

name string

First name

surname string

Last name

full_name string

Full name

email string

Email address

email_verified boolean

Whether the email is verified

avatar string

Avatar URL (from Google)

google_linked boolean

Whether a Google account is linked

google_locale string

Google account locale

created_at string

Creation date (ISO 8601)

updated_at string

Last update date (ISO 8601)

Product resource

The product lookup endpoint returns the following structure:

id integer

Unique identifier

barcode string

EAN barcode

product_name string

Product name

product_name_it string

Product name in Italian

brand string

Brand

image_url string

Product image URL

nutriscore_grade string

Nutri-Score grade (a-e)

ecoscore_grade string

Eco-Score grade (a-e)

nova_group integer

NOVA group (1-4)

Nutritional values (per 100g)

nutriments.energy_kcal decimal

Energy (kcal)

nutriments.fat decimal

Fat (g)

nutriments.saturated_fat decimal

Saturated fat (g)

nutriments.carbohydrates decimal

Carbohydrates (g)

nutriments.sugars decimal

Sugars (g)

nutriments.fiber decimal

Fiber (g)

nutriments.proteins decimal

Proteins (g)

nutriments.salt decimal

Salt (g)

nutriments.sodium decimal

Sodium (g)

Dietary filters

filters.is_vegetarian boolean

Suitable for vegetarians

filters.is_vegan boolean

Suitable for vegans

filters.is_palm_oil_free boolean

Palm oil free

filters.is_gluten_free boolean

Gluten free

filters.is_lactose_free boolean

Lactose free

filters.is_low_carbon boolean

Low environmental impact

filters.is_diabetic_friendly boolean

Suitable for diabetics

filters.is_ketogenic boolean

Suitable for ketogenic diet

GET /api/products/{barcode} Requires API Key

Product lookup

Look up a food product by barcode (EAN). The product is fetched from OpenFoodFacts and cached locally for 7 days.

Note: The response includes a "source" field indicating the data origin: "cache" if served from local database, "openfoodfacts" if freshly fetched from the OpenFoodFacts API.

Parameters

barcode
string Required

EAN barcode of the product (13 digits)

Example response 200

{
  "success": true,
  "message": "Product retrieved.",
  "source": "cache",
  "data": {
    "id": 1,
    "barcode": "3017620422003",
    "product_name": "Nutella",
    "product_name_it": "Nutella",
    "brand": "Ferrero",
    "image_url": "https://images.openfoodfacts.net/...",
    "nutriscore_grade": "e",
    "ecoscore_grade": null,
    "nova_group": 4,
    "nutriments": {
      "energy_kcal": "539.000",
      "fat": "30.900",
      "saturated_fat": "10.600",
      "carbohydrates": "57.500",
      "sugars": "56.300",
      "fiber": "0.000",
      "proteins": "6.300",
      "salt": "0.107",
      "sodium": "0.043"
    },
    "filters": {
      "is_vegetarian": true,
      "is_vegan": false,
      "is_palm_oil_free": false,
      "is_gluten_free": true,
      "is_lactose_free": false,
      "is_low_carbon": false,
      "is_diabetic_friendly": false,
      "is_ketogenic": false
    },
    "last_fetched_at": "2026-02-17T10:55:47+00:00",
    "created_at": "2026-02-17T10:55:47+00:00",
    "updated_at": "2026-02-17T10:55:47+00:00"
  }
}

Error responses 404

{
  "success": false,
  "message": "Product not found."
}

HTTP Status Codes

The API uses the following HTTP status codes:

Status Description
200 Request completed successfully
201 Resource created successfully
401 Not authenticated or invalid credentials
403 Access denied
404 Resource not found
422 Validation error in submitted data
429 Too many requests (rate limit exceeded)
500 Internal server error
In development

Help us build HaoChi

We're working hard to create the app you deserve. Support the project and get 1 year of Pro features access at launch!

Buy us a coffee