All Products
Search
Document Center

Simple Log Service:MetricStore HTTP API details

Last Updated:Apr 02, 2026

Simple Log Service provides multiple APIs to query time series metrics or write metric data to a MetricStore. These APIs are compatible with the open source Prometheus protocol.

Overview

Prometheus APIs are located in the /api/v1/ directory. MetricStore APIs follow the same convention. The complete URL format is https://{project}.{sls-endpoint}/prometheus/{project}/{metricstore}/api/v1/.

Parameter

Required

Description

{sls-endpoint}

Yes

The endpoint of Simple Log Service. The endpoint is the domain name used to access the service. The endpoint varies by the region where the project is located. For more information, see Endpoints.

{project}

Yes

Project Name: A project is the resource management unit of Simple Log Service and serves as the primary boundary for multi-user isolation and access control. For more information, see Manage Projects.

{metricstore}

Yes

The name of the MetricStore. For more information, see Create a MetricStore.

Important

These APIs require BasicAuth authentication. Set Username to your AccessKey ID and Password to your AccessKey secret. We recommend that you use the AccessKey pair of a Resource Access Management (RAM) user who has query permissions on the specified project. For more information, see Configure a permission assistant.

These APIs also support Security Token Service (STS) authentication. In this case, set the BasicAuth Password to the format {AccessKey Secret}${STS Token}. For more information, see What is STS?.

Time series metric query APIs

The time series metric query APIs include the Instant Queries API and Range Queries API.

Instant Queries API

The Instant Queries API queries metric data at a specific point in time.

GET https://{project}.{sls-endpoint}/prometheus/{project}/{metricstore}/api/v1/query
POST https://{project}.{sls-endpoint}/prometheus/{project}/{metricstore}/api/v1/query

The following table describes the parameters.

Parameter

Required

Description

query

Yes

A Prometheus Query Language (PromQL) expression. For more information, see PromQL syntax.

time

No

The point in time for the query. The value is a UNIX timestamp in seconds. Default value: the current time.

timeout

No

The query timeout period in seconds.

Time duration formats such as 1s, 2m, 3h, and 4d are also supported. Example: timeout=10s. For more information, see Time Durations.

lookback_delta

No

Overrides the `query.lookback-delta` flag in Prometheus for this query only. The value must follow the Time Durations format. Example: `lookback_delta=1m`. For more information, see Time Durations. This parameter specifies the maximum lookback interval for finding data points in PromQL calculations. Default value in an SLS MetricStore: `3m`.

  • Example

    curl -X GET 'https://haoqi-sls-metric-test.pub-cn-hangzhou.log.aliyuncs.com/prometheus/haoqi-sls-metric-test/prometheus-metrics/api/v1/query?query=up&time=1676700699' \
    -u username:password \
    -H 'Content-Type: application/x-www-form-urlencoded'
    
    # Set username and password to your Alibaba Cloud AccessKey.
  • Sample response

    {
        "status": "success",
        "data": {
            "resultType": "vector",
            "result": [
                {
                    "metric": {
                        "__name__": "up",
                        "instance": "demo.promlabs.com:10001",
                        "job": "demo"
                    },
                    "value": [
                        1676700550.696,
                        "1"
                    ]
                },
                {
                    "metric": {
                        "__name__": "up",
                        "instance": "demo.promlabs.com:10000",
                        "job": "demo"
                    },
                    "value": [
                        1676700550.696,
                        "1"
                    ]
                }
            ]
        }
    }

Range Queries API

The Range Queries API queries metric data at multiple points in time within a specified time range.

GET https://{project}.{sls-endpoint}/prometheus/{project}/{metricstore}/api/v1/query_range
POST https://{project}.{sls-endpoint}/prometheus/{project}/{metricstore}/api/v1/query_range

The following table describes the parameters.

Parameter

Required

Description

query

Yes

A PromQL expression. For more information, see PromQL syntax.

start

No

The start time of the query range. The value is a UNIX timestamp in seconds.

end

No

The end time of the query range. The value is a UNIX timestamp in seconds.

step

No

The query step interval in seconds.

Time duration formats such as 1s, 2m, 3h, and 4d are also supported. Example: `step=2m`. For more information, see Time Durations.

timeout

No

