Skip to main content
Use the Metadata API to define namespaced fields before attaching typed values to a recording or another supported entity. Sources separate fields that may share a name but come from different systems or represent different entities. All endpoints on this page accept either a user access token or an organization API key. The examples use an organization API key:
Base URL:

Resource model

A source is an organization-scoped namespace with a public UUID, a type, and an externalEntityName. Within an organization, the pair of type and externalEntityName identifies the source definition. Sources of different types can use the same entity name without colliding. A field belongs to exactly one source and is identified by its own public UUID. For example, separate API sources named accounts and subscriptions can each define a field named status without colliding. Field names need to be unique only within their source. All sourceId and fieldId values in this API are public UUIDs. Unknown, inaccessible, and cross-organization UUIDs return 404 Not Found rather than exposing another organization’s resources.

The recordings source

BuildBetter maintains one canonical source per organization with:
BuildBetter creates this source on demand instead of prepopulating it when the organization is provisioned. GET /v3/rest/metadata/sources ensures the source exists before returning results, so you can discover its public UUID and define recording fields before creating the organization’s first recording. POST /v3/rest/recordings also ensures it exists when creating a recording. BuildBetter owns this source’s name, so it cannot be recreated or renamed. You can create and rename fields beneath it because it is API-typed. POST /v3/rest/recordings always creates one canonical metadata record in this source. Recording create accepts record.values[].fieldId, but it does not accept sourceId; every supplied field must belong to the canonical recordings source.

Endpoint overview

Deletion is not exposed. Removing definitions that already have values requires separate lifecycle handling.

List sources

GET /v3/rest/metadata/sources

Query parameters

Success response

200 OK. The endpoint returns an array for the requested page.
managedBy can be customer, integration, or buildbetter. Provider-managed sources retain their provider type, while sources created through this API always have type api. Listing sources creates the canonical API-typed recordings source on demand if it does not exist yet. Concurrent list and recording-create requests still resolve to the same organization-scoped source. Request successive pages until a page contains fewer than limit results.

Create a source

POST /v3/rest/metadata/sources

Creates an API-typed namespace for an external entity.
externalEntityName is required, is trimmed, and must contain from 1 to 255 characters. The server sets type to api; the request cannot select an integration provider type.

Success response

201 Created
Creating an API source whose entity name is already used by another API source in the organization returns 409 Conflict. A provider source of another type may use the same entity name. The name recordings is reserved for the canonical BuildBetter-managed API source and also returns 409 Conflict. If a create response is lost, list sources and match externalEntityName before retrying. Retrying an already successful create returns 409 Conflict rather than creating a duplicate.

Get a source

GET /v3/rest/metadata/sources/{sourceId}

Returns 200 OK with the same source shape returned by create. An unknown or inaccessible sourceId returns 404 Not Found.

Update a source

PATCH /v3/rest/metadata/sources/{sourceId}

Renames a customer-managed API source.
The complete request body is { "externalEntityName": string }. type, managedBy, and isCanonicalRecordingSource are server-owned and cannot be patched. Returns 200 OK with the updated source.

List fields in a source

GET /v3/rest/metadata/sources/{sourceId}/fields

page defaults to 1; limit defaults to 10 and can be from 1 to 100.

Success response

200 OK. The endpoint returns an array for the requested page.
An unknown or inaccessible source UUID returns 404 Not Found. Request successive pages until a page contains fewer than limit results.

Create a field

POST /v3/rest/metadata/sources/{sourceId}/fields

name is required, is trimmed, and must contain from 1 to 255 characters. type is required and must be one of the field types below.

Success response

201 Created
Field names must be unique within one source. The same name can be used in a different source without conflict. Retrying an already successful create with the same source and name returns 409 Conflict.

Get a field

GET /v3/rest/metadata/fields/{fieldId}

Returns 200 OK with the same field shape returned by create. An unknown or inaccessible fieldId returns 404 Not Found.

Update a field

PATCH /v3/rest/metadata/fields/{fieldId}

Renames a field in an API-typed source.
The complete request body is { "name": string }. A field’s type and sourceId are immutable through this API. Returns 200 OK with the updated field.

Field types and values

Field definitions use one of these immutable types. Values are validated when an owning resource, such as a recording, creates its metadata record. Every type also accepts null. BuildBetter returns public values in their declared JSON types rather than as storage strings. A value that does not match the field definition returns 422 Unprocessable Entity from the owning resource endpoint.

Use recording fields

First find the canonical source by listing sources and selecting the item where isCanonicalRecordingSource is true. Create or list fields beneath its public id, then include their public field UUIDs in recording create:
The recording request deliberately omits sourceId. BuildBetter resolves the canonical API-typed recordings source and rejects a field from any other source with 422 Unprocessable Entity. See Create a recording for the complete request.

Common errors

REST errors include an HTTP status plus the standard error response fields statusCode, timestamp, path, error, and, when available, message. Handle status codes rather than matching human-readable messages. Across all metadata endpoints:
  • 401 Unauthorized means authentication is missing or invalid.
  • 403 Forbidden means the definition is visible but read-only for this API operation.
  • 404 Not Found also covers inaccessible and cross-organization UUIDs.
  • 409 Conflict indicates a source or field uniqueness collision.
Invalid requests do not create partial definitions. Correct the request and retry it.