Skip to main content

Call your app from anywhere

Intermediate ⏱ 12 min api · http · sse · integrations

You will build: your app driven entirely from outside — curl in, curl out, live stream — the surface every external system (n8n, LangGraph, Temporal, your own code) integrates against.

POST /in → pipeline → GET /events · SSE

Prerequisites

  • A deployed app (the hello quickstart works).
  • Its Pulse server reachable (dev mode: http://localhost:9090).

1 · Get a token

TOKEN=$(curl -s -X POST http://localhost:9090/api/auth/login \
-H 'Content-Type: application/json' \
-d '{"username":"you","password":"…"}' | jq -r .accessToken)

The JWT comes back under accessToken. In dev mode the CLI already logged itself in — this step is for external clients.

2 · Send an event over plain HTTP

curl -X POST "http://localhost:9090/api/pulse/x/hello/in" \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"severity":"error","msg":"from curl"}'

This is exactly what pulse events send does — and what an n8n HTTP node, a Temporal activity or any backend does. One surface, every client.

3 · Read results back

curl -H "Authorization: Bearer $TOKEN" \
"http://localhost:9090/api/pulse/events/hello.triage.out"

4 · Or stream them live (SSE)

curl -N -H "Authorization: Bearer $TOKEN" \
"http://localhost:9090/api/pulse/events/stream"

Server-sent events push each result as it lands — the browser-native, zero-dependency live feed.

5 · Level up: correlated request/response

# pulse-py
from pulse import Client
async with Client(...).duplex() as d:
reply = await d.send({"severity": "error", "msg": "hi"})

The Python SDK's duplex() gives you request/response semantics over a WebSocket — send an event, await its correlated result. SDKs exist for JS, Python, Rust, Go and Java.

What just happened

Every deployed app exposes the same four-verb surface: POST in, GET out, SSE stream, duplex WebSocket. That uniformity is why 14 orchestrator bridges (n8n, Node-RED, LangGraph, Temporal, Prefect, Dagster, Kestra, Airflow, Camel, Spring Integration, Step Functions, GCP Workflows, Azure Durable Functions & Logic Apps) are each just a thin client — the Pulse side never changes.

Troubleshooting

401 Unauthorized

The token is missing or expired — re-run the login call. Note the field is accessToken, not token.

SSE connection closes immediately

Keep -N (no buffering) on curl, and confirm you're hitting the /stream endpoint with a valid Bearer header.

Next