The query timeout period in seconds.

Time duration formats such as 1s, 2m, 3h, and 4d are also supported. Example: timeout=10s. For more information, see Time Durations.

lookback_delta

No

Overrides the `query.lookback-delta` flag in Prometheus for this query only. The value must follow the Time Durations format. Example: `lookback_delta=1m`. For more information, see Time Durations. This parameter specifies the maximum lookback interval for finding data points in PromQL calculations. Default value in an SLS MetricStore: `3m`.

  • Example

    This example queries metric data from 14:09:59 to 14:16:39 on 2023-02-18 with a step of 60s.

    curl -X GET 'https://haoqi-sls-metric-test.pub-cn-hangzhou.log.aliyuncs.com/prometheus/haoqi-sls-metric-test/prometheus-metrics/api/v1/query_range?query=up&start=1676700599&end=1676700999&step=60s' \
    -u username:password \
    -H 'Content-Type: application/x-www-form-urlencoded'
    
    # Set username and password to your Alibaba Cloud AccessKey.
  • Sample response

    {
      "status": "success",
      "data": {
        "resultType": "matrix",
        "result": [
          {
            "metric": {
              "__name__": "up",
              "instance": "demo.promlabs.com:10000",
              "job": "demo"
            },
            "values": [
              [
                1676700599,
                "1"
              ],
              [
                1676700659,
                "1"
              ],
              [
                1676700719,
                "0"
              ],
              [
                1676700779,
                "0"
              ],
              [
                1676700839,
                "1"
              ],
              [
                1676700899,
                "0"
              ],
              [
                1676700959,
                "1"
              ]
            ]
          },
          {
            "metric": {
              "__name__": "up",
              "instance": "demo.promlabs.com:10001",
              "job": "demo"
            },
            "values": [
              [
                1676700599,
                "1"
              ],
              [
                1676700659,
                "1"
              ],
              [
                1676700719,
                "0"
              ],
              [
                1676700779,
                "0"
              ],
              [
                1676700839,
                "1"
              ],
              [
                1676700899,
                "1"
              ],
              [
                1676700959,
                "1"
              ]
            ]
          }
        ]
      }
    }

Metadata query APIs

Simple Log Service also supports querying metadata such as labels and label values. The SLS metadata query APIs are compatible with the Querying metadata APIs in Prometheus. Use these APIs to retrieve all metrics, labels, and label values within a specific time period. The response does not include timestamps or numeric values.

Query Series API

The Query Series API retrieves all metric names and their corresponding label-value pairs that match specific conditions within a specified time period.

GET https://{project}.{sls-endpoint}/prometheus/{project}/{metricstore}/api/v1/series
POST https://{project}.{sls-endpoint}/prometheus/{project}/{metricstore}/api/v1/series

Parameters

Parameter

Required

Description

match[]

Yes

The filter condition. Example: match[]=up{instance="demo.*"}.

One or more values can be specified.

start

No

The start time of the query range. The value is a UNIX timestamp in seconds.

Default value: 5 minutes before the current time.

end

No

The end time of the query range. The value is a UNIX timestamp in seconds.

Default value: the current time.

Important

Even if you specify custom values for both start and end, this API only queries data within the 5 minutes before the end time. The actual query range is `(end - 5 minutes, end)`.

x-sls-disable-range-limit

No

Set this parameter to true to remove the 5-minute query range limit and use the specified start and end values instead.

forceMaxMetaTimeRangeSeconds

No

The maximum query range in seconds. When (end - start) exceeds this value, the query range is aligned to (end - forceMaxMetaTimeRangeSeconds, end).

For optimal query performance, we recommend that you always include this parameter.

  • Example

    curl -g -X GET 'https://haoqi-sls-metric-test.pub-cn-hangzhou.log.aliyuncs.com/prometheus/haoqi-sls-metric-test/prometheus-metrics/api/v1/series?match[]=up{instance="demo.promlabs.com:10000"}&match[]=go_sched_latencies_seconds_bucket&start=1676700599&end=1676700999' \
    -u username:password \
    -H 'Content-Type: application/x-www-form-urlencoded'
    
    # Set username and password to your Alibaba Cloud AccessKey.
  • Sample response

    {
        "status": "success",
        "data": [
            {
                "__name__": "go_gc_duration_seconds_count",
                "instance": "demo.promlabs.com:10000",
                "job": "demo"
            },
            {
                "__name__": "go_gc_duration_seconds_count",
                "instance": "demo.promlabs.com:10001",
                "job": "demo"
            },
            {
                "__name__": "up",
                "instance": "demo.promlabs.com:10000",
                "job": "demo"
            }
        ]
    }

