What your AI operator did last night.
Semant keeps every run of your agents, step by step, and marks the stretch where they went quiet. Reporting a run takes one HTTP request at the end of the flow.
For agents built on Senda or anywhere else.
The spans Semant would store
| span | duration | duration | status |
|---|---|---|---|
| invoke_agent inbox-triage249189a7b6e2999d | 2 min 41 s | error | |
| fetch-messagesa2b1520ba83e7117 | 4 s | fine | |
| classifyb2296e1792001763 | 37 s | fine | |
| draft-replies2c8da6f43fd21373 | 2 min 00 s | error |
curl -X POST https://semant.trysenda.xyz/v1/runs \ -H "Authorization: Bearer sk_semant_..." \ -H "Content-Type: application/json" \ -d '{ "agent": { "name": "inbox-triage" }, "run_id": "2026-10-01-0200", "started_at": "2026-10-01T02:00:00-03:00", "ended_at": "2026-10-01T02:02:41-03:00", "status": "error", "error_message": "draft-replies: no reply from the model after 120 s", "steps": [ { "name": "fetch-messages", "started_at": "2026-10-01T02:00:00-03:00", "ended_at": "2026-10-01T02:00:04-03:00", "status": "ok" }, { "name": "classify", "started_at": "2026-10-01T02:00:04-03:00", "ended_at": "2026-10-01T02:00:41-03:00", "status": "ok" }, { "name": "draft-replies", "started_at": "2026-10-01T02:00:41-03:00", "ended_at": "2026-10-01T02:02:41-03:00", "status": "error" } ], "metadata": { "trigger": "every 30 min" } }'
HTTP 200 { "trace_id": "e401386c50fd91d5e577c94da77f309d", "spans": 4 }
Swap sk_semant_... for your key. Keys will be created inside Semant.
Two ways to report.
No code: an HTTP step at the end of the flow.
If your agent runs in a flow tool, add one last step that sends the report. It is the request above, with your key.
- Every 30 minutes
- fetch-messages
- classify
- draft-replies
- POST /v1/runsReports the run
If your agent already emits OpenTelemetry: one line of environment.
Point the exporter at Semant with your key. Every span arrives as you sent it.
OTEL_EXPORTER_OTLP_ENDPOINT=https://semant.trysenda.xyz OTEL_EXPORTER_OTLP_HEADERS=Authorization=Bearer%20sk_semant_...
When the agent does not report, the line stays blank.
The agent writes down its run every half hour. Tonight the book was blank from 02:02 to 05:30, and Semant marks that stretch.
Shift logbook
inbox-triage · 22:00 to 06:00
ExampleNothing to report
2 min 28 sNothing to report
2 min 32 sNothing to report
2 min 19 sNothing to report
2 min 51 sNothing to report
2 min 24 sNothing to report
2 min 38 sNothing to report
2 min 30 sNothing to report
2 min 43 sdraft-replies: no reply from the model after 120 s
error2 min 41 sNo report for 3 h 27 min
Picked up on its own. Nothing to report
2 min 35 s
What does not reach it.
Semant sees what it is sent. Today this does not reach it, and we would rather say so first.
| What | Why |
|---|---|
| An agent someone else hosts, that you cannot edit. | If you cannot add a step to it or set an exporter, it reports nothing. |
| A tool with no outbound requests. | If your plan cannot send an HTTP request, the report has no way out. |
| What happens inside a step. | A report carries the run and the steps your flow writes down. To see more, send one report per step or use OpenTelemetry. |
| Full prompts and replies. | Semant does not capture them for now. It keeps what you send, nothing else. |
| OTLP over gRPC, metrics and logs. | For now, traces over OTLP/HTTP and run reports come in. |
Questions.
Do I need Line or the Corpus?
No. Semant is sold on its own and takes runs from agents built anywhere.
What if I send the same run twice?
If the report carries the same run_id, Semant keeps it once. A retry duplicates nothing.
And if the report is malformed?
Semant refuses it with a 400 that names the field and says why. Try it above: clear the agent's name.
Does it keep what my agents say?
It keeps what you send, as it arrives. The run report has no field for prompts or replies.
When can I use it?
Semant opens through a waitlist. We will write when you can create your key.
Keep the next night on the record.
Join the list. We will write when you can report your first run.