API

Autentikasi

Ambil token, kirim di setiap request, cabut, dan buat token pribadi yang berumur panjang.

Studio login dengan cookie. Script, server, dan aplikasi lain memakai bearer token.

Ambil token

POST /api/v1/auth/login

Kirim mode: "token" untuk mendapat token, bukan cookie.

curl -X POST 'http://127.0.0.1:8080/api/v1/auth/login' \
  -H 'Content-Type: application/json' \
  --data '{"email":"you@example.com","password":"YOUR_PASSWORD","mode":"token"}'
const res = await fetch('http://127.0.0.1:8080/api/v1/auth/login', {
	method: 'POST',
	headers: { 'Content-Type': 'application/json' },
	body: JSON.stringify({ email: 'you@example.com', password: 'YOUR_PASSWORD', mode: 'token' })
});
const { data } = await res.json();
const token = data.access_token;
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
)

func main() {
	body, _ := json.Marshal(map[string]string{
		"email": "you@example.com", "password": "YOUR_PASSWORD", "mode": "token",
	})
	res, err := http.Post("http://127.0.0.1:8080/api/v1/auth/login", "application/json", bytes.NewReader(body))
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	var out struct {
		Data struct {
			AccessToken string `json:"access_token"`
		} `json:"data"`
	}
	if err := json.NewDecoder(res.Body).Decode(&out); err != nil {
		panic(err)
	}
	fmt.Println(out.Data.AccessToken)
}
import requests

res = requests.post(
    "http://127.0.0.1:8080/api/v1/auth/login",
    json={"email": "you@example.com", "password": "YOUR_PASSWORD", "mode": "token"},
)
token = res.json()["data"]["access_token"]

Respons:

{
	"data": {
		"access_token": "YOUR_ACCESS_TOKEN",
		"token_type": "Bearer",
		"expires_in": 28800,
		"user": {
			"id": "7685a20f71a2e3535cdee4566a8e1b9f",
			"email": "you@example.com",
			"display_name": ""
		}
	},
	"meta": { "request_id": "TFUQWRNZQKSA27FNQMFQPBVR72", "response_time": 271.8 }
}

Token berlaku delapan jam (expires_in dalam detik) dan tidak ada cookie yang dipasang.

Kirim token

GET /api/v1/auth/me

Tambahkan Authorization: Bearer <token> di setiap request.

curl 'http://127.0.0.1:8080/api/v1/auth/me' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN'
const res = await fetch('http://127.0.0.1:8080/api/v1/auth/me', {
	headers: { Authorization: `Bearer ${token}` }
});
console.log(await res.json());
req, _ := http.NewRequest("GET", "http://127.0.0.1:8080/api/v1/auth/me", nil)
req.Header.Set("Authorization", "Bearer "+token)
res, err := http.DefaultClient.Do(req)
res = requests.get(
    "http://127.0.0.1:8080/api/v1/auth/me",
    headers={"Authorization": f"Bearer {token}"},
)
print(res.json())

Respons:

{
	"data": {
		"id": "7685a20f71a2e3535cdee4566a8e1b9f",
		"email": "you@example.com",
		"display_name": ""
	},
	"meta": { "request_id": "2DOAELS4STJYJ5CVYUJXGC6RMI", "response_time": 2.3 }
}

Logout

POST /api/v1/auth/logout

Logout dengan token langsung mencabut token itu. Responsnya 204 tanpa body.

curl -X POST 'http://127.0.0.1:8080/api/v1/auth/logout' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN'
await fetch('http://127.0.0.1:8080/api/v1/auth/logout', {
	method: 'POST',
	headers: { Authorization: `Bearer ${token}` }
});
req, _ := http.NewRequest("POST", "http://127.0.0.1:8080/api/v1/auth/logout", nil)
req.Header.Set("Authorization", "Bearer "+token)
_, err := http.DefaultClient.Do(req)
requests.post(
    "http://127.0.0.1:8080/api/v1/auth/logout",
    headers={"Authorization": f"Bearer {token}"},
)

Token API pribadi

Untuk server yang berjalan lama atau cron job, buat token pribadi di Account settings atau dengan POST /api/v1/auth/tokens.

  • Maksimal 20 token per pengguna, masing-masing kedaluwarsa dalam setahun.
  • Secret hanya ditampilkan sekali. Kanesh hanya menyimpan hash-nya.
  • Token bertindak sebagai pemiliknya, tetapi tidak bisa mengelola token atau mengganti password.

Untuk menerima token mentah di header kustom seperti X-Api-Key, atur AUTH_TOKEN_HEADER. Authorization tetap berfungsi.

Aturan kredensial

  • Kirim tepat satu kredensial. Cookie plus token, atau dua header, menghasilkan 401.
  • Token di query string tidak pernah diterima.
  • Token saja tidak cukup untuk memanggil dari browser di origin lain. Atur CORS untuk itu.
  • Login ditolak dari origin lain dengan 403 access_denied. Login dari servermu, bukan dari browser di situs yang berbeda.

Pemecahan masalah

  • 401 authentication_required: pastikan kamu mengirim satu kredensial dan token belum kedaluwarsa atau dicabut.
  • 429 Too Many Requests: login punya rate limit yang lebih ketat. Tunggu sesuai waktu Retry-After.

Langkah berikutnya

Traktir kopi