API Examples
☁️

API Examples

Computed URL

Computed URL

https://<org>.bettrdata.io:1337

This is the default BettrData API URL format. BettrData also supports deployments where the backend API is exposed on standard HTTPS port 443 using an additional backend domain. Use the API hostname and port supplied for your deployment.

Examples

Authentication (2.0)

Endpoint

/auth/token

Description

Get bearer token

HTTP Method

POST

Authentication

  • Required: Yes
  • Type: See Request Body
  • Scope / Permissions (if applicable):

Request

Headers

Name
Required
Type
Description
X-Amz-Target
Yes
String
AWSCognitoIdentityProviderService.InitiateAuth
Content-Type
Yes
String
application/x-amz-json-1.1

Request Body

{
    "AuthFlow": "USER_PASSWORD_AUTH",
    "ClientId": "<client_id>",
    "AuthParameters": {
      "USERNAME": "<username>",
      "PASSWORD": "<password>"
    }
}

Response

Success Response

Status Code: 200 OK

{
	"token":"jwt_token_here",
	"expires_in":3600
}

Field
Type
Description
token
String
JWT access token
expires_in
Number
Expiry time in seconds

Error Responses

Status Code
Message
When it Happens
400
Bad Request
Invalid input
401
Unauthorized
Invalid credentials
403
Forbidden
Insufficient permissions
500
Server Error
Unexpected failure

Notes / Edge Cases

  • Tokens expire after 1 hour
  • Rate limited to 100 requests/minute
  • This endpoint is idempotent

Example Request

BD Ingest: Prerequisites

Required permissions

  • BDIngest:Files:View
  • BDIngest:Files:Edit
  • Access to the target data owner
  • Access to the target convert type

Required deployment values

export BETTRDATA_API_URL="https://<org>.bettrdata.io:1337"
export BETTRDATA_TOKEN="<bearer-token>"

For deployments using a dedicated backend domain on port 443, set BETTRDATA_API_URL to the backend URL supplied for that deployment.

Required command-line tools

  • curl
  • jq
  • A POSIX-compatible shell for the provided examples

These examples operate on existing files, mappings, and convert types configured in BettrData. The API user must have access to each referenced resource.

BD Ingest: Search Datafile

BD Ingest permissions and preconditions

  • Searching requires BDIngest:Files:View and access to the relevant data owner.
  • Preparing and running a conversion additionally requires BDIngest:Files:Edit and access to the selected convert type.
  • The selected file must already be processed.
  • The selected file must not be locked by another user.
  • A missing assigned type does not necessarily prevent conversion when a compatible mapping is selected explicitly.

Filename search example

Optional reduced output:

jq '
  if type == "array" then
    map({_id, fileName, belongsTo, types, status})
  else
    {error: "Expected a datafile array", response: .}
  end
' <<<"$DATAFILES"

Fetch the selected file

export DATAFILE_ID="<datafile-id>"

DATAFILE="$(curl --fail-with-body --silent --show-error \
  "$BETTRDATA_API_URL/datafile/$DATAFILE_ID" \
  -H "Authorization: Bearer $BETTRDATA_TOKEN" \
  -H "Accept: application/json")"

Endpoint

/datafile

Description

Find a datafile

HTTP Method

GET

Authentication

Required: Yes

  • Type: Bearer Token
  • Scope / Permissions (if applicable):

Request

Headers

Name
Required
Type
Description
Authorization
Yes
String
Bearer <token>
Content-Type
Yes
String
application/json

Query Parameters

Name
Required
Type
Description
where
No
Object
Generally follows mongodb query structure, see query documents
sort
No
Object
limit
No
Number
Number of records to limit in the response

Response

Success Response

Status Code: 200 OK

[
	{DatafileModel}
]

Error Responses

Status Code
Message
When it Happens
400
Bad Request
Invalid input
401
Unauthorized
Invalid credentials
403
Forbidden
Insufficient permissions
500
Server Error
Unexpected failure

BD Ingest: Resolve the Conversion Mapping

A convert run requires an existing field mapping. When the file has an assigned type, first attempt to find the exact mapping associated with that type.

When no exact mapping exists, /convert/getOneBy may return an empty response with HTTP 200. List compatible mappings by data owner, format, and field count:

Do not choose a mapping solely because its field count matches the input file. Confirm that its field mapping, convert type, and qualifier are correct.

ownerMatches, formatMatches, and lengthMatches must all be true.

BD Ingest: Resolve the Convert Type

Load the selected mapping's convert type and verify that it is accessible to the API user.

If no accessible convert type is returned, stop. The convert type may not exist, or the API user's group may not have access to it.