Query Label Names API

The Query Label Names API retrieves all label names that match specific conditions within a specified time period.

GET https://{project}.{sls-endpoint}/prometheus/{project}/{metricstore}/api/v1/labels
POST https://{project}.{sls-endpoint}/prometheus/{project}/{metricstore}/api/v1/labels

Parameters

Parameter

Required

Description

match[]

Yes

The filter condition. Example: `match[]=up{instance="demo.*"}`.

Zero, one, or more values can be specified.

start

No

The start time of the query range. The value is a UNIX timestamp in seconds.

Default value: 5 minutes before the current time.

end

No

The end time of the query range. The value is a UNIX timestamp in seconds.

Default value: the current time.

Important

Even if you specify custom values for both start and end, this API only queries data within the 5 minutes before the end time. The actual query range is `(end - 5 minutes, end)`.

x-sls-disable-range-limit

No

Set this parameter to true to remove the 5-minute query range limit and use the specified start and end values instead.

forceMaxMetaTimeRangeSeconds

No

The maximum query range in seconds. When (end - start) exceeds this value, the query range is aligned to (end - forceMaxMetaTimeRangeSeconds, end).

For optimal query performance, we recommend that you always include this parameter.

  • Example

    This example queries all label names of all metrics within a specified time period.

    curl -X GET 'https://haoqi-sls-metric-test.pub-cn-hangzhou.log.aliyuncs.com/prometheus/haoqi-sls-metric-test/prometheus-metrics/api/v1/labels?start=1676700599&end=1676700999' \
    -u username:password \
    -H 'Content-Type: application/x-www-form-urlencoded'
    
    # Set username and password to your Alibaba Cloud AccessKey.
  • Sample response

    {
        "status": "success",
        "data": [
            "code",
            "instance",
            "job",
            "le",
            "method",
            "mode",
            "path",
            "quantile",
            "status",
            "type",
            "version",
            "__name__"
        ]
    }

Query Label Values API

The Query Label Values API retrieves all label values for a specific label name that match specific conditions within a specified time period.

Important

In the API URL, replace <label_name> with the actual label name.

GET https://{project}.{sls-endpoint}/prometheus/{project}/{metricstore}/api/v1/label/<label_name>/values

Parameters

Parameter

Required

Description

match[]

Yes

The filter condition. Example: `match[]=up{instance="demo.*"}`.

One or more values can be specified.

start

No

The start time of the query range. The value is a UNIX timestamp in seconds.

Default value: 5 minutes before the current time.

end

No

The end time of the query range. The value is a UNIX timestamp in seconds.

Default value: the current time.

Important

Even if you specify custom values for both start and end, this API only queries data within the 5 minutes before the end time. The actual query range is `(end - 5 minutes, end)`.

x-sls-disable-range-limit

No

Set this parameter to true to remove the 5-minute query range limit and use the specified start and end values instead.

forceMaxMetaTimeRangeSeconds

No

The maximum query range in seconds. When (end - start) exceeds this value, the query range is aligned to (end - forceMaxMetaTimeRangeSeconds, end).

For optimal query performance, we recommend that you always include this parameter.

  • Example

    This example queries all label values for the instance label of the up metric within a specified time period.

    curl -X GET 'https://haoqi-sls-metric-test.pub-cn-hangzhou.log.aliyuncs.com/prometheus/haoqi-sls-metric-test/prometheus-metrics/api/v1/label/instance/values?match[]=up&start=1676700599&end=1676700999' \
    -u username:password \
    -H 'Content-Type: application/x-www-form-urlencoded'
    
    # Set username and password to your Alibaba Cloud AccessKey.
  • Sample response

    {
        "status": "success",
        "data": [
            "demo.promlabs.com:10000",
            "demo.promlabs.com:10001",
            "demo.promlabs.com:10002"
        ]
    }

