NAV
shell python javascript

Introduction

January AI’s Enterprise API gives you direct access to metabolic health and food intelligence tools, built for seamless B2B integration. Use our RESTful APIs to integrate advanced metabolic health insights and lifestyle intelligence directly into your platform. Our proprietary food database, enhanced with AI/ML, covers 54 million+ verified items across branded foods, groceries, and restaurant menus.
Integrate the most accurate food logging, glucose prediction, and food analysis tools available into your platform.

With January’s APIs, developers can:

Authentication

To authorize, use this code:

import requests
import json

# Replace YOUR_API_KEY with your actual API key
api_key = 'YOUR_API_KEY'
headers = {
    'Authorization': f'Bearer {api_key}',
    'Content-Type': 'application/json'
}
# With shell, you can just pass the correct header with each request
curl "https://partners.january.ai/v1.1/endpoint" \
  -H "Authorization: Bearer YOUR_API_KEY"
const axios = require('axios');

// Replace YOUR_API_KEY with your actual API key
const apiKey = 'YOUR_API_KEY';
const headers = {
  'Authorization': `Bearer ${apiKey}`,
  'Content-Type': 'application/json'
};

Make sure to replace YOUR_API_KEY with your actual API key.

The January AI API uses bearer tokens for authentication. To obtain an API key, please send an email with your request.

The API key must be included in all API requests to the server in a header that looks like the following:

Authorization: Bearer YOUR_API_KEY

Lifestyle Intelligence APIs

Search, analyze, and interpret food data using these Lifestyle Intelligence APIs.

Food Search (By Name or Barcode)

import requests

url = 'https://partners.january.ai/v1.1/search/foods'
params = {
    'query': 'banana',
    'category': 'branded'
}
headers = {
    'Authorization': 'Bearer YOUR_API_KEY',
    'x-partner-user-id': 'your-user-id'
}

response = requests.get(url, params=params, headers=headers)
print(response.json())
curl --location 'https://partners.january.ai/v1.1/search/foods?query=banana&category=branded' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'x-partner-user-id: your-user-id'
const axios = require('axios');

const config = {
  method: 'get',
  url: 'https://partners.january.ai/v1.1/search/foods',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'x-partner-user-id': 'your-user-id'
  },
  params: {
    query: 'banana',
    category: 'branded'
  }
};

axios(config)
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.log(error);
  });

The above command returns JSON structured like this:

{
  "totalCount": 40,
  "items": [
    {
      "id": 84222716,
      "name": "banana",
      "protein": 2,
      "energy": 160,
      "brand_name": "One",
      "carbs": 15,
      "fat": 10,
      "fat_total_saturated": 5,
      "net_carbs": 13,
      "sodium": 20,
      "sugars": 13,
      "added_sugars": 11,
      "gi": 34.899727,
      "gl": 5.234959,
      "fiber": 2,
      "potassium": 170,
      "cholesterol": 2.5,
      "photo_url": null,
      "servings": [
        {
          "id": 67943292,
          "scaling_factor": 1,
          "quantity": 5,
          "unit": "pieces",
          "weight_grams": 28,
          "is_primary": true
        }
      ]
    }
  ]
}

Search for food items by name or barcode from January’s verified database of 54+ million foods, including branded, grocery, and restaurant items.

HTTP Request

GET https://partners.january.ai/v1.1/search/foods

Headers

Header Required Description
Authorization Yes Bearer token for authentication
x-partner-user-id No Unique user ID from your system

Query Parameters

Parameter Required Description
query Optional The search term for food items
category Optional The category of food items to filter results ('branded' or 'general')
upc Optional The UPC representing the barcode of a food item

Response Structure

The response includes:

import requests

url = 'https://partners.january.ai/v1.1/search/foods/nlp'
params = {
    'query': '1 banana, 1 bowl of oatmeal, glass of orange juice'
}
headers = {
    'Authorization': 'Bearer YOUR_API_KEY',
    'x-partner-user-id': 'your-user-id'
}

response = requests.get(url, params=params, headers=headers)
print(response.json())
curl --location 'https://partners.january.ai/v1.1/search/foods/nlp?query=1%20banana%2C%201%20bowl%20of%20oatmeal%2C%20glass%20of%20orange%20juice' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'x-partner-user-id: your-user-id'
const axios = require('axios');

const config = {
  method: 'get',
  url: 'https://partners.january.ai/v1.1/search/foods/nlp',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'x-partner-user-id': 'your-user-id'
  },
  params: {
    query: '1 banana, 1 bowl of oatmeal, glass of orange juice'
  }
};

axios(config)
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.log(error);
  });

The above command returns JSON structured like this:

{
  "totalNutrients": {
    "calories": {
      "value": 435,
      "unit": "kcal"
    },
    "carbs": {
      "value": 92,
      "unit": "g"
    },
    "protein": {
      "value": 8.5,
      "unit": "g"
    }
  },
  "detections": [
    {
      "food": {
        "name": "Banana",
        "id": 123456,
        "brandName": null,
        "nutrients": {
          "calories": {
            "value": 105,
            "unit": "kcal"
          }
        },
        "servings": [
          {
            "id": 78901,
            "quantity": 1,
            "unit": "medium banana"
          }
        ]
      }
    }
  ]
}

Search for multiple foods at once by describing them in plain English — via voice or text.

HTTP Request

GET https://partners.january.ai/v1.1/search/foods/nlp

Headers

Header Required Description
Authorization Yes Bearer token for authentication
x-partner-user-id No Unique user ID from your system

