List Sessions
List the project’s V4 sessions — one row per session (its most recent run), most-recent first.
A session is a conversation: follow-up runs reuse the same public_session_id, so GET /api/v4/runs would list one row per RUN. This collapses to one row per SESSION directly in Postgres with DISTINCT ON, so a chatty session with 100 runs is still a single row (no scan amplification), and selects only the slim columns the session list needs — never the heavy per-run text/token/cost fields.
Keyset-paginated on the latest run’s (created_at, id): pass next_cursor
back as cursor to page. Offset/COUNT was dropped — it doesn’t scale on
projects with many sessions.
const options = {method: 'GET', headers: {'X-Browser-Use-API-Key': '<api-key>'}};
fetch('https://api.browser-use.com/api/v4/sessions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));curl --request GET \
--url https://api.browser-use.com/api/v4/sessions \
--header 'X-Browser-Use-API-Key: <api-key>'import requests
url = "https://api.browser-use.com/api/v4/sessions"
headers = {"X-Browser-Use-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text){
"sessions": [
{
"sessionId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"workspaceId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"latestRunId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"task": "<string>",
"title": "<string>",
"status": "queued",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z"
}
],
"nextCursor": "<string>",
"hasMore": false
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}Authorizations
Query Parameters
Max sessions per page (max 100).
1 <= x <= 100Keyset cursor from a prior response.
Response
Successful Response
One entry per session (the session's most recent run), most-recent first.
A V4 session is a conversation: every follow-up run reuses the same public_session_id. GET /api/v4/runs returns one row per RUN, so callers that want a list of distinct sessions (e.g. the recent-sessions panel) should use this instead of de-duplicating runs client-side.
Was this page helpful?
const options = {method: 'GET', headers: {'X-Browser-Use-API-Key': '<api-key>'}};
fetch('https://api.browser-use.com/api/v4/sessions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));curl --request GET \
--url https://api.browser-use.com/api/v4/sessions \
--header 'X-Browser-Use-API-Key: <api-key>'import requests
url = "https://api.browser-use.com/api/v4/sessions"
headers = {"X-Browser-Use-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text){
"sessions": [
{
"sessionId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"workspaceId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"latestRunId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"task": "<string>",
"title": "<string>",
"status": "queued",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z"
}
],
"nextCursor": "<string>",
"hasMore": false
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}