curl --request GET \
--url https://{tenant}.earnie.dev/v1/audit-log \
--header 'Authorization: Bearer <token>'import requests
url = "https://{tenant}.earnie.dev/v1/audit-log"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://{tenant}.earnie.dev/v1/audit-log', 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://{tenant}.earnie.dev/v1/audit-log",
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://{tenant}.earnie.dev/v1/audit-log"
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://{tenant}.earnie.dev/v1/audit-log")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://{tenant}.earnie.dev/v1/audit-log")
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{
"events": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"actor": {
"kind": "user",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"display": "<string>"
},
"event_type": "<string>",
"payload": {},
"occurred_at": "2023-11-07T05:31:56Z",
"project_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"subject_kind": "<string>",
"subject_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"occurrence_count": 123,
"occurrences": [
"2023-11-07T05:31:56Z"
],
"occurrences_truncated": true,
"payloads_vary": true
}
],
"actors": [
{
"kind": "user",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"display": "<string>"
}
],
"event_types": [
"<string>"
],
"next_cursor": "<string>"
}{
"code": "<string>",
"message": "<string>"
}{
"code": "<string>",
"message": "<string>"
}{
"code": "<string>",
"message": "<string>"
}List instance-wide audit events
curl --request GET \
--url https://{tenant}.earnie.dev/v1/audit-log \
--header 'Authorization: Bearer <token>'import requests
url = "https://{tenant}.earnie.dev/v1/audit-log"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://{tenant}.earnie.dev/v1/audit-log', 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://{tenant}.earnie.dev/v1/audit-log",
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://{tenant}.earnie.dev/v1/audit-log"
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://{tenant}.earnie.dev/v1/audit-log")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://{tenant}.earnie.dev/v1/audit-log")
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{
"events": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"actor": {
"kind": "user",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"display": "<string>"
},
"event_type": "<string>",
"payload": {},
"occurred_at": "2023-11-07T05:31:56Z",
"project_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"subject_kind": "<string>",
"subject_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"occurrence_count": 123,
"occurrences": [
"2023-11-07T05:31:56Z"
],
"occurrences_truncated": true,
"payloads_vary": true
}
],
"actors": [
{
"kind": "user",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"display": "<string>"
}
],
"event_types": [
"<string>"
],
"next_cursor": "<string>"
}{
"code": "<string>",
"message": "<string>"
}{
"code": "<string>",
"message": "<string>"
}{
"code": "<string>",
"message": "<string>"
}Authorizations
An Earnie API key, sent as Authorization: Bearer sk_earnie_.... Create one under Settings > API keys. The key's scopes decide which operations it may call.
Query Parameters
user, api_key, integration, worker, agent, unauthenticated Free-text search. Matches case-insensitively as a literal substring against the actor display name or the event type; LIKE metacharacters are matched literally. Trimmed, and blank means no search. The event payload is deliberately out of scope.
200Fold like events into one row per occurrence group, keyed on (local day, event type, actor, project, subject). The row then reports the group's most recent member and carries occurrence_count, occurrences, occurrences_truncated and payloads_vary, and limit counts groups rather than events. Opt-in and default off: every other consumer keeps one row per event. A cursor minted in one mode cannot be replayed in the other.
IANA time zone the collapsed local day is computed in, e.g. Europe/Madrid. Defaults to UTC. An unrecognized zone is rejected rather than silently treated as UTC, because a group collapsed on a day the caller did not ask for would straddle two of their day headings.
641 <= x <= 100