Appearance
Projects
Create and manage log projects. Each project has its own ingest token, retention settings, and streams.
Base URL: https://app.krafter.dev/api/v1
List Projects
Retrieve all log projects.
GET /logs/projectsRequired scope: logs:read
Example Request
bash
curl https://app.krafter.dev/api/v1/logs/projects \
-H "Authorization: Bearer kr_live_abc123def456"Example Response
json
{
"data": [
{
"id": "a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
"name": "My App",
"description": "Production logs",
"retention_days": 30,
"daily_limit_mb": 500,
"ingest_token_prefix": "krl_live_kp7",
"created_at": "2025-01-15T10:00:00Z",
"updated_at": "2025-01-15T10:00:00Z"
},
{
"id": "b2c3d4e5-6f7a-8b9c-0d1e-2f3a4b5c6d7e",
"name": "Staging",
"description": "Staging environment logs",
"retention_days": 7,
"daily_limit_mb": 100,
"ingest_token_prefix": "krl_live_aab",
"created_at": "2025-01-10T08:00:00Z",
"updated_at": "2025-01-10T08:00:00Z"
}
]
}Create Project
Create a new log project. A unique ingest_token is generated automatically.
POST /logs/projectsRequired scope: logs:write
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Display name for the project. Must be unique within the team. |
description | string | No | Optional description. |
retention_days | integer | No | Number of days to retain log entries. From 1 up to your plan's limit — see Retention. Defaults to 7. |
daily_limit_mb | integer | No | Daily ingestion limit in megabytes. Must be greater than 0. Defaults to 500. |
Example Request
bash
curl -X POST https://app.krafter.dev/api/v1/logs/projects \
-H "Authorization: Bearer kr_live_abc123def456" \
-H "Content-Type: application/json" \
-d '{
"name": "My App",
"description": "Production logs",
"retention_days": 30
}'Example Response
json
// 201 Created
{
"data": {
"id": "a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
"name": "My App",
"description": "Production logs",
"retention_days": 30,
"daily_limit_mb": 500,
"ingest_token_prefix": "krl_live_kp7",
"ingest_token": "krl_live_kp7tx2bm4qrs6vwy3jnh5zfd7acmeg2j",
"created_at": "2025-01-15T10:00:00Z",
"updated_at": "2025-01-15T10:00:00Z"
}
}TIP
Save the ingest_token from the response — it is returned only on creation and rotation. List, get, and update responses include ingest_token_prefix (the first 12 characters) for identification but never the full token. Your services will use the full token to send logs to the Ingest API.
Get Project
Retrieve details of a specific project.
GET /logs/projects/:idRequired scope: logs:read
Example Request
bash
curl https://app.krafter.dev/api/v1/logs/projects/a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d \
-H "Authorization: Bearer kr_live_abc123def456"Example Response
json
{
"data": {
"id": "a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
"name": "My App",
"description": "Production logs",
"retention_days": 30,
"daily_limit_mb": 500,
"ingest_token_prefix": "krl_live_kp7",
"created_at": "2025-01-15T10:00:00Z",
"updated_at": "2025-01-15T10:00:00Z"
}
}Update Project
Update an existing project. Only provided fields are changed.
PUT /logs/projects/:idRequired scope: logs:write
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | Display name for the project. Must remain unique within the team. |
description | string | No | Optional description. |
retention_days | integer | No | Number of days to retain log entries. From 1 up to your plan's limit — see Retention. |
daily_limit_mb | integer | No | Daily ingestion limit in megabytes. Must be greater than 0. |
Example Request
bash
curl -X PUT https://app.krafter.dev/api/v1/logs/projects/a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d \
-H "Authorization: Bearer kr_live_abc123def456" \
-H "Content-Type: application/json" \
-d '{
"retention_days": 90,
"daily_limit_mb": 500
}'Example Response
json
{
"data": {
"id": "a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
"name": "My App",
"description": "Production logs",
"retention_days": 90,
"daily_limit_mb": 500,
"ingest_token_prefix": "krl_live_kp7",
"created_at": "2025-01-15T10:00:00Z",
"updated_at": "2025-01-16T09:30:00Z"
}
}Delete Project
Permanently delete a project and all its log data, streams, and alerts.
DELETE /logs/projects/:idRequired scope: logs:write
Example Request
bash
curl -X DELETE https://app.krafter.dev/api/v1/logs/projects/a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d \
-H "Authorization: Bearer kr_live_abc123def456"Example Response
// 204 No ContentRotate Ingest Token
Generate a new ingest token for a project. The old token is revoked immediately.
POST /logs/projects/:id/rotate_tokenRequired scope: logs:write
Example Request
bash
curl -X POST https://app.krafter.dev/api/v1/logs/projects/a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d/rotate_token \
-H "Authorization: Bearer kr_live_abc123def456"Example Response
json
{
"data": {
"id": "a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
"name": "My App",
"description": "Production logs",
"retention_days": 30,
"daily_limit_mb": 500,
"ingest_token_prefix": "krl_live_xn4",
"ingest_token": "krl_live_xn4w7bm2tk6qrs3vwy5jnh7zfdcameg2p",
"created_at": "2025-01-15T10:00:00Z",
"updated_at": "2025-01-16T12:00:00Z"
}
}WARNING
After rotating, the old ingest token stops working immediately. Update all services that send logs to this project with the new token.
List Streams
List all streams that have been auto-discovered for a project. Streams are created automatically from the stream field in ingested log entries.
GET /logs/projects/:id/streamsRequired scope: logs:read
Example Request
bash
curl https://app.krafter.dev/api/v1/logs/projects/a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d/streams \
-H "Authorization: Bearer kr_live_abc123def456"Example Response
json
{
"data": [
{
"id": "c3d4e5f6-7a8b-9c0d-1e2f-3a4b5c6d7e8f",
"name": "backend",
"inserted_at": "2025-01-15T10:01:00Z"
},
{
"id": "d4e5f6a7-8b9c-0d1e-2f3a-4b5c6d7e8f9a",
"name": "worker",
"inserted_at": "2025-01-15T10:02:00Z"
},
{
"id": "e5f6a7b8-9c0d-1e2f-3a4b-5c6d7e8f9a0b",
"name": "auth",
"inserted_at": "2025-01-15T10:03:00Z"
}
]
}Retention
Each project has a retention_days setting (default 7) that controls how long log entries are kept. A nightly cleanup worker deletes entries older than the configured value on a per-project basis.
The ceiling is your plan's log retention, not a fixed number:
| Plan | Longest retention_days |
|---|---|
| Free | 7 |
| Starter | 30 |
| Pro | 90 |
| Scale | 365 |
| Enterprise | 730 |
A value above your plan's limit is refused with 422.
Retention safety net
Underneath the per-project rule, the ClickHouse log_entries table carries a hard TTL of 2 years. It is the backstop for a cleanup worker that stops running, not the mechanism: entries are normally removed by the nightly worker at your project's own retention_days, well before the engine touches them. Nothing can be kept beyond 730 days, which is why that is also the enterprise ceiling.
Daily Ingestion Limit
Each project carries a daily_limit_mb setting (default 500). When an ingest request is received, Krafter checks today's usage and rejects further entries with 429 Daily log ingestion limit exceeded once the threshold is reached.
What counts toward the limit
bytes_in for each accepted entry is computed from the payload string fields only — specifically message, stream, service, trace_id, span_id, and the JSON-encoded metadata object. HTTP framing, JSON encoding overhead (quotes, commas, brackets), the timestamp, and the level field are not counted. Treat daily_limit_mb as a soft cap on logical payload size, not as a wire-byte budget.
The counter resets at the start of each UTC day.
The limit is per project: each project has its own counter for the day and is refused with 429 only once it has spent its own daily_limit_mb. A noisy project cannot use up a quieter one's allowance, and the projects of one team need not share a limit.
Team-wide totals
The logs_get_usage MCP tool reports the team's total for today — the sum across its projects. That figure is for display; nothing is refused on it. Log ingestion is not part of the monthly plan quotas under GET /api/v1/usage.