List user activity

Returns per-learner activity summaries in one batch (no pagination).

GET/ops/v1/users#

Query Parameters

user_idString
Partial-match search on user_id (case-insensitive)
start_dateString
Start date of the period filter. `YYYY-MM-DD` (KST). The period filter is applied only when **both** `start_date` and `end_date` are specified.
end_dateString
End date of the period filter. `YYYY-MM-DD` (KST). The period filter is applied only when **both** `start_date` and `end_date` are specified.
course_idString
Exact-match filter on `course_id` (case-sensitive). Omit to disable filtering
clip_idString
Exact-match filter on `clip_id` (case-sensitive). Omit to disable filtering
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

course_idString | null
The requested `course_id`, stripped and echoed back. `null` if omitted or blank
clip_idString | null
The requested `clip_id`, stripped and echoed back. `null` if omitted or blank
usersArray of objectsrequired
User activity list (no pagination, returned in one batch).
user_idString
Learner identifier
client_identityString | null
`client_identity` of the client the learner belongs to. The same `user_id` under different clients is returned as separate rows
session_countNumber
Cumulative session count for the learner
question_countNumber
Cumulative question count for the learner (number of role='user' messages)
last_question_atString (ISO 8601) | null
Last question time (latest created_at among role='user' messages, UTC)

Results are returned in one batch without pagination. When both start_date and end_date are specified, learners with no role='user' messages within that period are excluded from the results.

The course_id/clip_id filters use exact match and are case-sensitive. Values are trimmed; empty or whitespace-only values are treated as unset and echoed back as null. When both are provided, they are combined with AND.

curl -X GET "https://opsapi.edutap.ai/ops/v1/users?user_id=user_abc&start_date=2026-06-01&end_date=2026-06-25" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}"
# course_id/clip_id (optional filters, e.g. &course_id=course_abc&clip_id=clip_xyz)
import requests

res = requests.get(
    "https://opsapi.edutap.ai/ops/v1/users?user_id=user_abc&start_date=2026-06-01&end_date=2026-06-25",
    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/users?user_id=user_abc&start_date=2026-06-01&end_date=2026-06-25", nil)
	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/users?user_id=user_abc&start_date=2026-06-01&end_date=2026-06-25"))
        .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/users?user_id=user_abc&start_date=2026-06-01&end_date=2026-06-25", {
  method: "GET",
  headers: {"Authorization": "Bearer ${ACCESS_TOKEN}"},
});
console.log(await res.json());
Response
{
  "course_id": null,
  "clip_id": null,
  "users": [
    {
      "user_id": "user_abc123",
      "client_identity": "acme",
      "session_count": 12,
      "question_count": 84,
      "last_question_at": "2026-06-24T15:42:00Z"
    }
  ]
}