Skip to content
ChangelogBook a demoSign up

Events CLI

AudienceEngineers instrumenting Hightouch Events
PrerequisitesAn event source and at least one event contract

The Events CLI reads your event contracts and generates typed wrappers around supported Hightouch Events SDKs, such as the Browser and iOS SDKs. You call those wrappers in your app instead of sending untyped track calls.

This page is for the Events CLI (htevents). It is a different tool from the Hightouch CLI (ht), which manages workspace resources such as models and syncs.


Overview

Contracts define the events and fields Hightouch expects. The Events CLI generates typed functions from those contracts. You call the functions from application code.

When a contract changes, TypeScript, Python, and other typed languages flag mismatches in your editor. Hightouch still validates events when they arrive. The CLI adds an additional check that happens earlier, in the code you write.

Use the CLI when you instrument with a Hightouch Events SDK and you want generated helpers that match your contracts. Skip it if you send events only through the HTTP API or a streaming source such as Kafka.

The CLI never installs or constructs the Events SDK — you still initialize the SDK yourself. Generated files only wrap it.

Before you begin

Before you generate wrappers, make sure you have:

  • Node.js 18 or later, which includes npm and npx
  • An event source in Hightouch
  • At least one event contract in a domain attached to that source
  • The Events SDK for your language, installed in the same project

Copy the source slug from the event source. Go to Event Collection > Event sources, open the source, and click the Setup tab. The Slug field identifies this source in Git Sync YAML and the Events CLI. It is not the write key.

Install the CLI

Install the CLI as a development dependency:

npm install --save-dev @ht-sdks/events-cli

Run it from the project directory with npx:

npx htevents --help

A local install does not put htevents on your PATH; npx resolves the copy in node_modules. To put it on your PATH, install globally with npm install -g @ht-sdks/events-cli. Prefer the local install above so the CLI version stays pinned in CI and shared project environments.

If your repo has no package.json (for example, a Swift or Android app), npm install --save-dev will create one. You can also run the CLI without adding a dependency using:

npx @ht-sdks/events-cli --help

Create a configuration file

From your application repository, run:

npx htevents init

init asks for:

  • The event source slug
  • Whether to load contracts from the Hightouch API or a local Git Sync checkout
  • Which SDK to generate for
  • Where to write the generated files

It writes htevents.config.json. Commit that file. Do not put API tokens in it.

Non-interactive init

In CI or scripts, pass every value as a flag:

npx htevents init \
  --source web-app \
  --input api \
  --sdk browser-ts \
  --output ./src/analytics/generated.ts

--input git-sync also requires --git-sync-path. Use --force to overwrite an existing configuration file.

Load contracts from the API

API input fetches the contracts attached to your event source from Hightouch.

Create an API key as a workspace Admin:

  1. From the API keys tab on the Settings page, select Add API key.
  2. Enter a descriptive Name for your key.
  3. Copy your API key and store it in a safe location. The key will only be displayed once.
  4. Click Create API key.

API keys authenticate as the user who created them. See API overview for permissions and what happens if that user loses access.

Pass the key as HIGHTOUCH_API_TOKEN or --token. --token wins when both are set.

export HIGHTOUCH_API_TOKEN="YOUR_API_KEY"
npx htevents generate

Never store the API key in htevents.config.json. The CLI rejects a configuration file that contains token, apiKey, or api_key.

Load contracts from Git Sync

If your workspace version-controls event contracts, you can generate from a local checkout instead of the API. No API key is required.

Set input to git-sync and point path at the Git Sync repository root or its events directory:

{
  "source": "web-app",
  "input": { "type": "git-sync", "path": "./events" },
  "outputs": [{ "sdk": "browser-ts", "path": "./src/analytics/generated.ts" }]
}

The CLI reads events/domains (current layout) or events/contracts (legacy layout). Don't mix both layouts in the same repository.

Generate wrappers

npx htevents generate

generate writes typed wrappers to each path in outputs and writes htevents.lock.json next to the configuration file. The lock file records which contract versions produced the code.

Do not edit generated files. When contracts change, run generate again.

Commit htevents.config.json. You can commit the generated sources and htevents.lock.json, or add them to .gitignore and run generate after clone and in CI.

Committing generated files lets htevents check fail a PR when contracts changed but wrappers were not regenerated. If you ignore them, run generate in CI before you compile instead of check.

Configuration file

htevents.config.json looks like this:

{
  "$schema": "./node_modules/@ht-sdks/events-cli/schemas/config.schema.json",
  "source": "web-app",
  "input": { "type": "api" },
  "outputs": [{ "sdk": "browser-ts", "path": "./src/analytics/generated.ts" }]
}
FieldWhat it does
$schemaOptional. Points at the JSON Schema shipped with the package so editors can validate the file.
sourceEvent source slug from the Setup tab.
inputapi or git-sync. Git Sync also needs path.
outputsOne or more { "sdk", "path" } entries. Paths are relative to the configuration file.

To generate for more than one SDK, add another outputs entry:

{
  "outputs": [
    { "sdk": "browser-ts", "path": "./src/analytics/generated.ts" },
    { "sdk": "node-ts", "path": "./server/analytics/generated.ts" }
  ]
}

