Get experiment logs


Each experiment keeps a log of user events, such as requests made to the experiment by members of your team. You can retrieve these logs through the user-events endpoint:

Route: GET https://api.conjoint.ly/api/experiments/experimentId/user-events?order=occurred_at&direction=desc

Query parameters:

  • order: the field to sort by, for example occurred_at (the occurredAt field in the response). Use the snake_case name here, not the camelCase one.
  • direction: desc for newest first or asc for oldest first.
  • page: the page of results to return (starting from 1).

Example response

The response is paginated. Each page contains the events in data, links to other pages in links, and page counts in meta:

{
  "data": [
    {
      "occurredAt": "2026-09-01 10:15:42",
      "eventType": "request",
      "httpMethod": "GET",
      "url": "https://api.conjoint.ly/api/experiments/123456/get-settings",
      "success": true,
      "description": "",
      "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36",
      "experimentId": 123456,
      "userId": 98765,
      "isAdmin": 0,
      "ip": "203.0.113.42"
    },
    {
      "occurredAt": "2026-09-01 10:15:37",
      "eventType": "request",
      "httpMethod": "POST",
      "url": "https://api.conjoint.ly/api/experiments/123456/payment-data",
      "success": true,
      "description": "",
      "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36",
      "experimentId": 123456,
      "userId": 98765,
      "isAdmin": 0,
      "ip": "203.0.113.42"
    }
  ],
  "links": {
    "first": "https://api.conjoint.ly/api/experiments/123456/user-events?page=1",
    "last": "https://api.conjoint.ly/api/experiments/123456/user-events?page=42",
    "prev": null,
    "next": "https://api.conjoint.ly/api/experiments/123456/user-events?page=2"
  },
  "meta": {
    "current_page": 1,
    "from": 1,
    "last_page": 42,
    "path": "https://api.conjoint.ly/api/experiments/123456/user-events",
    "per_page": 10,
    "to": 10,
    "total": 415
  }
}

To get all events, keep requesting the next page until links.next is null. Note that the links URLs do not carry your order and direction parameters, so add them to each request, for example:

GET https://api.conjoint.ly/api/experiments/123456/user-events?page=2&order=occurred_at&direction=desc

Example in R

Here is how to use R (version 4.1 or later, for the |> pipe) to download all logs for an experiment:

CONJOINTLY_TOKEN <- "YOUR_TOKEN" # Get a token from https://run.conjoint.ly/utilities/tokens

getExperimentLogs <- function(experiment_id, max_pages = Inf, TOKEN = CONJOINTLY_TOKEN) {
  library(httr)
  library(data.table)

  headers <- add_headers(
    `Authorization` = paste("Bearer", TOKEN),
    `Content-Type` = "application/json",
    `Accept` = "application/json",
    `X-Requested-With` = "XMLHttpRequest"
  )

  url <- paste0("https://api.conjoint.ly/api/experiments/", experiment_id, "/user-events")
  query <- list(page = 1, order = "occurred_at", direction = "desc")
  pages <- list()

  repeat {
    response <- GET(url, headers, query = query)
    stop_for_status(response, task = paste("download page", query$page))
    result <- content(response, "parsed", encoding = "UTF-8")
    pages[[length(pages) + 1]] <- result$data
    message("Downloaded page ", result$meta$current_page, " of ", result$meta$last_page)

    if (is.null(result$links$`next`) || length(pages) >= max_pages) break
    query$page <- query$page + 1
  }

  records <- unlist(pages, recursive = FALSE) |>
    lapply(\(record) lapply(record, \(value) if (is.null(value)) NA else value))
  rbindlist(records, fill = TRUE)
}

logs <- getExperimentLogs(123456)

Use max_pages to limit how many pages are downloaded for experiments with long histories.