Query Parameters

Parameter Required Description
query Yes The search term for food items in natural language

Response Structure

The response includes:

import requests

url = 'https://partners.january.ai/v1.1/search/restaurants'
params = {
    'query': 'mcdonalds',
    'lat': 37.549,
    'lon': -121.989
}
headers = {
    'Authorization': 'Bearer YOUR_API_KEY'
}

response = requests.get(url, params=params, headers=headers)
print(response.json())
curl --location 'https://partners.january.ai/v1.1/search/restaurants?query=mcdonalds&lat=37.549&lon=-121.989' \
--header 'Authorization: Bearer YOUR_API_KEY'
const axios = require('axios');

const config = {
  method: 'get',
  url: 'https://partners.january.ai/v1.1/search/restaurants',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY'
  },
  params: {
    query: 'mcdonalds',
    lat: 37.549,
    lon: -121.989
  }
};

axios(config)
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.log(error);
  });

The above command returns JSON structured like this:

{
  "items": [
    {
      "type": "restaurant",
      "id": "53fc3b8a-e6bf-404d-83c8-9f42124d1bee",
      "name": "McDonald's",
      "is_chain": false,
      "distance": 8,
      "city": "San Francisco",
      "address1": "123 Main Street",
      "address2": "Suite 100"
    }
  ]
}

This endpoint allows you to search for restaurants (local and/or chain) by name.

HTTP Request

GET https://partners.january.ai/v1.1/search/restaurants

Headers

Header Required Description
Authorization Yes Bearer token for authentication

Query Parameters

Parameter Required Description
query Yes The search term related to the restaurant. Leave empty to return all nearest restaurants.
lat Optional Latitude coordinate for proximity search
lon Optional Longitude coordinate for proximity search
distance Optional Distance in meters to search for restaurants. Default is 16093 meters (~10 miles)
limit Optional Maximum number of results to return. Default is 50

Response Structure

The response includes:

import requests

url = 'https://partners.january.ai/v1.1/search/restaurants/menu'
params = {
    'query': 'burger',
    'lat': 37.549,
    'lon': -121.989
}
headers = {
    'Authorization': 'Bearer YOUR_API_KEY'
}

response = requests.get(url, params=params, headers=headers)
print(response.json())
curl --location 'https://partners.january.ai/v1.1/search/restaurants/menu?query=burger&lat=37.549&lon=-121.989' \
--header 'Authorization: Bearer YOUR_API_KEY'
const axios = require('axios');

const config = {
  method: 'get',
  url: 'https://partners.january.ai/v1.1/search/restaurants/menu',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY'
  },
  params: {
    query: 'burger',
    lat: 37.549,
    lon: -121.989
  }
};

axios(config)
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.log(error);
  });

The above command returns JSON structured like this:

{
  "items": [
    {
      "type": "menu_item",
      "id": "228990954",
      "name": "burger",
      "restaurant_name": "morning due cafe",
      "is_chain": false,
      "data_source_id": 12,
      "source_original_id": "ngxZD7tEA1cQGCuOYBF05Ckft2ZP3z3Ja88wVaXYqqr7P7F3QiGFN1BSCl6H0Bt_5iN7y",
      "protein": 48,
      "energy": 800,
      "carbs": 40,
      "net_carbs": 38,
      "sugars": 6,
      "added_sugars": null,
      "fat": 45,
      "gi": 48.507698,
      "gl": 36.67089,
      "fiber": 2,
      "photo_url": "https://cdn-img.ai/23361362e6a706567",
      "servings": [
        {
          "id": 189343592,
          "scaling_factor": 1,
          "quantity": 1,
          "unit": "serving",
          "weight_grams": null,
          "is_primary": true
        }
      ],
      "distance": 124
    }
  ]
}

This endpoint allows you to search for restaurants (local and/or chain) by name.

HTTP Request

GET https://partners.january.ai/v1.1/search/restaurants/menu

Headers

Header Required Description
Authorization Yes Bearer token for authentication

Query Parameters

Parameter Required Description
query Yes The search term related to the menu (food name or restaurant name)
lat Yes Latitude coordinate for proximity search
lon Yes Longitude coordinate for proximity search
distance Optional Distance in meters to search for restaurant menus. Default is 16093 meters (~10 miles)
limit Optional Maximum number of results to return. Default is 50

Response Structure

The response includes:

Photo Scan

import requests
import json

url = 'https://partners.january.ai/v1.1/vision/foods'
headers = {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
    'x-partner-user-id': 'your-user-id'
}
data = {
    "photoUrl": "https://i.imgur.com/bTQIGxf.png"
}

response = requests.post(url, headers=headers, json=data)
print(response.json())
curl --location 'https://partners.january.ai/v1.1/vision/foods' \
--header 'Content-Type: application/json' \
--header 'x-partner-user-id: your-user-id' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--data '{
  "photoUrl": "https://i.imgur.com/bTQIGxf.png"
}'
const axios = require('axios');

const config = {
  method: 'post',
  url: 'https://partners.january.ai/v1.1/vision/foods',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
    'x-partner-user-id': 'your-user-id'
  },
  data: {
    photoUrl: 'https://i.imgur.com/bTQIGxf.png'
  }
};

axios(config)
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.log(error);
  });

The above command returns JSON structured like this:

