Custom Foods reference

Create, update and delete the user's own foods, with macros per 100 g or 100 ml.

The DailyGoal API is not available on the Free plan. It works with a paid plan or during a free trial. See plans.

Usage notes

Free app accounts can create up to 5 custom foods. Pro has no plan cap. The API itself requires Pro or a trial.

All operations require Pro or a trial. GET and DELETE take query parameters; other methods take a JSON body. The input table also includes any MCP-only idempotency_key argument; REST sends it as a header. See retrying creates. Example ids are synthetic; find your own with the search and list operations.

Operations

save_custom_food

POST https://api.dailygoal.fit/v1/custom-foods

MCP tool save_custom_food · Changes data · Destructive · DailyGoal data only · Accepts Idempotency-Key

Create a custom food, or update one by passing its id. Replaces every field, with macros in grams per 100 g (or 100 ml) and one serving's size. Use it for foods search_foods cannot find. It records nothing eaten: call log_food_entry with the returned id to log the food.

Input

FieldTypeDescription
idoptionalstringThe custom food to update, from a previous save_custom_food or search_foods. Omit it to create a new custom food.
namestringFood name, for example 'Greek yoghurt 2%'.
brandNameoptionalstringBrand, if any. Blank or omitted means no brand.
proteinnumberProtein in grams per 100 g, or per 100 ml when servingSizeUnit is ml.
carbsnumberCarbohydrate in grams per 100 g or 100 ml.
fatnumberFat in grams per 100 g or 100 ml.
alcoholoptionalnumberAlcohol in grams per 100 g or 100 ml. Defaults to 0.
servingSizenumberSize of one serving, in servingSizeUnit, for example 150.
servingSizeUnit"g" | "ml"Unit of servingSize and of the per-100 macro values.
servingSizeTextoptionalstringLabel for one serving, for example '1 pot'. Blank or omitted means '1 serving'.
idempotency_keyoptionalstringOptional. A unique value for this create, for example a UUID. Retrying with the same key and arguments within 24 hours returns the first result instead of creating a duplicate.
Full input schema, including bounds and nested alternatives (MCP)
JSON Schema
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "description": "The custom food to update, from a previous save_custom_food or search_foods. Omit it to create a new custom food."
    },
    "name": {
      "type": "string",
      "pattern": "\\S",
      "description": "Food name, for example 'Greek yoghurt 2%'."
    },
    "brandName": {
      "type": "string",
      "description": "Brand, if any. Blank or omitted means no brand."
    },
    "protein": {
      "type": "number",
      "minimum": 0,
      "description": "Protein in grams per 100 g, or per 100 ml when servingSizeUnit is ml."
    },
    "carbs": {
      "type": "number",
      "minimum": 0,
      "description": "Carbohydrate in grams per 100 g or 100 ml."
    },
    "fat": {
      "type": "number",
      "minimum": 0,
      "description": "Fat in grams per 100 g or 100 ml."
    },
    "alcohol": {
      "type": "number",
      "minimum": 0,
      "description": "Alcohol in grams per 100 g or 100 ml. Defaults to 0."
    },
    "servingSize": {
      "type": "number",
      "exclusiveMinimum": 0,
      "description": "Size of one serving, in servingSizeUnit, for example 150."
    },
    "servingSizeUnit": {
      "type": "string",
      "enum": [
        "g",
        "ml"
      ],
      "description": "Unit of servingSize and of the per-100 macro values."
    },
    "servingSizeText": {
      "type": "string",
      "description": "Label for one serving, for example '1 pot'. Blank or omitted means '1 serving'."
    },
    "idempotency_key": {
      "type": "string",
      "maxLength": 255,
      "description": "Optional. A unique value for this create, for example a UUID. Retrying with the same key and arguments within 24 hours returns the first result instead of creating a duplicate."
    }
  },
  "required": [
    "name",
    "protein",
    "carbs",
    "fat",
    "servingSize",
    "servingSizeUnit"
  ],
  "additionalProperties": true
}

Output