Data write API

Ingest time series data into a MetricStore by configuring the `remote_write` parameter in the Prometheus configuration file. For more information, see Ingest Prometheus monitoring data using the remote write protocol. Because MetricStore is compatible with the Prometheus remote write protocol, you can also write data to a MetricStore by directly calling the `remote_write` API over HTTP without a Prometheus process.

MetricStore provides the following remote write-compatible API that parses time series data and writes it to backend storage.

Important

When time series data is written to an SLS MetricStore using the remote write protocol, SLS uses `MetricName` and `Labels` as the hash key by default. This routes time series data from different time series to specific shards to improve data locality in storage.

POST https://{project}.{sls-endpoint}/prometheus/{project}/{metricstore}/api/v1/write

The following code shows an example.

import (
	"bytes"
	"flag"
	"fmt"
	"github.com/gogo/protobuf/proto"
	"github.com/golang/snappy"
	"github.com/prometheus/prometheus/prompb"
	"io/ioutil"
	"net/http"
	"time"
)

func MockRemoteWrite() {
	project := flag.String("project", "xxxx", "")
	metricStore := flag.String("metricstore", "xxxx", "")
	endpoint := flag.String("endpoint", "xxxx", "")
	akId := flag.String("akid", "xxxx", "") // AccessKey information.
	akKey := flag.String("aksecret", "xxxx", "")
	flag.Parse()

	Url := fmt.Sprintf("https://%s.%s/prometheus/%s/%s/api/v1/write", *project, *endpoint, *project, *metricStore)
	timestamp := time.Now().UnixNano()
	timeSeries := []prompb.TimeSeries{
		{
			Labels: []prompb.Label{
				{Name: "__name__", Value: "test_metric"},
				{Name: "app", Value: "HOST"},
				{Name: "device", Value: "vda"},
			},
			Samples: []prompb.Sample{
				{Timestamp: timestamp / 1000000, Value: 100},
				{Timestamp: timestamp/1000000 + 10000, Value: 200},
				{Timestamp: timestamp/1000000 + 20000, Value: 400},
				{Timestamp: timestamp/1000000 + 30000, Value: 300},
			},
		},
		{
			Labels: []prompb.Label{
				{Name: "__name__", Value: "test_metric"},
				{Name: "app", Value: "HOST"},
				{Name: "device", Value: "vda"},
				{Name: "uid", Value: "123456"},
			},
			Samples: []prompb.Sample{
				{Timestamp: timestamp / 1000000, Value: 100},
				{Timestamp: timestamp/1000000 + 10000, Value: 200},
				{Timestamp: timestamp/1000000 + 20000, Value: 400},
				{Timestamp: timestamp/1000000 + 30000, Value: 600},
			},
		},
	}
	data, _ := proto.Marshal(&prompb.WriteRequest{Timeseries: timeSeries})
	bufBody := snappy.Encode(nil, data)
	rwR, err := http.NewRequest("POST", Url, ioutil.NopCloser(bytes.NewReader(bufBody)))
	rwR.Header.Add("Content-Encoding", "snappy")
	rwR.Header.Set("Content-Type", "application/x-protobuf")
	rwR.SetBasicAuth(*akId, *akKey) // Set the basic auth information.
	if err != nil {
		fmt.Println(err.Error())
		return
	}

	start := time.Now().UnixNano() / 1000000 // ms
	do, err := client.Do(rwR)
	end := time.Now().UnixNano() / 1000000 // ms
	if err != nil {
		panic(err)
	}
	status, result := parseResp(do)

	fmt.Println("status:", status, "result:", result, "duration:", end-start)
}

func parseResp(resp *http.Response) (status, data string) {
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body) // The body content must be read completely.
	if err != nil {
		panic(err)
	}
	return resp.Status, string(body)
}

SDK examples

Access the query API over HTTP

import (
	"flag"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"time"
)

const separator = "#"