BD Ingest: Load Global Conversion Snippets

The standard UI conversion flow includes compiled global snippets in the convert-run request.

Load the snippets immediately before constructing the convert-run request.

BD Ingest: Prepare the Datafile for Conversion

Refetch the file immediately before updating it:

DATAFILE="$(curl --fail-with-body --silent --show-error \
  "$BETTRDATA_API_URL/datafile/$DATAFILE_ID" \
  -H "Authorization: Bearer $BETTRDATA_TOKEN" \
  -H "Accept: application/json")"

RUN_AT="$(date -u +'%Y-%m-%dT%H:%M:%SZ')"

Prepare the complete data-file document:

Update the file:

curl --fail-with-body --silent --show-error \
  -X PATCH "$BETTRDATA_API_URL/datafile/$DATAFILE_ID" \
  -H "Authorization: Bearer $BETTRDATA_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  --data-binary "$PREPARED_DATAFILE"
This operation sends the complete data-file document and may overwrite concurrent updates. Refetch the file immediately before preparing it, and ensure that no other user or process is modifying it.

Incrementing version alone must not be treated as a guarantee of optimistic locking.

The example removes status.deleted. Continue only when reactivating a deleted file is intentional.

BD Ingest: Submit a Convert Run

Build the convert-run request:

Submit the run:

A successful HTTP response means that the run was accepted and queued. It does not mean conversion has completed.

Priority 3 is used only when neither the data file nor convert type defines a priority.

BD Ingest: Check Convert Status

Check the convert-run document:

curl --fail-with-body --silent --show-error \
  "$BETTRDATA_API_URL/convertrun/$CONVERT_RUN_ID" \
  -H "Authorization: Bearer $BETTRDATA_TOKEN" \
  -H "Accept: application/json" \
  | jq '{_id, status, output}'

status.exitCode: 0 means that the convert process completed successfully.

Check the corresponding file state:

curl --fail-with-body --silent --show-error \
  "$BETTRDATA_API_URL/datafile/$DATAFILE_ID" \
  -H "Authorization: Bearer $BETTRDATA_TOKEN" \
  -H "Accept: application/json" \
  | jq '.status.converted'

BD Ingest: Troubleshooting

Result
Likely cause or action
API 401
The bearer token is missing, expired, or malformed.
API 403
The user lacks BDIngest:Files:View, BDIngest:Files:Edit, data-owner access, or convert-type access.
Datafile search returns 403
Grant BDIngest:Files:View and verify data-owner access.
Exact mapping returns an empty response with HTTP 200
No mapping matches the assigned type and qualifier; list compatible mappings.
Convert-type result is empty
The convert type is missing or the user's group cannot access it.
Selected mapping fails compatibility checks
The mapping belongs to a different owner, format, or field length.
Convert remains queued
Processing may be paused or the convert worker may be unavailable.
status.exitCode is nonzero
Conversion failed; review the applicable conversion log or report.
Datafile update overwrites another change
The file was modified concurrently; refetch and follow the approved concurrency process.

After the required convert runs complete successfully, the resulting outputs may be used in the merge-run workflows documented below.

Create: Merge Run

Endpoint

/mergerun

Description

Create a Merge job to union, omit, select, or join multiple feeds together.

HTTP Method

POST

Authentication

  • Required: Yes
  • Type: Bearer Token
  • Scope / Permissions (if applicable):

Request

Headers

Name
Required
Type
Description
Authorization
Yes
String
Bearer <token>
Content-Type
Yes
String
application/json

Query Parameters

Name
Required
Type
Description

Path Parameters

Name
Required
Type
Description

Request Body Examples

Example 1 — Sequential UNION (priority “waterfall” across 3 sources)

Example 2 — Base UNION + JOIN match flags (exists-style tagging)

Example 3 — Suppression OMIT + equitable split across 2 UNION sources (same priority)

Top Level

Field
Type
Description
convertsToMerge
ConvertsToMerge []
Merge Item Entry
convertType
String
Output Schema / Process to apply
description
String
Freeform text description
ready
Boolean
Run now if set to true

ConvertsToMerge

Field
Type
Description
fileId
String
Unique ID
path
String
Full path to convert output / merge input
fileName
String
Filename as initially received
mergeInputType
Enumeration
UNION | OMIT | SELECT | JOIN
mergeDetails
MergeDetails {}
Complex object describing intra and inter file behavior / relationships

Additional Notes:

  • Union - core set of records to be “acted on”
  • Omit - records to be removed based on common key to Union
  • Select - records to be selected based on common key to Union
  • Join - file use to append specific values based on common key to Union

MergeDetails

