Quickstart
Four steps from nothing to a profile with an event on it. Everything you send is scoped to the organization you create first.
1. Create an organization and an API key
Section titled “1. Create an organization and an API key”Sign up on the Cowliss dashboard. Tenancy is Clerk organizations, so the first sign-up creates (or selects) your org, and everything below lands in it.
Then, under Settings → API keys, create a key. The secret is shown exactly once, in the create dialog, so copy it now. It is the Bearer credential for every identify/track call, and it is org-level: one key serves all of your apps.
2. Register an app and read its source id
Section titled “2. Register an app and read its source id”Every event and profile carries the app it came from, so register one before sending data: Apps → New app in the dashboard, or from the CLI:
cow login # browser flow, oncecow apps create --name "my-app" # prints the new app, e.g. app_my-appcow apps sources list app_my-appAn app belongs to one environment, picked at creation and immutable: production by default, development for anything you want walled off behind its own profiles and events (the dashboard create dialog has the picker; see Environments). The app id is a readable slug of the name, so my-app is app_my-app from the start.
Creating the app also creates its api source, the pipe your calls arrive through, and that source’s src_ id is what you send. The create response does not include it, which is why the second command reads it back (the dashboard shows it on the app page with a copy button). Keep both ids: sourceId goes in your SDK config and rides on every call, appId is what segments and journey triggers filter on. An unknown sourceId is a 422. See Apps and sources for Clerk, which pushes your auth provider’s users into the same app with no integration code.
3. Install the SDK and send your first data
Section titled “3. Install the SDK and send your first data”npm install @cowliss/sdkimport { Cow } from "@cowliss/sdk";
const cow = new Cow({ apiKey: process.env.COW_KEY!, sourceId: "src_01j2x8q7v9e3atn5m4kd7yz0bp", baseUrl: process.env.COW_API_URL, // the origin your Cowliss API is served at});
await cow.identify({ identifiers: { userId: "user_1" },});
await cow.track({ identifiers: { userId: "user_1" }, event: "checkout_started",});The sourceId on the client is the default for every call it makes, which is
what one app wants. A process that writes into two apps names sourceId on the
call instead, or holds one client per app.
Every call carries identifiers: a map naming who the write is about (your userId, an anonymousId, a clerkId, an email), and Cowliss generates the profile id and resolves the map to it. There is no alias call: sending two identifiers in one call links them. See Identity.
The SDK generates a messageId per call and retries transient failures. The same two calls are plain HTTP with a { data } envelope, so any language works:
curl -X POST $COW_API_URL/v1/identify \ -H "Authorization: Bearer $COW_KEY" \ -H "Content-Type: application/json" \ -d '{ "data": { "sourceId": "src_01j2x8q7v9e3atn5m4kd7yz0bp", "identifiers": { "userId": "user_1" }, "traits": { "email": "[email protected]", "plan": "free" } } }'curl -X POST $COW_API_URL/v1/track \ -H "Authorization: Bearer $COW_KEY" \ -H "Content-Type: application/json" \ -d '{ "data": { "sourceId": "src_01j2x8q7v9e3atn5m4kd7yz0bp", "identifiers": { "userId": "user_1" }, "event": "checkout_started", "messageId": "msg-quickstart-1" } }'messageId is the dedupe key: send the same one twice and the event is stored once. The full tracking surface, every field and every client option, is in Tracking code; API conventions covers envelopes, errors, and idempotency.
4. See the profile
Section titled “4. See the profile”Open Users in the dashboard: the profile is there with its traits, and checkout_started in its event history. Writes are synchronous, so the profile exists the moment identify returns. The same through the CLI, by any of its identifiers:
cow users find --identifier userId:user_1cow users events usr_…Where next
Section titled “Where next”- Start a project:
cow init, then build, push, and deploy your journeys from your own repo. - Author a journey:
checkout_startedis exactly the event the abandoned-checkout example triggers on. - Copy an example:
cow add example <name>, thencow test <name> --scenario scenarios/<file>. - Send history: batch imports with historical timestamps that never fire journeys at the past.
- Read the API reference: generated from the schemas the server validates with.