Events & AsyncAPI
The public transaction-status stream: six SSE messages, payload schemas, resumption, and observed examples.
For decoded on-chain pool, swap and liquidity observations, use the core event reference.
Track one transaction signature through HTTP server-sent events. This observer does not sign or submit transactions.
AsyncAPI JSON · YAML · HTTP handshake
Address
/v1/swap/status/{signature}/eventsAuthorization
x-api-keyIn: header
Required path parameter: signature — a base58 Solana transaction signature, 64–88 characters.
Messages
Bindings
Connect and resume
Send GET /v1/swap/status/{signature}/events with the x-api-key integration credential. Use an HTTP streaming client that supports custom headers; the browser's native EventSource does not accept an arbitrary API-key header. Keep backend credentials out of browser code.
curl --no-buffer --fail-with-body \
"${GRAPL_API_ORIGIN}/v1/swap/status/${SIGNATURE}/events" \
--header "x-api-key: ${GRAPL_API_KEY}" \
--header "Last-Event-ID: ${LAST_DURABLE_EVENT_ID}"Omit Last-Event-ID on the first connection. The optional value is a positive decimal string of at most 19 digits. The cursor must belong to the same signature and configured observer; an unavailable or mismatched cursor returns 409 CURSOR_NOT_AVAILABLE before the stream starts. See the OpenAPI reference for handshake errors, rate limits and the complete request schema.
Each SSE data field contains a JSON payload. Every frame carries retry: 3000. Only transaction.status has an id field, equal to payload.id. Slots and IDs remain strings, including values above JavaScript's safe integer range.
event: transaction.status
id: 9007199254740994
retry: 3000
data: {"signature":"1111111111111111111111111111111111111111111111111111111111111111","status":"finalized","commitment":"finalized","slot":"9007199254740993","observedAt":"2026-10-12T12:00:00.000Z","id":"9007199254740994"}This example was captured from the API publisher using an isolated test observation. It is not a public-network transaction.
Handle the lifecycle
| Message | Client action |
|---|---|
snapshot | Show the current observation. Do not advance the resume cursor. |
transaction.status | Store the durable string ID and deduplicate repeated observations. |
complete | Close the connection: the terminal observation is finalized or failed. |
heartbeat | Keep waiting. This is connection liveness, not transaction confirmation. |
reconnect | Reconnect after retryAfterMs, using the last durable ID when present. |
stream-error | Read the safe code; retry only when retryable is true and your retry policy allows it. |
The default publisher polls every 1 second, emits a heartbeat after 15 seconds without one, and closes a connection after 60 seconds. These are implementation defaults, not a delivery SLA. A resumed terminal cursor receives complete without repeating the acknowledged durable event. Delivery can repeat across reconnects: deduplicate by ID; exactly-once delivery is not promised.
Authorization is checked during streaming. After headers are committed, errors become stream-error frames; authorization/cursor failures with status 401, 403 or 409 are non-retryable. Transport disconnects can end a stream without a final control frame. Before headers, failures remain normal HTTP responses. Transaction observation and the configured indexer are required; no public service hostname is announced.
Contract conventions
The AsyncAPI application is the grapl API server. Its send operation describes messages sent to your client. The schema uses the standard HTTP 0.3.0 GET binding. The documented x-sse extension records framing and resume behavior; it is not a standardized SSE binding, and frame fields are not HTTP headers. There are no WebSocket, Kafka, mint or pool subscription channels in this public contract.
Continue with status and streams, authentication, or the API Reference.