Skip to main content
A resource running outside a supported cloud has no instance type, region or provider ID for CostGraph to price against. Instead of inventing those, tag the resource with the ID of a rate you registered in the pricing marketplace. A pricing ID is per dimension, so one object can carry a compute rate and a storage rate at the same time:
Register a rate once, then tag every resource that bills at it: A pin can reference only your own organization’s rates or public catalog prices. A label naming another organization’s rate is ignored, and the resource stays unpriced. The same ID can be tagged onto as many resources as bill at that rate, and changing the rate reprices all of them at once.

Dimensions

Register a rate

Full request and response schema: Publish compute prices for compute, and Publish disk prices for storage. Creating, changing or deleting a rate needs an API key with the pricing:write scope, or an admin signed in. Reading rates needs pricing:read or pricing:write, or a member signed in. Only admins can create keys with pricing:write.
A disk rate takes capacity bounds instead of CPU and memory:
The response carries an id for each entry. That UUID is what you tag with.

Assign a price to a virtual machine

Choose a price in the agent install step, or open the virtual machine’s page and set its Price field. The machine is costed at that price from the next hour. Unassigning it returns the machine to automatic pricing. Assigning a price needs an admin, or an API key with the pricing:write scope. Listing prices needs a member, or an API key with the pricing:read scope. Through the API, list your compute prices, then set or remove the tag:
Send {"remove":["costgraph.ai/pricing-id.compute"]} to unassign. Only your organization’s own prices and public catalog prices can be assigned; any other id is rejected. Each disk takes its own storage price, whether it is attached to a virtual machine or backs a Kubernetes volume. On the machine’s page, expand the disk and pick a price; on a volume’s page, pick it in the volume details. Through the API, list your disk prices, then assign one to a disk, or send null to return it to automatic pricing:
A volume tagged with costgraph.ai/pricing-id.storage in the cluster keeps the label’s price: change or remove the label to change it. A volume no workload mounts yet cannot be priced this way until one does.

Tag the resource

On Kubernetes, use labels:
Review what is tagged with:
Pins are read from Kubernetes objects: nodes, volumes and volume claims. A tagged resource needs no other metadata. CPU and memory still come from the node’s capacity, and volume size from the PV, because those are the billed quantities.

Key spellings

Some platforms reject the canonical key, and a label set on a cloud instance can reach the node in a rewritten form. CostGraph matches keys case-insensitively after replacing /, . and - with _, so every spelling below resolves to the same pin. Set whichever your tooling accepts.

Inheritance

Every object is priced in its own right. An object with no pin of its own takes the rate from the nearest scope above it, so tagging one node can price the volumes on it without tagging each one. The nearest pin wins, and each kind of object looks outward along its own path: A volume and its claim are separate objects and can carry different rates. A volume with no consumer has no node above it, so with no pin of its own it falls straight to attribute matching.
A node is not in any namespace, so tagging a namespace never changes a node’s own rate. It reaches the claims in that namespace.

What a pin changes

A pin decides the rate CostGraph uses to cost that resource, replacing attribute matching for that dimension. Nothing else about the resource changes: CPU and memory still come from the node’s capacity and size from the volume, because those are the billed quantities. A pin is how a resource gets a cost at all when CostGraph has nothing to match on, such as a bare-metal node with no cloud provider behind it.

Change a rate

PATCH the rate by its ID with the new cost_per_hour. The ID is unchanged and every tagged resource picks up the new rate from the next hour. Already-billed hours keep the rate they were billed at.
A compute or database rate has an hourly price and per-vCPU and per-GB memory rates (plus a per-GPU rate for GPU machines). Send one side and CostGraph works out the other:
  • Send only cost_per_hour and it is split into per-vCPU and per-GB rates, after taking off the GPU cost.
  • Send only cpu_cores_cost_per_hour and ram_gb_cost_per_hour (and gpu_cost_per_hour) and the hourly price is their total for the machine’s size.
  • Send both and they must add up, or the request fails with 422 naming both numbers.
You can also re-POST the full entry with a new cost_per_hour, which keeps the same ID. If you copied the entry from a GET, remove cpu_cores_cost_per_hour and ram_gb_cost_per_hour first: they still hold the old rates, no longer match the new price, and the request fails with 422.
Changing region, instance_type or period_billing_hours creates a new rate with a new ID, because those describe a different SKU. Re-tag the affected resources with the new ID.

Delete a rate

A compute or disk rate that is assigned to a resource cannot be deleted. The request fails with 409 and code price_in_use, and the response lists the resources that use it under affected. Unassign the price from each of them, then delete it again.

Fix a mistake

Re-tag with the correct ID and the change applies on the next sync. Remove a Kubernetes label with a trailing hyphen:
Removing the tag removes the pin. The resource falls back to a pin inherited from an ancestor, then to normal attribute matching. If the ID is malformed, or names a rate that has been deleted, CostGraph logs a warning naming the resource and the value, and leaves that dimension unpriced. It never falls back to attribute matching to cover for a bad ID.