{
  "mealName": "Breakfast Bowl",
  "totalNutrients": {
    "calories": {
      "value": 520,
      "unit": "kcal"
    },
    "carbs": {
      "value": 68,
      "unit": "g"
    },
    "protein": {
      "value": 15,
      "unit": "g"
    }
  },
  "detections": [
    {
      "confidenceScore": "high",
      "food": {
        "name": "Oatmeal",
        "id": 789012,
        "brandName": null,
        "nutrients": {
          "calories": {
            "value": 300,
            "unit": "kcal"
          }
        },
        "servings": [
          {
            "id": 45678,
            "quantity": 1,
            "unit": "cup"
          }
        ]
      }
    }
  ]
}

Scan a photo of a meal to identify and retrieve nutritional data for the foods detected.

HTTP Request

POST https://partners.january.ai/v1.1/vision/foods

Headers

Header Required Description
Authorization Yes Bearer token for authentication
Content-Type Yes Must be application/json
x-partner-user-id Yes Unique user ID from your system

Request Body

Parameter Required Description
photoUrl No The URL of the image to be analyzed
photoBase64 No Base64 encoded image data (if not using photoUrl)

Photo Requirements

Response Structure

The response includes:

Edit Photo Scan Results

import requests
import json

url = 'https://partners.january.ai/v1.1/vision/fix-ai'
headers = {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
    'x-partner-user-id': 'your-user-id'
}
data = {
  "mealName": "Breakfast Bowl",
  "detections": [
    {
      "confidenceScore": "high",
      "food": {
        "name": "Oatmeal",
        "id": 789012,
        "brandName": null,
        "nutrients": {
          "calories": {
            "value": 300,
            "unit": "kcal"
          }
        },
        "servings": [
          {
            "id": 45678,
            "quantity": 1,
            "unit": "cup"
          }
        ]
      }
    }
  ],
  "userInput": "change oatmeal to steel-cut oats"
}

response = requests.post(url, headers=headers, json=data)
print(response.json())
curl --location 'https://partners.january.ai/v1.1/vision/fix-ai' \
--header 'Content-Type: application/json' \
--header 'x-partner-user-id: your-user-id' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--data '{
  "mealName": "Breakfast Bowl",
  "detections": [
    {
      "confidenceScore": "high",
      "food": {
        "name": "Oatmeal",
        "id": 789012,
        "brandName": null,
        "nutrients": {
          "calories": {
            "value": 300,
            "unit": "kcal"
          }
        },
        "servings": [
          {
            "id": 45678,
            "quantity": 1,
            "unit": "cup"
          }
        ]
      }
    }
  ],
  "userInput": "change oatmeal to steel-cut oats"
}'
const axios = require('axios');

const config = {
  method: 'post',
  url: 'https://partners.january.ai/v1.1/vision/fix-ai',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
    'x-partner-user-id': 'your-user-id'
  },
  data: {
    "mealName": "Breakfast Bowl",
    "detections": [
      {
        "confidenceScore": "high",
        "food": {
          "name": "Oatmeal",
          "id": 789012,
          "brandName": null,
          "nutrients": {
            "calories": {
              "value": 300,
              "unit": "kcal"
            }
          },
          "servings": [
            {
              "id": 45678,
              "quantity": 1,
              "unit": "cup"
            }
          ]
        }
      }
    ],
    "userInput": "change oatmeal to steel-cut oats"
  }
};

axios(config)
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.log(error);
  });

The above command returns JSON structured like this:

{
  "mealName": "Breakfast Bowl",
  "totalNutrients": {
    "calories": {
      "value": 520,
      "unit": "kcal"
    },
    "carbs": {
      "value": 68,
      "unit": "g"
    },
    "protein": {
      "value": 15,
      "unit": "g"
    }
  },
  "detections": [
    {
      "confidenceScore": "high",
      "food": {
        "name": "Oatmeal",
        "id": 789012,
        "brandName": null,
        "nutrients": {
          "calories": {
            "value": 300,
            "unit": "kcal"
          }
        },
        "servings": [
          {
            "id": 45678,
            "quantity": 1,
            "unit": "cup"
          }
        ]
      }
    }
  ]
}

This API lets users update food types and quantities from a photo scan using natural language, either by voice or text. For example, after scanning a photo of a Mexican chicken and rice bowl and noticing a couple of inaccuracies, a user might say:

"It was actually 1 cup of chicken. It was also white rice, not brown rice."

The API parses this input and updates the scan results accordingly.

HTTP Request

POST https://partners.january.ai/v1.1/vision/fix-ai

Headers

Header Required Description
Authorization Yes Bearer token for authentication
Content-Type Yes Must be application/json
x-partner-user-id Yes Unique user ID from your system

Request Body

Parameter Required Description
mealName Yes Name of the meal to edit
detections Yes Array of detected food items to edit
userInput Yes Text representation of changes to make

Response Structure

The response includes:

Healthy Alternatives

import requests
import json

url = 'https://partners.january.ai/v1.1/food-alternatives/5467772'
headers = {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
}
data = {
    "dietRestrictions": ["Gluten"],
    "dietPreferences": ["Vegan"]
}

response = requests.post(url, headers=headers, json=data)
print(response.json())
curl --location 'https://partners.january.ai/v1.1/food-alternatives/5467772' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--data '{
  "dietRestrictions": ["Gluten"],
  "dietPreferences": ["Vegan"]
}'
const axios = require('axios');

const config = {
  method: 'post',
  url: 'https://partners.january.ai/v1.1/food-alternatives/5467772',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  data: {
    dietRestrictions: ["Gluten"],
    dietPreferences: ["Vegan"]
  }
};

axios(config)
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.log(error);
  });

The above command returns JSON structured like this:

