Saltar al contenido
Almendra
Esc
↑↓navegar↵abrir⌘Jvista previa

Create a meal plan

Creates a complete meal plan for a patient: daily (a menu per weekday), flexible (model days of options) or exchange (model days of portions per exchange group). Foods and recipes come from GET /foods and GET /recipes; quantities are in grams unless unit names one of the food’s measures. The plan is a draft the professional can review in the dashboard; set send: true to send it to the patient right away.

Requires the meal_plans:write permission.

POST/meal-plans
Autorización
AuthorizationToken Bearer (API Key) · headerobligatorio

Almendra API key, bound to one professional account. Send it as Authorization: Bearer YOUR_API_KEY.

Ámbitos:meal_plans:write
Cuerpo de la solicitud
application/json
patient_idstringobligatorio

Patient the plan is for

coincide con ^[0-9a-fA-F]{24}$
namestringobligatorio
longitud mín. 1 · longitud máx. 120
typestringobligatorio

daily: a menu for each day of the week; flexible: 1 to 7 model days of options the patient chooses from; exchange: 1 to 7 model days of portions per exchange group.

Valores permitidos:dailyflexibleexchange
startDatestring<date>

First day, in the account's time zone. Defaults to the day after the patient's last plan ends, or tomorrow.

endDatestring<date>

Last day (defaults to 6 days after startDate). daily and text plans last whole weeks. When editing, a new startDate alone keeps the plan's length.

objectivestring
longitud máx. 200
indicationsstring[]

Recommendations shown with the plan (defaults to the patient's previous plan's)

máx. 50 elementos
daysMealPlanDayInput[]obligatorio
mín. 1 elementos · máx. 7 elementos
Mostrar propiedades
Array de MealPlanDayInput
weekdaystring

daily plans: the day of the week (each at most once). Weekdays left out are free days.

Valores permitidos:mondaytuesdaywednesdaythursdayfridaysaturdaysunday
namestring