Field
Type
Description
priority
Integer
File level priority (lower value, higher priority);
suppressPriorSelections
Boolean
Determines if prior selected records should be suppressed; Defaulted to true
segments
Segement Item []
Ordered list defining the segments within a single file
tag
Tag {}
Complex object defining field and default values for JOIN mergeInputType

Segments

Field
Type
Description
name
String
Segment name / identifier
window
Integer
Isolated quantity
take
Take {}
Complex object describing how to select records within the window

Take

Field
Type
Description
strategy
Enumeration
ALL | TOP | EVEN_NTH
count
Integer
Number of records selected from within the segment window based on strategy.

Tag

Field
Type
Description
outputField
String
Field to populate
trueValue
String
Default value for a match
falseValue
String
Default value for no match

Response

Success Response

Status Code: 200 OK

{
	<updated object w/ ID here>
}

Error Responses

Status Code
Message
When it Happens
400
Bad Request
Invalid input
401
Unauthorized
Invalid credentials
403
Forbidden
Insufficient permissions
500
Server Error
Unexpected failure

Notes / Edge Cases

Dedupe

  • Ability to group by primary key (usually ids dupes) - CONVERT
  • Ability to sort within group (usually by score/file) - REDUCE (add)
  • Ability to select top record - REDUCE

Nth

  • Ability to nth (post sort, ie score) by priority (file) - Deterministic:
  • Distributed nth (by sort order)
  • Top (by sort order)
  • Distribute even across dupes, then distributed nth across remainder

Select

  • Ability to JOIN flag multiple files (flags) to a single

Suppress

  • Ability to OMIT multiple files (flags) to a single

Flag

Create/Update BD Select Order

Endpoint

Post /audience/create

Put /audience/update/:orderId

Description

Create a BD Select Order to filter data

HTTP Method

POST

Authentication

  • Required: Yes
  • Type: Bearer Token
  • Scope / Permissions (if applicable):

Request

Headers

Name
Required
Type
Description
Authorization
Yes
String
Bearer <token>
Content-Type
Yes
String
application/json

Query Parameters

Name
Required
Type
Description

Path Parameters

Name
Required
Type
Description

Request Body Examples

Example 1 — BDS Order with Segments (without deduplication and suppression)

Example 2 — BDS Order with suppression and deduplication

BDSOrder

Field
Type
Description
name
String
Order’s Name
description
String
Order’s description
belongsTo
String
Data Owner ID
createdBy
String
User email
dataSource
String
BDS Source ID
audienceSegments
AudiencesSegment[]
Field Segments
suppressionRules
SuppressionRule[]
Supp Rules (If empty, suppression is disabled)
autoUpdateAiDescription(Optional)
Boolean | null
Update desc automatically
deduplicateSegments
Boolean
enable/disable deduplication
deduplicationKeyFields
DeduplicationField[]
Fields for deduplication

DeduplicationField

Field
Type
Description
fieldId
String
Existing BDS Source Field ID
fieldName
String
Existing BDS Source Field Name ID

SuppressionRule

Field
Type
Description
suppkey
Object
Target Suppression Field
type
SuppressionRuleScopes(Enum)
type of scope (”all-exports”, “specific-export”, “daterange”)
exports (Optional, base on supp type)
String[] | null
(If “specific-export” scope selected) IDs list of previous exportation results
dateRule (Optional, base on supp type)
DateRangeRule | null
(If “daterange” scope selected) Suppresion by Date Range Filters

SuppressionRule.suppkey

Field
Type
Description
_id
String
Existing BDS Source Field ID
name
String
Existing BDS Source Field Name ID

SuppressionRule.DateRangeRule