{
  "alternatives": [
    {
      "food": {
        "name": "Gluten-Free Oat Bread",
        "id": 9876543,
        "brandName": "Nature's Path",
        "nutrients": {
          "calories": {
            "value": 80,
            "unit": "kcal"
          },
          "carbs": {
            "value": 15,
            "unit": "g"
          }
        },
        "servings": [
          {
            "id": 12345,
            "quantity": 1,
            "unit": "slice"
          }
        ]
      }
    }
  ]
}

Get healthier alternatives for individual foods based on nutrition, context, and user preferences.

HTTP Request

POST https://partners.january.ai/v1.1/food-alternatives/{foodId}

Headers

Header Required Description
Authorization Yes Bearer token for authentication
Content-Type Yes Must be application/json

URL Parameters

Parameter Description
foodId The unique identifier of the food item to find alternatives for

Request Body

Parameter Required Description
dietRestrictions Yes Array of dietary restrictions/allergies
dietPreferences Yes Array of dietary preferences

Dietary Restrictions

Valid dietary restrictions include:

Dietary Preferences

Valid dietary preferences include:

Response Structure

The response includes:

Food Logging APIs

Create, retrieve, and manage food logs with these Food Logging APIs.

Create Food Logs

import requests
import json

url = 'https://partners.january.ai/v1.1/logs/foods'
headers = {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
    'x-partner-user-id': 'your-user-id'
}
data = {
    "foods": [
        {
            "id": 101963552,
            "serving": {
                "id": 68051535,
                "quantity": 1.4
            }
        }
    ],
    "timestampUtc": "2024-09-13T11:34:56Z"
}

response = requests.post(url, headers=headers, json=data)
print(response.json())
curl --location 'https://partners.january.ai/v1.1/logs/foods' \
--header 'Content-Type: application/json' \
--header 'x-partner-user-id: your-user-id' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--data '{
  "foods": [
    {
      "id": 101963552,
      "serving": {
        "id": 68051535,
        "quantity": 1.4
      }
    }
  ],
  "timestampUtc": "2024-09-13T11:34:56Z"
}'
const axios = require('axios');

const config = {
  method: 'post',
  url: 'https://partners.january.ai/v1.1/logs/foods',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
    'x-partner-user-id': 'your-user-id'
  },
  data: {
    foods: [
      {
        id: 101963552,
        serving: {
          id: 68051535,
          quantity: 1.4
        }
      }
    ],
    timestampUtc: "2024-09-13T11:34:56Z"
  }
};

axios(config)
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.log(error);
  });

Associate logged foods with a specific user.

HTTP Request

POST https://partners.january.ai/v1.1/logs/foods

Headers

Header Required Description
Authorization Yes Bearer token for authentication
Content-Type Yes Must be application/json
x-partner-user-id Yes Unique user ID from your system

Request Body

Parameter Required Description
foods Yes Array of food items to be logged
foods[].id Yes Unique identifier of the food item
foods[].serving Yes Serving details of the food item
foods[].serving.id Yes Serving size identifier
foods[].serving.quantity Yes Amount of the serving consumed
timestampUtc Yes UTC timestamp when food was consumed (YYYY-MM-DDTHH:MM:SSZ)
name Optional Name of the meal

Retrieve Food Logs

import requests

url = 'https://partners.january.ai/v1.1/logs/foods'
params = {
    'start': '2023-09-12',
    'end': '2024-09-15'
}
headers = {
    'Authorization': 'Bearer YOUR_API_KEY',
    'x-partner-user-id': 'your-user-id'
}

response = requests.get(url, params=params, headers=headers)
print(response.json())
curl --location 'https://partners.january.ai/v1.1/logs/foods?start=2023-09-12&end=2024-09-15' \
--header 'x-partner-user-id: your-user-id' \
--header 'Authorization: Bearer YOUR_API_KEY'
const axios = require('axios');

const config = {
  method: 'get',
  url: 'https://partners.january.ai/v1.1/logs/foods',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'x-partner-user-id': 'your-user-id'
  },
  params: {
    start: '2023-09-12',
    end: '2024-09-15'
  }
};

axios(config)
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.log(error);
  });

Retrieve food logs for a specific user over a defined date range.

HTTP Request

GET https://partners.january.ai/v1.1/logs/foods

Headers

Header Required Description
Authorization Yes Bearer token for authentication
x-partner-user-id Yes Unique user ID from your system

Query Parameters

Parameter Required Description
start Yes Start date (YYYY-MM-DD format)
end Yes End date (YYYY-MM-DD format)

Delete Food Log

import requests

url = 'https://partners.january.ai/v1.1/logs/foods/78129823-8ba2-4183-b13b-71f0e963c606'
headers = {
    'Authorization': 'Bearer YOUR_API_KEY',
    'x-partner-user-id': 'user123'
}

response = requests.delete(url, headers=headers)
print(response.status_code)
curl --location --request DELETE 'https://partners.january.ai/v1.1/logs/foods/78129823-8ba2-4183-b13b-71f0e963c606' \
--header 'x-partner-user-id: user123' \
--header 'Authorization: Bearer YOUR_API_KEY'
const axios = require('axios');

const config = {
  method: 'delete',
  url: 'https://partners.january.ai/v1.1/logs/foods/78129823-8ba2-4183-b13b-71f0e963c606',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'x-partner-user-id': 'user123'
  }
};

axios(config)
  .then(response => {
    console.log(response.status);
  })
  .catch(error => {
    console.log(error);
  });

Delete food logs associated with a specific user.

