Skip to content

Commit 433783a

Browse files
authored
Merge pull request #112 from Microck/feat/api-key-token-split
feat(auth)!: split API keys from legacy tokens
2 parents 7bfdacd + 9d25b77 commit 433783a

26 files changed

Lines changed: 1356 additions & 325 deletions

.env.example

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
# Preferred for base search when your account has Search API access.
1+
# Current Kagi API key for /api/v1 endpoints such as Search API and Extract.
2+
KAGI_API_KEY=
3+
4+
# Legacy Kagi API token for /api/v0 endpoints such as FastGPT, Summarizer, and Enrich.
25
KAGI_API_TOKEN=
36

47
# Required for lens-aware search and the proven HTML/session path.

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,20 @@ Before `1.0.0`, breaking changes may still ship in minor releases.
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- Added `KAGI_API_KEY`, `[auth].api_key`, and `kagi auth set --api-key` for current `/api/v1` Search and Extract API credentials.
13+
14+
### Changed
15+
16+
- Breaking: split current API keys from legacy API tokens. `KAGI_API_TOKEN` and `[auth].api_token` now represent legacy `/api/v0` credentials only, while base Search API mode requires `KAGI_API_KEY` or `[auth].api_key`.
17+
1018
## [0.6.2]
1119

1220
### Added
1321

1422
- Added `kagi_extract` to the built-in MCP server tool list, matching the existing paid Extract API command behavior.
23+
- `kagi extract` and MCP `kagi_extract` now reject session-only Extract on Kagi accounts whose API portal disallows Extract API access, avoiding legacy token regeneration loops.
1524

1625
## [0.6.1]
1726

README.md

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
`kagi` is a terminal CLI for Kagi that gives you command-line access to search, quick answers, ask-page, assistant, translate, summarization, public feeds through `news` and `smallweb`, paid API commands like `fastgpt` and `enrich`, and account-level settings like lenses, custom assistants, custom bangs, and redirect rules. it is built for people who want one command surface for interactive use, shell workflows, and structured JSON output.
2020

21-
the main setup path is `kagi auth`. on a real terminal it opens a guided setup flow where you choose `Session Link` or `API Token`, get the official instructions inline, paste the credential, save it to `./.kagi.toml`, and validate it immediately. if you also use Kagi's paid API, the same wizard can add that too.
21+
the main setup path is `kagi auth`. on a real terminal it opens a guided setup flow where you choose `Session Link`, `API Key`, or `Legacy API Token`, get the official instructions inline, paste the credential, save it to `./.kagi.toml`, and validate it immediately. if you also use Kagi's paid API, the same wizard can add that too.
2222

