REST API
API versions
The REST API is served under /api/v2. The previous /api/v1 API was deprecated with the 2.0.0 release and removed in 2.4.0; there is no compatibility layer left. If you still call /api/v1, switch the base path to /api/v2 and note the two endpoints that also changed location:
/api/v1/fddbdata/migrateToInfluxDb→/api/v2/migration/toInfluxDb/api/v1/fddbdata/statsand/stats/averages→/api/v2/statsand/api/v2/stats/averages
Overview
This API allows you to retrieve and export data from the database. The endpoints support operations such as retrieving all data, filtering by date, searching for specific products, and exporting data for a specified date range.
Interactive API reference
Your own instance serves an always-current specification, generated from the running code:
/swagger-ui.html | Swagger UI, with "try it out" enabled against your own data |
/api-docs | The OpenAPI document itself, as JSON |
That generated document is the authoritative one — it cannot disagree with the code it was produced from. A snapshot is also committed to this repository for reading without a running instance: fddb-exporter-api-v2.yaml. It is regenerated by hand, so if the two ever disagree, believe /api-docs.
Both paths are unauthenticated, like the rest of the application, and Swagger UI's "try it out" executes
real requests — including exports. Do not expose them publicly; see Securing your instance.
Example responses:
- example response for querying data from the database
- example response when querying a product name
- example response when retrieving stats
Endpoints
Retrieve All Data
GET
/api/v2/fddbdata
Description: Retrieves all data from the database as JSON.
Response: A JSON array containing all entries (see full example response of an entry in this array).
json[ { "id": "66d18658bc73187ea859f67c", "date": "2024-08-28", "products": [ { "name": "Panini Rolls", "amount": "75 g", "calories": 176.0, "fat": 2.2, "carbs": 33.8, "protein": 2.8, "link": "/db/en/food/schaer_panini_rolls/index.html" }, [...] ], "totalCalories": 2437.0, "totalFat": 93.5, "totalCarbs": 285.5, "totalSugar": 76.3, "totalProtein": 103.9, "totalFibre": 10.3 }, [...] ]
Retrieve Data by Date
GET
/api/v2/fddbdata/{date}
Description: Retrieves data for a specific day from the database as JSON.
Path Parameter:
date(required): The specific date inYYYY-MM-DDformat.
Example:
/api/v2/fddbdata/2024-08-24Response: A JSON object containing the data for the specified date (see full example response).
json{ "id": "66d18658bc73187ea859f67c", "date": "2024-08-28", "products": [ { "name": "Panini Rolls", "amount": "75 g", "calories": 176.0, "fat": 2.2, "carbs": 33.8, "protein": 2.8, "link": "/db/en/food/schaer_panini_rolls/index.html" }, [...] ], "totalCalories": 2437.0, "totalFat": 93.5, "totalCarbs": 285.5, "totalSugar": 76.3, "totalProtein": 103.9, "totalFibre": 10.3 }
Retrieve Data by Date Range 2.3.0+
GET
/api/v2/fddbdata/range?fromDate={startDate}&toDate={endDate}&includeProducts={bool}
- Description: Retrieves all entries between two dates (both inclusive), oldest first. Product lists are omitted unless explicitly requested, since a long range with products is a very large response.
- Query Parameters:
fromDate(required): The start date inYYYY-MM-DDformat.toDate(required): The end date inYYYY-MM-DDformat.includeProducts(optional): Whether to include each day's product list. Defaults tofalse.
- Example:
/api/v2/fddbdata/range?fromDate=2024-12-01&toDate=2024-12-31 - Response: A JSON array of entries, same shape as Retrieve All Data.
- Error Responses:
- Returns HTTP 400 Bad Request if
fromDateis aftertoDate. - Returns HTTP 400 Bad Request if the range exceeds 366 days.
- Returns HTTP 400 Bad Request if
Search Products by Name
GET
/api/v2/fddbdata/products?name={product}
Description: Retrieves all entries matching the given product name as JSON. The search is fuzzy, allowing for partial matches. Optionally you can restrict results to specific days of the week, a date range, and/or cap the number of results.
Query Parameters:
name(required): The name of the product to search for.days(optional): One or more day names (ISO weekday names) to filter results by day-of-week. Accepts a comma-separated list of values. Valid values:MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY.fromDate(optional): Restrict matches to this date and later, format:YYYY-MM-DD.toDate(optional): Restrict matches to this date and earlier, format:YYYY-MM-DD.limit(optional): Maximum number of results to return.- If
daysis omitted or empty, the endpoint returns matches for all dates. - If one or more days are provided, the endpoint returns only the product occurrences whose date falls on any of the specified weekdays.
- If
Examples:
All matches for "Strawberry":
/api/v2/fddbdata/products?name=StrawberryMatches for "Banana" that occurred on Mondays only:
/api/v2/fddbdata/products?name=Banana&days=MONDAYMatches for "Banana" that occurred on Mondays and Saturdays:
/api/v2/fddbdata/products?name=Banana&days=MONDAY,SATURDAYLatest 10 matches for "Banana" in 2024:
/api/v2/fddbdata/products?name=Banana&fromDate=2024-01-01&toDate=2024-12-31&limit=10
Behavior notes:
- The
daysparameter uses the standard JavaDayOfWeeknames (ISO weekdays). Provide the weekday names in uppercase to match the enum values; the OpenAPI spec documents the permitted values. - The filtering is performed server-side in the v2 API. The response contains a list of objects with the
dateand aproductobject. When filtered by days, only those entries whosedate's weekday matches any of the provided days are returned.
- The
Response: A JSON array containing all matching entries (see full example response).
json[ { "date": "2023-01-06", "product": { "name": "Pizza Brot", "amount": "150 g", "calories": 391.0, "fat": 5.1, "carbs": 71.1, "protein": 15.0, "link": "/db/en/food/marziale_pizza_brot/index.html" } }, [...] ]Error Responses:
- Returns HTTP 400 Bad Request if
fromDateis aftertoDate.
- Returns HTTP 400 Bad Request if
List Distinct Product Names 2.3.0+
GET
/api/v2/fddbdata/products/distinct?search={term}&limit={amount}
Description: Lists the distinct product names in the database, so a fuzzy term (e.g. "oats") can be resolved to the exact, brand-prefixed name FDDB stores (e.g. "Haferflocken kernig").
Query Parameters:
search(optional): Case-insensitive substring the name has to contain. If omitted, all distinct names are considered.limit(optional): Maximum number of names to return (1-1000). Defaults to100.
Example:
/api/v2/fddbdata/products/distinct?search=hafer&limit=20Response: A JSON array of matching names in alphabetical order.
json[ "Haferflocken kernig", "Haferflocken zart", [...] ]
Get Product Summary 2.3.0+
GET
/api/v2/fddbdata/products/summary?name={product}&fromDate={startDate}&toDate={endDate}
Description: Aggregates every occurrence of the products matching a search term into a single summary: how often they were logged, first and last date, the totals they contributed, and the weekday distribution.
Query Parameters:
name(required): The product name to search for.fromDate(optional): Restrict the aggregation to this date and later, format:YYYY-MM-DD.toDate(optional): Restrict the aggregation to this date and earlier, format:YYYY-MM-DD.
Example:
/api/v2/fddbdata/products/summary?name=HaferflockenResponse: A JSON object containing the aggregated summary.
json{ "searchTerm": "haferflocken", "matchedProductNames": [ "Haferflocken kernig", "Haferflocken zart" ], "timesEaten": 42, "firstDate": "2024-01-03", "lastDate": "2024-12-19", "totalCalories": 12600.5, "totalFat": 310.2, "totalCarbs": 1850.7, "totalProtein": 540.3, "averageCalories": 300.0, "weekdayDistribution": { "MONDAY": 8, "TUESDAY": 5, "WEDNESDAY": 6, "THURSDAY": 7, "FRIDAY": 6, "SATURDAY": 5, "SUNDAY": 5 } }Error Responses:
- Returns HTTP 400 Bad Request if
fromDateis aftertoDate.
- Returns HTTP 400 Bad Request if
Get Top Products 2.3.0+
GET
/api/v2/fddbdata/products/top?by={ranking}&fromDate={startDate}&toDate={endDate}&limit={amount}
Description: Ranks products by how often they were logged (
FREQUENCY) or by the nutrient totals they contributed - "what do I actually eat the most, and where do my calories come from?"Query Parameters:
by(optional): Ranking criterion. Valid values:FREQUENCY,CALORIES,FAT,CARBS,PROTEIN. Defaults toFREQUENCY.fromDate(optional): Restrict the ranking to this date and later, format:YYYY-MM-DD.toDate(optional): Restrict the ranking to this date and earlier, format:YYYY-MM-DD.limit(optional): Maximum number of products to return (1-500). Defaults to20.
Example:
/api/v2/fddbdata/products/top?by=CALORIES&limit=10Response: A JSON array of ranked products, highest first.
json[ { "name": "Haferflocken kernig", "timesEaten": 42, "totalCalories": 12600.5, "totalFat": 310.2, "totalCarbs": 1850.7, "totalProtein": 540.3, "averageCalories": 300.0 }, [...] ]Error Responses:
- Returns HTTP 400 Bad Request if
fromDateis aftertoDate.
- Returns HTTP 400 Bad Request if
Export Data by Date Range
POST
/api/v2/fddbdata
Description: Exports all entries within a specified date range.
Request Body:
fromDate(required): The start date inYYYY-MM-DDformat.toDate(required): The end date inYYYY-MM-DDformat.
Example Payload:
json{ "fromDate": "2021-05-13", "toDate": "2021-08-18" }Response: A JSON object containing the data:
json{ "successfulDays": [ "2024-08-30", "2024-08-31" ], "unsuccessfulDays": [ "2024-08-29" ] }Error Responses:
- Returns HTTP 400 Bad Request if
fromDateis aftertoDate. - Returns HTTP 409 Conflict if another export is already running - see only one export at a time. The request is not queued; retry it once the running export has finished.
- Returns HTTP 500 Internal Server Error if logging in to fddb.info fails.
- Returns HTTP 400 Bad Request if
Export Data for Last N Days
GET
/api/v2/fddbdata/export?days={amount}&includeToday={bool}
Description: Exports entries for the last specified number of days.
Query Parameters:
days(required): The number of days to export.includeToday(optional): Whether to include the current day in the export. (trueorfalse)
Example:
/api/v2/fddbdata/export?days=5&includeToday=trueResponse: A JSON object containing the data:
json{ "successfulDays": [ "2024-08-30", "2024-08-31" ], "unsuccessfulDays": [ "2024-08-29" ] }Error Responses:
- Returns HTTP 400 Bad Request if
daysis outside the window configured byFDDB-EXPORTER_FDDB_MIN-DAYS-BACKandFDDB-EXPORTER_FDDB_MAX-DAYS-BACK(1-365 by default). - Returns HTTP 409 Conflict if another export is already running - see only one export at a time. The request is not queued; retry it once the running export has finished.
- Returns HTTP 500 Internal Server Error if logging in to fddb.info fails.
- Returns HTTP 400 Bad Request if
Retrieve Stats to Data
GET
/api/v2/stats
Description: Retrieve the stats to the saved data.
Note: The
last7DaysAverageandlast30DaysAveragefields have been removed from this endpoint. Use the new rolling averages endpoint for flexible period-based averages.Note:
missingDaysCount,currentStreakandlongestStreakarenullwhen MongoDB is not configured, since they require querying individual entries rather than aggregated totals.currentStreakonly counts today once it has an entry, so a day still in progress does not break the streak.Response: A JSON object containing the data (see example response).
json{ "amountEntries": 606, "firstEntryDate": "2023-01-01", "lastEntryDate": "2024-12-22", "mostRecentMissingDay": "2024-12-20", "missingDaysCount": 18, "currentStreak": 2, "longestStreak": 94, "entryPercentage": 95.1, "uniqueProducts": 150, "averageTotals": { "avgTotalCalories": 2505.7, "avgTotalFat": 125.7, "avgTotalCarbs": 204.4, "avgTotalSugar": 63.4, "avgTotalProtein": 118.0, "avgTotalFibre": 18.4 }, "highestCaloriesDay": { "date": "2024-07-31", "total": 5317.0 }, "highestFatDay": { "date": "2023-09-23", "total": 260.3 }, "highestCarbsDay": { "date": "2024-07-31", "total": 501.7 }, "highestProteinDay": { "date": "2024-08-03", "total": 234.1 }, "highestFibreDay": { "date": "2023-05-09", "total": 53.8 }, "highestSugarDay": { "date": "2023-10-21", "total": 220.4 } }
Retrieve Rolling Averages
GET
/api/v2/stats/averages?fromDate={startDate}&toDate={endDate}
Description: Retrieve rolling averages for a specified date range. This endpoint calculates averages for all entries between the from and to dates (inclusive).
Query Parameters:
fromDate(required): The start date inYYYY-MM-DDformat.toDate(required): The end date inYYYY-MM-DDformat.
Example:
/api/v2/stats/averages?fromDate=2024-01-01&toDate=2024-01-31Response: A JSON object containing the rolling averages (see example response).
json{ "fromDate": "2024-01-01", "toDate": "2024-01-31", "averages": { "avgTotalCalories": 3054.4, "avgTotalFat": 123.9, "avgTotalCarbs": 303.7, "avgTotalSugar": 85.6, "avgTotalProtein": 136.8, "avgTotalFibre": 25.8 } }Error Responses:
- Returns HTTP 400 Bad Request if
fromDateis aftertoDate. - Returns HTTP 400 Bad Request if dates are not in the format
YYYY-MM-DD.
- Returns HTTP 400 Bad Request if
Get a Trend Time Series 2.3.0+
GET
/api/v2/stats/trend?metric={metric}&fromDate={startDate}&toDate={endDate}&granularity={granularity}
Description: Builds a time series of one metric over a date range, bucketed by day, ISO week or month. Buckets without a single entry are omitted, so unlogged days never drag an average down.
Query Parameters:
metric(optional): Metric to trend. Valid values:CALORIES,FAT,CARBS,SUGAR,PROTEIN,FIBRE. Defaults toCALORIES.fromDate(required): The start date inYYYY-MM-DDformat.toDate(required): The end date inYYYY-MM-DDformat.granularity(optional): Bucket size. Valid values:DAY,WEEK(ISO week, Monday-Sunday),MONTH. Defaults toDAY.
Example:
/api/v2/stats/trend?metric=CALORIES&fromDate=2024-01-01&toDate=2024-03-31&granularity=WEEKResponse: A JSON array of buckets in chronological order. For
DAYgranularity,averageandtotalare identical anddayCountis1.json[ { "bucket": "2024-W03", "fromDate": "2024-01-15", "toDate": "2024-01-21", "dayCount": 7, "average": 2143.7, "total": 15005.9 }, [...] ]Error Responses:
- Returns HTTP 400 Bad Request if
fromDateis aftertoDate.
- Returns HTTP 400 Bad Request if
Get a Weekday Breakdown 2.3.0+
GET
/api/v2/stats/weekdays?fromDate={startDate}&toDate={endDate}
Description: Averages the daily totals grouped by day of the week - "do my weekends wreck the average?". Days of the week without a single entry are omitted.
Query Parameters:
fromDate(optional): Restrict the aggregation to this date and later, format:YYYY-MM-DD.toDate(optional): Restrict the aggregation to this date and later, format:YYYY-MM-DD.
Example:
/api/v2/stats/weekdays?fromDate=2024-01-01&toDate=2024-12-31Response: A JSON array of averages per day of the week, Monday first.
json[ { "dayOfWeek": "MONDAY", "dayCount": 48, "averages": { "avgTotalCalories": 2400.1, "avgTotalFat": 110.3, "avgTotalCarbs": 190.2, "avgTotalSugar": 55.4, "avgTotalProtein": 120.5, "avgTotalFibre": 17.8 } }, [...] ]Error Responses:
- Returns HTTP 400 Bad Request if
fromDateis aftertoDate.
- Returns HTTP 400 Bad Request if
Get the Macro Split 2.3.0+
GET
/api/v2/stats/macro-split?fromDate={startDate}&toDate={endDate}
Description: Share of energy from fat, carbs and protein over a date range. The split is kcal-weighted (fat 9 kcal/g, carbs and protein 4 kcal/g), not gram-weighted. Because of that,
macroCaloriesis derived from the macros and will usually differ slightly fromaverageCalories, which is the calorie figure FDDB itself reports.Query Parameters:
fromDate(required): The start date inYYYY-MM-DDformat.toDate(required): The end date inYYYY-MM-DDformat.
Example:
/api/v2/stats/macro-split?fromDate=2024-01-01&toDate=2024-01-31Response: A JSON object containing the macro split.
json{ "fromDate": "2024-01-01", "toDate": "2024-01-31", "fatPercentage": 34.5, "carbsPercentage": 45.2, "proteinPercentage": 20.3, "fatCalories": 690.3, "carbsCalories": 904.8, "proteinCalories": 406.4, "macroCalories": 2001.5, "averageCalories": 2000.5 }Error Responses:
- Returns HTTP 400 Bad Request if
fromDateis aftertoDate.
- Returns HTTP 400 Bad Request if
List Missing Days 2.3.0+
GET
/api/v2/stats/missing-days?fromDate={startDate}&toDate={endDate}
Description: Lists every day in the range that has no entry at all or an entry without a single calorie - "when did I forget to log?"
Query Parameters:
fromDate(required): The start date inYYYY-MM-DDformat.toDate(required): The end date inYYYY-MM-DDformat.
Example:
/api/v2/stats/missing-days?fromDate=2024-01-01&toDate=2024-01-31Response: A JSON array of missing dates in chronological order.
json[ "2024-01-05", "2024-01-12", [...] ]Error Responses:
- Returns HTTP 400 Bad Request if
fromDateis aftertoDate.
- Returns HTTP 400 Bad Request if
Download Data in Various Formats
GET
/api/v2/fddbdata/download
Description: Download your FDDB data in CSV or JSON format. This endpoint allows you to export your nutritional data for further analysis or backup purposes. You can choose to download all data or filter by a specific date range, include product details or just daily totals, and customize CSV formatting options.
Query Parameters:
fromDate(optional): Start date for filtering (inclusive), format:YYYY-MM-DD. If not provided, downloads from the beginning.toDate(optional): End date for filtering (inclusive), format:YYYY-MM-DD. If not provided, downloads until the most recent entry.format(required): Download format. Valid values:CSV,JSON.includeProducts(optional): Whether to include product details (true) or just daily totals (false). Defaults tofalse.decimalSeparator(optional): Decimal separator for CSV format. Valid values:comma,dot. Defaults tocomma. Only applicable when format isCSV.
Examples:
Download all data as CSV with daily totals only:
/api/v2/fddbdata/download?format=CSV&includeProducts=falseDownload data for January 2024 as JSON with product details:
/api/v2/fddbdata/download?fromDate=2024-01-01&toDate=2024-01-31&format=JSON&includeProducts=trueDownload all data as CSV with dot decimal separator and product details:
/api/v2/fddbdata/download?format=CSV&includeProducts=true&decimalSeparator=dot
Response: Binary file download with appropriate content type and filename. The filename is automatically generated based on the selected parameters (e.g.,
fddb-export-2024-01-01-to-2024-01-31-with-products.csv).CSV Format:
- Daily totals only (
includeProducts=false): Each row represents one day with columns for date, total calories, total fat, total carbs, total sugar, total protein, and total fiber. - With product details (
includeProducts=true): Each row represents one product consumed on a specific date, including all nutritional values and product information.
- Daily totals only (
JSON Format:
- Returns data in the same structure as the
/api/v2/fddbdataendpoint, but filtered by the specified date range if provided.
- Returns data in the same structure as the
Error Responses:
- Returns HTTP 400 Bad Request if
fromDateis aftertoDate. - Returns HTTP 400 Bad Request if an invalid
format,decimalSeparator, or date format is provided. - Returns HTTP 400 Bad Request with
This operation requires MongoDB to be enabledif MongoDB is disabled. The download reads individual entries, which only MongoDB stores.
- Returns HTTP 400 Bad Request if
Migrate MongoDB data to InfluxDb
POST
/api/v2/migration/toInfluxDb
- Description: Migrates existing data from MongoDB to InfluxDb.
- Response: HTTP 200 if successful.