Quickstart
Send your first event in 60 seconds with one HTTP POST — copy-paste snippets for curl, JavaScript, Python, Elixir, and Go.
Sending an event is a single HTTP POST to your route's URL. There is no SDK, no client library, and nothing to install — if your language can make an HTTP request, it can send events.
1. Get your route token
In the dashboard, open Routes and create a route (or open an existing one). The route card shows
its route token — a value starting with es_ — with a copy button beside it. That token is the
credential, so treat it like a password: keep it in an environment variable or your secret manager,
and never ship it in client-side code. If it ever leaks, Regenerate Token in the route's settings
issues a new one and stops the old one immediately.
The endpoint is the same for every route; the token goes in an Authorization header:
POST https://eventsend.io/api/events
Authorization: Bearer es_YOUR_TOKEN
The older form — the token in the path, POST /api/events/es_YOUR_TOKEN — still works and is not
going away. Prefer the header: a token in a URL ends up in proxy logs, shell history and CI output,
where a header does not.
2. Send an event
Every snippet below sends the same event. Pick your language and paste it in.
Building with an AI coding tool? Skip the snippets: paste the EventSend prompt into your agent and it wires the helper and the tracking calls for you, failure paths included. There is a version for Cursor, Claude Code, Codex, Devin Desktop, GitHub Copilot, Lovable, Bolt, v0 and Replit. You still need the route token from step 1.
curl
curl -X POST https://eventsend.io/api/events \
-H "Authorization: Bearer es_YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"event": "user-signup",
"message": "New user signed up: [email protected]",
"level": "success",
"payload": {"user_id": 123, "plan": "free"}
}'
JavaScript
await fetch("https://eventsend.io/api/events", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.EVENTSEND_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
event: "user-signup",
level: "success",
payload: { user_id: 123, plan: "free" },
}),
});
Python
import os
import requests
requests.post(
"https://eventsend.io/api/events",
headers={"Authorization": f"Bearer {os.environ['EVENTSEND_TOKEN']}"},
json={
"event": "user-signup",
"message": "New user signed up: [email protected]",
"level": "success",
"payload": {"user_id": 123, "plan": "free"},
},
timeout=5,
)
Elixir
Req.post!("https://eventsend.io/api/events",
auth: {:bearer, System.fetch_env!("EVENTSEND_TOKEN")},
json: %{
event: "user-signup",
level: "success",
payload: %{user_id: 123, plan: "free"}
}
)
Go
package main
import (
"bytes"
"net/http"
"os"
)
func main() {
body := []byte(`{
"event": "user-signup",
"message": "New user signed up: [email protected]",
"level": "success",
"payload": {"user_id": 123, "plan": "free"}
}`)
req, err := http.NewRequest("POST", "https://eventsend.io/api/events", bytes.NewBuffer(body))
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("EVENTSEND_TOKEN"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
3. Confirm it arrived
An accepted event returns 202 Accepted:
{"success": true, "message": "Event received"}
202 means the event was queued for processing, not that it has already been delivered. Open
Events in the dashboard and you will see it appear, along with a delivery attempt for every
destination it was routed to.
202 is the only status that means the event was accepted — anything else, 2xx included, means
nothing was queued. The Events API reference lists every response code and what causes
it. The most common ones while getting started are 404 (the token is wrong), 422 (a field failed
validation — the response body names the field, or the Authorization header is missing or
malformed), and 200 with "debug": true (the route is in debug mode, so events are validated and
dropped).
4. Route it somewhere
A brand-new route has nowhere to deliver to yet, so your first event will be recorded and marked
dropped. To get it into a chat channel:
- Create a destination (Slack, Discord, Telegram, an HTTPS webhook of your own, or a personal push destination — Pushover or browser push).
- Create a topic and connect your route to that destination through it.
Topics are also where filtering lives — "only error and above", "only payment-*" — so you can
send everything and let EventSend decide what is worth interrupting someone for. See
Concepts for how the pieces fit together, or jump straight to a
recipe.