API Authentication

Every Kibot API session starts with a login request that exchanges a username and password for a server-side session keyed to the caller's IP address. Three commands manage that session: login opens it, status keeps it alive (and confirms the server is up), and logout closes it. Sessions auto-expire after 20 minutes of inactivity, and a "skip login" shortcut lets stateless callers attach credentials to every data request and bypass the session entirely. This article documents all three commands and the patterns the official docs recommend for high-throughput clients.

Login request

The login URL is the first command any client calls:

http://api.kibot.com?action=login&user=[username]&password=[password]

A successful login returns 200 OK followed by the list of authorizations attached to the account, the data packages the user has purchased plus their effective dates. The response body looks like:

200 OK
Authorizations
=====================
All Stocks,1/1/1998,1

Each authorization line names a package, the start date Kibot has on file, and a flag indicating whether the entitlement is currently active. Calling code rarely needs to parse this list, the per-symbol authorization is enforced by the history endpoint at request time, but it is useful for diagnostics.

If the credentials are missing or wrong, the server returns the generic 401 Unauthorized. Login Failed message regardless of which field was bad. Kibot intentionally does not distinguish "unknown user" from "wrong password" in the response.

Parameters

Parameter Required Values
action yes login
user yes Username or email address; or the literal guest for the free guest account
password conditional Account password; may be omitted for the guest account

The user field accepts either the username chosen at signup or the email address on file, both resolve to the same account.

Guest account

The guest account exists for testing and has no password requirement:

http://api.kibot.com?action=login&user=guest&password=guest

(password=guest is the documented form; the field may also be omitted entirely.) Guest sessions are limited to daily end-of-day data and a capped download volume; tick, intraday, snapshot, and adjustment endpoints require a paid account. See API overview for the access-tier breakdown.

Session timeout

The server keeps a session alive for 20 minutes after the most recent request. After that idle window, the session is closed and the next data request returns 401 Not Logged In. Two patterns prevent unnecessary re-logins:

Active downloads keep the session alive automatically. As long as history requests keep arriving, the 20-minute clock resets on each one, so a long-running batch download never needs to re-authenticate.

Status pings keep idle sessions alive. Calling ?action=status before the 20-minute window expires resets the timer without performing any data work, useful for clients that hold a session open between user-initiated requests.

Login best practices

The official docs are unusually emphatic that callers should not re-login before every request. The reason is throughput: each extra HTTP round trip nearly doubles the per-symbol cost when downloading many small files. The recommended pattern is:

  1. Call login once at startup.
  2. Issue all history (or adjustments, snapshot) calls back-to-back.
  3. Catch 401 Not Logged In, re-login, and retry the failed request.

The docs frame this as a performance improvement: "In order to significantly speed up the download process write code to login once and login again only in case you receive '401 Not Logged In' error" (per the login docs). For a 1000-symbol overnight batch, the difference between login-per-symbol and login-once is roughly a 2× wall-clock saving.

Skipping login entirely

The API supports a "stateless" mode that skips the explicit login call by appending credentials to every data URL:

http://api.kibot.com?action=history&symbol=MSFT&interval=daily&period=10&user=USERNAME&password=PASSWORD

The server interprets the embedded credentials, opens or reuses the session for that IP, and processes the request in one round trip. This is convenient for serverless functions, scheduled jobs, and any caller that doesn't want to track session state. The trade-off is wire size, every request carries the credentials, and a small attack surface increase if the URLs are ever logged. For most automation it is the simplest pattern.

Concurrent connections and IP tracking

Sessions are tied to the source IP. Running parallel clients from different IPs against the same account is tracked and "restricted" (per the login docs); five concurrent connections from one IP is the published guidance, with the per-server hard ceiling at 40 in flight and 50 per 500 ms before the rate limiter kicks in. The per-server limits and how Kibot's distributed front tier interacts with them live in Data updates.

Logout request

The logout URL is parameterless:

http://api.kibot.com?action=logout

It invalidates the current session immediately and returns 200 OK. The docs are clear that logout is not required, sessions auto-close after 20 minutes of inactivity, but it is offered as "a security feature that should be called when the user wants to stop their current session or close the client application" (per the logout docs). For server-side automation that runs short-lived jobs, calling logout at the end is good hygiene but rarely necessary.