func http_main() {

	project := flag.String("project", "xxxx", "")
	metricStore := flag.String("metricstore", "xxxx", "")
	endpoint := flag.String("endpoint", "xxxx", "")
	akId := flag.String("akid", "xxxx", "")
	akKey := flag.String("aksecret", "xxxx", "")
	query := flag.String("query", "avg(up)", "")
	queryType := flag.String("type", "values", "range or query or labels or values or series")
	matches := flag.String("match", "up", "") // Use the # symbol to concatenate multiple match[] parameters.
	labelName := flag.String("label", "instance", "")
	step := flag.String("step", "1m", "")
	fromtime := flag.String("from", "2023-02-15T00:00:00Z", "time 2006-01-02T15:04:05Z07:00")
	totime := flag.String("to", "2023-02-15T00:15:00Z", "time 2006-01-02T15:04:05Z07:00")

	flag.Parse()

	timeFrom, err := time.Parse(time.RFC3339, *fromtime)
	if err != nil {
		panic(err)
	}
	timeTo, err := time.Parse(time.RFC3339, *totime)
	if err != nil {
		panic(err)
	}

	// URL: https://{project}.{sls-endpoint}/prometheus/{project}/{metricstore}
	prometheusEndpoint := fmt.Sprintf("https://%s/prometheus/%s/%s", *project+"."+*endpoint, *project, *metricStore)

	var uri string
	urlVal := url.Values{}
	urlVal.Add("start", strconv.FormatInt(timeFrom.Unix(), 10))
	urlVal.Add("end", strconv.FormatInt(timeTo.Unix(), 10))

	switch *queryType {
	case "range":
		urlVal.Add("query", *query)
		urlVal.Add("step", *step)
		uri = fmt.Sprintf("%s/api/v1/query_range?%v", prometheusEndpoint, urlVal.Encode())
	case "query":
		urlVal.Add("query", *query)
		urlVal.Add("time", strconv.FormatInt(timeTo.Unix(), 10))
		uri = fmt.Sprintf("%s/api/v1/query?%v", prometheusEndpoint, urlVal.Encode())
	case "labels":
		extractAddMatches(*matches, urlVal)
		uri = fmt.Sprintf("%s/api/v1/labels?%v", prometheusEndpoint, urlVal.Encode())
	case "values":
		extractAddMatches(*matches, urlVal)
		uri = fmt.Sprintf("%s/api/v1/label/%s/values?%v", prometheusEndpoint, *labelName, urlVal.Encode())
	case "series":
		extractAddMatches(*matches, urlVal)
		uri = fmt.Sprintf("%s/api/v1/series?%v", prometheusEndpoint, urlVal.Encode())
	}

	req, _ := http.NewRequest(http.MethodGet, uri, nil)
	req.SetBasicAuth(*akId, *akKey)

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	buf, err := ioutil.ReadAll(resp.Body)
	resp.Body.Close()
	if err != nil {
		panic(err)
	}

	fmt.Println(string(buf))

}

func extractAddMatches(matches string, uVal url.Values) {
	splits := strings.Split(matches, separator)
	for _, match := range splits {
		uVal.Add("match[]", match)
	}
}

Access the query API using the Prometheus SDK

This example uses Prometheus client_golang v1.14.0.

import (
	"context"
	"flag"
	"fmt"
	"github.com/prometheus/client_golang/api"
	v1 "github.com/prometheus/client_golang/api/prometheus/v1"
	"net"
	"net/http"
	"net/url"
	"time"
)

