Get Fields Schema
curl --request GET \
--url https://api.qobra.co/v2/data-structures/{table_id}/fields \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.qobra.co/v2/data-structures/{table_id}/fields"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.qobra.co/v2/data-structures/{table_id}/fields', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.qobra.co/v2/data-structures/{table_id}/fields",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.qobra.co/v2/data-structures/{table_id}/fields"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.qobra.co/v2/data-structures/{table_id}/fields")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.qobra.co/v2/data-structures/{table_id}/fields")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"schema_hash": "a3f9d8c7b2e1",
"count": 6,
"fields": [
{
"api_key": "standard.id",
"name": "ID",
"type": "string",
"format": null,
"origin": "standard",
"created_at": "2024-01-01T00:00:00Z",
"currencies": null,
"enum_values": null,
"frequency": null,
"properties": null
},
{
"api_key": "standard.user",
"name": "User",
"type": "object",
"format": "user_reference",
"origin": "standard",
"created_at": "2024-01-01T00:00:00Z",
"currencies": null,
"enum_values": null,
"frequency": null,
"properties": {
"id": {
"type": "string",
"required": true
},
"email": {
"type": "string",
"required": true
}
}
},
{
"api_key": "standard.date",
"name": "Date",
"type": "string",
"format": "date",
"origin": "standard",
"created_at": "2024-01-01T00:00:00Z",
"currencies": null,
"enum_values": null,
"frequency": null,
"properties": null
},
{
"api_key": "standard.total_commission",
"name": "Total Commission",
"type": "object",
"format": "currency",
"origin": "standard",
"created_at": "2024-01-01T00:00:00Z",
"currencies": [
"USD",
"EUR"
],
"enum_values": null,
"frequency": null,
"properties": {
"value": {
"type": "number",
"required": true
},
"currency": {
"type": "string",
"required": true
}
}
},
{
"api_key": "standard.status",
"name": "Status",
"type": "string",
"format": "enum",
"origin": "standard",
"created_at": "2024-01-01T00:00:00Z",
"currencies": null,
"enum_values": [
"paid",
"pending",
"validated",
"cancelled"
],
"frequency": null,
"properties": null
},
{
"api_key": "custom.quota_attainment",
"name": "Quota Attainment",
"type": "number",
"format": "percentage",
"origin": "custom",
"created_at": "2024-01-15T10:30:00Z",
"currencies": null,
"enum_values": null,
"frequency": null,
"properties": null
}
]
}Discovery
Get Fields Schema
Retrieves the complete schema (field names, types, formats) for a specific data structure. Essential for understanding what fields are available before extracting data. Accepts the id of a reporting table or of a quota.
GET
/
v2
/
data-structures
/
{table_id}
/
fields
Get Fields Schema
curl --request GET \
--url https://api.qobra.co/v2/data-structures/{table_id}/fields \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.qobra.co/v2/data-structures/{table_id}/fields"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.qobra.co/v2/data-structures/{table_id}/fields', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.qobra.co/v2/data-structures/{table_id}/fields",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.qobra.co/v2/data-structures/{table_id}/fields"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.qobra.co/v2/data-structures/{table_id}/fields")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.qobra.co/v2/data-structures/{table_id}/fields")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"schema_hash": "a3f9d8c7b2e1",
"count": 6,
"fields": [
{
"api_key": "standard.id",
"name": "ID",
"type": "string",
"format": null,
"origin": "standard",
"created_at": "2024-01-01T00:00:00Z",
"currencies": null,
"enum_values": null,
"frequency": null,
"properties": null
},
{
"api_key": "standard.user",
"name": "User",
"type": "object",
"format": "user_reference",
"origin": "standard",
"created_at": "2024-01-01T00:00:00Z",
"currencies": null,
"enum_values": null,
"frequency": null,
"properties": {
"id": {
"type": "string",
"required": true
},
"email": {
"type": "string",
"required": true
}
}
},
{
"api_key": "standard.date",
"name": "Date",
"type": "string",
"format": "date",
"origin": "standard",
"created_at": "2024-01-01T00:00:00Z",
"currencies": null,
"enum_values": null,
"frequency": null,
"properties": null
},
{
"api_key": "standard.total_commission",
"name": "Total Commission",
"type": "object",
"format": "currency",
"origin": "standard",
"created_at": "2024-01-01T00:00:00Z",
"currencies": [
"USD",
"EUR"
],
"enum_values": null,
"frequency": null,
"properties": {
"value": {
"type": "number",
"required": true
},
"currency": {
"type": "string",
"required": true
}
}
},
{
"api_key": "standard.status",
"name": "Status",
"type": "string",
"format": "enum",
"origin": "standard",
"created_at": "2024-01-01T00:00:00Z",
"currencies": null,
"enum_values": [
"paid",
"pending",
"validated",
"cancelled"
],
"frequency": null,
"properties": null
},
{
"api_key": "custom.quota_attainment",
"name": "Quota Attainment",
"type": "number",
"format": "percentage",
"origin": "custom",
"created_at": "2024-01-15T10:30:00Z",
"currencies": null,
"enum_values": null,
"frequency": null,
"properties": null
}
]
}Overview
This endpoint returns the complete field schema for a specific data structure. It tells you what fields are available, their types, formats, and constraints — enabling dynamic adaptation to your data structure.Schema discovery is a V2 superpower. You no longer need to guess what
fields exist — the API tells you.
This endpoint accepts the id of a reporting table or of a quota, and only
from your company’s live environment. A
table_id that belongs to a
sandbox environment returns 404 Not Found, even if the id was copied from
the Qobra app. Discover valid ids with
GET /v2/data-structures.Understanding API key prefixes
Everyapi_key starts with a prefix that indicates its origin:
| Prefix | Meaning | Description |
|---|---|---|
standard. | Standard Metric | Built-in Qobra fields (commission amounts, periods, status) |
custom. | Custom Metric | Your custom commission metrics and calculations |
datatable. | Data Table | Fields from external sources (CRM, databases) |
standard.fields are consistent across all Qobra accountscustom.anddatatable.fields are specific to your account- Always use
api_key(notname) as your code identifier
Best practice: Map by
api_key, display by name. Use api_key in your
database/code, but show users the human-readable name.Quota fields are fixed
A quota always exposes the same fivestandard. fields, whatever its
configuration:
api_key | Type | Format | Notes |
|---|---|---|---|
standard.id | string | — | The quota value id |
standard.user | object | user_reference | Who the target is for |
standard.period | string | period | Carries frequency |
standard.value | varies | varies | The target, see below |
standard.source | string | enum | local or integration |
standard.period carries a frequency field — monthly, quarterly,
semesterly or annually — which tells you how long one period covers and how
to read the period strings the values endpoint returns. It is the only place the
frequency is stated.
Only standard.value changes, and it follows the type of the quota:
| Quota type | Type | Format | Extra |
|---|---|---|---|
amount | object | currency | Carries currencies |
percentage | number | percentage | — |
float | number | float | — |
These five keys never change. They do not derive from the column mapping
of an integration, so a quota synchronized from your CRM exposes exactly the
same keys as a quota filled in Qobra. Read the values with
GET /v2/quotas/{quota_id}/values.Field types reference
Type: number
Used for: Numeric values (integers, decimals, percentages)
Formats:
"percentage": Decimal percentage (0.85 = 85%)"float": Floating point number
{
"custom.quota_attainment": 0.87,
"datatable.deal_size": 50000
}
Type: string
Formats:
"enum": Limited set of allowed values"period": A quota period, whosefrequencyfield says how long it coversnull(no format): Free text
{
"standard.status": "paid",
"datatable.account_name": "Acme Corporation"
}
Type: object
Used for: Nested structures (currency amounts, user reference, record reference)
Includes: properties field describing nested structure
In extracted data:
{
"standard.user": {
"id": "507f191e810c19729de860ea",
"email": "john.doe@company.com"
},
"standard.record": {
"id": "507f191e810c19729de860ea",
"name": "John Doe"
},
"standard.total_commission": {
"value": 4250.0,
"currency": "USD"
}
}
Schema hash: detecting changes
Theschema_hash is a cryptographic fingerprint of your schema. It changes when a field is added, removed, or modified.
Store
schema_hash after each successful sync to detect schema drift in
production.Recommended workflow: Fetch fields at the start of each extraction,
compare
schema_hash to your stored value, and only remap fields when it
changes.Best practices
Cache schema during session
Fetch schema once, reuse for the entire extraction.
Always use api_key
Never use
name for field identification — it doesn’t display when extracting
data.Monitor schema_hash
Store hash and compare on each run to detect changes.
Validate before extraction
Check for required fields before long extractions.
Call this endpoint once per extraction session. Cache the schema for the
duration of your data sync.
Authorizations
Your Qobra API key. Generate it from Settings > API Keys in Qobra.
Path Parameters
Unique identifier of the data structure, reporting table or quota (from /v2/data-structures)
Response
Successfully retrieved the fields schema for the data structure. Returns an object with the schema hash and an array of fields.
Was this page helpful?