Publish custom metrics (project-scoped).
curl --request POST \ --url https://stratum.example.com/v1/projects/example/observability/metrics/actions/put-metric-data \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "namespace": "MyApp", "metricData": [ { "metricName": "RequestLatencyMs", "dimensions": { "additionalProperty": "example" }, "value": 1, "timestamp": "2026-04-15T12:00:00Z" } ] }'. An application publishes metrics of its own (request latency,
queue depth, a business counter), the CloudWatch PutMetricData shape.
Cedar action observability:PutMetricData; an instance-profile
credential is the expected caller.
Each datum is stored in VictoriaMetrics as
custom_<namespace>:<metricName> (dots and dashes become _), with the
datum’s dimensions as labels plus namespace, and with project_id and
category="workload" stamped by the server: a body can neither set nor
override them, and a dimension named like a reserved label is refused.
The custom_ prefix keeps a tenant metric from ever carrying a platform
metric’s name. The response names the stored series, so they can be
queried back through query-instant / query-range in the same project.
Another project never sees them.
Up to 1000 data per request. Timestamps may be up to 2 hours old and 10
minutes ahead (default now). Samples are rate-limited per project by the
quota dimension observability.custom_metrics.samples.rate (per minute,
default 60000): 429 with Retry-After beyond it.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Request Bodyrequired
Section titled “Request Bodyrequired”. A batch of custom metric data in one namespace.
object
Example
MyApp. One custom metric sample.
object
Example
RequestLatencyMsLabels on the sample. Names are Prometheus label names
([a-zA-Z_][a-zA-Z0-9_]*, not starting with __); project_id,
category, namespace, job and instance are reserved. Values are
up to 256 characters.
object
A finite number.
When the value was measured (default now; at most 2 hours old, 10 minutes ahead).
Responses
Section titled “Responses”Accepted and written.
object
Samples written.
The stored series names, to query back (for example custom_MyApp:RequestLatencyMs).
Example generated
{ "accepted": 1, "metricNames": [ "example" ]}Bad request.
object
The findings of a rejected IAM policy document (custom and resource policies).
One finding of a rejected IAM policy document. A rejection lists every finding, so the author fixes the document in one round trip.
object
The finding, e.g. INVALID_DOCUMENT, UNKNOWN_ACTION, ACTION_NOT_APPLICABLE.
Index of the statement at fault; -1 for the document as a whole.
The offending action, where one is at fault (ACTION_NOT_APPLICABLE).
Field errors, for codes that carry them: each problem at its field
(see FieldError). Documented on the responses that set it, e.g.
approveNodeJoin’s INVALID_INPUT and JOIN_APPROVAL_REFUSED.
Absent otherwise.
One field’s problem, the stage-2 installer API’s shape.
field is the field’s path, message what is wrong with it.
object
The field’s path, e.g. links[0].interface, disks[1].confirm,
mgmt.address or role; empty for the whole request.
Structured facts about the refusal, for codes that carry them. The
shape is fixed per code and documented on the response that answers
it, e.g. IMAGE_POOL_MISMATCH (see ImagePoolMismatchDetails) and
IMAGE_IN_USE. Absent for codes that carry none.
object
Example
{ "issues": [ { "code": "ACTION_NOT_APPLICABLE", "action": "compute:CreateVpc" } ]}Authenticated but not authorized.
object
The findings of a rejected IAM policy document (custom and resource policies).
One finding of a rejected IAM policy document. A rejection lists every finding, so the author fixes the document in one round trip.
object
The finding, e.g. INVALID_DOCUMENT, UNKNOWN_ACTION, ACTION_NOT_APPLICABLE.
Index of the statement at fault; -1 for the document as a whole.
The offending action, where one is at fault (ACTION_NOT_APPLICABLE).
Field errors, for codes that carry them: each problem at its field
(see FieldError). Documented on the responses that set it, e.g.
approveNodeJoin’s INVALID_INPUT and JOIN_APPROVAL_REFUSED.
Absent otherwise.
One field’s problem, the stage-2 installer API’s shape.
field is the field’s path, message what is wrong with it.
object
The field’s path, e.g. links[0].interface, disks[1].confirm,
mgmt.address or role; empty for the whole request.
Structured facts about the refusal, for codes that carry them. The
shape is fixed per code and documented on the response that answers
it, e.g. IMAGE_POOL_MISMATCH (see ImagePoolMismatchDetails) and
IMAGE_IN_USE. Absent for codes that carry none.
object
Example
{ "issues": [ { "code": "ACTION_NOT_APPLICABLE", "action": "compute:CreateVpc" } ]}Request rate limit exceeded. The API-boundary throttle caps request throughput per principal and per project; code is RATE_LIMITED (distinct from the quota engine’s QUOTA_EXCEEDED). The Retry-After header carries the seconds to wait. Applies to any authenticated endpoint — it is enforced by middleware, not per-path.
object
The findings of a rejected IAM policy document (custom and resource policies).
One finding of a rejected IAM policy document. A rejection lists every finding, so the author fixes the document in one round trip.
object
The finding, e.g. INVALID_DOCUMENT, UNKNOWN_ACTION, ACTION_NOT_APPLICABLE.
Index of the statement at fault; -1 for the document as a whole.
The offending action, where one is at fault (ACTION_NOT_APPLICABLE).
Field errors, for codes that carry them: each problem at its field
(see FieldError). Documented on the responses that set it, e.g.
approveNodeJoin’s INVALID_INPUT and JOIN_APPROVAL_REFUSED.
Absent otherwise.
One field’s problem, the stage-2 installer API’s shape.
field is the field’s path, message what is wrong with it.
object
The field’s path, e.g. links[0].interface, disks[1].confirm,
mgmt.address or role; empty for the whole request.
Structured facts about the refusal, for codes that carry them. The
shape is fixed per code and documented on the response that answers
it, e.g. IMAGE_POOL_MISMATCH (see ImagePoolMismatchDetails) and
IMAGE_IN_USE. Absent for codes that carry none.
object
Example
{ "issues": [ { "code": "ACTION_NOT_APPLICABLE", "action": "compute:CreateVpc" } ]}Headers
Section titled “Headers”Seconds to wait before retrying.
Upstream temporarily unavailable (driver / scheduler / dependency).
object
The findings of a rejected IAM policy document (custom and resource policies).
One finding of a rejected IAM policy document. A rejection lists every finding, so the author fixes the document in one round trip.
object
The finding, e.g. INVALID_DOCUMENT, UNKNOWN_ACTION, ACTION_NOT_APPLICABLE.
Index of the statement at fault; -1 for the document as a whole.
The offending action, where one is at fault (ACTION_NOT_APPLICABLE).
Field errors, for codes that carry them: each problem at its field
(see FieldError). Documented on the responses that set it, e.g.
approveNodeJoin’s INVALID_INPUT and JOIN_APPROVAL_REFUSED.
Absent otherwise.
One field’s problem, the stage-2 installer API’s shape.
field is the field’s path, message what is wrong with it.
object
The field’s path, e.g. links[0].interface, disks[1].confirm,
mgmt.address or role; empty for the whole request.
Structured facts about the refusal, for codes that carry them. The
shape is fixed per code and documented on the response that answers
it, e.g. IMAGE_POOL_MISMATCH (see ImagePoolMismatchDetails) and
IMAGE_IN_USE. Absent for codes that carry none.
object
Example
{ "issues": [ { "code": "ACTION_NOT_APPLICABLE", "action": "compute:CreateVpc" } ]}