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.

  1. 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.)

  2. 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 Origin header 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:

LevelWhen to use
debugVerbose diagnostic information
infoNormal operational events
warningUnexpected but recoverable conditions
errorFailures that need attention
criticalSystem-wide failures, requires immediate action
heartbeatPeriodic 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-TypeFormat
application/jsonPlain Loguro JSON or OTLP JSON
application/x-protobufOTLP 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

LimitValue
Max payload size1 MB per request
Rate limit10,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

StatusMeaning
202Log accepted
401Missing or invalid API key
402Subscription inactive or monthly quota exhausted
413Payload exceeds 1 MB
429Rate limit exceeded — back off and retry
500Ingest 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