Skip to content

Observe transaction status

Read finalized outcomes and consume resumable authenticated event streams.

Subscribe to GET /v1/swap/status/{signature}/events with your integration key in the x-api-key header. The response is text/event-stream. It tracks observations for the configured grapl program and chain. Polling GET /v1/swap/status/{signature} returns the same current snapshot in the normal { "success": true, "data": ... } envelope.

Outcomes

StatusMeaning
not_observedThis observer has no committed receipt yet. It does not prove absence, failure or expiry on chain.
finalizedA finalized receipt reports meta.err: null.
failedA finalized receipt reports an execution error.

The current observer does not emit processed or confirmed. Submission acceptance is separate from chain finality. Failed execution is not a successful swap, and finalized success does not itself describe amounts, rewards or LP movements. Those require decoded transaction events.

Event contract

SSE eventPayload and client action
snapshotInitial status when no durable observation exists. No event ID.
transaction.statusObserved outcome with a stable decimal-string id, signature, status, commitment, slot and observation timestamp. Save its SSE ID after processing.
heartbeatConnection liveness timestamp; no event ID or additional request charge. It does not certify indexer freshness.
completeTerminal snapshot. Stop reading and do not reconnect for this signature.
reconnectConnection lifetime reached. Reconnect after the indicated delay, preserving the last processed ID.
stream-errorSafe code and retryable fields. Stop; retry only when indicated.

An illustrative durable event looks like this:

event: transaction.status
data: {"id":"123","signature":"<signature>","status":"finalized","commitment":"finalized","slot":"456","observedAt":"2026-10-12T12:00:00.000Z"}
id: 123
retry: 3000

Keep IDs and slots as strings. The SSE payload is the event object directly, without the REST success envelope. An HTTP 200 stream may subsequently report stream-error; receiving headers alone does not mean the transaction succeeded.

Reconnection and authentication

Send the last processed ID in Last-Event-ID on reconnect. Resume is scoped to the same signature and observer. A previously acknowledged terminal event is not repeated; complete still supplies its current snapshot. Delivery can repeat after an interrupted connection if the client has not recorded the ID. Deduplicate by ID and never infer ordering from JavaScript floating-point conversion.

An unknown, deleted or mismatched cursor returns HTTP 409 before opening the stream. Fetch a fresh REST snapshot and restart without a cursor if still needed. Honor HTTP 429 Retry-After and use backoff with jitter for transient failures. Reauthentication is required after revocation or expiry.

Use an SSE-capable client supporting request headers, or an authenticated same-origin server proxy. Native browser EventSource cannot set x-api-key; never place API keys in a URL. With fetch, parse complete SSE frames across arbitrary chunk boundaries using a maintained parser; a network chunk is not one event. Cancel the reader after complete and when the view is closed.

Each admitted connection, including reconnects, counts as one API request. Frames do not count separately. A separate shared team cap bounds concurrent streams. Heartbeats are sent every 15 seconds and connections rotate after 60 seconds by default. This feed follows chain finality and indexer observation; it does not promise immediate blockchain delivery.

SSE framing and reconnect semantics follow the server-sent events standard usage. The HTTP transport uses Hono streaming.

See Events & AsyncAPI for every message schema, observed payload examples, and JSON/YAML downloads.