{"openapi":"3.1.0","info":{"title":"Loki API","description":"Log aggregation and LogQL queries","version":"2.9","contact":{"name":"Grafana","url":"https://grafana.com/loki/"},"license":{"name":"AGPL-3.0","url":"https://www.gnu.org/licenses/agpl-3.0.html"}},"servers":[{"url":"http://loki:3100","description":"Internal Docker network (primary — no public Traefik route)"},{"url":"http://localhost:3100","description":"Local development (port-forward only)"}],"paths":{"/loki/api/v1/query":{"get":{"summary":"Instant query","description":"Execute an instant LogQL query at a single point in time","operationId":"queryInstant","parameters":[{"name":"query","in":"query","required":true,"schema":{"type":"string"},"description":"LogQL query expression (e.g., 'rate({job=\"prometheus\"}[5m])')","example":"{job=\"prometheus\"}"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"minimum":1,"maximum":10000},"description":"Maximum number of log entries to return"},{"name":"time","in":"query","required":false,"schema":{"type":"string","format":"date-time"},"description":"Query time (Unix timestamp or RFC3339 format)"},{"name":"direction","in":"query","required":false,"schema":{"type":"string","enum":["forward","backward"],"default":"backward"},"description":"Direction for returned log lines"}],"responses":{"200":{"description":"Successful query result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QueryResult"}}}},"400":{"description":"Bad request (invalid query syntax)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Service unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/loki/api/v1/query_range":{"get":{"summary":"Range query","description":"Execute a LogQL query over a time range","operationId":"queryRange","parameters":[{"name":"query","in":"query","required":true,"schema":{"type":"string"},"description":"LogQL query expression with range (e.g., 'rate({job=\"prometheus\"}[5m])')","example":"rate({job=\"prometheus\"}[5m])"},{"name":"start","in":"query","required":true,"schema":{"type":"string","format":"date-time"},"description":"Start time for range query (Unix timestamp or RFC3339 format)"},{"name":"end","in":"query","required":true,"schema":{"type":"string","format":"date-time"},"description":"End time for range query (Unix timestamp or RFC3339 format)"},{"name":"step","in":"query","required":false,"schema":{"type":"string"},"description":"Query resolution step width (e.g., '30s', '1m')","default":"auto"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"minimum":1,"maximum":10000},"description":"Maximum number of data points to return"},{"name":"direction","in":"query","required":false,"schema":{"type":"string","enum":["forward","backward"],"default":"backward"},"description":"Direction for returned log lines"}],"responses":{"200":{"description":"Successful range query result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QueryResult"}}}},"400":{"description":"Bad request (invalid query or time range)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Service unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/loki/api/v1/labels":{"get":{"summary":"List available labels","description":"List all available label names","operationId":"listLabels","parameters":[{"name":"start","in":"query","required":false,"schema":{"type":"string","format":"date-time"},"description":"Start time for label discovery (Unix timestamp or RFC3339 format)"},{"name":"end","in":"query","required":false,"schema":{"type":"string","format":"date-time"},"description":"End time for label discovery (Unix timestamp or RFC3339 format)"}],"responses":{"200":{"description":"List of available label names","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"data":{"type":"array","items":{"type":"string"},"description":"Array of label names","example":["job","instance","level","service"]}}}}}},"503":{"description":"Service unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/loki/api/v1/label/{name}/values":{"get":{"summary":"List label values","description":"List all values for a specific label","operationId":"listLabelValues","parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string"},"description":"Label name (e.g., 'job', 'instance')"},{"name":"start","in":"query","required":false,"schema":{"type":"string","format":"date-time"},"description":"Start time for label value discovery"},{"name":"end","in":"query","required":false,"schema":{"type":"string","format":"date-time"},"description":"End time for label value discovery"},{"name":"query","in":"query","required":false,"schema":{"type":"string"},"description":"LogQL matcher query to filter label values"}],"responses":{"200":{"description":"List of values for the label","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"data":{"type":"array","items":{"type":"string"},"description":"Array of label values","example":["prometheus","loki","grafana"]}}}}}},"400":{"description":"Bad request (invalid label name)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Service unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/loki/api/v1/push":{"post":{"summary":"Push logs","description":"Push log entries to Loki","operationId":"pushLogs","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PushRequest"}},"application/x-protobuf":{"schema":{"type":"string","format":"binary","description":"Protobuf-encoded push request"}}}},"responses":{"204":{"description":"Logs accepted (no content)"},"400":{"description":"Bad request (invalid push format)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests (rate limited)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Service unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/ready":{"get":{"summary":"Readiness check","description":"Check if Loki is ready to accept requests","operationId":"readinessCheck","responses":{"200":{"description":"Loki is ready","content":{"text/plain":{"schema":{"type":"string","example":"ready"}}}},"503":{"description":"Loki is not ready","content":{"text/plain":{"schema":{"type":"string","example":"service unavailable"}}}}}}},"/metrics":{"get":{"summary":"Prometheus metrics","description":"Expose Prometheus metrics for monitoring Loki itself","operationId":"prometheusMetrics","responses":{"200":{"description":"Prometheus metrics in text format","content":{"text/plain; version=0.0.4":{"schema":{"type":"string"}}}}}}},"/config":{"get":{"summary":"Current configuration","description":"Retrieve the current Loki configuration","operationId":"getConfiguration","responses":{"200":{"description":"Current configuration","content":{"application/json":{"schema":{"type":"object","description":"Loki configuration object"}}}}}}},"/api/prom/tail":{"get":{"summary":"Tail logs (tail endpoint)","description":"Stream logs in real-time using WebSocket","operationId":"tailLogs","parameters":[{"name":"query","in":"query","required":true,"schema":{"type":"string"},"description":"LogQL query expression"},{"name":"delay_for","in":"query","required":false,"schema":{"type":"integer","default":0},"description":"Delay in seconds before returning new log entries"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100},"description":"Maximum number of log entries to return"}],"responses":{"101":{"description":"Switching Protocols (WebSocket upgrade)"},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"components":{"schemas":{"QueryResult":{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["success","error"],"description":"Query execution status"},"data":{"type":"object","properties":{"resultType":{"type":"string","enum":["streams","matrix","vector","scalar"],"description":"Type of result"},"result":{"oneOf":[{"$ref":"#/components/schemas/StreamResult"},{"$ref":"#/components/schemas/MatrixResult"},{"$ref":"#/components/schemas/VectorResult"}],"description":"Query result data"}}},"error":{"type":"string","description":"Error message if status is 'error'"}}},"StreamResult":{"type":"array","items":{"type":"object","required":["stream","values"],"properties":{"stream":{"type":"object","description":"Log stream labels","additionalProperties":{"type":"string"},"example":{"job":"prometheus","instance":"localhost:9090"}},"values":{"type":"array","items":{"type":"array","minItems":2,"maxItems":2,"items":{"type":"string"},"description":"[timestamp_nanoseconds, log_line]"},"example":[["1577836800000000000","log entry text"]]}}}},"MatrixResult":{"type":"array","items":{"type":"object","required":["metric","values"],"properties":{"metric":{"type":"object","description":"Metric labels","additionalProperties":{"type":"string"}},"values":{"type":"array","items":{"type":"array","minItems":2,"maxItems":2,"items":[{"type":"string","format":"date-time"},{"type":"string"}],"description":"[timestamp, value]"}}}}},"VectorResult":{"type":"array","items":{"type":"object","required":["metric","value"],"properties":{"metric":{"type":"object","description":"Metric labels","additionalProperties":{"type":"string"}},"value":{"type":"array","minItems":2,"maxItems":2,"items":[{"type":"string"},{"type":"string"}],"description":"[timestamp, value]"}}}},"PushRequest":{"type":"object","required":["streams"],"properties":{"streams":{"type":"array","items":{"type":"object","required":["stream","values"],"properties":{"stream":{"type":"object","description":"Log stream labels","additionalProperties":{"type":"string"},"example":{"job":"my-app","env":"production"}},"values":{"type":"array","items":{"type":"array","minItems":2,"maxItems":2,"items":{"type":"string"},"description":"[timestamp_nanoseconds, log_line]"},"example":[["1577836800000000000","Application started"]]}}},"minItems":1,"description":"Array of log streams to push"}},"example":{"streams":[{"stream":{"job":"my-application","env":"production"},"values":[["1577836800000000000","Request received"],["1577836801000000000","Request processed"]]}]}},"ErrorResponse":{"type":"object","required":["status","error"],"properties":{"status":{"type":"string","enum":["error"]},"error":{"type":"string","description":"Error message describing what went wrong"},"details":{"type":"object","description":"Additional error details","additionalProperties":true}},"example":{"status":"error","error":"parse error at line 1, col 1: syntax error"}}}},"tags":[{"name":"Queries","description":"LogQL query endpoints"},{"name":"Labels","description":"Label discovery endpoints"},{"name":"Ingestion","description":"Log push endpoints"},{"name":"Health","description":"Health and status checks"}]}