func main() {
	project := flag.String("project", "xxxx", "")
	metricStore := flag.String("metricstore", "xxxx", "")
	endpoint := flag.String("endpoint", "xxxx", "")
	akId := flag.String("akid", "xxxx", "")
	akKey := flag.String("aksecret", "xxxx", "")
	flag.Parse()

	// URL: https://{project}.{sls-endpoint}/prometheus/{project}/{metricstore}
	prometheusEndpoint := fmt.Sprintf("https://%s.%s/prometheus/%s/%s", *project, *endpoint, *project, *metricStore)

	client, err := api.NewClient(api.Config{
		Address: prometheusEndpoint,
		RoundTripper: &http.Transport{
			// set basic auth
			Proxy: func(req *http.Request) (*url.URL, error) {
				req.SetBasicAuth(*akId, *akKey)
				return nil, nil
			},
			DialContext: (&net.Dialer{
				Timeout:   60 * time.Second,
				KeepAlive: 60 * time.Second,
			}).DialContext,
			TLSHandshakeTimeout: 10 * time.Second,
		},
	})
	if err != nil {
		panic(err)
	}

	v1api := v1.NewAPI(client)
	ctx, _ := context.WithTimeout(context.Background(), 60*time.Second)
	r := v1.Range{
		Start: time.Now().Add(-15 * time.Minute),
		End:   time.Now(),
		Step:  time.Minute,
	}
	// query range
	result, warnings, err := v1api.QueryRange(ctx, "avg(up)", r)
	if err != nil {
		panic(err)
	}
	if len(warnings) > 0 {
		fmt.Printf("Warnings: %v %v\n", warnings, result)
	}
	fmt.Println(result)

	// query
	result, warnings, err = v1api.Query(ctx, "avg(up)", time.Now())
	if err != nil {
		panic(err)
	}
	if len(warnings) > 0 {
		fmt.Printf("Warnings: %v %v\n", warnings, result)
	}
	fmt.Println(result)

	// series
	series, warnings, err := v1api.Series(ctx, []string{"up"}, time.Now().Add(-15*time.Minute), time.Now())
	if err != nil {
		panic(err)
	}
	if len(warnings) > 0 {
		fmt.Printf("Warnings: %v %v\n", warnings, result)
	}
	fmt.Println(series)

	// labels
	names, warnings, err := v1api.LabelNames(ctx, []string{"up"}, time.Now().Add(-15*time.Minute), time.Now())
	if err != nil {
		panic(err)
	}
	if len(warnings) > 0 {
		fmt.Printf("Warnings: %v %v\n", warnings, result)
	}
	fmt.Println(names)

	// labelValues
	values, warnings, err := v1api.LabelValues(ctx, "instance", []string{"up"}, time.Now().Add(-15*time.Minute), time.Now())
	if err != nil {
		panic(err)
	}
	if len(warnings) > 0 {
		fmt.Printf("Warnings: %v %v\n", warnings, result)
	}
	fmt.Println(values)
}

Response structure

The query and write APIs return responses in the following structure:

{
  "status": "success" | "error",
  "data": <data>,

  // The following two items are returned when an error occurs during query analysis.
  "errorType": "<string>",
  "error": "<string>",
  
	// A warning message is returned, usually for an incomplete query.
  "warnings": ["<string>"]
}

Error handling

The following are common errors and solutions.

Authentication failed

  • If the following response is returned, authentication failed. Verify your AccessKey pair.

    {
        "status": "error",
        "code": "401",
        "errorType": "unauthorized",
        "error": "get query instance error: {\n    \"httpCode\": 401,\n    \"errorCode\": \"Unauthorized\",\n    \"errorMessage\": \"AccessKeyId not found: xxxx\",\n    \"requestID\": \"xxxx\"\n}"
    }
  • If the following response is returned, the source IP address is not in the VPC CIDR block whitelist. Add the IP address to the whitelist.

    {
        "status": "error",
        "code": "401",
        "errorType": "unauthorized",
        "error": "get query instance error: {\n    \"httpCode\": 401,\n    \"errorCode\": \"Unauthorized\",\n    \"errorMessage\": \"AccessKeyId not found: xxxx\",\n    \"requestID\": \"xxxx\"\n}"
    }

PromQL expression error

If the following response is returned, the PromQL expression contains an error. Fix the expression in the query parameter.

--> /api/v1/query_range?query=up[2m]&start=1676700599&end=1676700999&step=60s
{
    "status": "error",
    "errorType": "bad_data",
    "error": "invalid expression type \"range vector\" for range query, must be Scalar or instant Vector"
}

Timeout error

If the following response is returned, the query timed out. Increase the timeout value.

{
    "status": "error",
    "errorType": "timeout",
    "error": "query timed out in expression evaluation"
}

Incomplete query results

If the following response is returned, the query result is incomplete. Narrow the query time range and try again.

{
    "status": "success",
    "data": {
        "resultType": "matrix",
        "result": [
            {
                "metric": {},
                "values": [
                    [
                        1673798460,
                        "11111111"
                    ],
                    [
                        1673799060,
                        "22222222"
                    ],
                    [
                        1673799660,
                        "33333333"
                    ]
                ]
            }
        ]
    },
    "warnings": [
        "Request to Sls partial incompleted, incomplete task count : 11, total : 108"
    ]
}