Authentication API
JanuaryClient
public struct JanuaryClient: Sendable {
public let foods: FoodsResource
public let restaurants: RestaurantsResource
public let foodAnalysis: FoodAnalysisResource
public let foodLogs: FoodLogsResource
public let glucose: GlucoseResource
public let waterLogs: WaterLogsResource
public let weightLogs: WeightLogsResource
public init(
endUserID: String,
timezone: TimeZone? = nil,
clientTokenProvider: @escaping JanuaryClientTokenProvider,
tokenRetryPolicy: JanuaryTokenRetryPolicy = .default
) throws
public init(
endUserID: String,
timezone: TimeZone? = nil,
clientTokenProvider: any JanuaryTokenProvider,
tokenRetryPolicy: JanuaryTokenRetryPolicy = .default
) throws
public init(
clientToken: String,
endUserID: String,
timezone: TimeZone? = nil
) throws
// Debug builds only.
public init(
developmentAPIKey: String,
endUserID: String,
timezone: TimeZone? = nil
) throws
}clientToken rejects an empty value, and the SDK can't refresh it. developmentAPIKey is for local development only (local development).
Token provider
JanuaryClientToken decodes January's token response unchanged: it reads token and either expires_in or expiresIn. It encodes expiresIn.
Throw JanuaryTokenProviderError from your provider for every failure, with retryable: true only for transient ones: network errors, timeouts, and HTTP 408, 429, and 5xx. Errors shows what each kind of failure becomes, and Retries and concurrency covers caching, refresh, and retries.
Development token provider
It mints 300-second tokens with your API key, for the scopes foods:read, food_analysis:write, food_logs:read, food_logs:write, glucose:read, and restaurants:read. See local development.
Retry policy
Invalid values fail a precondition. See provider retries.
User context
Request-value forms of the log operations take a PartnerUserContext as user. On a JanuaryClient, the client's required end-user ID and timezone replace it. The client's foods, restaurants, foodAnalysis, foodLogs, glucose, waterLogs, and weightLogs resources all use them (User identity and timezone). An omitted timezone resolves to TimeZone.current.
Last updated
Was this helpful?