Getting Started

Base URL, versioning, authentication, rate limits, and response conventions for the Klipfolio public API.

The Klipfolio public API lets you create and manage PowerMetrics assets, including metrics, goals, tags, dashboards, and data connections programmatically — the same assets you'd otherwise build by hand in the PowerMetrics UI. Every request is authenticated and rate-limited per API key.

Status: public beta (1.0-beta). Shapes may change before GA.

Field-level shape (names, types, enums, required and read-only status) for Metrics, Goals, Tags, Dashboards, Direct connections, Data feed connections, and Data feeds is generated from the OpenAPI 3.1 document and is authoritative there — see the API Reference tab, or fetch the live document directly at GET https://api-public.klipfolio.com/v1.0-beta/openapi.json (an API key is required, same as any other request — see Authentication below). These guides are authoritative for everything else: base URL/versioning, authentication, rate limiting, response conventions, which endpoints to call in what order to create each kind of asset, and endpoints without an OpenAPI schema (Query builder, Events/webhooks, and read-only/action sub-endpoints such as /data_feeds/generate and /metrics/:metricId/query). Examples in these guides are illustrative — they show the shape and field names you should expect, not values captured verbatim from a live response.

Base URL & versioning

https://api-public.klipfolio.com/<version>/<resource>

A request's leading path segment selects the API version. For the public API the beta marker is required:

Request pathResult
/v1.0-beta/...✅ served (canonical beta)
/v1-beta/...✅ served (alias)
/... (no segment)✅ served — defaults to 1.0-beta
/v1/...400 — beta marker required
/v1.0/..., /v1.5/...400 — specific subversions rejected

All accepted versions route to the same v1 controller.

Authentication

Every request must present a Klipfolio v2 API key as a bearer token:

Authorization: Bearer kf_live_<keyid>.<secret>.<checksum>

Issue keys from your Klipfolio account under My Profile → API Keys. (If your account also shows a legacy API Key (Klips Only) field, that's a different system — it won't work here.)

  • Scopes: GET/HEAD require the key's api:read scope; all other methods require api:write. A scope mismatch returns 403.
  • A malformed key, an unknown key, or a wrong secret all return a bare 401 (the API does not reveal which check failed).
  • If the key service is unreachable, the API fails closed (503).

Rate limiting

Each request is throttled per API key. Responses carry the draft-7 RateLimit / RateLimit-Policy headers. A throttled request receives:

HTTP/1.1 429 Too Many Requests
Retry-After: <seconds>

{ "status": 429, "message": "Too Many Requests" }

Default limits for the standard tier are 60 requests/minute and 10,000/day (both enforced). Limits are set per tier by Klipfolio, not encoded in the key — your limits can change without needing to reissue a key.

Conventions

Error responses use a consistent shape:

{
  "errorId": "required.openapi.validation",
  "status": 400,
  "message": "Bad Request",
  "meta": {}
}

errorId is the part to branch on: message is the bare status text for most errors, since an upstream message can describe internals. The exception is a read-only conflict, which returns its own message naming the fields that cannot be changed — that message is the point of rejecting rather than ignoring.

Common statuses: 400 validation error (missing or invalid fields), 401 auth failure, 403 scope mismatch, 404 not found, 429 rate limited, 503 upstream unavailable.

An update checks the resource exists before it checks the body, so a write to something that isn't there answers 404 even when the body is also invalid.

Create envelope. POST create endpoints for metrics, goals, tags, direct connections, generated data feeds, and event subscriptions return 201 with a meta/data envelope:

{
  "meta": { "url": "/metrics/abc123" },
  "data": { "id": "abc123", "...": "..." }
}

The one exception: a POST /events/subscriptions request that fans out into more than one subscription (mixing datafeed.source.* with other events) has no single resource for meta.url to name, so that case returns a bare array instead — see the Events guide.

GET, PUT, and list endpoints return the resource (or an array of resources) directly, without the envelope, unless noted otherwise in a resource's own guide.

Deletes return 204 No Content with an empty body.

Field conventions:

  • Read-only fields (ids, createdAt, updatedAt, status, etc.) are returned in responses but never writable. Sending one back is not an error as long as it still matches the stored value, so a resource fetched with GET can be edited and sent straight back with PUT — there is no need to strip these fields first. Sending one with a different value is rejected with 400, naming the fields and both values, rather than being quietly discarded. On create, where there is nothing to compare against, a read-only field is always ignored.
  • Server-maintained fields are never compared, so a value that went stale between your GET and your PUT is not an error: createdAt, updatedAt, dataUpdatedAt, timeRangeStart, timeRangeEnd, status, last_refresh_outcome, last_successful_refresh_timestamp and source.date_last_refresh. They change on their own — a metric that refreshes between your two calls moves status and dataUpdatedAt with no action from you. A data feed's joined_to_ids is read-only but is compared: it describes the data model, not refresh state. Which category each field of each asset falls into is listed in Field Reference.
  • Dates are ISO 8601 strings (e.g. 2026-05-28T23:59:59.999Z) in responses.
  • Enums (e.g. status, positiveDirection, column type) are surfaced in UPPER CASE publicly.
  • A version field may accompany a resource; if you send it on write it must match the resource's mapper version ("1.0").
  • Required fields must be present on every write, PUT included — a PUT replaces rather than merges, so a required field you leave out is missing, not inherited. Which fields those are is listed per asset in Field Reference; name on a metric, tag or goal is the common case.
  • Extra/unknown fields in a write body are rejected with 400.

Where to go next

See the API Reference tab, or these two one-page overviews: the API Endpoint Index for every endpoint, and the Field Reference for every field of every asset with its editable/read-only status. If you're trying to create an asset, start at Creating a Metric — it routes you to the right workflow guide depending on where your data lives.


Did this page help you?