When explicit logout actually matters

There are a few cases where calling logout pays off in practice:

  • Releasing a concurrency slot. Open sessions count against the 5-concurrent-connection guidance for the account. A short-lived batch script that finishes in 90 seconds but leaves its session open is holding a slot for the remainder of the 20-minute idle window. For accounts running multiple parallel jobs (one Python downloader, one Kibot Agent, one ad-hoc CSV pull), explicit logout at the end of each finished job is the difference between hitting the rate limiter on the next start-up and not.
  • Switching credentials on the same IP. The session is keyed to the source IP, not the account. If a single host needs to alternate between two Kibot accounts (test vs production, two teams sharing a box), calling logout before the second login avoids the older session's authorizations leaking into the new one.
  • Shared desktop / kiosk use. If the API is being driven by a GUI on a multi-user machine, an explicit logout on application close is the only thing that prevents the next user from inheriting an active session against another user's account.

For everything else, the 20-minute idle timeout does the same job for free.

Status request

The status URL is also parameterless:

http://api.kibot.com?action=status

A healthy server returns 200 OK plus a single line with the current server time:

200 OK
Server Time: 8/30/2011 1:44:16 PM.

In almost all cases the response is 200 OK. During a maintenance window or an internal incident the body carries a different message describing what's wrong, which is how the documented status flag is meant to be read.

Two things status is useful for

Server health check. Status is the cheapest possible probe of api.kibot.com's liveness: no parameters, no per-account state, no symbol lookup. A monitor that fires ?action=status every minute and alerts on non-200 catches outages without consuming any of the rate-limit budget data requests use.

Idle-session heartbeat. A client that opens a session at startup and then waits for user input (a desktop GUI, an interactive notebook, a long-running web request handler) can call status every few minutes to keep the session alive past the 20-minute window. Each status call resets the idle timer the same way a history call would, but without any data-side work. This is the recommended pattern for any application where login latency matters and the request cadence is bursty.

When status is not the right tool

A status ping does not detect a partial-failure mode that occasionally surfaces: status returns 200 OK while a specific data endpoint returns errors for a subset of symbols. If a download starts failing mid-run, the diagnostic to reach for is the actual failing URL with verbose logging, not a status probe. The status command tells you the server is reachable; it does not tell you the data path is healthy for every package.

Authentication failures and what they mean

The full HTTP-status reference lives in Server responses, but three codes show up around authentication specifically:

Code Meaning What to do
401 Unauthorized. Login Failed Wrong username or password on login Fix credentials; the same code is returned for both bad user and bad password
401 Not Logged In The session expired or was never established Re-login and retry the request
403 Login Failed Rate limit tripped (40 in flight or 50 per 500 ms exceeded) Back off; the code is reused for both auth and throttle (per support, see Data updates)
402 Unauthorized Logged in, but the account is not entitled to the requested symbol Check the package list returned by login; this symbol is not in any owned package

The reuse of 403 Login Failed for throttle responses is a known gotcha, it makes "auth broken" and "you're going too fast" look identical to a naive client. Robust callers distinguish them by tracking request rate and treating any 403 after a successful login as a throttle signal rather than re-credentialing in a tight loop.

Key Takeaways

  • login, logout, and status are the three session commands; only login is mandatory and logout is optional because sessions auto-expire after 20 minutes of inactivity.
  • The guest account (user=guest&password=guest) is free, returns only end-of-day data, and is rate-limited; everything else needs a paid account.
  • Login once at startup, catch 401 Not Logged In to detect expiry, re-login on demand. Never re-login per request, it roughly halves throughput.
  • The "skip login" shortcut (&user=...&password=... on every data URL) sidesteps session management entirely and is the simplest pattern for stateless callers.
  • status can be used as a heartbeat to keep an idle session alive past the 20-minute timeout.
  • The 403 Login Failed code is reused for both bad credentials and rate-limiter trips, so callers should track request rate to disambiguate.
  • API overview, What the API is, how to access it, and what the v2 features unlocked.
  • History request, The main data endpoint that requires an active session.
  • Server responses, Full HTTP status code reference.
  • Data updates, Per-server concurrency and per-second ceilings.
  • API client examples, Login-and-fetch flow in Python, Rust, Go, JS/TS, and Kibot's official .NET samples.