HTTP Request

DELETE https://partners.january.ai/v1.1/logs/foods/{logId}

URL Parameters

Parameter Description
logId The unique identifier of the food log to delete

Headers

Header Required Description
Authorization Yes Bearer token for authentication
x-partner-user-id Yes Unique user ID from your system

Glucose Insights APIs

Predict post-meal glucose responses with these Glucose Insights APIs.

Glucose Prediction

import requests
import json

url = 'https://partners.january.ai/v1.1/cgm/glucose-predict'
headers = {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
    'x-partner-timezone': 'America/Los_Angeles'
}
data = {
    "userProfile": {
        "age": 25,
        "gender": "male",
        "height": 65,
        "weight": 165,
        "activityLevel": "very_active",
        "healthConditions": ["Type 2 diabetes"]
    },
    "startTime": "2025-04-09T19:06:12Z",
    "foods": [
        {
            "id": 70380652,
            "serving": {
                "id": 34176931,
                "quantity": 1
            }
        }
    ],
    "cgmData": [
        # Optional CGM data array
        {
            "timestamp": "2025-04-03T14:56:03Z",
            "value": 92
        },
        {
            "timestamp": "2025-04-03T14:59:40Z",
            "value": 95
        }
    ],
    "consumedFoods": [
        # Optional historical user foods
        {
            "timestamp": "2025-04-03T14:56:03Z",
            "id": 70380652,
            "serving": {
                "id": 34176931,
                "quantity": 1
            }
        }
    ]
}

response = requests.post(url, headers=headers, json=data)
print(response.json())
curl --location 'https://partners.january.ai/v1.1/cgm/glucose-predict' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'x-partner-timezone: America/Los_Angeles' \
--data '{
  "userProfile": {
    "age": 25,
    "gender": "male",
    "height": 65,
    "weight": 165,
    "activityLevel": "very_active",
    "healthConditions": ["Type 2 diabetes"]
  },
  "startTime": "2025-04-09T19:06:12Z",
  "foods": [
    {
      "id": 70380652,
      "serving": {
        "id": 34176931,
        "quantity": 1
      }
    }
  ],
  "cgmData": [
    {
      "timestamp": "2025-04-03T14:56:03Z",
      "value": 92
    },
    {
      "timestamp": "2025-04-03T14:59:40Z",
      "value": 95
    }
  ],
  "consumedFoods": [
    {
      "timestamp": "2025-04-03T14:56:03Z",
      "id": 70380652,
      "serving": {
          "id": 34176931,
          "quantity": 1
      }
    }
  ]
}'
const axios = require('axios');

const config = {
  method: 'post',
  url: 'https://partners.january.ai/v1.1/cgm/glucose-predict',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
    'x-partner-timezone': 'America/Los_Angeles'
  },
  data: {
    userProfile: {
      age: 25,
      gender: "male",
      height: 65,
      weight: 165,
      activityLevel: "very_active",
      healthConditions: ["Type 2 diabetes"]
    },
    startTime: "2025-04-09T19:06:12Z",
    foods: [
      {
        id: 70380652,
        serving: {
          id: 34176931,
          quantity: 1
        }
      }
    ],
    cgmData: [
        // Optional CGM data array
        {
            "timestamp": "2025-04-03T14:56:03Z",
            "value": 92
        }
    ],
    consumedFoods: [
        // Optional historical user foods
        {
            timestamp: "2025-04-03T14:56:03Z",
            id: 70380652,
            serving: {
                id: 34176931,
                quantity: 1
            }
        }
    ]
  }
};

axios(config)
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.log(error);
  });

The above command returns JSON structured like this:

{
  "cgp": [
    [0, 95],
    [15, 110],
    [30, 140],
    [45, 155],
    [60, 145],
    [75, 125],
    [90, 110],
    [105, 100],
    [120, 95],
    [135, 92]
  ],
  "scoring": "medium_impact",
  "cgp_min": 70,
  "cgp_max": 140
}

This endpoint returns two-hour glucose predictions for a user based on individual food or meal lookups.

You can optionally provide cgmData and consumedFoods to enable hyper-personalized glucose predictions. To complete training, the data must include at least five “complete” training days.

A training day is considered complete if it meets both of the following criteria: - At least 12 hours of CGM data - At least 2 logged meals at different times of the day

HTTP Request

POST https://partners.january.ai/v1.1/cgm/glucose-predict

Headers

Header Required Description
Authorization Yes Bearer token for authentication
Content-Type Yes Must be application/json
x-partner-timezone Yes User local timezone (e.g. America/New_York or US/Pacific)

Request Body

Parameter Required Description
userProfile Yes User's profile data
userProfile.age Yes User's age
userProfile.gender Yes User's gender ('male' or 'female')
userProfile.height Yes User's height in inches
userProfile.weight Yes User's weight in pounds
userProfile.activityLevel Yes Activity level ('sedentary', 'lightly_active', 'moderately_active', 'very_active')
userProfile.healthConditions Yes Array of health conditions
foods Yes Array of foods and servings for prediction
foods[].id Yes Unique identifier of the food item
foods[].serving Yes Serving details
foods[].serving.id Yes Serving size identifier
foods[].serving.quantity Yes Amount of serving consumed
startTime Yes ISO 8601 timestamp for when foods are consumed
cgmData No CGM data array for AI training. Please provide at least one data point per 15 minutes. If cgmData is provided, consumedFoods must be provided also.
cgmData[].timestamp Yes ISO 8601 timestamp for the CGM data point
cgmData[].value Yes Blood sugar level (in mg/dL)
consumedFoods No Array of historical user foods and servings for AI training.
consumedFoods[].timestamp Yes ISO 8601 timestamp for when the food is consumed
consumedFoods[].id Yes Unique identifier of the food item
consumedFoods[].serving Yes Serving details
consumedFoods[].serving.id Yes Serving size identifier
consumedFoods[].serving.quantity Yes Amount of serving consumed