Field
Type
Description
operator
EDateRangeOperators(Enum)
Type of date search across previous exports ("date-range" | "single-date" | "after-date" | "before-date" | "before-equal-date" | "after-equal-date" | "dynamic-range-days-weeks-months”)
startDate (Optional, base on operator)
String
Begining date value
endDate (Optional, base on operator)
String
(If “date-range” operator selected) Ending Date Value
dynamicRangeNumber (Optional, base on operator)
Number
(If “date-range” operator selected) Number of units to search previous exports
dynamicRangeType (Optional, base on operator)
EDynamicRangeOptions(Enum)
(If “date-range” operator selected) Unit to Select previous export from lasts: ("weeks" | "months" | "days" | "quarters" | "years”)

audienceSegment

Field
Type
Description
name
String
Name of the segment, can’t be duplicated
aiDescription(Optional)
String | null
Written AI prompt by the user to generate the segment content base in the existing BDS source fields
limit
Number
Limit of records per segment
includedFields
BDSField[]
Filters to match data Conjunctively (AND)
excludedFields
BDSField[]
Filters to omit data Conjunctively (AND)

BDSField

Field
Type
Description
_id
String
Existing BDS Source Field ID
name
String
Existing BDS Source Field Name
groupTags
String[]
Tags to group fields across segments disjunctively (OR) ,fields can be added simultaneously into different groups
displayType
String
Type of Widget and DataType ⇒ ("number-slider" | "number-input" | "range-slider" | "selection-unique" | "selection-multi" | "boolean" | "data-relation" | "multi-text" | "date-picker" | "date-range-selector" | "contains" | "zip-code-radius" | "address-radius" | "client-cid" | "sql-variable" | "case-statement") [This have to match with existing BDS Field]
showAsRange (Optional)
Boolean
if display type equals "number-slider" Toggle to range slider widget in front end
showAsSingleSlider(Optional)
Boolean
if display type equals "range-slider" Toggle to single slider widget in front end
value
Any
This Atributte change depending of the selected displayType (Check below data types)

"number-input" value

Field
Type
Description
numberValue
Number
logicalOperator
String

"number-slider" value

Field
Type
Description
min(Required if showAsRange is true)
Number
Starting Range Match Value
max(Required if showAsRange is true)
Number
Ending Range Match Value
numberValue(Required if showAsRange is not true)
Number
Single Match Value
logicalOperator(Required if showAsRange is not true)
String
filter operator (”equals”, “less-than”, “less-than-or-equals”, “greater-than”, “greater-than-or-equals”)

"range-slider" value

Field
Type
Description
min(Required if showAsSingleSlider is not true)
Number
Starting Range Match Value
max(Required if showAsSingleSlider is not true)
Number
Ending Range Match Value
numberValue(Required if showAsSingleSlider is true)
Number
Single Match Value
logicalOperator(Required if showAsSingleSlider is true)
String
filter operator (”equals”, “less-than”, “less-than-or-equals”, “greater-than”, “greater-than-or-equals”)

“selection-unique” value

(Value must exist in existing BDS Field)

Field
Type
Description
label
String
Option Selected label
value
String
Option Selected Value

“selection-multi” value

A List of values (Values must exist in existing BDS Field)

Field
Type
Description
label
String
Option Selected label
value
String
Option Selected Value

“selection-multi” value

Can be empty

“data-relation” value

An object or a list of objects that must contains FileID

“multi-text” value

A list of string values

“date-range-selector” value

Is the same DateRangeRule object

“contains” value

A list of string values

On each value you can use “%” char for LIKE statement operator

“%son” → Match with any value that ends in “son”

“Jeff%” → Match with any value that starts with “Jeff”

“%fer%” → Match with any value that contains “fer”

If you don’t add operator it will added at both sides

“Jefferson” → “%Jefferson%”

Example Field Value: [”Jeff%”, “%son”, “%fer%” , … , … , …]

“client-cid” value

A list of DataOwners’ IDs

Enumerations

SuppressionRuleScopes

Value
Type
Description
all-exports
String
Suppress all previous exports
specific-export
String
Suppress an specific list of exports
daterange
String
Suppress an specific list of exports created within an specific date

EDateRangeOperators

Value
Type
Description
date-range
String
Suppress exports between 2 dates
single-date
String
Suppress exports created on a specific date
after-date
String
Suppress exports created after an specific date
before-date
String
Suppress exports created before an specific date
before-equal-date
String
Suppress exports created before or in an specific date
after-equal-date
String
Suppress exports created after or in an specific date
dynamic-range-days-weeks-months
String
Suppress exports created the last (days, weeks, months, quarters, years)

EDynamicRangeOptions

Value
Type
Description
days
String
weeks
String
months
String
quarters
String
years
String

Response

Success Response

Status Code: 200 OK

{
	<updated object w/ ID here>
}

Error Responses

Status Code
Message
When it Happens
400
Bad Request
Invalid input
401
Unauthorized
Invalid credentials
403
Forbidden
Insufficient permissions
500
Server Error
Unexpected failure

Run BDS Count

Endpoint

/audience/count/:orderId/:queryName

Description

Execute an existing BDS order

HTTP Method

POST

Authentication

Required: Yes

  • Type: Bearer Token
  • Scope / Permissions (if applicable):

Request

Headers

Name
Required
Type
Description
Authorization
Yes
String
Bearer <token>
Content-Type
Yes
String
application/json

Query Parameters

Name
Required
Type
Description
orderId
YES
String
Existing BDS Order ID
queryName
YES
String
Existing BDS Order’s Source query

Request Body

{
	"currentUser": "user@email.com",
}

Success Response

Status Code: 200 OK

{
	"dbOrigin": "SNOWFLAKE",
	"executionHash": "qr4heq8e8w7hdaiefubiaubf"
}

Error Responses

Status Code
Message
When it Happens
400
Bad Request
Invalid input
401
Unauthorized
Invalid credentials
403
Forbidden
Insufficient permissions
500
Server Error
Unexpected failure
400
Data Source Is Disabled
The BDS Source referenced in the BDS Order was disabled
400
Origin database not valid
BDS Source DB does not exists or not supported
400
Some interpolated variables not sent
BDS Source query contains unexisting interpolated variables
400
No Audience Found
400
No DataSource Found
400
No Query Found in DataSource
400
No DataSource Connection Found

Listen BDS Count Status

Endpoint

/audience/streamresult/:executionHash/:dbOrigin

Description

Check count execution status

It returns an streaming response that emits status every 3 seconds

HTTP Method

GET

Authentication

Required: Yes

  • Type: Bearer Token
  • Scope / Permissions (if applicable):

Request

Headers

Name
Required
Type
Value
Authorization
Yes
String
Bearer <token>
Content-Type
Yes
String
application/json

Response

Headers

Name
Value
Transfer-Encoding
chunked

Query Parameters

Name
Required
Type
Description
executionHash
YES
String
Execution ID
dbOrigin
YES
String
Execution database

Request Body

N/A

Success Responses

//When count is started
{"status": "started" }

//Count in progress
{"status": "in progress" }

//Count failed
{"status": "error", "error": "error message" }

//Count end
{"status": "end" }

Error Responses

Status Code
Message
When it Happens
400
Bad Request
Invalid input
401
Unauthorized
Invalid credentials
403
Forbidden
Insufficient permissions
500
Server Error
Unexpected failure
500
Database Origin Not Supported
Invalid Database Origin
“status”: “error”
“message”: “Count Failed”
“status”: “error”
“message”: “<COUNT_ERROR_MESSAGE>”
“status”: “error”
“message”: “Count Canceled”
"status”: “error”
“message”: “Execution not found”

Cancel BDS Count Execution

Endpoint

/audience/statement/count/:executionHash/:dbOrigin

Description

Cancel an execution in progress

HTTP Method

DELETE

Authentication

Required: Yes

  • Type: Bearer Token
  • Scope / Permissions (if applicable):

Request

Headers

Name
Required
Type
Description
Authorization
Yes
String
Bearer <token>
Content-Type
Yes
String
application/json

Query Parameters

Name
Required
Type
Description
executionHash
YES
String
Execution ID
dbOrigin
YES
String
Execution database

Request Body

N/A

Status Code: 200 OK

{
	"message": "SQL statement canceled"
}

Error Response

Status Code
Message
When it Happens
400
Bad Request
Invalid input
401
Unauthorized
Invalid credentials
403
Forbidden
Insufficient permissions
500
Server Error
Unexpected failure
400
Database Origin Not Supported
Invalid Database origin
400
SQL Statement not found
Unexisting Execution

Get Count Query Historical Results

Endpoint

/audience/count/:audienceId/:queryName

Description

Get historical count results from a specific Query

HTTP Method

GET

Authentication

Required: Yes

  • Type: Bearer Token
  • Scope / Permissions (if applicable):

Request

Headers

Name
Required
Type
Description
Authorization
Yes
String
Bearer <token>
Content-Type
Yes
String
application/json

Query Parameters

Name
Required
Type
Description
executionHash
YES
String
Execution ID
dbOrigin
YES
String
Execution database

Request Body

N/A

Status Code: 200 OK

Error Response

Status Code
Message
When it Happens
400
Bad Request
Invalid input
401
Unauthorized
Invalid credentials
403
Forbidden
Insufficient permissions
500
Server Error
Unexpected failure

Get Count Result

Endpoint

/audience/count-result/:countResultId?page=1&limit=1000

Description

Get count result rows

HTTP Method

GET

Authentication

Required: Yes

  • Type: Bearer Token
  • Scope / Permissions (if applicable):

Request

Headers

Name
Required
Type
Description
Authorization
Yes
String
Bearer <token>
Content-Type
Yes
String
application/json

Query Parameters

Name
Required
Type
Description
countResultId
YES
String
Count Result Object ID
page
NO
Number
Page Number
limit
NO
Number
Page Size

Request Body

N/A

Example Response

Status Code: 200 OK

Error Response

Status Code
Message
When it Happens
400
Bad Request
Invalid input
401
Unauthorized
Invalid credentials
403
Forbidden
Insufficient permissions
500
Server Error
Unexpected failure

Additional References