🚧 Work in Progress: This documentation is actively being developed and is subject to change.
Core Functions

Meal Tracking

Learn how to track meals and food items to award PlanetPoints for sustainable food choices.


Overview

Food tracking enables users to earn PlanetPoints by logging their meals and food consumption. When a user tracks food through your app, you send the data to Reewild for carbon and health scoring, and points are awarded based on the environmental and nutritional impact.

There are two tracking endpoints:

  1. Meal Tracking (/track/meals) - For logging meals with multiple ingredients
  2. Food Tracking (/track/food) - For logging single food items
ScenarioEndpoint
Single snack or packaged product/track/food
Recipe or homemade meal/track/meals
Packaged combo meal/track/meals
Multiple items from different merchants/track/meals

Both endpoints accept data asynchronously and return results via webhooks.


Meal Tracking

Use this endpoint when users log a meal containing multiple food items.

Endpoint: POST /track/meals

Headers:

HeaderValue
Content-Typeapplication/json
x-client-idYour client ID
x-client-secretYour client secret

Query Parameters:

ParameterRequiredDescription
api-versionYesAPI version (e.g., 1.0)

Request Body

FieldTypeRequiredDescription
userIdStringYesUser's Reewild ID
transactionIdStringYesYour unique transaction reference
mealNameStringYesName of the meal
imageUrlStringYesImage URL of the meal
loggedAtString (ISO 8601)YesWhen the meal was logged
mealTypeStringYesbreakfast, lunch, dinner, snack, or other
countryStringNoISO country code
locationStringNoFree-text location
metadataObjectNoOptional metadata
ingredientsArrayNoArray of ingredient objects

Ingredient Object

FieldTypeRequiredDescription
foodIdStringYesUnique ID of the food item
nameStringYesName of the food item
imageUrlStringNoImage URL of the food
merchantObjectNoMerchant details
weightNumberNoWeight of the food
unitStringNoUnit of measure (e.g., g, ml)
quantityNumberNoQuantity (default: 1)
amountNumberNoMonetary value (default: £1)
currencyStringNoCurrency code (required if amount provided)
nutritionObjectNoNutritional information

Merchant Object

FieldTypeRequiredDescription
nameStringNoMerchant name
logoStringNoLogo URL
websiteStringNoMerchant website
domainStringNoMerchant domain
countryStringNoMerchant country

Nutrition Object

FieldTypeDescription
energyKcalNumberCalories
proteinGNumberProtein in grams
carbsGNumberCarbohydrates in grams
fatGNumberFat in grams
sugarGNumberSugar in grams
fiberGNumberFiber in grams
saltGNumberSalt in grams

Example Request

{
  "userId": "08FE9Q",
  "transactionId": "meal-20251126-002",
  "mealName": "Avocado Quinoa Bowl",
  "imageUrl": "https://example.com/images/meals/avocado-quinoa-bowl.jpg",
  "loggedAt": "2025-11-26T19:40:00Z",
  "mealType": "dinner",
  "country": "GBR",
  "location": "London, UK",
  "metadata": {
    "source": "mobile_app",
    "appVersion": "4.2.1"
  },
  "ingredients": [
    {
      "foodId": "FOOD-221",
      "name": "Quinoa",
      "imageUrl": "https://example.com/images/foods/quinoa.jpg",
      "merchant": {
        "name": "Whole Foods",
        "domain": "wholefoods.com",
        "country": "GBR"
      },
      "weight": 150,
      "unit": "g",
      "quantity": 1,
      "amount": 2.80,
      "currency": "GBP",
      "nutrition": {
        "energyKcal": 110,
        "proteinG": 4,
        "carbsG": 20,
        "fatG": 2,
        "sugarG": 0,
        "fiberG": 3,
        "saltG": 0
      }
    },
    {
      "foodId": "FOOD-874",
      "name": "Avocado",
      "imageUrl": "https://example.com/images/foods/avocado.jpg",
      "merchant": {
        "name": "Local Market",
        "country": "GBR"
      },
      "weight": 100,
      "unit": "g",
      "quantity": 1,
      "amount": 3.40,
      "currency": "GBP",
      "nutrition": {
        "energyKcal": 160,
        "proteinG": 2,
        "carbsG": 9,
        "fatG": 15,
        "sugarG": 0,
        "fiberG": 7,
        "saltG": 0
      }
    }
  ]
}