Health Conditions

Valid health conditions include:

Response Structure

The response includes:

AI-Trained Glucose Prediction

import requests
import json

url = 'https://partners.january.ai/v1.1/cgm/user-glucose-predict'
headers = {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
    'x-partner-user-id': 'YOUR_PARTNER_USER_ID',
    'x-partner-timezone': 'America/Los_Angeles'
}
data = {
    "startTime": "2025-04-09T19:06:12Z",
    "foods": [
        {
            "id": 70380652,
            "serving": {
                "id": 34176931,
                "quantity": 1
            }
        }
    ]
}

response = requests.post(url, headers=headers, json=data)
print(response.json())
curl --location 'https://partners.january.ai/v1.1/cgm/user-glucose-predict' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'x-partner-user-id: YOUR_PARTNER_USER_ID' \
--header 'x-partner-timezone: America/Los_Angeles' \
--data '{
  "startTime": "2025-04-09T19:06:12Z",
  "foods": [
    {
      "id": 70380652,
      "serving": {
        "id": 34176931,
        "quantity": 1
      }
    }
  ]
}'
const axios = require('axios');

const config = {
  method: 'post',
  url: 'https://partners.january.ai/v1.1/cgm/user-glucose-predict',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
    'x-partner-user-id': 'YOUR_PARTNER_USER_ID',
    'x-partner-timezone': 'America/Los_Angeles'
  },
  data: {
    startTime: "2025-04-09T19:06:12Z",
    foods: [
      {
        id: 70380652,
        serving: {
          id: 34176931,
          quantity: 1
        }
      }
    ]
  }
};

axios(config)
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.log(error);
  });

The above command returns JSON structured like this:

{
  "cgp": [
    [0, 95],
    [15, 110],
    [30, 140],
    [45, 155],
    [60, 145],
    [75, 125],
    [90, 110],
    [105, 100],
    [120, 95],
    [135, 92]
  ],
  "scoring": "medium_impact",
  "cgp_min": 70,
  "cgp_max": 140
}

Returns a two-hour glucose prediction using a personalized AI model trained on a specific user's CGM and meal history.

To use this endpoint, pass the user’s ID in the x-partner-user-id header. The user must already exist and have completed AI training (see User Management APIs).

Accepts either the foods or nutrients parameter as input. Unlike the standard glucose prediction endpoint, this version does not require passing CGM data in the request — improving performance by using previously stored training data.

HTTP Request

POST https://partners.january.ai/v1.1/cgm/user-glucose-predict

Headers

Header Required Description
Authorization Yes Bearer token for authentication
Content-Type Yes Must be application/json
x-partner-user-id Yes Partner User ID (UUID format)
x-partner-timezone Yes User local timezone (e.g. America/New_York or US/Pacific)

Request Body

Parameter Required Description
startTime No ISO 8601 timestamp for when foods are consumed (default is current time)
foods No Array of foods and servings for prediction. If not specified, then nutrients parameter is applied.
foods[].id Yes Unique identifier of the food item
foods[].serving Yes Serving details
foods[].serving.id Yes Serving size identifier
foods[].serving.quantity Yes Amount of serving consumed
nutrients No Object with nutrients quantities (applied only when foods parameter is not specified)
nutrients.water No Quantity of water (g)
nutrients.energy No Quantity of energy (calories)
nutrients.protein No Quantity of protein (g)
nutrients.fat_total_lipid No Quantity of total fat (g)
nutrients.carbohydrate No Quantity of carbohydrates (g)
nutrients.fiber No Quantity of fiber (g)
nutrients.sugars No Quantity of sugars (g)
nutrients.calcium No Quantity of calcium (g)
nutrients.iron No Quantity of iron (g)
nutrients.potassium No Quantity of potassium (g)
nutrients.sodium No Quantity of sodium (mg)
nutrients.vit_c No Quantity of vit C (g)
nutrients.vit_a_iu No Quantity of vit A iu (g)
nutrients.fat_total_saturated No Quantity of saturated fat (g)
nutrients.fat_total_monounsaturated No Quantity of monounsaturated fat (g)
nutrients.fat_total_polyunsaturated No Quantity of polyunsaturated fat (g)
nutrients.fat_total_trans No Quantity of trans fat (g)
nutrients.cholesterol No Quantity of cholesterol (g)
nutrients.caffeine No Quantity of caffeine (g)

Response Structure

The response includes:

User Management APIs

Create, update, and delete users, and check whether they meet the criteria for AI training to enable personalized glucose predictions.

Create User

import requests
import json

url = 'https://partners.january.ai/v1.1/user'
headers = {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
}
data = {
    "profile": {
        "age": 20,
        "gender": "male",
        "weight": 80,
        "height": 36,
        "activity_level": "sedentary",
        "medical_conditions": []
    }
}

response = requests.post(url, headers=headers, json=data)
print(response.json())
curl --location 'https://partners.january.ai/v1.1/user' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--data '{
    "profile": {
        "age": 20,
        "gender": "male",
        "weight": 80,
        "height": 36,
        "activity_level": "sedentary",
        "medical_conditions": []
    }
}'
const axios = require('axios');

