Dump session messages (since last)

Returns only session messages created since the previous call. Used for incremental syncs.

GET/ops/v1/sessions/messages/dumps/since-last#

Query Parameters

retryBoolean
Default false. When true, returns the previous dump window again (for retries).
client_identityString
`client_identity` of the target client. Defaults to the signed-in member's client. Must be the signed-in client or one of its descendants; any other value returns 403 `OuterClientScopeForbidden`
include_descendantsBooleandefault: false
If `true`, returns data for the target client and all of its descendant clients. If `false`, returns data for the target client only

Response Fields

Same structure as Dump session messages (date range): messages array (no pagination).

The per-caller last-call timestamp is tracked on the server at the client_member level, separately for each client_identity and include_descendants combination. Calling with a new combination is treated as the first call for that combination. If ingestion fails, you can re-request the same window with retry=true.

curl -X GET "https://opsapi.edutap.ai/ops/v1/sessions/messages/dumps/since-last" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}"

# Retry (re-fetch the previous window)
curl -X GET "https://opsapi.edutap.ai/ops/v1/sessions/messages/dumps/since-last?retry=true" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}"
import requests

res = requests.get(
    "https://opsapi.edutap.ai/ops/v1/sessions/messages/dumps/since-last?retry=true",
    headers={"Authorization": "Bearer ${ACCESS_TOKEN}"},
)
print(res.json())
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://opsapi.edutap.ai/ops/v1/sessions/messages/dumps/since-last?retry=true", nil)
	req.Header.Set("Authorization", "Bearer ${ACCESS_TOKEN}")
	req.Header.Set("Authorization", "Bearer ${ACCESS_TOKEN}")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	b, _ := io.ReadAll(res.Body)
	fmt.Println(string(b))
}
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class Main {
  public static void main(String[] args) throws Exception {
    HttpRequest req = HttpRequest.newBuilder()
        .uri(URI.create("https://opsapi.edutap.ai/ops/v1/sessions/messages/dumps/since-last?retry=true"))
        .header("Authorization", "Bearer ${ACCESS_TOKEN}")
        .header("Authorization", "Bearer ${ACCESS_TOKEN}")
        .GET()
        .build();
    HttpResponse<String> res = HttpClient.newHttpClient().send(req, HttpResponse.BodyHandlers.ofString());
    System.out.println(res.body());
  }
}
const res = await fetch("https://opsapi.edutap.ai/ops/v1/sessions/messages/dumps/since-last?retry=true", {
  method: "GET",
  headers: {"Authorization": "Bearer ${ACCESS_TOKEN}"},
});
console.log(await res.json());
Response
{
  "messages": [
    {
      "message_id": "msg_01HXEFGH1234ABCD5678",
      "chat_session_id": "sess_01HXABCD1234EFGH5678",
      "client_identity": "acme",
      "role": "user",
      "message": "Please explain how to solve x^2 - 5x + 6 = 0.",
      "created_at": "2026-06-20T03:21:30Z",
      "answer_style": null,
      "clip_id": "clip_01",
      "course_title": null,
      "user_id": null,
      "clip_play_head": 0,
      "is_floating": false,
      "is_retry": false,
      "is_preemptive_question": false,
      "is_follow_up_question": false,
      "is_fixed_guide_message": false,
      "references": [],
      "pdf_highlight_texts": [],
      "message_generation_time_seconds": null,
      "files": [],
      "question_message_id": null
    }
  ]
}