2323
[documentation](https://kagi.micr.dev) | [npm](https://www.npmjs.com/package/kagi-cli) | [mcp](https://github.com/Microck/kagi-mcp)
2424

@@ -31,7 +31,7 @@ if you already use Kagi and want to access it from scripts, shell workflows, or
3131
- use your existing session-link URL for subscriber features
3232
- get structured JSON for scripts, agents, and other tooling
3333
- use one CLI for search, quick answers, assistant, translate, summarization, `news`, and `smallweb`
34-
- add `KAGI_API_TOKEN` only when you want the paid public API commands
34+
- add `KAGI_API_KEY` for current `/api/v1` commands, or `KAGI_API_TOKEN` for legacy `/api/v0` commands
3535

3636
## quickstart
3737

@@ -79,7 +79,8 @@ kagi auth
7979
the wizard is the default setup path. it guides you through:
8080

8181
- `Session Link` from `https://kagi.com/settings/user_details`
82-
- `API Token` from `https://kagi.com/settings/api`
82+
- `API Key` from `https://kagi.com/api/keys`
83+
- `Legacy API Token` from `https://kagi.com/settings/api`
8384
- saving into `./.kagi.toml`
8485
- immediate validation
8586

@@ -101,29 +102,29 @@ kagi auth set --session-token 'https://kagi.com/search?token=...'
101102
kagi auth check
102103
```
103104

104-
add an api token when you want the paid public api commands:
105+
add an api key when you want current paid api commands:
105106

106107

107108
how to get it:
108109

109110
1. click the top-right menu icon
110111
2. go into `Settings`
111-
3. click `Advanced` in the left sidebar
112-
4. go into `Open API Portal`
113-
5. under `API Token`, click `Generate New Token`
112+
3. open `https://kagi.com/api/keys`
113+
4. generate or copy an API key
114114

115115
![api token tutorial](images/tutorials/api-token.gif)
116116

117117
```bash
118-
export KAGI_API_TOKEN='...'
118+
export KAGI_API_KEY='...'
119119
```
120120

121121
## auth model
122122

123123
| credential | what it unlocks |
124124
| --- | --- |
125-
| `KAGI_SESSION_TOKEN` | base search fallback, `search --lens`, filtered search, `quick`, `ask-page`, `assistant`, `translate`, `summarize --subscriber` |
126-
| `KAGI_API_TOKEN` | public `summarize`, `extract`, `fastgpt`, `enrich web`, `enrich news` |
125+
| `KAGI_SESSION_TOKEN` | base search fallback, `search --lens`, filtered search, `quick`, `ask-page`, `assistant`, `translate`, `summarize --subscriber`, and Extract eligibility checks through the authenticated API portal |
126+
| `KAGI_API_KEY` | current `/api/v1` Search API and Extract API with `Bearer` auth |
127+
| `KAGI_API_TOKEN` | legacy `/api/v0` public `summarize`, `fastgpt`, `enrich web`, and `enrich news` with `Bot` auth |
127128
| none | `news`, `smallweb`, `auth status`, `--help` |
128129

129130
example config:
@@ -133,15 +134,19 @@ example config:
133134
# Full Kagi session-link URL or just the raw token value.
134135
session_token = "https://kagi.com/search?token=kagi_session_demo_1234567890abcdef"
135136

136-
# Paid API token for summarize, fastgpt, and enrich commands.
137-
api_token = "kagi_api_demo_abcdef1234567890"
137+
# Current API key for Search API and Extract.
138+
api_key = "kagi_api_key_demo_abcdef1234567890"
139+
140+
# Legacy API token for summarize, fastgpt, and enrich commands.
141+
api_token = "kagi_api_token_demo_abcdef1234567890"
138142

139143
# Base `kagi search` auth preference: "session" or "api".
140144
preferred_auth = "api"
141145

142146
[profiles.work.auth]
143147
session_token = "https://kagi.com/search?token=work_session_demo"
144-
api_token = "kagi_api_work_demo"
148+
api_key = "kagi_api_key_work_demo"
149+
api_token = "kagi_api_token_work_demo"
145150
preferred_auth = "session"
146151
```
147152
notes:
@@ -165,7 +170,7 @@ for the full command-to-token matrix, use the [`auth-matrix`](https://kagi.micr.
165170
| `kagi batch` | run multiple searches in parallel with JSON, TOON, compact, pretty, markdown, or csv output and shared filters |
166171
| `kagi auth` | launch the auth wizard, or inspect, validate, and save credentials |
167172
| `kagi summarize` | use the paid public summarizer API or the subscriber summarizer with `--subscriber` |
168-
| `kagi extract` | extract a page's full content as markdown through the paid API |
173+
| `kagi extract` | extract a page's full content as markdown through the current paid API, using `KAGI_API_KEY` directly; session-only auth is rejected when Kagi's API portal does not allow Extract access |
169174
| `kagi watch` | rerun a search on an interval and emit added/removed result URLs |
170175
| `kagi notify` | send search or news output to a webhook |
171176
| `kagi history` | inspect local command history and aggregate query stats |

docs/SKILL.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ kagi auth
4747
```
4848

4949
Opens a guided TTY wizard that walks through:
50-
- Choosing Session Link (subscriber, free) or API Token (paid)
50+
- Choosing Session Link, API Key, or Legacy API Token
5151
- Pasting credentials
5252
- Saving to `./.kagi.toml`
5353
- Immediate validation
@@ -61,7 +61,10 @@ kagi auth set --session-token 'https://kagi.com/search?token=...'
6161
# Or via environment variable
6262
export KAGI_SESSION_TOKEN='...'
6363

64-
# API token (from https://kagi.com/settings/api)
64+
# API key for current /api/v1 endpoints (from https://kagi.com/api/keys)
65+
export KAGI_API_KEY='...'
66+
67+
# Legacy API token for /api/v0 endpoints (from https://kagi.com/settings/api)
6568
export KAGI_API_TOKEN='...'
6669
```
6770

@@ -70,10 +73,11 @@ export KAGI_API_TOKEN='...'
7073
| Credential | What It Unlocks |
7174
|------------|-----------------|
7275
| `KAGI_SESSION_TOKEN` | base search fallback, `search --lens`, `search --news`, filtered search, `quick`, `ask-page`, `assistant`, `translate`, `summarize --subscriber` |
76+
| `KAGI_API_KEY` | search API, extract |
7377
| `KAGI_API_TOKEN` | summarize, fastgpt, enrich web, enrich news |
7478
| none | news, smallweb, auth status, --help |
7579

76-
Environment variables override `./.kagi.toml`. When both tokens are present, base `kagi search` defaults to session token; set `[auth] preferred_auth = "api"` in config to prefer API.
80+
Environment variables override `./.kagi.toml`. When a session token and API key are both present, base `kagi search` defaults to the session token; set `[auth] preferred_auth = "api"` in config to prefer the API key.
7781

7882
## Commands
7983

docs/commands/auth.mdx

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ description: "Reference for the kagi auth wizard and non-interactive credential
55

66
# `kagi auth`
77

8-
`kagi auth` is the main onboarding path for this CLI. On a real terminal, it launches an interactive setup wizard that lets you choose `Session Link` or `API Token`, shows the official Kagi settings page for that credential, accepts a paste, saves into `./.kagi.toml`, and validates the selected credential immediately.
8+
`kagi auth` is the main onboarding path for this CLI. On a real terminal, it launches an interactive setup wizard that lets you choose `Session Link`, `API Key`, or `Legacy API Token`, shows the official Kagi settings page for that credential, accepts a paste, saves into `./.kagi.toml`, and validates the selected credential immediately.
99

1010
![Auth command demo](/images/demos/auth.gif)
1111

@@ -29,7 +29,7 @@ kagi auth
2929
The wizard flow is:
3030

3131
1. shows your current auth state and config path
32-
2. lets you choose `Session Link` or `API Token`
32+
2. lets you choose `Session Link`, `API Key`, or `Legacy API Token`
3333
3. shows the official place to get that credential
3434
4. accepts the pasted value
3535
5. asks before overwriting an existing config value of the same type
@@ -50,7 +50,19 @@ It accepts either:
5050
- the full Session Link URL
5151
- the raw token value
5252

53-
### API Token Path
53+
### API Key Path
54+
55+
The wizard points you to:
56+
57+
```text
58+
https://kagi.com/api/keys
59+
```
60+
61+
It accepts:
62+
63+
- the raw API key
64+
65+
### Legacy API Token Path
5466

5567
The wizard points you to:
5668

@@ -60,7 +72,7 @@ https://kagi.com/settings/api
6072

6173
It accepts:
6274

63-
- the raw API token
75+
- the raw legacy API token
6476

6577
### Non-TTY Behavior
6678

@@ -94,7 +106,8 @@ Example:
94106
selected: session-token (config)
95107
profile: default
96108
preferred auth for base search: session
97-
api token: not configured
109+
api key: not configured
110+
legacy api token: not configured
98111
session token: configured via config
99112
config path: .kagi.toml
100113
precedence: env > selected profile config > default config; base search defaults to session unless preferred_auth = "api"; lens search requires session token
@@ -118,21 +131,27 @@ auth check passed: session-token (config)
118131
auth check passed: api-token (env)
119132
```
120133

134+
```text
135+
auth check passed: api-key (env)
136+
```
137+
121138
## `kagi auth set`
122139

123140
Use this when you want scripting or explicit non-interactive config writes.
124141

125142
```bash
126143
kagi auth set --session-token 'https://kagi.com/search?token=...'
144+
kagi auth set --api-key '...'
127145
kagi auth set --api-token '...'
128-
kagi auth set --session-token 'https://kagi.com/search?token=...' --api-token '...'
146+
kagi auth set --session-token 'https://kagi.com/search?token=...' --api-key '...' --api-token '...'
129147
kagi --profile work auth set --session-token 'https://kagi.com/search?token=...'
130148
```
131149

132150
Options:
133151

134152
- `--session-token <TOKEN_OR_URL>` saves a Session Link or raw session token
135-
- `--api-token <TOKEN>` saves a raw API token
153+
- `--api-key <KEY>` saves a current API key for `/api/v1` endpoints
154+
- `--api-token <TOKEN>` saves a legacy API token for `/api/v0` endpoints
136155

137156
Behavior:
138157

@@ -145,7 +164,7 @@ Behavior:
145164

146165
The CLI resolves credentials in this order:
147166

148-
1. `KAGI_API_TOKEN` / `KAGI_SESSION_TOKEN`
167+
1. `KAGI_API_KEY` / `KAGI_API_TOKEN` / `KAGI_SESSION_TOKEN`
149168
2. selected profile config, such as `[profiles.work.auth]`
150169
3. default `./.kagi.toml` `[auth]`
151170

@@ -154,7 +173,8 @@ Environment variables override the config file. Use `--profile <NAME>` to select
154173
```toml
155174
[profiles.work.auth]
156175
session_token = "work-session"
157-
api_token = "work-api"
176+
api_key = "work-api-key"
177+
api_token = "work-legacy-api-token"
158178
preferred_auth = "session"
159179
```
160180

@@ -184,17 +204,17 @@ kagi auth set --session-token 'https://kagi.com/search?token=...'
184204
kagi auth check
185205
```
186206

187-
### Add API Token Later
207+
### Add API Credentials Later
188208

189209
```bash
190210
kagi auth
191211
```
192212

193-
Choose `API Token`, paste it, then verify:
213+
Choose `API Key` for current Search API or Extract access. Choose `Legacy API Token` for FastGPT, public Summarizer, or Enrich.
194214

195215
```bash
196216
kagi auth status
197-
kagi fastgpt "what changed in rust 1.86?"
217+
kagi search --format pretty "what changed in rust 1.86?"
198218
```
199219

200220
## Security Notes

docs/commands/enrich.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ These endpoints provide enhanced search capabilities beyond standard search, off
2626

2727
**Required:** `KAGI_API_TOKEN`
2828

29-
Enrichment APIs require API access and consume API credit.
29+
Enrichment currently uses Kagi's legacy `/api/v0` API with `Bot` auth. It requires API access and consumes API credit.
3030

3131
## Subcommands
3232

docs/commands/extract.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ The command uses JSON mode internally because that is the stable envelope return
2121

2222
## Authentication
2323

24-
**Required:** `KAGI_API_TOKEN`
24+
**Required:** `KAGI_API_KEY`
2525

26-
Extract is part of Kagi's paid API surface and consumes API credit per request.
26+
Extract is part of Kagi's current `/api/v1` paid API surface, uses `Bearer` auth, and consumes API credit per request.
2727

2828
## Arguments
2929

docs/commands/fastgpt.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ The `kagi fastgpt` command queries Kagi's FastGPT API, which provides quick, fac
2727

2828
**Required:** `KAGI_API_TOKEN`
2929

30-
FastGPT requires API access and consumes API credit per request.
30+
FastGPT currently uses Kagi's legacy `/api/v0` API with `Bot` auth. It requires API access and consumes API credit per request.
3131

3232
## Arguments
3333

docs/commands/mcp.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ kagi mcp
1717

1818
- `kagi_search` - search Kagi
1919
- `kagi_summarize` - summarize a URL or text through the public API
20-
- `kagi_extract` - extract a page's full content as markdown through the paid Extract API. Accepts `url`.
20+
- `kagi_extract` - extract a page's full content as markdown through the current `/api/v1` Extract API. Uses `KAGI_API_KEY` directly and rejects session-only auth when Kagi's API portal does not allow Extract access. Accepts `url`.
2121
- `kagi_quick` - get a Kagi Quick Answer
2222
- `kagi_news` - fetch Kagi News stories (no auth required). Accepts `category` (default `world`), `limit` (default `12`), and `lang` (default `default`).
2323
- `kagi_news_search` - search the News tab of kagi.com and return story clusters (session token required). Accepts `query`, optional `region`, `freshness` (`day`/`week`/`month`), `order` (`default`/`recency`/`website`), and `limit`.

docs/commands/search.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ This matters because the Kagi Search API is still base-search only in this CLI.
3838
Plain base search keeps the existing repo behavior:
3939

4040
- default session-first search when a session token is available
41-
- API-first only when you explicitly configure `[auth.preferred_auth] = "api"`
41+
- API-first only when you configure `[auth.preferred_auth] = "api"` and provide `KAGI_API_KEY`
4242
- session fallback only when the API path was selected first and rejected
4343

4444
### Filtered Search

0 commit comments

Comments
 (0)