Skip to content

Authentication

KUKAN API supports two authentication methods.

Browser access uses Better Auth session cookies (prefixed with __Secure- over HTTPS). After login, they are sent automatically with fetch.

const res = await fetch('/api/v1/users/me', {
credentials: 'include',
})

Use API tokens for programmatic access.

Create tokens from the API Tokens page (user menu → API Tokens), or via the API:

ターミナルウィンドウ
curl -X POST https://your-kukan-site/api/v1/api-tokens \
-H "Content-Type: application/json" \
-H "Cookie: <session-cookie>" \
-d '{"name":"my-script","expiresInDays":90}'

Response:

{
"id": "3f2c9a1e-...",
"name": "my-script",
"token": "kukan_xxxxxxxx...",
"expiresAt": "2026-07-13T00:00:00.000Z",
"created": "2026-04-14T00:00:00.000Z"
}

The status is 201 and id is a UUID. expiresInDays takes 1–365; leave it out for a token that never expires.

Send the token in the Authorization: Bearer header.

ターミナルウィンドウ
curl https://your-kukan-site/api/v1/users/me \
-H "Authorization: Bearer kukan_xxxxxxxx..."

When the site sits behind basic auth, the Authorization header carries the basic auth credentials. Send the token in the X-KUKAN-API-Key header instead. It works on the REST API, MCP and the CKAN-compatible API alike.

ターミナルウィンドウ
curl https://your-kukan-site/api/v1/users/me \
-u "<basic-user>:<basic-password>" \
-H "X-KUKAN-API-Key: kukan_xxxxxxxx..."

When both are sent, Authorization: Bearer takes precedence.

ターミナルウィンドウ
# List
curl https://your-kukan-site/api/v1/api-tokens \
-H "Authorization: Bearer <token>"
# Revoke
curl -X DELETE https://your-kukan-site/api/v1/api-tokens/<id> \
-H "Authorization: Bearer <token>"
Level Description
Public (no auth) Search, view public datasets
Authenticated Own profile, private datasets in member orgs
Organization member / editor / admin Create, edit, manage organization data
Category member / editor / admin Add, manage datasets in categories
System administrator (sysadmin) Manage all users, organizations, jobs
HTTP Meaning
400 Validation error
401 Not authenticated (login or token required)
403 Insufficient permissions
404 Resource not found
409 Conflict (e.g., duplicate resource)
429 Too many requests (e.g., the AI suggestion limit)
503 Temporarily unavailable