curl --request GET \
--url https://api.moda.app/v1/events \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.moda.app/v1/events"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.moda.app/v1/events', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.moda.app/v1/events",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.moda.app/v1/events"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.moda.app/v1/events")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.moda.app/v1/events")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": [
{
"id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"operation_id": "<string>",
"endpoint": "<string>",
"trigger_source": "<string>",
"status_code": 123,
"duration_ms": 123,
"api_key": {
"id": "<string>",
"name": "<string>",
"created_by_name": "<string>"
},
"client_surface": "<string>",
"client_name": "<string>",
"client_version": "<string>",
"client_channel": "<string>",
"client_platform": "<string>",
"error_code": "<string>",
"error_message": "<string>",
"credits_charged": 123,
"prompt_preview": "<string>",
"resource": {
"id": "<string>",
"type": "<string>",
"canvas_id": "<string>",
"canvas_name": "<string>",
"canvas_url": "<string>"
}
}
],
"next_cursor": "<string>",
"returned": 0,
"has_more": false,
"limit": 123,
"total": 123
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}List Api Events
Cursor-paginated activity log for the caller’s team.
Role-scoped identically to GET /v1/usage: admins/owners see every
row in the team, members see only rows attributable to their own API
keys plus their own MCP-origin rows. Sort is (timestamp DESC, id DESC); iterate next_cursor until null to drain.
curl --request GET \
--url https://api.moda.app/v1/events \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.moda.app/v1/events"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.moda.app/v1/events', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.moda.app/v1/events",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.moda.app/v1/events"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.moda.app/v1/events")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.moda.app/v1/events")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": [
{
"id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"operation_id": "<string>",
"endpoint": "<string>",
"trigger_source": "<string>",
"status_code": 123,
"duration_ms": 123,
"api_key": {
"id": "<string>",
"name": "<string>",
"created_by_name": "<string>"
},
"client_surface": "<string>",
"client_name": "<string>",
"client_version": "<string>",
"client_channel": "<string>",
"client_platform": "<string>",
"error_code": "<string>",
"error_message": "<string>",
"credits_charged": 123,
"prompt_preview": "<string>",
"resource": {
"id": "<string>",
"type": "<string>",
"canvas_id": "<string>",
"canvas_name": "<string>",
"canvas_url": "<string>"
}
}
],
"next_cursor": "<string>",
"returned": 0,
"has_more": false,
"limit": 123,
"total": 123
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}Authorizations
API key from Settings > Developer > REST API
Headers
Calendar-dated API version pin. New integrations should pin 2026-05-01 to opt into the newest response shapes. For back-compat the server also accepts requests with no header and resolves them to the current default (today: 2026-04-12); that default advances on each sunset date. Any unsupported value returns 400 unsupported_version.
2026-04-12, 2026-05-01 "2026-05-01"
Query Parameters
Optional API-key UUID filter.
Optional exact-match filter on the event's OpenAPI operationId.
Restrict to api or mcp origin rows.
api, mcp Restrict to generic REST, the Moda CLI, or the new MCP connector.
api, cli, mcp_connector succeeded → 200-399; failed → status >= 400.
succeeded, failed ISO8601 UTC lower bound (inclusive). Defaults to to - 7d.
ISO8601 UTC upper bound (exclusive). Defaults to now.
Max rows per page (cap: 200).
1 <= x <= 200Opaque cursor from the previous page's next_cursor.
Response
Successful Response
Items in this page, in the endpoint's declared sort order.
Show child attributes
Show child attributes
Opaque cursor to pass as ?cursor= on the next request. null means you've reached the end of the collection.
Number of items in this page (always len(data); derived server-side).
true when more items exist beyond this page — keep requesting with next_cursor until this is false. Never trust len(data) < limit alone.
The effective page-size limit this response was computed with.
True total number of items in the collection (after filters), when the endpoint can count cheaply. null on log/search lanes — use has_more there.