flexible and exchange plans: the model day name (defaults to "Día Modelo 1", "Día Modelo 2"… in the account's language)

longitud mín. 1 · longitud máx. 40
isFreeDayboolean

A day without a menu (daily plans)

targetsMealPlanDayTargets

Required unless isFreeDay

Mostrar propiedades
caloriesKcalnumberobligatorio
mín. 0
proteinGnumberobligatorio
mín. 0
carbsGnumberobligatorio
mín. 0
fatGnumberobligatorio
mín. 0
mealsMealPlanMealInput[]
máx. 12 elementos · predeterminado: []
Mostrar propiedades
Array de MealPlanMealInput
namestringobligatorio
longitud mín. 1 · longitud máx. 60
timestring

24-hour HH:MM

coincide con ^([01]?\d|2[0-3]):[0-5]\d$
commentstring
longitud máx. 1000
caloriesPercentagenumber

Share of the day's calories this meal targets

mín. 0 · máx. 100
proteinTargetGnumber
mín. 0
carbsTargetGnumber
mín. 0
fatTargetGnumber
mín. 0
optionsobject[]

daily and flexible plans. Each option is one item of the meal; in flexible plans its foods are alternatives the patient picks one of, in daily plans the patient app shows the first food of each option.

máx. 20 elementos
Mostrar propiedades
Array de object
namestring
longitud máx. 60
foodsIngredientInput[]obligatorio
mín. 1 elementos · máx. 30 elementos
Mostrar propiedades
Array de IngredientInput
foodstringobligatorio

Food ID (GET /foods)

coincide con ^[0-9a-fA-F]{24}$
quantitynumberobligatorio
mín. 0
unitstring

Grams (g, the default) or one of the food's measures (measures[].description in GET /foods/{food_id}).

longitud mín. 1
exchangesobject[]

exchange plans: portions per group

máx. 40 elementos
Mostrar propiedades
Array de object
groupstringobligatorio

Exchange group: an id from GET /exchange-groups or a built-in group code of the account's exchange system (e.g. CENAN-01, SMAE-06)

longitud mín. 1
quantitynumberobligatorio
mín. 0
excludedFoodsstring[]
sendboolean

Finish it and send it to the patient right away (same as POST /meal-plans/{meal_plan_id}/send). Otherwise it stays a draft in the dashboard.

predeterminado: false
Respuestas
201

Meal plan created

_idstringobligatorio
namestringobligatorio
patientstringobligatorio

Patient ID

typestringobligatorio

daily: a menu per day; flexible: the same options every day; exchange: portions per exchange group; text: meals written as free text (meals[].text); pdf: an uploaded PDF (pdfUrl).

Valores permitidos:dailyflexibleexchangetextpdf
startDatestring<date-time>
endDatestring<date-time>
sentbooleanobligatorio

Finished and visible to the patient in the Almendra app

objectivestring
pdfUrlstring
createdAtstring<date-time>obligatorio
updatedAtstring<date-time>obligatorio

Send it back as expectedUpdatedAt when editing to avoid overwriting newer changes

indicationsstring[]obligatorio

Recommendations shown to the patient with the plan

daysMealPlanDay[]obligatorio
Mostrar propiedades
Array de MealPlanDay
namestringobligatorio
isFreeDaybooleanobligatorio
caloriesKcalnumber
proteinGnumber
carbsGnumber
fatGnumber
mealsMealPlanMeal[]obligatorio
Mostrar propiedades
Array de MealPlanMeal
namestringobligatorio
timestring
commentstring
textstring

text plans: the meal written as free text by the professional

caloriesPercentagenumber

Share of the day's calories this meal targets (0–100)

proteinTargetGnumber
carbsTargetGnumber
fatTargetGnumber
optionsMealPlanOption[]obligatorio

Alternatives the patient can choose from for this meal

Mostrar propiedades
Array de MealPlanOption
namestring
foodsMealPlanFood[]obligatorio
Mostrar propiedades
Array de MealPlanFood
foodstringobligatorio

Food or recipe ID

foodNamestringobligatorio
quantitynumberobligatorio
unitstringobligatorio
exchangesMealPlanExchange[]obligatorio

Exchange portions (exchange meal plans)

Mostrar propiedades
Array de MealPlanExchange
groupstringobligatorio

Exchange group: the id of a stored group (GET /exchange-groups) or a built-in group code

quantitynumberobligatorio
excludedFoodsstring[]obligatorio

Food IDs of the group the patient should not pick

400

Invalid path parameter, query parameter or request body

successbooleanobligatorio
Valores permitidos:false
messagestringobligatorio

Same as error.message.

errorobjectobligatorio
Mostrar propiedades
statusintegerobligatorio

HTTP status code of the response.

codestringobligatorio

Machine-readable error code, stable across versions; branch on this rather than on message.

Valores permitidos:bad_requestunauthorizedforbiddennot_foundmethod_not_allowedconflictpayload_too_largeunsupported_media_typeunprocessable_entityrate_limitedinternal_errornot_implementedbad_gatewayservice_unavailablegateway_timeout
messagestringobligatorio

Human-readable explanation of what went wrong.

401

Missing or invalid API key

successbooleanobligatorio
Valores permitidos:false
messagestringobligatorio

Same as error.message.

errorobjectobligatorio
Mostrar propiedades
statusintegerobligatorio

HTTP status code of the response.

codestringobligatorio

Machine-readable error code, stable across versions; branch on this rather than on message.

Valores permitidos:bad_requestunauthorizedforbiddennot_foundmethod_not_allowedconflictpayload_too_largeunsupported_media_typeunprocessable_entityrate_limitedinternal_errornot_implementedbad_gatewayservice_unavailablegateway_timeout
messagestringobligatorio

Human-readable explanation of what went wrong.

403

The account behind the API key has no active paid plan, or the key lacks the permission this operation needs

successbooleanobligatorio
Valores permitidos:false
messagestringobligatorio

Same as error.message.

errorobjectobligatorio
Mostrar propiedades
statusintegerobligatorio

HTTP status code of the response.

codestringobligatorio

Machine-readable error code, stable across versions; branch on this rather than on message.

Valores permitidos:bad_requestunauthorizedforbiddennot_foundmethod_not_allowedconflictpayload_too_largeunsupported_media_typeunprocessable_entityrate_limitedinternal_errornot_implementedbad_gatewayservice_unavailablegateway_timeout
messagestringobligatorio

Human-readable explanation of what went wrong.

404

Patient, food or exchange group not found

successbooleanobligatorio
Valores permitidos:false
messagestringobligatorio

Same as error.message.

errorobjectobligatorio
Mostrar propiedades
statusintegerobligatorio

HTTP status code of the response.

codestringobligatorio

Machine-readable error code, stable across versions; branch on this rather than on message.

Valores permitidos:bad_requestunauthorizedforbiddennot_foundmethod_not_allowedconflictpayload_too_largeunsupported_media_typeunprocessable_entityrate_limitedinternal_errornot_implementedbad_gatewayservice_unavailablegateway_timeout
messagestringobligatorio

Human-readable explanation of what went wrong.

415

Request body sent without Content-Type: application/json

successbooleanobligatorio
Valores permitidos:false
messagestringobligatorio

Same as error.message.

errorobjectobligatorio
Mostrar propiedades
statusintegerobligatorio

HTTP status code of the response.

codestringobligatorio

Machine-readable error code, stable across versions; branch on this rather than on message.

Valores permitidos:bad_requestunauthorizedforbiddennot_foundmethod_not_allowedconflictpayload_too_largeunsupported_media_typeunprocessable_entityrate_limitedinternal_errornot_implementedbad_gatewayservice_unavailablegateway_timeout
messagestringobligatorio

Human-readable explanation of what went wrong.

429

Rate limit exceeded (600 requests per 60 seconds); retry after Retry-After seconds

successbooleanobligatorio
Valores permitidos:false
messagestringobligatorio

Same as error.message.

errorobjectobligatorio
Mostrar propiedades
statusintegerobligatorio

HTTP status code of the response.

codestringobligatorio

Machine-readable error code, stable across versions; branch on this rather than on message.

Valores permitidos:bad_requestunauthorizedforbiddennot_foundmethod_not_allowedconflictpayload_too_largeunsupported_media_typeunprocessable_entityrate_limitedinternal_errornot_implementedbad_gatewayservice_unavailablegateway_timeout
messagestringobligatorio

Human-readable explanation of what went wrong.

500

Unexpected server error

successbooleanobligatorio
Valores permitidos:false
messagestringobligatorio

Same as error.message.

errorobjectobligatorio
Mostrar propiedades
statusintegerobligatorio

HTTP status code of the response.

codestringobligatorio

Machine-readable error code, stable across versions; branch on this rather than on message.

Valores permitidos:bad_requestunauthorizedforbiddennot_foundmethod_not_allowedconflictpayload_too_largeunsupported_media_typeunprocessable_entityrate_limitedinternal_errornot_implementedbad_gatewayservice_unavailablegateway_timeout
messagestringobligatorio

Human-readable explanation of what went wrong.

Pruébalo
Servidor
Autorización
Cuerpoapplication/json
Solicitud
curl -X POST 'https://api.almendra.io/openapi/v1/meal-plans' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "patient_id": "507f1f77bcf86cd799439011",
  "name": "Plan semana 1",
  "type": "daily",
  "startDate": "2026-11-02",
  "endDate": "2026-11-02",
  "objective": "string",
  "indications": [
    "string"
  ],
  "days": [
    {
      "weekday": "monday",
      "name": "string",
      "isFreeDay": true,
      "targets": {
        "caloriesKcal": 1800,
        "proteinG": 110,
        "carbsG": 200,
        "fatG": 60
      },
      "meals": []
    }
  ],
  "send": false
}'
Respuesta
{
  "_id": "string",
  "name": "Plan semana 1",
  "patient": "string",
  "type": "daily",
  "startDate": "2019-08-24T14:15:22Z",
  "endDate": "2019-08-24T14:15:22Z",
  "sent": true,
  "objective": "string",
  "pdfUrl": "string",
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z",
  "indications": [
    "string"
  ],
  "days": [
    {
      "name": "Lunes",
      "isFreeDay": true,
      "caloriesKcal": 0,
      "proteinG": 0,
      "carbsG": 0,
      "fatG": 0,
      "meals": [
        {
          "name": "Desayuno",
          "time": "08:00",
          "comment": "string",
          "text": "string",
          "caloriesPercentage": 0,
          "proteinTargetG": 0,
          "carbsTargetG": 0,
          "fatTargetG": 0,
          "options": [
            {
              "name": "Opción 1",
              "foods": [
                {
                  "food": "string",
                  "foodName": "Avena en hojuelas",
                  "quantity": 40,
                  "unit": "g"
                }
              ]
            }
          ],
          "exchanges": [
            {
              "group": "string",
              "quantity": 2,
              "excludedFoods": [
                "string"
              ]
            }
          ]
        }
      ]
    }
  ]
}

¿No encuentras lo que buscas?

Nuestro equipo responde en menos de 1 día hábil, de lunes a viernes de 9:30 a 18:00 (GMT-5).

Escríbenos

¿Te ha resultado útil esta página?