If your team already sends data through Segment, Kirora takes it in Segment’s own format: point a Segment library at Kirora, or add Kirora as a webhook destination in your Segment workspace. Nothing in your tracking calls changes.
Point a Segment library at Kirora
Segment’s server libraries send to whatever host you give them. Use a Kirora API key
with the contacts:write and events:write scopes as the write key, and
https://api.kirora.io/segment as the host:
import { Analytics } from '@segment/analytics-node';
const analytics = new Analytics({
writeKey: process.env.KIRORA_API_KEY,
host: 'https://api.kirora.io/segment',
});
analytics.identify({ userId: 'customer-881', traits: { email: '[email protected]' } });
analytics.track({ userId: 'customer-881', event: 'Order Completed', properties: { total: 125.5 } });import os
import segment.analytics as analytics
analytics.write_key = os.environ["KIRORA_API_KEY"]
analytics.host = "https://api.kirora.io/segment"Other Segment libraries take the address in different forms. Use the form your library expects:
| Library | Setting |
|---|---|
| Python | analytics.host = "https://api.kirora.io/segment" |
| Go | Endpoint: "https://api.kirora.io/segment" |
| PHP | "host" => "api.kirora.io/segment" |
| Ruby | host: "api.kirora.io", path: "/segment/v1/import" |
| Java | setUploadURL("https://api.kirora.io/segment/v1/import") |
The libraries post to /segment/v1/batch (Ruby and Java to /segment/v1/import),
with the key as Basic auth’s user name. Kirora also accepts the call types
(/segment/v1/identify, track, page, screen) and a trailing slash. Segment’s
browser and mobile SDKs also load settings from Segment’s CDN, so use Kirora’s web SDK in
the browser instead.
Requirements
- Scopes: the key needs
contacts:writeandevents:write. - Plan: every
/segment/v1call needs the integrations feature (Starter and above). On Free, each call is refused with 403PLAN_FEATURE_UNAVAILABLE. Track, page and screen calls count against the plan’s monthly event allowance. - Key kind: an
agentkey is refused with 403, because it cannot write contacts or track events. See Agents.
From your Segment workspace
Add a Webhooks (Actions) destination with the URL
https://api.kirora.io/segment/v1/webhook and a header
Authorization: Bearer <your Kirora API key>. Send the raw Segment event as the body,
one at a time or batched (an array of events). A destination function can fetch the same URL.
How calls become Kirora data
| Segment call | In Kirora |
|---|---|
identify |
Creates or updates the contact: userId is its externalId, else the email trait finds it. email, firstName/first_name, lastName/last_name, phone and name fill the contact’s fields; other traits become attributes, a nested object one level flat (address.city → address_city), a key’s spaces and symbols as _, the first 50 kept. |
track |
An event of that name with its properties, on the contact, created when new. An email in context.traits finds a contact you imported by email, rather than making a second one. |
page |
A Page Viewed event; name and category join its properties. |
screen |
A Screen Viewed event, the same way. |
group, alias |
Skipped. |
- Consent is never read from traits: a contact Segment creates has no marketing consent until your app records it through the contacts API or a form.
- Anonymous calls, with an
anonymousIdand nouserIdoremailtrait, are skipped: Kirora keeps no anonymous profiles. - Retries record once: each call’s
messageIdis its idempotency key. - Times:
timestampis when it happened. An event more than 72 hours old starts no journey (as in e-commerce events). - Limits: 32 KB a call, 500 KB and 500 calls a request. Each call counts as one request against the events rate limit.
The response is 200 with what became of each call, by its place in the request:
{
"data": {
"accepted": 3,
"skipped": [{ "index": 3, "reason": "anonymous" }],
"refused": [{ "index": 5, "code": "VALIDATION_ERROR", "message": "Invalid batch entry" }]
}
}A wrong key is 401, a body that is not JSON 400, and one over 500 KB 413. A
temporary failure on Kirora’s side is a 5xx for the whole request, which the libraries
retry; retried calls are not recorded twice.