Skip to main content
GET
Fetch Quota Values

Overview

This endpoint returns the values of a quota — the target assigned to each person, for each period. Use it to put objectives next to results. Use this endpoint for:
  • BI dashboards comparing targets with attainment
  • Replicating quotas into a data warehouse
  • Feeding forecast models with committed objectives
Quotas = targets. This endpoint gives you what each person was expected to achieve. What they actually earned comes from statements.
Only quotas from your company’s live environment are reachable. A quota_id that belongs to a sandbox environment returns 404 Not Found, even if the id was copied from the Qobra app while viewing that sandbox. Discover valid ids with GET /v2/data-structures, where every quota is listed with "type": "quota".

Your first call

Example response


One row per person and per period

The response is flat: one row for each combination of a user and a period. A quarterly quota covering 40 people over 4 quarters returns up to 160 rows. Only cells that hold a value produce a row, so a person with no target for a period is simply absent rather than returned with a zero. The response is not grouped by user. The Qobra app shows one line per person with their periods side by side — this endpoint does not. Group on standard.user.id yourself if you need the app’s shape. Every row carries the same five keys, whatever the quota’s configuration. They never depend on the column mapping of an integration, so you can hard-code them: If you load several quotas into one table, tag each row with the quota_id you requested — the response does not repeat it.

Periods follow the quota’s frequency

The frequency is not part of the rows. Read it on standard.period from GET /v2/data-structures/{quota_id}/fields rather than guessing it from the string:
Periods follow your company’s fiscal year. 2026-Q1 is the first quarter of your fiscal year, which is not necessarily January to March.

Everyone’s values are returned

This endpoint returns the values of every user in the quota, whoever owns the API key.

The value depends on the quota type

A percentage is served as stored. 0.85 means 85%. Multiply it yourself if you display a percentage.
0.85 and 42.0 look alike, so a number on its own does not tell you whether it is a ratio or an absolute value. What distinguishes them is the format of standard.value on the fields endpoint — currency, percentage or float. Read it once per quota before loading numbers into a typed column. An amount carries the currency of its own value, so a quota whose people are paid in different currencies returns rows with different currencies inside the same page. Changing a quota’s type flips standard.value for every existing row without touching any value. last_modified_after will not surface that; the schema_hash on the fields endpoint will.

Pagination

Pages are linked: every response carries a next_url that already includes your limit and any date filters you sent. Follow it until has_more is false.
Two things worth knowing:
  • limit defaults to its maximum, 2000. Omitting it gives you the largest page, not a small one. It is validated rather than capped, so ?limit=5000 returns 400 instead of 2000 rows.
  • Rows come in creation order, not by period and not by user.

Filtering by modification date

last_modified_after and last_modified_before restrict the response to values modified inside a window. Both bounds are inclusive, and they cannot be equal — passing the same datetime twice returns 400.
Always include the timezone in your timestamp, as in the example above. A timestamp without one is interpreted for you, so a client running in another timezone shifts its window on every run and permanently misses the rows in the gap. The modification timestamp is filterable but never returned, and a change to the quota itself — switching its type, for instance — moves no value timestamp at all. Re-walk the whole quota periodically rather than trusting the window alone.

What this endpoint does not do

  • No filter by user or period. To read part of a quota, paginate through it and filter on your side.
  • No writes. Importing quota values is not part of this endpoint.
  • No attainment. Targets only — results come from statements.

Archived quotas stay readable

Archiving a quota in Qobra does not hide it from the API. It stays listed by GET /v2/data-structures — with "status": "archived" — and this endpoint still serves its values. Read status from the discovery response to leave archived quotas out of a sync.

Errors

A 400 is the one you are most likely to meet. Its causes are a limit above 2000, a malformed start_id, and a last_modified_after equal to or later than last_modified_before.

Authorizations

X-API-Key
string
header
required

Your Qobra API key. Generate it from Settings > API Keys in Qobra.

Path Parameters

quota_id
string<ObjectId>
required

ID of a quota, listed with the type 'quota' by /v2/data-structures

Query Parameters

start_id
string<ObjectId>

Start after this quota value ID. This is the only pagination this endpoint supports

limit
integer
default:2000

Number of quota values per page (1-2000)

Required range: 1 <= x <= 2000
last_modified_after
string<date-time>

ISO 8601 datetime - Only return values modified at or after this date (for incremental sync)

last_modified_before
string<date-time>

ISO 8601 datetime - Only return values modified at or before this date

Response

Successfully retrieved the values of the quota. Returns one row per user and period, ordered by id, with pagination metadata for navigating through large quotas.

data
object[]
required

List of quota values, one per user and period

meta
object
required