List, filter, and poll messages on a session or a single thread.
Two endpoints share the same paginated response shape and query parameters. Use the first to list every message in a session; use the second to scope to a single thread (for example, to poll the latest follow-up’s reply).
GET /rest/v1/sessions/{session_id}/messagesGET /rest/v1/sessions/{session_id}/threads/{thread_id}/messages
Results are sorted by created_at (newest first by default). Soft-deleted messages are excluded.
// All messages on the session.const url = `https://api.blocks.team/rest/v1/sessions/${sessionId}/messages?type=final_message&role=assistant`;// Or scope to a specific thread:// const url = `https://api.blocks.team/rest/v1/sessions/${sessionId}/threads/${threadId}/messages?type=final_message&role=assistant`;const page = await fetch(url, { headers: { Authorization: `ApiKey ${process.env.BLOCKS_API_KEY}` },}).then((r) => r.json());
import os, requests# All messages on the session.url = f"https://api.blocks.team/rest/v1/sessions/{session_id}/messages"# Or scope to a specific thread:# url = f"https://api.blocks.team/rest/v1/sessions/{session_id}/threads/{thread_id}/messages"page = requests.get( url, headers={"Authorization": f"ApiKey {os.environ['BLOCKS_API_KEY']}"}, params={"type": "final_message", "role": "assistant"},).json()
# All messages on the session.curl "https://api.blocks.team/rest/v1/sessions/$SESSION_ID/messages?type=final_message&role=assistant" \ -H "Authorization: ApiKey $BLOCKS_API_KEY"# Or scope to a specific thread:curl "https://api.blocks.team/rest/v1/sessions/$SESSION_ID/threads/$THREAD_ID/messages?type=final_message&role=assistant" \ -H "Authorization: ApiKey $BLOCKS_API_KEY"
import java.net.URI;import java.net.http.*;String url = "https://api.blocks.team/rest/v1/sessions/" + sessionId + "/messages?type=final_message&role=assistant";// Or scope to a specific thread:// String url = "https://api.blocks.team/rest/v1/sessions/" + sessionId// + "/threads/" + threadId + "/messages?type=final_message&role=assistant";HttpResponse<String> res = HttpClient.newHttpClient().send( HttpRequest.newBuilder(URI.create(url)) .header("Authorization", "ApiKey " + System.getenv("BLOCKS_API_KEY")) .build(), HttpResponse.BodyHandlers.ofString());
require "net/http"require "json"# All messages on the session.url = "https://api.blocks.team/rest/v1/sessions/#{session_id}/messages?type=final_message&role=assistant"# Or scope to a specific thread:# url = "https://api.blocks.team/rest/v1/sessions/#{session_id}/threads/#{thread_id}/messages?type=final_message&role=assistant"page = JSON.parse(Net::HTTP.get(URI(url), { "Authorization" => "ApiKey #{ENV['BLOCKS_API_KEY']}",}))
url := "https://api.blocks.team/rest/v1/sessions/" + sessionID + "/messages?type=final_message&role=assistant"// Or scope to a specific thread:// url := "https://api.blocks.team/rest/v1/sessions/" + sessionID +// "/threads/" + threadID + "/messages?type=final_message&role=assistant"req, _ := http.NewRequest("GET", url, nil)req.Header.Set("Authorization", "ApiKey "+os.Getenv("BLOCKS_API_KEY"))res, _ := http.DefaultClient.Do(req)
Cursor for incremental polling, in epoch seconds. Returns only messages whose ts is strictly greater than this value. Use _links.new_messages.href from the previous page to get a pre-built URL with this cursor already set.
Pre-built URL with ?gts=<cursor> appended. Poll this URL to receive only messages newer than the latest one in this page. Always present — when items is empty, the cursor is the server’s current epoch second, so the next poll returns anything created after now.