PHP writes several files. Set path to a directory, not a single file.

Pass -c / --config when the file is not ./htevents.config.json. generate and check resolve paths from that file's directory, not from the current working directory.

Call generated wrappers

Install and initialize the Events SDK the same way you would without the CLI. Then import the generated helpers.

For browser-ts, bind the SDK instance once, then call a wrapper for each event:

import { HtEventsBrowser } from "@ht-sdks/events-sdk-js-browser";
import { setHtEvents, trackOrderCompleted } from "./src/analytics/generated";

const analytics = HtEventsBrowser.load(
  { writeKey: "WRITE_KEY" },
  { apiHost: "us-east-1.hightouch-events.com" },
);
setHtEvents(analytics);

trackOrderCompleted({ orderId: "abc-123", total: 49.99 });

Replace WRITE_KEY and apiHost with the values from the event source Setup tab. See the Browser SDK for initialization options.

Each contract version becomes a named wrapper. Order Completed version v2 becomes trackOrderCompletedV2 in TypeScript, or track_order_completed_v2 in Python and Ruby.

The latest version of each event also gets an unversioned alias, such as trackOrderCompleted. Wrappers inject the schema version on the event so Hightouch validates against the matching contract. You do not need to set context.htevents.schemaVersion yourself.

Other SDKs follow the same pattern. Some languages take the SDK client as an argument instead of calling setHtEvents.

Keep generated code in sync

htevents check rebuilds the expected files in memory and compares them to disk. It exits 0 when they match. It exits 2 when a generated file is missing or different:

Generated files are out of date:
  src/analytics/generated.ts
Run `htevents generate` to update.

If generated files are committed, run check in CI so a contract change cannot land without regenerating wrappers:

- run: npx htevents check
  env:
    HIGHTOUCH_API_TOKEN: ${{ secrets.HIGHTOUCH_API_TOKEN }}

If generated files are gitignored, run generate in CI before you compile. check always reports drift when those files are missing.

If you generate from Git Sync, check out that repository in CI and omit the token.

Supported SDKs

Set outputs[].sdk to one of these identifiers. Install the matching Events SDK in the same project.

CLI identifierEvents SDKSDK docs
browser-ts@ht-sdks/events-sdk-js-browserBrowser
node-ts@ht-sdks/events-sdk-js-nodeNode.js
pythonevents-sdk-pythonPython
rubyevents-sdk-rubyRuby
phpht-sdks/events-sdk-phpPHP
csharpHightouch.Events.CSharpC# (.NET)
gogithub.com/ht-sdks/events-sdk-goGo
swiftevents-sdk-swiftiOS
androidcom.hightouch.analytics.android:analyticsAndroid
react-native@ht-sdks/events-sdk-react-nativeReact Native
flutter@ht-sdks/events-sdk-flutterFlutter
kotlincom.github.ht-sdks.events-sdk-kotlin:coreComing soon
javacom.github.ht-sdks.events-sdk-java:analyticsJava

Generated files record the minimum peer SDK version they were tested against.

Commands

htevents [options] [command]

Global options

OptionDescription
-c, --config <path>Path to the configuration file. Default: ./htevents.config.json.
--token <token>Workspace API token. Overrides HIGHTOUCH_API_TOKEN.
--debugPrint stack traces for errors.
-V, --versionPrint the CLI version.

init

Creates htevents.config.json.

OptionDescription
--source <slug>Event source slug.
--input <type>api or git-sync.
--git-sync-path <path>Local Git Sync directory. Required with --input git-sync.
--sdk <sdk>Target SDK. Default: browser-ts.
--output <path>Output path for generated code.
--forceOverwrite an existing configuration file.

generate

Fetches contracts and writes typed wrappers plus htevents.lock.json.

check

Verifies generated files match the current contracts. Exit code 2 means they are out of date.

Troubleshooting

Authentication failed (401)

Cause: --token or HIGHTOUCH_API_TOKEN is missing, expired, or not a workspace API key.

Resolution: Create a new API key as an Admin and pass it to generate or check. See API overview.

Event source slug was rejected (422)

Cause: The source value in the configuration file is not a valid event source slug.

Resolution: Copy the Slug from the event source Setup tab. Do not use the write key or the source name.

Event domains API returned 404

Cause: The API key's workspace cannot list event domains.

Resolution: Confirm you can open Event Collection > Contracts in that workspace. Confirm the API key belongs to the same workspace as the event source.

Generated files are out of date

Cause: Contracts changed, or generated files were edited by hand.

Resolution: Run htevents generate and commit the updated files.

Configuration file contains a token

You may see this error if htevents.config.json includes a secret:

Config must not contain "token". Pass the API token via --token or the HIGHTOUCH_API_TOKEN environment variable.

Cause: The configuration file includes token, apiKey, or api_key.

Resolution: Remove the secret from the file. Pass it with --token or HIGHTOUCH_API_TOKEN.

Next steps

Ready to get started?

Jump right in or a book a demo. Your first destination is always free.

Book a demoSign upBook a demo

Need help?

Our team is relentlessly focused on your success. Don't hesitate to reach out!

Feature requests?

We'd love to hear your suggestions for integrations and other features.

Privacy PolicyTerms of Service