Getting Started
Loguro is a structured log management platform or better said Log OS. This guide walks you through creating a project, generating an API key, and shipping your first log.
Create a project
Sign in to your Loguro account and head to the Console.
- Click New Project, give it a name, and you’re set.
If you wanna be a pro open the command palette and type
--project::create > --keys::create:<name>to create a project and an API key in one go. (the>works as a chain operator, so the project is created first, then the API key is created for it.) - Each project gets its own isolated log stream and API key namespace.
Get an API key (in case you did not chose the path from above)
Inside your project, open the command palette and type --keys::create:<name>, if you don’t pass the <name> directly don’t worry, it will ask for it always.
Browser keys (frontend logging)
By default, API keys are server keys — meant to be kept secret on your backend. If you want to send logs directly from a browser or frontend app, create a browser key instead.
Browser keys are safe to expose in client-side code because they are locked to a list of allowed origins. The ingest service checks the Origin header on every request and rejects anything not on the whitelist.
To create a browser key, open the command palette and type --keys::create:browser:<name>, or use the API Keys page and select the Browser type when creating a key. You’ll be asked to provide a comma-separated list of allowed origins (e.g. https://myapp.com, http://localhost:3000).
// Example: send a log from the browser
fetch('https://ingest.logu.ro', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_BROWSER_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
level: 'error',
message: 'Unhandled exception',
context: { path: window.location.pathname }
})
}); The
Originheader is set automatically by the browser and cannot be spoofed by JavaScript — this is what makes browser keys safe to use in public code.
Send your first log
Loguro accepts structured JSON, OTLP and OTLP proto by default, you just need to send it. POST to the ingest endpoint:
curl -X POST https://ingest.logu.ro \
-H "Authorization: Bearer $LOGURO_API_KEY" \
-H "Content-Type: application/json" \
-H "X-Request-Id: Optional" \
-d '{
"level": "info",
"message": "Server started",
"timestamp": "", // If not, i will put it for you, but the timezones might be off
"context": { // Anything you want in the context, send relevant data, it will be searchable by context.something:"everything"
"port": 3000,
"env": "production"
}
}' A 202 means the log was accepted. Head to your project’s Logs view and you should see it appear within miliseconds.
Log levels
Loguro supports six log levels. Use them consistently across your services:
| Level | When to use |
|---|---|
debug | Verbose diagnostic information |
info | Normal operational events |
warning | Unexpected but recoverable conditions |
error | Failures that need attention |
critical | System-wide failures, requires immediate action |
heartbeat | Periodic health pulse from a service — used to detect when a service goes silent. See Alerting for how to trigger alerts when heartbeats stop arriving. |
Using context
The context field is a flat or nested JSON object. Any key you include becomes searchable in the filter bar using the context.key:value syntax.
{
"level": "error",
"message": "Payment failed",
"context": {
"userId": 42,
"orderId": "ord_9xk2",
"gateway": "stripe",
"errorCode": "card_declined"
}
} You can then search for context.gateway:"stripe" or context.errorCode:"card_declined" or context.status_code:404 directly in the console.
Batch ingestion
To send multiple logs in a single request, POST an array to /batch:
curl -X POST https://ingest.logu.ro/batch \
-H "Authorization: Bearer $LOGURO_API_KEY" \
-H "Content-Type: application/json" \
-d '[
{ "level": "info", "message": "Request received", "context": { "path": "/api/users" } },
{ "level": "error", "message": "DB timeout", "context": { "query": "SELECT *", "ms": 5100 } }
]' Each object in the array follows the same schema as a single log. The response is still 202 Accepted.
OTLP support
Loguro accepts OpenTelemetry logs natively. The format is detected automatically via Content-Type:
| Content-Type | Format |
|---|---|
application/json | Plain Loguro JSON or OTLP JSON |
application/x-protobuf | OTLP Protobuf binary |
OTLP JSON example (OpenTelemetry Log Data Model):
curl -X POST https://ingest.logu.ro \
-H "Authorization: Bearer $LOGURO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"resourceLogs": [{
"resource": { "attributes": [{ "key": "service.name", "value": { "stringValue": "payments" } }] },
"scopeLogs": [{
"logRecords": [{
"timeUnixNano": "1711234567000000000",
"severityText": "ERROR",
"body": { "stringValue": "Payment failed" },
"attributes": [
{ "key": "userId", "value": { "intValue": "42" } }
]
}]
}]
}]
}' Limits & quotas
| Limit | Value |
|---|---|
| Max payload size | 1 MB per request |
| Rate limit | 10,000 requests/min per API key |
When your project has consumed more than 80% of its monthly log quota, the ingest service adds a response header:
X-Quota-Warning: 85 The value is the percentage used. Monitor this header to avoid hitting your plan limit.
Error responses
| Status | Meaning |
|---|---|
202 | Log accepted |
401 | Missing or invalid API key |
402 | Subscription inactive or monthly quota exhausted |
413 | Payload exceeds 1 MB |
429 | Rate limit exceeded — back off and retry |
500 | Ingest service error |
Next steps
- Read the Query Syntax guide to master the advanced filter bar
- Learn how to connect Integrations for Slack and issue trackers