List logs
curl --request GET \
--url https://api.markifact.com/v1/logs \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.markifact.com/v1/logs"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.markifact.com/v1/logs', 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.markifact.com/v1/logs",
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.markifact.com/v1/logs"
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.markifact.com/v1/logs")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.markifact.com/v1/logs")
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>",
"operation_id": "gads_get_campaigns",
"status": "success",
"source": {
"type": "mcp",
"id": "<string>",
"run_id": "<string>",
"name": "<string>"
},
"user": {
"id": "<string>",
"email": "<string>"
},
"started_at": 1784874174,
"credits_used": 123,
"cache_hit": true,
"metadata": {},
"operation_version": 123,
"completed_at": 123,
"input": "<unknown>",
"output": "<unknown>"
}
],
"has_more": true,
"next_cursor": "<string>"
}{
"detail": "<unknown>"
}{
"detail": "<unknown>"
}Logs
List logs
List the operation logs your Markifact team has produced across workflows, MCP servers, and agents.
GET
/
v1
/
logs
List logs
curl --request GET \
--url https://api.markifact.com/v1/logs \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.markifact.com/v1/logs"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.markifact.com/v1/logs', 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.markifact.com/v1/logs",
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.markifact.com/v1/logs"
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.markifact.com/v1/logs")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.markifact.com/v1/logs")
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>",
"operation_id": "gads_get_campaigns",
"status": "success",
"source": {
"type": "mcp",
"id": "<string>",
"run_id": "<string>",
"name": "<string>"
},
"user": {
"id": "<string>",
"email": "<string>"
},
"started_at": 1784874174,
"credits_used": 123,
"cache_hit": true,
"metadata": {},
"operation_version": 123,
"completed_at": 123,
"input": "<unknown>",
"output": "<unknown>"
}
],
"has_more": true,
"next_cursor": "<string>"
}{
"detail": "<unknown>"
}{
"detail": "<unknown>"
}Returns one log per operation your team ran, newest first, whatever produced it: a workflow node, an MCP tool call, or an agent step. API keys can only be created by team owners, so a key sees every log the team wrote, including operations run by other members and through private MCP servers.
How far back you can read depends on your plan’s history window. Logs outside that window are not returned even though Markifact still stores them.
Keep every other parameter identical while paging. The cursor marks a position in the ordered result set, not the query that produced it, so changing a filter mid-walk gives you a page that does not line up with the previous one.
Treat the cursor as opaque. Its contents are internal and can change.
Logs come back newest first, so reverse them to read the run in execution order. A run that failed before any node executed, for example when the team ran out of credits, produces no logs at all.
Endpoint
GET /v1/logs
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
source_type | string | No | Only return logs from one source: mcp, agent, or workflow. Omit for all three. |
status | string | No | Only return logs with this status: success, error, skipped, stop, or start. |
operation_id | string | No | Exact operation ID, such as gads_get_campaigns. |
source_id | string | No | Only return logs from one MCP server, agent conversation, or workflow. |
source_run_id | string | No | Only return logs from a single workflow run. This is how you fetch every step of one run. |
started_after | integer | No | Only logs started at or after this Unix second. Cannot reach past your plan’s history window. |
started_before | integer | No | Only logs started at or before this Unix second. |
limit | integer | No | Logs per page, 1 to 100. Defaults to 25. |
cursor | string | No | The next_cursor from the previous page. |
Example Request
curl "https://api.markifact.com/v1/logs?source_type=workflow&status=error&limit=25" \
-H "Authorization: Bearer YOUR_API_KEY"
Response
{
"data": [
{
"id": "1e38c1c2-1d85-4094-ab55-1f35c78ab436",
"operation_id": "sheets_read_data",
"operation_version": 1,
"status": "success",
"source": {
"type": "workflow",
"id": "bcd0e853-dd0c-4347-bd35-b86148cf2c96",
"run_id": "411de6e1-9a3d-4838-a1a7-21cbc8dfe15f",
"name": "Meta Ads Upload"
},
"user": {
"id": "Q8Wvn9gL8GUQ11SsJAnMfiyyGOA2",
"email": "member@example.com"
},
"started_at": 1784874165,
"completed_at": 1784874172,
"credits_used": 1,
"cache_hit": false,
"input": { "spreadsheet_id": "1AbC...", "range": "Sheet1!A1:F200" },
"output": { "rows": 199, "file_id": "f_9c21..." },
"metadata": {
"node_id": "node_3",
"node_label": "Read campaign sheet",
"retry_attempts": 0
}
}
],
"has_more": true,
"next_cursor": "eyJzIjoxNzg0ODc0MTY1LCJpIjoiNjI2OWRhYTUifQ"
}
Pagination
Readnext_cursor from the response and pass it back as cursor to get the next page. When has_more is false, next_cursor is null and you have reached the end.
# First page
curl "https://api.markifact.com/v1/logs?limit=100" \
-H "Authorization: Bearer YOUR_API_KEY"
# Next page
curl "https://api.markifact.com/v1/logs?limit=100&cursor=eyJzIjoxNzg0ODc0MTY1LCJpIjoiNjI2OWRhYTUifQ" \
-H "Authorization: Bearer YOUR_API_KEY"
Log Object
| Field | Type | Description |
|---|---|---|
id | string | Log ID. |
operation_id | string | The Markifact operation that ran. |
operation_version | integer or null | Version of the operation. |
status | string | success, error, skipped, stop, or start. start means the operation was still running when the log was written. |
source | object | What ran the operation. See below. |
user | object | The team member who ran it, with id and email. |
started_at | integer | Start time in Unix seconds. |
completed_at | integer or null | Completion time in Unix seconds. Null while still running. |
credits_used | integer | Credits the operation consumed. |
cache_hit | boolean | Whether the result came from cache instead of the provider. |
input | any | Input the operation ran with. Shape depends on the operation. |
output | any | What the operation returned, or the error payload when status is error. Shape depends on the operation. |
metadata | object | Extra context. node_id, node_label, and retry_attempts for workflows, tool_name for MCP. |
Source Object
| Field | Type | Description |
|---|---|---|
type | string | mcp, agent, or workflow. |
id | string or null | The MCP server, agent conversation, or workflow the operation belongs to. |
run_id | string or null | A single execution. Set on workflow logs, null otherwise. |
name | string or null | Current name of the parent. Falls back to the name recorded at log time if the parent was deleted. |
Timestamps in this resource are Unix seconds. Connection timestamps are in milliseconds.
Reconstructing a Workflow Run
A workflow writes one log per node, all sharing asource_run_id. To pull a whole run in order, filter by it:
curl "https://api.markifact.com/v1/logs?source_run_id=411de6e1-9a3d-4838-a1a7-21cbc8dfe15f" \
-H "Authorization: Bearer YOUR_API_KEY"
Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Query Parameters
Only return logs from this source. Omit for all sources.
Available options:
mcp, agent, workflow Only return logs with this status.
Available options:
success, error, skipped, stop, start Exact operation ID to filter by.
Example:
"gads_get_campaigns"
Only return logs from one MCP server, agent conversation, or workflow.
Only return logs from a single workflow run.
Only return logs started at or after this Unix second. Cannot reach past your plan's history window.
Required range:
x >= 0Only return logs started at or before this Unix second.
Required range:
x >= 0Logs per page.
Required range:
1 <= x <= 100The next_cursor from the previous page. Keep every other filter unchanged while paging.

