Send Your First Structured Event
This walkthrough sends one synthetic API outcome to Telemetry. The goal is not only to receive a 200 response. It is to begin with an event contract that can support SQL, dashboards, alerts, and later debugging without collecting a raw request payload.
Before you start
Create a team and a write-scoped key in Team Settings → API Keys. Keep the value in a local environment variable or secret manager:
export TELEMETRY_API_KEY="replace-with-your-key"
Do not expose a team key in browser JavaScript, a mobile application, a public repository, or a screenshot. See API Keys and Authentication for scope and rotation guidance.
Choose one completed workflow
Start at a boundary where the application knows the outcome. Good first events include:
api_request_completedbackground_job_completedwebhook_processing_completedcheckout_completedagent_run_completed
Prefer a completed outcome over a generic message such as something_happened. A stable event name gives every producer and query the same grain.
For this example, use a synthetic API request:
{
"route_template": "/api/reports/:report_id",
"method": "POST",
"status": "success",
"status_code": 200,
"latency_ms": 184,
"release": "local-demo",
"environment": "development",
"request_id": "req_demo_001"
}
The URL is a route template rather than a raw URL containing identifiers. The event includes categorized outcome fields and a safe correlation identifier, but no request body, authorization header, cookie, or customer content.
Send the event with cURL
curl https://api.telemetry.sh/log \
-H "Authorization: Bearer $TELEMETRY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"table": "api_request_completed",
"data": {
"route_template": "/api/reports/:report_id",
"method": "POST",
"status": "success",
"status_code": 200,
"latency_ms": 184,
"release": "local-demo",
"environment": "development",
"request_id": "req_demo_001"
}
}'
Use the exact request shape documented by the Log API if your SDK or API version differs from this example.
Send the same event from JavaScript
import telemetry from "telemetry-sh";
telemetry.init(process.env.TELEMETRY_API_KEY);
await telemetry.log("api_request_completed", {
route_template: "/api/reports/:report_id",
method: "POST",
status: "success",
status_code: 200,
latency_ms: 184,
release: "local-demo",
environment: "development",
request_id: "req_demo_001"
});
Initialize the SDK in trusted server-side code. Keep field names and units consistent across services—for example, always store duration in latency_ms rather than mixing seconds and milliseconds.
What success means
A successful send proves only that the API accepted the event. Continue with Verify Event Ingestion to check the table name, inferred types, generated timestamp, and exact row. Do not instrument more workflows until the first event contract is queryable and safe.
For a larger schema, read Designing an Event Schema. For sensitive fields, use Redacting Sensitive Data.