874a242149
- Add v1.2.0 version badge to app header - Update CHANGELOG with v1.2.0 entries - Bump manifest.json version to 1.2.0 - Bump OpenAPI spec version to 1.2.0
692 lines
16 KiB
YAML
692 lines
16 KiB
YAML
openapi: "3.1.0"
|
|
info:
|
|
title: EverShelf API
|
|
description: |
|
|
REST API for EverShelf — a self-hosted pantry management system.
|
|
All endpoints use the query parameter `action` to determine the operation.
|
|
|
|
**Base URL:** `api/index.php?action={action_name}`
|
|
|
|
Rate limits apply:
|
|
- General: 120 requests/minute
|
|
- AI endpoints: 15 requests/minute
|
|
- Login endpoints: 5 requests/minute
|
|
version: "1.2.0"
|
|
contact:
|
|
name: Stimpfl Daniel
|
|
email: evershelfproject@gmail.com
|
|
license:
|
|
name: MIT
|
|
url: https://opensource.org/licenses/MIT
|
|
|
|
servers:
|
|
- url: /api
|
|
description: Local server
|
|
|
|
paths:
|
|
/index.php?action=search_barcode:
|
|
get:
|
|
summary: Search product by barcode in local database
|
|
tags: [Products]
|
|
parameters:
|
|
- name: barcode
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Product found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Product"
|
|
"404":
|
|
description: Product not found
|
|
|
|
/index.php?action=lookup_barcode:
|
|
get:
|
|
summary: Lookup barcode on Open Food Facts
|
|
tags: [Products]
|
|
parameters:
|
|
- name: barcode
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Product data from Open Food Facts
|
|
|
|
/index.php?action=product_save:
|
|
post:
|
|
summary: Create or update a product
|
|
tags: [Products]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ProductInput"
|
|
responses:
|
|
"200":
|
|
description: Product saved
|
|
|
|
/index.php?action=product_get:
|
|
get:
|
|
summary: Get product by ID
|
|
tags: [Products]
|
|
parameters:
|
|
- name: id
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: integer
|
|
responses:
|
|
"200":
|
|
description: Product details
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Product"
|
|
|
|
/index.php?action=product_delete:
|
|
post:
|
|
summary: Delete a product
|
|
tags: [Products]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: integer
|
|
responses:
|
|
"200":
|
|
description: Product deleted
|
|
|
|
/index.php?action=products_list:
|
|
get:
|
|
summary: List all products
|
|
tags: [Products]
|
|
responses:
|
|
"200":
|
|
description: Array of all products
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Product"
|
|
|
|
/index.php?action=products_search:
|
|
get:
|
|
summary: Search products by name
|
|
tags: [Products]
|
|
parameters:
|
|
- name: q
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Matching products
|
|
|
|
/index.php?action=inventory_list:
|
|
get:
|
|
summary: List all inventory items
|
|
tags: [Inventory]
|
|
responses:
|
|
"200":
|
|
description: Inventory items grouped by product
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/InventoryItem"
|
|
|
|
/index.php?action=inventory_add:
|
|
post:
|
|
summary: Add item to inventory
|
|
tags: [Inventory]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [product_id, quantity, location]
|
|
properties:
|
|
product_id:
|
|
type: integer
|
|
quantity:
|
|
type: number
|
|
location:
|
|
type: string
|
|
enum: [dispensa, frigo, freezer, altro]
|
|
expiry_date:
|
|
type: string
|
|
format: date
|
|
conf_size:
|
|
type: number
|
|
vacuum:
|
|
type: boolean
|
|
responses:
|
|
"200":
|
|
description: Item added to inventory
|
|
|
|
/index.php?action=inventory_use:
|
|
post:
|
|
summary: Use/consume items from inventory
|
|
tags: [Inventory]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [product_id, quantity, location]
|
|
properties:
|
|
product_id:
|
|
type: integer
|
|
quantity:
|
|
type: number
|
|
location:
|
|
type: string
|
|
use_all:
|
|
type: boolean
|
|
responses:
|
|
"200":
|
|
description: Item consumed
|
|
|
|
/index.php?action=inventory_update:
|
|
post:
|
|
summary: Update an inventory entry
|
|
tags: [Inventory]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [id]
|
|
properties:
|
|
id:
|
|
type: integer
|
|
quantity:
|
|
type: number
|
|
location:
|
|
type: string
|
|
expiry_date:
|
|
type: string
|
|
format: date
|
|
responses:
|
|
"200":
|
|
description: Inventory entry updated
|
|
|
|
/index.php?action=inventory_delete:
|
|
post:
|
|
summary: Remove an inventory entry
|
|
tags: [Inventory]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [id]
|
|
properties:
|
|
id:
|
|
type: integer
|
|
responses:
|
|
"200":
|
|
description: Inventory entry removed
|
|
|
|
/index.php?action=inventory_summary:
|
|
get:
|
|
summary: Get inventory summary (counts per location)
|
|
tags: [Inventory]
|
|
responses:
|
|
"200":
|
|
description: Summary object with counts
|
|
|
|
/index.php?action=transactions_list:
|
|
get:
|
|
summary: List operations log
|
|
tags: [Log]
|
|
parameters:
|
|
- name: limit
|
|
in: query
|
|
schema:
|
|
type: integer
|
|
default: 50
|
|
- name: offset
|
|
in: query
|
|
schema:
|
|
type: integer
|
|
default: 0
|
|
responses:
|
|
"200":
|
|
description: Array of transactions
|
|
|
|
/index.php?action=stats:
|
|
get:
|
|
summary: Get waste/consumption statistics
|
|
tags: [Log]
|
|
responses:
|
|
"200":
|
|
description: Statistics for the last 30 days
|
|
|
|
/index.php?action=gemini_expiry:
|
|
post:
|
|
summary: Use AI to read expiry date from image
|
|
tags: [AI / Gemini]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
image:
|
|
type: string
|
|
description: Base64-encoded image
|
|
responses:
|
|
"200":
|
|
description: Parsed expiry date
|
|
|
|
/index.php?action=generate_recipe:
|
|
post:
|
|
summary: Generate a recipe based on available ingredients
|
|
tags: [AI / Gemini]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
persons:
|
|
type: integer
|
|
preferences:
|
|
type: object
|
|
responses:
|
|
"200":
|
|
description: Generated recipe
|
|
|
|
/index.php?action=gemini_identify:
|
|
post:
|
|
summary: Identify a product from photo using AI
|
|
tags: [AI / Gemini]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
image:
|
|
type: string
|
|
description: Base64-encoded image
|
|
responses:
|
|
"200":
|
|
description: Identified product data
|
|
|
|
/index.php?action=gemini_chat:
|
|
post:
|
|
summary: Chat with Gemini AI kitchen assistant
|
|
tags: [AI / Gemini]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
message:
|
|
type: string
|
|
history:
|
|
type: array
|
|
items:
|
|
type: object
|
|
responses:
|
|
"200":
|
|
description: AI response
|
|
|
|
/index.php?action=bring_list:
|
|
get:
|
|
summary: Get Bring! shopping list
|
|
tags: [Bring! Integration]
|
|
responses:
|
|
"200":
|
|
description: Shopping list items
|
|
|
|
/index.php?action=bring_add:
|
|
post:
|
|
summary: Add item to Bring! shopping list
|
|
tags: [Bring! Integration]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
name:
|
|
type: string
|
|
spec:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Item added
|
|
|
|
/index.php?action=bring_remove:
|
|
post:
|
|
summary: Remove item from Bring! shopping list
|
|
tags: [Bring! Integration]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
name:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Item removed
|
|
|
|
/index.php?action=bring_suggest:
|
|
post:
|
|
summary: Get AI shopping suggestions
|
|
tags: [Bring! Integration]
|
|
responses:
|
|
"200":
|
|
description: AI-generated shopping suggestions
|
|
|
|
/index.php?action=smart_shopping:
|
|
get:
|
|
summary: Get smart shopping predictions
|
|
tags: [Bring! Integration]
|
|
responses:
|
|
"200":
|
|
description: Predicted shopping needs
|
|
|
|
/index.php?action=save_settings:
|
|
post:
|
|
summary: Save server-side settings (.env values)
|
|
tags: [Settings]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
responses:
|
|
"200":
|
|
description: Settings saved
|
|
|
|
/index.php?action=get_settings:
|
|
get:
|
|
summary: Get server settings (masked passwords)
|
|
tags: [Settings]
|
|
responses:
|
|
"200":
|
|
description: Current settings
|
|
|
|
/index.php?action=app_settings_get:
|
|
get:
|
|
summary: Get application settings from database
|
|
tags: [Settings]
|
|
responses:
|
|
"200":
|
|
description: App settings object
|
|
|
|
/index.php?action=app_settings_save:
|
|
post:
|
|
summary: Save application settings to database
|
|
tags: [Settings]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
responses:
|
|
"200":
|
|
description: App settings saved
|
|
|
|
/index.php?action=recipes_list:
|
|
get:
|
|
summary: List saved recipes
|
|
tags: [Recipes]
|
|
responses:
|
|
"200":
|
|
description: Array of saved recipes
|
|
|
|
/index.php?action=recipes_save:
|
|
post:
|
|
summary: Save a recipe
|
|
tags: [Recipes]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
responses:
|
|
"200":
|
|
description: Recipe saved
|
|
|
|
/index.php?action=recipes_delete:
|
|
post:
|
|
summary: Delete a recipe
|
|
tags: [Recipes]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: integer
|
|
responses:
|
|
"200":
|
|
description: Recipe deleted
|
|
|
|
/index.php?action=dupliclick_login:
|
|
post:
|
|
summary: Login to DupliClick (online shopping)
|
|
tags: [DupliClick]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
email:
|
|
type: string
|
|
password:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Login successful
|
|
|
|
/index.php?action=dupliclick_search:
|
|
get:
|
|
summary: Search DupliClick product catalog
|
|
tags: [DupliClick]
|
|
parameters:
|
|
- name: q
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Search results
|
|
|
|
/index.php?action=tts_proxy:
|
|
post:
|
|
summary: Proxy TTS request to external endpoint
|
|
tags: [TTS]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
text:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: TTS request sent
|
|
|
|
/index.php?action=expiry_history:
|
|
get:
|
|
summary: Get expiry scan history for a product
|
|
tags: [Inventory]
|
|
parameters:
|
|
- name: product_id
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: integer
|
|
responses:
|
|
"200":
|
|
description: Expiry history entries
|
|
|
|
components:
|
|
schemas:
|
|
Product:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: integer
|
|
name:
|
|
type: string
|
|
brand:
|
|
type: string
|
|
barcode:
|
|
type: string
|
|
category:
|
|
type: string
|
|
enum:
|
|
- latticini
|
|
- carne
|
|
- pesce
|
|
- frutta
|
|
- verdura
|
|
- pasta
|
|
- pane
|
|
- surgelati
|
|
- bevande
|
|
- condimenti
|
|
- snack
|
|
- conserve
|
|
- cereali
|
|
- igiene
|
|
- pulizia
|
|
- altro
|
|
unit:
|
|
type: string
|
|
enum: [pz, conf, g, ml]
|
|
default_quantity:
|
|
type: number
|
|
package_size:
|
|
type: number
|
|
package_unit:
|
|
type: string
|
|
notes:
|
|
type: string
|
|
created_at:
|
|
type: string
|
|
format: date-time
|
|
|
|
ProductInput:
|
|
type: object
|
|
required: [name]
|
|
properties:
|
|
id:
|
|
type: integer
|
|
description: If provided, updates existing product
|
|
name:
|
|
type: string
|
|
brand:
|
|
type: string
|
|
barcode:
|
|
type: string
|
|
category:
|
|
type: string
|
|
unit:
|
|
type: string
|
|
default_quantity:
|
|
type: number
|
|
package_size:
|
|
type: number
|
|
|
|
InventoryItem:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: integer
|
|
product_id:
|
|
type: integer
|
|
product_name:
|
|
type: string
|
|
quantity:
|
|
type: number
|
|
location:
|
|
type: string
|
|
expiry_date:
|
|
type: string
|
|
format: date
|
|
opened:
|
|
type: boolean
|
|
created_at:
|
|
type: string
|
|
format: date-time
|
|
|
|
responses:
|
|
TooManyRequests:
|
|
description: Rate limit exceeded
|
|
headers:
|
|
Retry-After:
|
|
schema:
|
|
type: integer
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
|
|
tags:
|
|
- name: Products
|
|
description: Product catalog management
|
|
- name: Inventory
|
|
description: Inventory tracking (stock in/out)
|
|
- name: Log
|
|
description: Operations log and statistics
|
|
- name: AI / Gemini
|
|
description: Google Gemini AI integration (identification, recipes, chat)
|
|
- name: Bring! Integration
|
|
description: Bring! shopping list integration
|
|
- name: Recipes
|
|
description: Recipe storage
|
|
- name: Settings
|
|
description: Application and server settings
|
|
- name: DupliClick
|
|
description: DupliClick online shopping integration
|
|
- name: TTS
|
|
description: Text-to-Speech proxy
|