const config = {
  method: 'post',
  url: 'https://partners.january.ai/v1.1/user',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  data: {
    "profile": {
        "age": 20,
        "gender": "male",
        "weight": 80,
        "height": 36,
        "activity_level": "sedentary",
        "medical_conditions": []
    }
  }
};

axios(config)
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.log(error);
  });

The above command returns JSON structured like this:

{
    "user_id": "a88888ef-cc9c-5882-ba2c-9cbee8a4b73c",
    "profile": {
        "age": 20,
        "gender": "male",
        "weight": 80,
        "height": 36,
        "activity_level": "sedentary",
        "medical_conditions": []
    }
}

Creates a user and returns the user ID. Requires a user profile in the request.

HTTP Request

POST https://partners.january.ai/v1.1/user

Headers

Header Required Description
Authorization Yes Bearer token for authentication
Content-Type Yes Must be application/json

Request Body

Parameter Required Description
profile Yes User profile object
profile.age Yes User's age
profile.gender Yes User's gender ('male' or 'female')
profile.height Yes User's height in inches
profile.weight Yes User's weight in pounds
profile.activityLevel No Activity level ('sedentary', 'lightly_active', 'moderately_active', 'very_active')
profile.healthConditions No Array of health conditions

Health Conditions

Valid health conditions include:

Response Structure

The response includes:

Get User Profile

import requests
import json

url = 'https://partners.january.ai/v1.1/user'
headers = {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
    'x-partner-user-id': 'your-user-id'
}

response = requests.get(url, headers=headers)
print(response.json())
curl --location 'https://partners.january.ai/v1.1/user' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'x-partner-user-id: your-user-id'
const axios = require('axios');

const config = {
  method: 'get',
  url: 'https://partners.january.ai/v1.1/user',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
    'x-partner-user-id': 'your-user-id'
  }
};

axios(config)
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.log(error);
  });

The above command returns JSON structured like this:

{
    "user_id": "a88888ef-cc9c-5882-ba2c-9cbee8a4b73c",
    "profile": {
        "age": 20,
        "gender": "male",
        "weight": 80,
        "height": 36,
        "activity_level": "sedentary",
        "medical_conditions": []
    }
}

Returns the partner user's ID and profile. Returns a 404 Not Found error if the specified user ID does not exist.

HTTP Request

GET https://partners.january.ai/v1.1/user

Headers

Header Required Description
Authorization Yes Bearer token for authentication
Content-Type Yes Must be application/json
x-partner-user-id Yes Your user ID

Response Structure

The response includes:

Update User Profile

import requests
import json

url = 'https://partners.january.ai/v1.1/user'
headers = {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
    'x-partner-user-id': 'your-user-id'
}
data = {
    "profile": {
        "age": 20,
        "gender": "male",
        "weight": 80,
        "height": 36,
        "activity_level": "sedentary",
        "medical_conditions": []
    }
}

response = requests.patch(url, headers=headers, json=data)
print(response.json())
curl --location --request PATCH 'https://partners.january.ai/v1.1/user' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'x-partner-user-id: your-user-id'
--data '{
    "profile": {
        "age": 20,
        "gender": "male",
        "weight": 80,
        "height": 36,
        "activity_level": "sedentary",
        "medical_conditions": []
    }
}'
const axios = require('axios');

const config = {
  method: 'patch',
  url: 'https://partners.january.ai/v1.1/user',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
    'x-partner-user-id': 'your-user-id'
  },
  data: {
    "profile": {
        "age": 20,
        "gender": "male",
        "weight": 80,
        "height": 36,
        "activity_level": "sedentary",
        "medical_conditions": []
    }
  }
};

axios(config)
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.log(error);
  });

The above command returns JSON structured like this:

{
    "user_id": "a88888ef-cc9c-5882-ba2c-9cbee8a4b73c",
    "profile": {
        "age": 20,
        "gender": "male",
        "weight": 80,
        "height": 36,
        "activity_level": "sedentary",
        "medical_conditions": []
    }
}

Updates the user's profile and returns their user information. Requires a user profile in the request body.

HTTP Request

PATCH https://partners.january.ai/v1.1/user

Headers

Header Required Description
Authorization Yes Bearer token for authentication
Content-Type Yes Must be application/json
x-partner-user-id Yes Your user ID

Request Body

Parameter Required Description
profile Yes User profile object
profile.age Yes User's age
profile.gender Yes User's gender ('male' or 'female')
profile.height Yes User's height in inches
profile.weight Yes User's weight in pounds
profile.activityLevel No Activity level ('sedentary', 'lightly_active', 'moderately_active', 'very_active')
profile.healthConditions No Array of health conditions

Health Conditions

Valid health conditions include:

Response Structure

The response includes:

Delete User

import requests
import json

url = 'https://partners.january.ai/v1.1/user'
headers = {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
    'x-partner-user-id': 'your-user-id'
}

response = requests.delete(url, headers=headers)
print(response.json())
curl --location --request DELETE 'https://partners.january.ai/v1.1/user' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'x-partner-user-id: your-user-id'
const axios = require('axios');

const config = {
  method: 'delete',
  url: 'https://partners.january.ai/v1.1/user',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
    'x-partner-user-id': 'your-user-id'
  }
};

axios(config)
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.log(error);
  });

Deletes the user. If the specified user ID does not exist, the request still returns a success status.

HTTP Request

DELETE https://partners.january.ai/v1.1/user

Headers