FieldTypeDescription
createdbooleanTrue when this call created the custom food, false when it updated one.
customFoodobject
customFood.idstringCustom food id. Pass it to log_food_entry as the custom food id.
customFood.namestring
customFood.brandNameoptionalstring
customFood.proteinnumberGrams per 100 g or 100 ml.
customFood.carbsnumberGrams per 100 g or 100 ml.
customFood.fatnumberGrams per 100 g or 100 ml.
customFood.alcoholnumberGrams per 100 g or 100 ml.
customFood.caloriesnumberKilocalories per 100 g or 100 ml, calculated from the macros.
customFood.servingSizenumber
customFood.servingSizeUnitstringg or ml. Foods created by the in-app assistant can also use count units such as item.
customFood.servingSizeTextstring
Full output schema
JSON Schema
{
  "type": "object",
  "properties": {
    "created": {
      "type": "boolean",
      "description": "True when this call created the custom food, false when it updated one."
    },
    "customFood": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Custom food id. Pass it to log_food_entry as the custom food id."
        },
        "name": {
          "type": "string"
        },
        "brandName": {
          "type": "string"
        },
        "protein": {
          "type": "number",
          "description": "Grams per 100 g or 100 ml."
        },
        "carbs": {
          "type": "number",
          "description": "Grams per 100 g or 100 ml."
        },
        "fat": {
          "type": "number",
          "description": "Grams per 100 g or 100 ml."
        },
        "alcohol": {
          "type": "number",
          "description": "Grams per 100 g or 100 ml."
        },
        "calories": {
          "type": "number",
          "description": "Kilocalories per 100 g or 100 ml, calculated from the macros."
        },
        "servingSize": {
          "type": "number"
        },
        "servingSizeUnit": {
          "type": "string",
          "description": "g or ml. Foods created by the in-app assistant can also use count units such as item."
        },
        "servingSizeText": {
          "type": "string"
        }
      },
      "required": [
        "id",
        "name",
        "protein",
        "carbs",
        "fat",
        "alcohol",
        "calories",
        "servingSize",
        "servingSizeUnit",
        "servingSizeText"
      ],
      "additionalProperties": true
    }
  },
  "required": [
    "created",
    "customFood"
  ],
  "additionalProperties": true
}

Example request

The REST example uses OpenSSL to generate a fresh key for a new create. To retry that create, rerun only the curl command with the same key and input. You may send that key as idempotency_key in the MCP arguments too.

REST
DAILYGOAL_IDEMPOTENCY_KEY="$(openssl rand -hex 16)"
curl -X POST "https://api.dailygoal.fit/v1/custom-foods" \
  -H "Authorization: Bearer $DAILYGOAL_API_TOKEN" \
  -H "Idempotency-Key: $DAILYGOAL_IDEMPOTENCY_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Greek yoghurt 2%","protein":9.9,"carbs":3.9,"fat":2,"servingSize":150,"servingSizeUnit":"g","servingSizeText":"1 pot"}'
MCP tools/call
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "save_custom_food",
    "arguments": {
      "name": "Greek yoghurt 2%",
      "protein": 9.9,
      "carbs": 3.9,
      "fat": 2,
      "servingSize": 150,
      "servingSizeUnit": "g",
      "servingSizeText": "1 pot"
    }
  }
}

Example response

Synthetic data. REST returns this object as the body; MCP returns it as structuredContent.

json
{
  "created": true,
  "customFood": {
    "id": "j572k9d3m6q8x1v4n7r0t2w5b8y3h6ca",
    "name": "Greek yoghurt 2%",
    "protein": 9.9,
    "carbs": 3.9,
    "fat": 2,
    "alcohol": 0,
    "calories": 73.2,
    "servingSize": 150,
    "servingSizeUnit": "g",
    "servingSizeText": "1 pot"
  }
}

Errors

delete_custom_food

DELETE https://api.dailygoal.fit/v1/custom-foods

MCP tool delete_custom_food · Changes data · Destructive · DailyGoal data only

Delete one of the user's custom foods from their library. It fails with conflict while diary entries or saved meals still use the food. To remove something the user logged, use delete_food_entry instead.

Input

FieldTypeDescription
idstringThe custom food to delete: an id from search_foods with kind custom_food, or from save_custom_food.
Full input schema, including bounds and nested alternatives (MCP)
JSON Schema
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "description": "The custom food to delete: an id from search_foods with kind custom_food, or from save_custom_food."
    }
  },
  "required": [
    "id"
  ],
  "additionalProperties": true
}

Output

FieldTypeDescription
idstring
deletedtrue
Full output schema
JSON Schema
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string"
    },
    "deleted": {
      "type": "boolean",
      "enum": [
        true
      ]
    }
  },
  "required": [
    "id",
    "deleted"
  ],
  "additionalProperties": true
}

Example request

REST
curl -X DELETE "https://api.dailygoal.fit/v1/custom-foods?id=j572k9d3m6q8x1v4n7r0t2w5b8y3h6ca" \
  -H "Authorization: Bearer $DAILYGOAL_API_TOKEN"
MCP tools/call
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "delete_custom_food",
    "arguments": {
      "id": "j572k9d3m6q8x1v4n7r0t2w5b8y3h6ca"
    }
  }
}

Example response

Synthetic data. REST returns this object as the body; MCP returns it as structuredContent.

json
{
  "id": "j572k9d3m6q8x1v4n7r0t2w5b8y3h6ca",
  "deleted": true
}

Errors