Data Hub API
The runtime and management routes of Data Hub, a curl example, and the error format and codes.
Beta
Data Hub is in Beta. It is off by default; an administrator turns it on per tenant.
Data Hub has two sets of routes:
- Runtime routes under
/api/v1/runtime/data-hubfor running automations. They take an execution token (vpx_rt_...) and address entities by name. - Management routes under
/api/v1/tenants/{tenantId}/workspaces/{workspaceId}/data-hubfor the web app and your own tools. They address entities by id.
See API overview and Authentication.
Runtime routes#
| Route | What it does |
|---|---|
GET entities |
The workspace's entities |
GET entities/{entity} |
One entity's fields |
GET entities/{entity}/json-schema |
The JSON Schema of a record |
POST entities/{entity}/records/query |
One page of records |
GET entities/{entity}/records/{id} |
One record |
POST entities/{entity}/records |
Create ({data, idempotencyKey?}). Answers 201. |
POST entities/{entity}/records/upsert |
Create or update by a unique field ({keyField, data}). Answers 201 when created, 200 when updated. |
PATCH entities/{entity}/records/{id} |
Change the fields sent ({data, revision?}) |
DELETE entities/{entity}/records/{id} |
Delete, where the entity allows automations to |
Try it with curl#
Outside a job, a design-time run gives you an execution token:
BashCopyO=https://orchestrator.example.com; T=<tenant id>; W=<workspace id>
RUN=$(curl -s -X POST "$O/api/v1/tenants/$T/design-time-runs" \
-H "Authorization: Bearer $VELOPHEX_API_KEY" -H "Content-Type: application/json" \
-d "{\"workspaceId\":\"$W\"}")
RT=$(echo "$RUN" | jq -r .runtimeToken); JOB=$(echo "$RUN" | jq -r .jobId)
curl -s -X POST "$O/api/v1/runtime/data-hub/entities/Invoice/records/upsert" \
-H "Authorization: Bearer $RT" -H "Content-Type: application/json" \
-d '{"keyField":"invoiceNumber","data":{"invoiceNumber":"INV-1001","amount":"1250.00","status":"open"}}'
curl -s -X POST "$O/api/v1/runtime/data-hub/entities/Invoice/records/query" \
-H "Authorization: Bearer $RT" -H "Content-Type: application/json" \
-d '{"filter":{"field":"status","op":"eq","value":"open"},"sort":[{"field":"amount","dir":"desc"}]}'
curl -s -X POST "$O/api/v1/tenants/$T/design-time-runs/$JOB/end" \
-H "Authorization: Bearer $VELOPHEX_API_KEY" -H "Content-Type: application/json" -d '{"outcome":"Succeeded"}'
In JSON, a sort is a list: [{"field":"amount","dir":"desc"},{"field":"invoiceNumber"}].
Management routes#
| Area | Routes |
|---|---|
| Entities | GET, POST entities; GET, PATCH, DELETE entities/{entityId}; PUT entities/{entityId}/automation-settings; GET entities/{entityId}/versions; GET entities/{entityId}/json-schema |
| Schema changes | POST entities/{entityId}/schema-changes/preview; POST entities/{entityId}/schema-changes |
| Records | POST entities/{entityId}/records/query; POST entities/{entityId}/records; POST entities/{entityId}/records/upsert; POST entities/{entityId}/records/batch; GET, PATCH, DELETE entities/{entityId}/records/{recordId}; GET entities/{entityId}/records/{recordId}/history |
| Import and export | POST entities/{entityId}/imports (multipart: file and options); GET entities/{entityId}/imports/{importId}; GET entities/{entityId}/imports/{importId}/errors; POST entities/{entityId}/exports; GET entities/{entityId}/exports/{exportId}; GET entities/{entityId}/exports/{exportId}/content |
| Choice sets | GET, POST choice-sets; GET, PATCH, DELETE choice-sets/{choiceSetId} |
A batch takes at most 1,000 operations and 16 MiB. The full request and response shapes are in the Orchestrator's OpenAPI document.
Errors#
Every refusal is application/problem+json with:
code: thedh_*coderetryable,causeandfixerrorskeyed bydata.<field>on a 422,pointeron a filter error, andfieldon a unique violation
| Code | HTTP | Retry | Meaning |
|---|---|---|---|
dh_filter_invalid |
400 | No | Unknown field, an operator the type does not allow, a wrong value type, or a filter limit exceeded |
dh_cursor_invalid |
400 | Yes | The cursor expired or no longer matches the query. Start from the first page. |
dh_access_denied |
403 | No | The role lacks the permission, or the job is an agent run |
dh_delete_disabled |
403 | No | The entity does not allow automations to delete records |
dh_entity_not_found |
404 | No | No entity with that name in the job's workspace |
dh_record_not_found |
404 | No | The record id is wrong or the record was deleted |
dh_unique_violation |
409 | No | Another record holds the same unique value |
dh_revision_conflict |
409 | Yes | Someone updated the record after the revision you sent |
dh_schema_changed |
409 | Yes | The schema changed while the record was written |
dh_limit_reached |
409 | No | A tenant or entity limit is reached |
dh_idempotency_key_reused |
409 | No | The same idempotency key with other data |
dh_schema_change_unsafe |
409 | No | Existing records break the new rule |
dh_import_running |
409 | Yes | An import or export is already running for the entity, or five for the tenant |
dh_import_too_large |
413 | No | The import file is over 20 MB or 100,000 rows |
dh_batch_too_large |
413 | No | The batch is over 1,000 operations or 16 MiB |
dh_result_too_large |
413 | No | Fetch all passed 10,000 records or 64 MiB |
dh_validation_failed |
422 | No | A required field is missing, or a value has the wrong type or breaks a rule |
dh_field_not_indexed |
422 | No | An unindexed filter on more than 50,000 records |
dh_query_too_expensive |
422 | No | The query could not use an index and ran past the time limit |
dh_key_field_not_unique |
422 | No | Create or update named a key field that is not unique |
plan_limit_reached |
409 | No | The organization holds as many records as its plan allows |
service_disabled |
403 | No | Data Hub is off for the tenant |
Runtime routes
Try it with curl
Management routes
Errors