Header Required Description
Authorization Yes Bearer token for authentication
Content-Type Yes Must be application/json
x-partner-user-id Yes Your user ID to delete

Get All Users

import requests
import json

url = 'https://partners.january.ai/v1.1/users'
headers = {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
}

response = requests.get(url, headers=headers)
print(response.json())
curl --location 'https://partners.january.ai/v1.1/users' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_API_KEY'
const axios = require('axios');

const config = {
  method: 'get',
  url: 'https://partners.january.ai/v1.1/users',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

axios(config)
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.log(error);
  });

The above command returns JSON array like this:

[
  {
    "user_id": "a88888ef-cc9c-5882-ba2c-9cbee8a4b73c",
    "profile": {
      "age": 20,
      "gender": "male",
      "weight": 80,
      "height": 36,
      "activity_level": "sedentary",
      "medical_conditions": []
    }
  },
  ....
]

This endpoint returns all partner user IDs and profiles.

HTTP Request

GET https://partners.january.ai/v1.1/users

Headers

Header Required Description
Authorization Yes Bearer token for authentication
Content-Type Yes Must be application/json

Response Structure

The response includes array of:

Mark User as AI-Trained

import requests
import json

url = 'https://partners.january.ai/v1.1/user/training'
headers = {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
    'x-partner-user-id': 'your-user-id'
}
data = {
    "cgm_data": [
        # CGM data array
        {
            "timestamp": "2025-04-03T14:56:03Z",
            "value": 92
        },
        {
            "timestamp": "2025-04-03T14:59:40Z",
            "value": 95
        }
    ],
    "consumed_foods": [
        # Historical user foods
        {
            "timestamp": "2025-04-03T14:56:03Z",
            "id": 70380652,
            "serving": {
                "id": 34176931,
                "quantity": 1
            }
        }
    ]
}

response = requests.post(url, headers=headers, json=data)
print(response.json())
curl --location 'https://partners.january.ai/v1.1/user/training' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'x-partner-user-id: your-user-id' \
--data '{
    "cgm_data": [
        {
            "timestamp": "2025-04-03T14:56:03Z",
            "value": 92
        },
        {
            "timestamp": "2025-04-03T14:59:40Z",
            "value": 95
        }
    ],
    "consumed_foods": [
        {
            "timestamp": "2025-04-03T14:56:03Z",
            "id": 70380652,
            "serving": {
                "id": 34176931,
                "quantity": 1
            }
        }
    ]
}'
const axios = require('axios');

const config = {
  method: 'post',
  url: 'https://partners.january.ai/v1.1/user/training',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
    'x-partner-user-id': 'your-user-id'
  },
  data: {
    "cgm_data": [
      // CGM data array
      {
        "timestamp": "2025-04-03T14:56:03Z",
        "value": 92
      },
      {
        "timestamp": "2025-04-03T14:59:40Z",
        "value": 95
      }
    ],
    "consumed_foods": [
      // Historical user foods
      {
        "timestamp": "2025-04-03T14:56:03Z",
        "id": 70380652,
        "serving": {
          "id": 34176931,
          "quantity": 1
        }
      }
    ]
  }
};

axios(config)
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.log(error);
  });

The above command returns JSON structured like this:

{
    "good_days": [
        "2025-09-01",
        "2025-09-02",
        "2025-09-03",
        "2025-09-04",
        "2025-09-05"
    ]
}

Sets user AI training data for personalized glucose predictions.

Requires cgm_data and consumed_foods parameters with sufficient data to complete training. Training is considered complete if the input includes five or more valid training days.

A valid training day must include:

If the data does not meet these requirements, the endpoint returns a 400 Bad Request error.

HTTP Request

POST https://partners.january.ai/v1.1/user/training

Headers

Header Required Description
Authorization Yes Bearer token for authentication
Content-Type Yes Must be application/json
x-partner-user-id Yes Your user ID

Request Body

Parameter Required Description
cgm_data Yes CGM data array for AI training. Please provide at least one data point per 15 minutes.
cgm_data[].timestamp Yes ISO 8601 timestamp for the CGM data point
cgm_data[].value Yes Blood sugar level (in mg/dL)
consumed_foods Yes Array of historical user foods and servings for AI training.
consumed_foods[].timestamp Yes ISO 8601 timestamp for when the food is consumed
consumed_foods[].id Yes Unique identifier of the food item
consumed_foods[].serving Yes Serving details
consumed_foods[].serving.id Yes Serving size identifier
consumed_foods[].serving.quantity Yes Amount of serving consumed

Response Structure

The response includes:

Errors

The January AI API uses the following error codes:

Error Code Meaning
400 Bad Request -- Your request is invalid or malformed.
401 Unauthorized -- Your API key is invalid or missing.
403 Forbidden -- You don't have permission to access this resource.
404 Not Found -- The specified resource could not be found.
405 Method Not Allowed -- You tried to access a resource with an invalid HTTP method.
406 Not Acceptable -- You requested a format that isn't supported.
422 Unprocessable Entity -- The request was well-formed but contains semantic errors.
429 Too Many Requests -- You're making too many requests! Please slow down.
500 Internal Server Error -- We had a problem with our server. Try again later.
503 Service Unavailable -- We're temporarily offline for maintenance. Please try again later.

Error Response Format

Error responses are formatted like this:

{
  "error": {
    "code": 400,
    "message": "Bad Request",
    "details": "The 'query' parameter is required for this endpoint."
  }
}

All error responses follow a consistent format with an error object containing:

Common Error Scenarios

Authentication Errors

Request Errors

Server Errors