Form field keys (certhub-key)
CertHub forms are dynamic: fields are generated by a form builder, and the APIs need a way to refer to those fields in a stable format.
This page explains the three identifiers you will see in integration code.
1. Opaque form keys
When you export or write records, the payload contains the record data keyed by opaque form keys such as textarea_rs0jwr.
These keys are not stable:
- they can change when a KT or form is edited
- they are not meaningful on their own
2. certhub-key
To make integrations resilient to form changes, CertHub lets you assign a stable semantic identifier to each field via certhub-key.
Each form component in the schema can carry a certhub-key in its properties object:
{
"label": "Release Number",
"key": "textfield_xd6x5",
"properties": {
"certhub-key": "release-number"
}
}
If certhub-key is not present, you can still find the field, but you will have to fall back to less stable identifiers such as labels or titles.
Write path: on any knowledge topic you create records into (for example a Release Record KT), set certhub-key on every field your integration writes. Cadence requires release-number, release-id, generated-at, evidence-url, and details on that KT.
Read path: inbound requirement topics may not have certhub-key on every field yet. Prefer certhub-key when present; fall back to labels. Do not treat missing keys on export-only KTs as a blocker the way missing keys on a write KT are.
3. Field labels and titles
Labels are useful for humans, but they can be renamed over time. Do not use them as the stable anchor for automation if certhub-key is available.
The mapping you implement
Your integration typically does this:
- Fetch the KT schema from the Tech Doc API (
knowledge_topic_schema.components) - Build a mapping from
certhub-key(in each component'sproperties) to the component'skey(the opaque form key) - When exporting, rename record
datakeys to your semantic names - When writing, translate your semantic names back to the opaque form keys required by the Records API
Minimal example:
key_map = {}
for component in schema.get("components", []):
form_key = component.get("key")
if not form_key:
continue
ck = component.get("properties", {}).get("certhub-key")
if ck:
key_map[ck] = form_key
value = record["data"][key_map["evidence-url"]]