> For the complete documentation index, see [llms.txt](https://docs.january.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.january.ai/rest-api/api-overview.md).

# API overview

The January API provides food search, food analysis, food, water, and weight logging, restaurant discovery, and sensor-free glucose prediction through one versioned HTTP API.

## Base URL

```
https://partners.january.ai
```

Paths start with the API version, `/v1.2`; for example, `https://partners.january.ai/v1.2/foods`. [API v1.1](/rest-api/v1-1-legacy.md) is the legacy version.

Send a credential on every request, either an API key (`sk-…`) from your backend or a client token (`ct-…`) from an app:

```http
Authorization: Bearer YOUR_CREDENTIAL
```

## Credentials

* An **API key** (`sk-…`) identifies your account. Create one in the [January Developer Dashboard](https://dashboard.january.ai) and use it only from your backend, where it can call every endpoint.
* A **client token** (`ct-…`) is a short-lived credential your backend mints for one signed-in end user. It lets an app call January directly without holding the API key. The token acts only as that user, and only within the scopes it was granted.

Apps running on an end user's device use client tokens, never an API key. [How authentication works](/docs/authentication.md) walks through the token flow and the endpoint your backend adds, and [Client tokens](/rest-api/authentication.md) documents minting, revocation, and scopes.

## End-user identity

The [food-log](/rest-api/food-logs.md), [water-log](/rest-api/water-logs.md), and [weight-log](/rest-api/weight-logs.md) operations read and write one end user's logs. With an API key, name the user with the `January-End-User-ID` header, set to your [end-user ID](/docs/authentication.md) for that person:

```http
January-End-User-ID: YOUR_END_USER_ID
```

* With an API key, a log operation without the header fails with `400 end_user_id_required`.
* With a client token, the user comes from the token. The header is optional, and a value naming a different user fails with `403 end_user_id_mismatch`.
* Other endpoints ignore the header.

## Identifiers

* Food, serving, and menu-item IDs are strings of one to ten digits with no leading zero (`^[1-9]\d{0,9}$`). Responses always include them. Treat them as opaque strings and pass them back exactly as returned.
* Food-log and water-log IDs are UUIDs. Save the `id` a create returns: a food log can be fetched, updated, and deleted by it, and a water log deleted. Rarely, a listed food log has `id: null`; it can't be addressed, so show it read-only.
* Weight logs have no ID and can't be updated or deleted.

## Days and timezones

Every food, water, and weight log has a `created_at`: when the meal was eaten, the water was consumed, or the weight was measured. Send it with any ISO 8601 offset, or omit it to mean now. January returns it in UTC with milliseconds.

List and summary calls take inclusive `YYYY-MM-DD` dates plus an IANA `timezone`, and group logs into that timezone's calendar days when you read them. For example, `2026-09-10T23:30:00-07:00` is stored as `2026-09-11T06:30:00.000Z`. It lists under September 10 with `timezone=America/Los_Angeles` and under September 11 with `timezone=UTC`. Pass the user's own timezone.

|                   | Food logs              | Water logs                                                     | Weight logs                             |
| ----------------- | ---------------------- | -------------------------------------------------------------- | --------------------------------------- |
| A list returns    | Every log              | One total per day                                              | One weight per day, the latest measured |
| Longest range     | 60 days (summary: 366) | The most recent 100 days; `start_date` at most five years back | Same as water logs                      |
| Addressable by ID | Get, update, delete    | Delete                                                         | No                                      |

A range longer than these limits fails with `400 date_range_too_large`. The 24 L daily water cap counts the UTC calendar day of each entry's `created_at`, whatever offset you send, so near midnight a listed day's total can differ from what the cap counted.

## Errors

Every error response has the HTTP status and a JSON body with a stable `code` and a developer-facing `message`:

```json
{ "code": "invalid_request", "message": "query is required: the food name to search for, e.g. ?query=greek yogurt." }
```

Branch on `code`, not on the message wording. New codes may appear over time; handle a code you don't recognize by its HTTP status class. Each operation in this reference lists the codes it returns.

| Code                                                                                     | Status | Meaning                                                                                                                                                              | Retry                                                                                                                          |
| ---------------------------------------------------------------------------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `invalid_request`                                                                        | 400    | A parameter or body field is missing, malformed, or out of range; the message names it.                                                                              | No                                                                                                                             |
| `image_unreachable`, `image_corrupt`, `image_format_unsupported`, `image_invalid_base64` | 400    | The image for a food analysis couldn't be used; the message says what to fix.                                                                                        | No                                                                                                                             |
| `end_user_id_required`                                                                   | 400    | An API-key request to a log operation omitted `January-End-User-ID`.                                                                                                 | No                                                                                                                             |
| `date_range_too_large`                                                                   | 400    | A date range is longer than the operation allows, or starts too far back.                                                                                            | No                                                                                                                             |
| `daily_water_limit_exceeded`                                                             | 400    | The water log would take the user's total for the day past 24 L.                                                                                                     | No                                                                                                                             |
| `unauthorized`                                                                           | 401    | The `Authorization` header is missing or malformed, or the key isn't recognized.                                                                                     | No                                                                                                                             |
| `token_expired`                                                                          | 401    | The client token is past its lifetime.                                                                                                                               | Get a new token, then retry once                                                                                               |
| `token_invalid`, `token_revoked`                                                         | 401    | The client token doesn't exist or was revoked.                                                                                                                       | No                                                                                                                             |
| `forbidden`                                                                              | 403    | The credential is valid but not allowed to make this request; for example, the key is for API v1.1, or client tokens are switched off.                               | No                                                                                                                             |
| `client_token_not_allowed`                                                               | 403    | The operation accepts only an API key.                                                                                                                               | No                                                                                                                             |
| `scope_insufficient`                                                                     | 403    | The client token lacks the scope the operation needs.                                                                                                                | No                                                                                                                             |
| `end_user_id_mismatch`                                                                   | 403    | `January-End-User-ID` names a different user than the client token.                                                                                                  | No                                                                                                                             |
| `not_found`                                                                              | 404    | The resource doesn't exist.                                                                                                                                          | No                                                                                                                             |
| `conflict`                                                                               | 409    | The request conflicts with an existing resource.                                                                                                                     | After resolving it                                                                                                             |
| `payload_too_large`                                                                      | 413    | The request body is too large.                                                                                                                                       | No                                                                                                                             |
| `rate_limited`                                                                           | 429    | A per-endpoint limit or the rolling 24-hour burst guard.                                                                                                             | After `Retry-After`, which can be up to a day                                                                                  |
| `request_limit_exceeded`, `credit_limit_exceeded`                                        | 429    | The request or credit allowance for your billing period is spent, or the call costs more credits than you have left. Enterprise accounts are billed overage instead. | Not before the reset that [Credits](/rest-api/credits.md) reports; see [Credits and pricing](/rest-api/credits-and-pricing.md) |
| `cancelled`                                                                              | 499    | The client disconnected before the request completed; the body may not arrive.                                                                                       | —                                                                                                                              |
| `internal_error`                                                                         | 500    | An unexpected server error.                                                                                                                                          | With backoff                                                                                                                   |
| `not_implemented`                                                                        | 501    | The feature isn't available yet.                                                                                                                                     | No                                                                                                                             |
| `upstream_error`                                                                         | 502    | A dependency failed.                                                                                                                                                 | With backoff                                                                                                                   |
| `service_unavailable`, `client_token_revocation_incomplete`                              | 503    | The service is temporarily unavailable, or a revocation stopped only part of its batch.                                                                              | With backoff                                                                                                                   |
| `upstream_timeout`                                                                       | 504    | A dependency timed out.                                                                                                                                              | With backoff                                                                                                                   |

## Endpoint groups

* [Client tokens](/rest-api/authentication.md): mint and revoke client tokens, and the scope each operation needs.
* [Foods](/rest-api/foods.md): autocomplete, search, barcode lookup, food details, and alternatives.
* [Food analysis](/rest-api/food-analysis.md): analyze a meal photo, a nutrition label, or a description, and correct the result.
* [Food logs](/rest-api/food-logs.md): create, list, summarize, get, update, and delete diary entries.
* [Water logs](/rest-api/water-logs.md): log water in fluid ounces, milliliters, or cups, list daily totals, and delete entries.
* [Weight logs](/rest-api/weight-logs.md): log body weight in pounds or kilograms and list one weight per day.
* [Glucose prediction](/rest-api/glucose.md): predict a meal's glucose response without a sensor.
* [Restaurants](/rest-api/restaurants.md): find restaurants and menu items near a location.
* [Credits](/rest-api/credits.md): check your allowance for the current billing period. For prices, see [Credits and pricing](/rest-api/credits-and-pricing.md).

You can also use the [interactive OpenAPI reference](https://partners.january.ai/v1.2/docs) or [download the OpenAPI specification](https://partners.january.ai/v1.2/openapi.json).
