IVGraph uses two authentication methods: JWT tokens (for web users via Notion OAuth) and Service Tokens (for LLM agents and automation).
Notion OAuth (JWT)
IVGraph authenticates users through Notion's OAuth2 flow. There is no username/password registration.
Flow
User clicks "Sign in with Notion"
|
v
GET /api/integrations/auth/notion/
| -> Redirects to Notion consent screen
v
User authorizes IVGraph in Notion
|
v
Notion redirects to /api/integrations/auth/notion/callback?code=...
| -> Backend exchanges code for Notion token
| -> Creates/updates Django user
| -> Issues JWT tokens
v
Redirect to dashboard with tokens in URL fragment
JWT Tokens
| Token | Lifetime | Purpose |
|---|---|---|
| Access token | 4 hours | API authentication |
| Refresh token | 7 days | Get new access token |
Using the access token:
curl -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." \
"https://ivgraph.com/api/notion-graph/"
Refreshing an expired token:
curl -X POST "https://ivgraph.com/api/auth/refresh/" \
-H "Content-Type: application/json" \
-d '{"refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."}'
Response:
{"access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."}
Logout (blacklist refresh token):
curl -X POST "https://ivgraph.com/api/auth/logout/" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{"refresh": "<refresh_token>"}'
Auth Endpoints
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/integrations/auth/notion/ |
Start Notion OAuth flow |
| GET | /api/integrations/auth/notion/callback |
OAuth callback (internal) |
| GET | /api/integrations/auth/notion/status |
Check OAuth status |
| POST | /api/auth/refresh/ |
Refresh access token |
| POST | /api/auth/logout/ |
Blacklist refresh token |
| GET | /api/auth/validate/ |
Check if token is valid |
| GET | /api/auth/me/ |
Get current user info |
Service Tokens (for LLM agents)
Service tokens provide scoped, long-lived access to the V1 read-only API. Designed for LLM agents, automation scripts, and CI/CD pipelines.
Token Format
- Prefix:
ivg_(e.g.,ivg_a1b2c3d4e5f6...) - Length: 32 random characters after prefix
- Storage: only SHA-256 hash stored in database — raw token shown once at creation
Creating a Token
Via API (requires JWT auth):
curl -X POST "https://ivgraph.com/api/tokens/" \
-H "Authorization: Bearer <jwt_access_token>" \
-H "Content-Type: application/json" \
-d '{
"name": "My LLM Agent",
"scopes": ["graph:search", "graph:read", "graph:neighbors"],
"workspace_ids": ["your-workspace-uuid"],
"expires_in_days": 90
}'
Response (token shown only once!):
{
"id": 1,
"name": "My LLM Agent",
"token": "ivg_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
"prefix": "ivg_a1b2c3",
"scopes": ["graph:search", "graph:read", "graph:neighbors"],
"workspace_ids": ["your-workspace-uuid"],
"is_active": true,
"created_at": "2026-04-10T12:00:00Z",
"expires_at": "2026-07-09T12:00:00Z"
}
Scopes
| Scope | Permits |
|---|---|
graph:search |
Search nodes by title |
graph:read |
Read node details and page content |
graph:neighbors |
Get neighbors and traverse paths |
Limits
- Maximum 10 tokens per user
- Each token must have at least one scope
- Each token must have at least one workspace_id (deny-by-default)
- Optional expiration (
expires_in_days) — omit for no expiry
Token Management
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/tokens/ |
List your tokens (no raw values) |
| POST | /api/tokens/ |
Create new token |
| DELETE | /api/tokens/<id>/ |
Revoke token (permanent) |