Response

{
  "trackId": "5765279d-0e9b-4f16-b462-0f75d06d0c7a",
  "message": "Meal accepted for scoring"
}
FieldTypeDescription
trackIdStringReewild's internal tracking ID
messageStringConfirmation message

Response Codes

CodeDescription
202Meal accepted for processing
400Invalid request parameters
500Internal server error

Food Tracking

Use this endpoint when users log a single food item.

Endpoint: POST /track/food

Headers:

HeaderValue
Content-Typeapplication/json
x-client-idYour client ID
x-client-secretYour client secret

Query Parameters:

ParameterRequiredDescription
api-versionYesAPI version (e.g., 1.0)

Request Body

FieldTypeRequiredDescription
userIdStringYesUser's Reewild ID
transactionIdStringYesYour unique transaction reference
foodIdStringYesUnique ID of the food item
nameStringYesName of the food item
imageUrlStringYesImage URL of the food
merchantObjectYesMerchant details
weightNumberYesWeight of the food
unitStringYesUnit of measure
nutritionObjectYesNutritional information
quantityNumberNoQuantity (default: 1)
amountNumberNoMonetary value (default: £1)
currencyStringNoCurrency code

Example Request

{
  "userId": "08FE9Q",
  "transactionId": "food-20251126-038",
  "foodId": "FOOD-44521",
  "name": "Grilled Chicken Quinoa Bowl",
  "imageUrl": "https://example.com/foods/grilled-chicken-quinoa.jpg",
  "merchant": {
    "name": "Health Kitchen",
    "logo": "https://example.com/logos/health-kitchen.png",
    "website": "https://www.healthkitchen.co.uk",
    "domain": "healthkitchen.co.uk",
    "country": "GBR"
  },
  "weight": 420,
  "unit": "g",
  "quantity": 1,
  "amount": 8.40,
  "currency": "GBP",
  "nutrition": {
    "energyKcal": 610,
    "proteinG": 38,
    "carbsG": 54,
    "fatG": 22,
    "sugarG": 5,
    "fiberG": 8,
    "saltG": 1.1
  }
}

Response

{
  "trackId": "5765279d-0e9b-4f16-b462-0f75d06d0c7a",
  "message": "Food accepted for scoring"
}

Response Codes

CodeDescription
202Food accepted for processing
400Invalid request parameters
500Internal server error

Webhook Events

After submitting a meal or food item, Reewild processes the data asynchronously and sends webhook notifications as processing progresses.

EventDescription
intake.receivedMeal/food payload accepted for processing
intake.scoredCarbon and health metrics calculated
intake.completedPlanetPoints awarded
intake.failedProcessing failed

intake.received

Sent when Reewild receives and queues the submission for processing.

{
  "event": "intake.received",
  "source": "meal",
  "transactionId": "meal-20251126-002",
  "trackId": "5765279d-0e9b-4f16-b462-0f75d06d0c7a",
  "userId": "08FE9Q",
  "loggedAt": "2025-11-26T19:45:00Z",
  "country": "GBR",
  "createdAt": "2025-11-26T19:45:02Z"
}

intake.scored

Sent when carbon and health metrics have been calculated.

