---
name: log-food
description: Log a meal to the user's Eat My Words food diary from a natural-language description and return calorie and macronutrient totals.
---

# log-food

Log food to a user's Eat My Words diary using a plain-English description (e.g. "two eggs scrambled with butter and a slice of sourdough"). The server's nutrition model parses the description into one or more food items, persists them to the diary, and returns calories plus macros for each item.

## When to use

- The user describes something they ate or drank and wants it tracked.
- The user wants to know the calories or macros of a meal *and* is OK with logging it.

Skip if the user only wants a hypothetical estimate without saving — there is no estimate-only mode today.

## Endpoint

```
POST https://words.my/api/v1/logs/
```

Headers:

| Header | Value |
| --- | --- |
| `Authorization` | `Api-Key <USER_KEY>` |
| `Content-Type` | `application/json` |

Body:

```json
{
  "text": "two eggs scrambled with butter and a slice of sourdough",
  "timezone": "America/Toronto",
  "timestamp": "2026-05-06T12:30:00Z"
}
```

| Field | Required | Notes |
| --- | --- | --- |
| `text` | yes | Plain-English description of one or more foods. Quantities and units welcome. |
| `timezone` | no | IANA name. Sets the local time the entry is filed under. Falls back to the user's profile timezone, then UTC. |
| `timestamp` | no | ISO-8601 UTC timestamp for when the food was consumed. Defaults to now. |

## Response

Success (HTTP 201):

```json
{
  "created": [
    {
      "id": 12345,
      "timestamp": "2026-05-06T08:30:00-04:00",
      "food_name": "scrambled eggs",
      "quantity": 100,
      "calories": 196,
      "carbohydrates": 1.5,
      "proteins": 13.0,
      "fats": 14.0,
      "fiber": 0,
      "sugars": 1,
      "sodium": 175
    }
  ],
  "usage": {
    "month": "2026-05",
    "estimated_cost_usd": 0.42,
    "budget_usd": 2.0,
    "remaining_usd": 1.58,
    "over_budget": false
  }
}
```

Quantities are in grams; macros in grams; calories in kcal; sodium in mg. The
`usage` block reports the caller's current-month AI spend against their budget.

No foods parsed (HTTP 422):

```json
{ "detail": "No food items could be extracted from the text." }
```

When this happens, ask the user to rephrase with concrete foods and quantities — don't retry the same text.

## How to summarize for the user

After a successful call, condense the response into a short summary. Suggested format:

> Logged: scrambled eggs (100 g) — 196 kcal · 13 P / 1.5 C / 14 F
> Logged: sourdough toast (40 g) — 110 kcal · 4 P / 22 C / 0.5 F
> **Total: 306 kcal · 17 g protein · 23.5 g carbs · 14.5 g fat**

Rules:
- One line per item: name, mass in grams, calories, then `P / C / F` in grams.
- One total line summing `calories`, `proteins`, `carbohydrates`, `fats` across `food_items`.
- Round calories to whole numbers. Round macros to one decimal when below 10 g, whole numbers above.
- Don't surface fields the user didn't ask about (sodium, water, alcohol, fiber, sugars) unless they're relevant to the user's question.

## Authentication

Each user manages their own API keys at `https://words.my/users/profile/`. Keys are scoped to one user and inherit that user's data permissions. Treat them as secrets.

## Errors

| Status | Cause | Recovery |
| --- | --- | --- |
| 401 / 403 | Missing or invalid `Authorization` header | Ask the user to create an API key at their profile. |
| 400 | Body is not valid JSON, or `text` field missing | Fix the request body. |
| 422 | Model couldn't parse a food list out of the text | Ask the user for a more concrete description. |
| 429 | The user has reached their monthly AI budget | Stop; tell the user the budget resets next month. Check `GET /api/v1/chat/usage/`. |
| 502 | Transient AI outage while parsing | Retry once after a short delay; surface the error if it persists. |

## Example — curl

```bash
curl -sS https://words.my/api/v1/logs/ \
  -H "Authorization: Api-Key $EMW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text": "a cup of black coffee and a banana"}'
```

## Related endpoints

- `GET /api/v1/logs/` — read recent diary entries (filter by `date=YYYY-MM-DD`).
- `GET /api/v1/daily-summary/` — consumed totals and goals for a day.
- `GET /api/schema/` — full OpenAPI schema for every public endpoint.
