Reference

HTTP API

Send logs, metrics, events and heartbeats from any language, and read your logs, metrics and monitors with a personal API key.

Everything the SDKs and the dashboard do goes through one HTTP API at https://api.logdash.io. Use it from a language without an SDK, from a shell script, or to read your data into your own tools. Requests and responses are JSON.

Authentication

Sending data and reading data use different keys, so the key on your servers can never read anything. See Keys and IDs.

ToSendHeader
Send logs, metrics and app eventsThe ingest key of the domainproject-api-key: ldi_…
Read your dataA personal API keyAuthorization: Bearer ldp_…
Ping a heartbeat, read a status pageNothing. These endpoints are public.-

Errors

Errors answer with a status code and a JSON body. message is a string, or a list of strings when the body has more than one problem.

{
  "message": "Invalid API key",
  "error": "Unauthorized",
  "statusCode": 401
}
StatusMeans
400The body or a query parameter is not valid, such as a missing field or a field the endpoint does not know.
401The key is missing, wrong, revoked or expired.
403The personal API key lacks the scope, or does not reach the domain.
404The monitor, metric or status page does not exist.
409A plan limit is reached, such as the number of apps or metrics.
429Too many requests. Wait for the window to end and try again.

Logs

Send a log

curl -X POST https://api.logdash.io/logs \
  -H "project-api-key: $LOGDASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "createdAt": "2026-11-09T10:15:00.000Z",
    "level": "error",
    "message": "Payment failed for order 1042",
    "namespace": "billing",
    "app": "api"
  }'
FieldTypeDescription
createdAtstring, requiredWhen it happened, in ISO 8601.
levelstring, requiredOne of error, warning, info, http, verbose, debug or silly. See Levels.
messagestring, requiredThe text of the log. Longer than 4,096 characters is cut.
namespacestringA part of your app, such as billing. Up to 255 characters.
appstringThe app that sent it. Defaults to default. See Apps.
sequenceNumbernumberOrders logs that share the same createdAt. The SDKs set it for you.

A sent log answers 201 with {"success": true}. Fields the endpoint does not know answer 400.

Send a batch

Send 1 to 100 logs in one request to POST /logs/batch. Each item takes the same fields as a single log.

POST /logs/batch
{
  "logs": [
    { "createdAt": "2026-11-09T10:15:00.000Z", "level": "info", "message": "Job started" },
    { "createdAt": "2026-11-09T10:15:02.000Z", "level": "info", "message": "Job finished" }
  ]
}

Log limits

  • Each app can send a fixed number of logs per hour. Past it, logs answer 429 with "Rate limit exceeded" until the hour ends.
  • A log for a new app past the apps limit of your plan answers 409 with "You have reached the maximum number of apps for your plan".
  • Request bodies can be up to 2 MB. The endpoints accept requests from any origin, so a browser can send logs too.

Metrics

curl -X PUT https://api.logdash.io/metrics \
  -H "project-api-key: $LOGDASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "queue_length", "value": 42, "operation": "set", "app": "worker"}'
FieldTypeDescription
namestring, requiredThe name of the metric. Up to 255 characters.
valuenumber, requiredThe value to set, or to add.
operationstring, requiredset replaces the value. change adds to it. See Set or change.
appstringThe app the metric belongs to. Defaults to default.

A value answers 200 with {"success": true}. A new metric past the metrics limit of the app answers 409.

App events

Send web analytics events from your backend or a native app to POST /events with the ingest key. The fields and examples are on Events from your apps.

Heartbeats

Ping a heartbeat monitor with POST /ping/<monitor-id>. It needs no key. See Cron and heartbeats.

Read your data

Read endpoints take a personal API key with the matching scope, and most of them a domain ID. To find it, open your domain, go to Settings and press Copy domain ID in the Domain card.

export LOGDASH_PERSONAL_KEY="ldp_…"
export LOGDASH_DOMAIN_ID="6650f1c2a3b4c5d6e7f80a01"