{
  "event": "intake.scored",
  "source": "meal",
  "transactionId": "meal-20251126-002",
  "trackId": "5765279d-0e9b-4f16-b462-0f75d06d0c7a",
  "name": "Avocado Quinoa Bowl",
  "imageUrl": "https://example.com/images/meals/avocado-quinoa-bowl.jpg",
  "userId": "08FE9Q",
  "mealType": "dinner",
  "ingredients": [
    {
      "foodId": "FOOD-221",
      "name": "Quinoa",
      "imageUrl": "https://example.com/images/foods/quinoa.jpg",
      "weight": 150,
      "unit": "g",
      "quantity": 1,
      "amount": 2.80,
      "currency": "GBP",
      "carbonImpactRating": 2,
      "healthImpactRating": 1,
      "co2e": 0.45
    },
    {
      "foodId": "FOOD-874",
      "name": "Avocado",
      "imageUrl": "https://example.com/images/foods/avocado.jpg",
      "weight": 100,
      "unit": "g",
      "quantity": 1,
      "amount": 3.40,
      "currency": "GBP",
      "carbonImpactRating": 3,
      "healthImpactRating": 2,
      "co2e": 0.68
    }
  ],
  "loggedAt": "2025-11-26T19:40:00Z",
  "country": "GBR",
  "totalAmount": 6.20,
  "currency": "GBP",
  "totalCo2e": 1.13,
  "carbonImpactRating": 2,
  "healthImpactRating": 1,
  "createdAt": "2025-11-26T19:45:20Z"
}

intake.completed

Sent when PlanetPoints have been credited.

{
  "event": "intake.completed",
  "source": "meal",
  "transactionId": "meal-20251126-002",
  "trackId": "5765279d-0e9b-4f16-b462-0f75d06d0c7a",
  "userId": "08FE9Q",
  "totalAmount": 6.20,
  "currency": "GBP",
  "ingredients": [
    {
      "foodId": "FOOD-221",
      "name": "Quinoa",
      "imageUrl": "https://example.com/images/foods/quinoa.jpg",
      "weight": 150,
      "unit": "g",
      "quantity": 1,
      "amount": 2.80,
      "currency": "GBP",
      "carbonImpactRating": 2,
      "healthImpactRating": 1,
      "co2e": 0.45,
      "totalPoints": 40,
      "totalCarbonPoints": 10,
      "totalHealthPoints": 30
    },
    {
      "foodId": "FOOD-874",
      "name": "Avocado",
      "imageUrl": "https://example.com/images/foods/avocado.jpg",
      "weight": 100,
      "unit": "g",
      "quantity": 1,
      "amount": 3.40,
      "currency": "GBP",
      "carbonImpactRating": 3,
      "healthImpactRating": 2,
      "co2e": 0.68,
      "totalPoints": 22,
      "totalHealthPoints": 16,
      "totalCarbonPoints": 6
    }
  ],
  "totalPoints": 62,
  "totalGreenProducts": 2,
  "totalHealthyProducts": 2,
  "totalCo2e": 1.13,
  "totalHealthPoints": 40,
  "totalCarbonPoints": 22,
  "createdAt": "2025-11-26T19:45:25Z"
}

intake.failed

Sent when processing fails.

{
  "event": "intake.failed",
  "source": "meal",
  "transactionId": "meal-20251126-002",
  "trackId": "5765279d-0e9b-4f16-b462-0f75d06d0c7a",
  "userId": "08FE9Q",
  "errorType": "DATA_INCOMPLETE",
  "errorMessage": "Missing nutrition.energyKcal for ingredient FOOD-442",
  "failedAt": "2025-11-26T19:47:10Z"
}

Error types:

Error TypeDescription
NO_VALID_FOOD_ITEMSNo valid food items found
OLD_MEAL_LOGMeal logged outside allowed time window
DUPLICATE_MEALDuplicate transaction ID
DATA_INCOMPLETERequired data missing
INTERNAL_ERRORServer error

Impact Ratings

Carbon and health impact ratings use a 1-5 scale:

RatingGradeMeaning
1ABest
2BGood
3CAverage
4DBelow average
5EWorst

Products rated A or B are counted as "green" (carbon) or "healthy" (health) products.


Next Steps