Read logs

Needs Logs: Read. Returns the newest logs first.

curl -G "https://api.logdash.io/clusters/$LOGDASH_DOMAIN_ID/logs" \
  -H "Authorization: Bearer $LOGDASH_PERSONAL_KEY" \
  --data-urlencode "levels=error" \
  --data-urlencode "searchString=payment failed" \
  --data-urlencode "limit=20"
ParameterDescription
limit1 to 100 logs. Defaults to 50.
startDate, endDateISO 8601 dates. A start before the retention of your plan moves up to it.
levelsOnly these levels. Repeat it for more than one, such as levels=error&levels=warning.
namespacesOnly these namespaces. Repeat it for more than one.
appsOnly these apps, by name. Repeat it for more than one.
searchStringOnly logs that contain every word, in any case.
lastId, directionPages from a log. direction=before returns older logs, direction=after newer ones. Send both or neither.
Response
[
  {
    "id": "6650f1c2a3b4c5d6e7f80c21",
    "createdAt": "2026-11-09T10:15:00.000Z",
    "message": "Payment failed for order 1042",
    "level": "error",
    "sequenceNumber": 0,
    "namespace": "billing",
    "app": "api"
  }
]

To read the next page, send the id of the last log you got as lastId, with direction=before. An empty list means there is nothing older.

Follow logs live

Needs Logs: Read. GET /clusters/<domain-id>/logs/sse streams each new log of the domain as a server-sent event, with the fields above. Send lastId to first get up to 100 logs that arrived after it.

curl -N "https://api.logdash.io/clusters/$LOGDASH_DOMAIN_ID/logs/sse" \
  -H "Authorization: Bearer $LOGDASH_PERSONAL_KEY"

Read metrics

Needs Metrics: Read. GET /clusters/<domain-id>/metrics lists the metrics of the domain with their current value and app.

Response
[
  {
    "id": "6650f1c2a3b4c5d6e7f80b11",
    "name": "queue_length",
    "value": 42,
    "metricRegisterEntryId": "6650f1c2a3b4c5d6e7f80b10",
    "app": "worker",
    "projectId": "6650f1c2a3b4c5d6e7f80a02"
  }
]

For the history of one metric, call GET /clusters/<domain-id>/metrics/<metricRegisterEntryId>. granularity picks minute, hour or day points, and limit returns up to 1,000 of the newest. Each point has its date and value.

curl "https://api.logdash.io/clusters/$LOGDASH_DOMAIN_ID/metrics/<metricRegisterEntryId>?granularity=hour&limit=24" \
  -H "Authorization: Bearer $LOGDASH_PERSONAL_KEY"

Read monitors

Needs Monitors: Read. GET /clusters/<domain-id>/http_monitors lists the monitors of the domain with their lastStatus: up, down or unknown. GET /clusters/<domain-id>/monitors/<monitor-id>/http_pings returns the newest checks of one monitor, up to 160 with limit, 100 by default.

A check
{
  "id": "6650f1c2a3b4c5d6e7f80d31",
  "httpMonitorId": "6650f1c2a3b4c5d6e7f80912",
  "statusCode": 200,
  "responseTimeMs": 184,
  "createdAt": "2026-11-09T10:15:00.000Z"
}

Read an overview

Needs Domains: Read. GET /overview answers "is anything wrong?" across every domain the key reaches, and GET /clusters/<domain-id>/overview for one domain. It returns the error logs per app, the status of each monitor, the number of monitors that are down, and when each app last sent a log and a metric. since sets the window, such as 30m, 24h or 7d. It defaults to 1h.

curl "https://api.logdash.io/overview?since=24h" \
  -H "Authorization: Bearer $LOGDASH_PERSONAL_KEY"

Read web analytics

Read web analytics through the MCP server. It takes the same personal API key, with Web analytics: Read.

Status pages

GET /v1/status_pages/<status-page-id> returns a published status page as JSON. It needs no key. See Build your own.