> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vexlo.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Functions

> The function index: which marked functions ran, who called them, and example calls with captured values.

The Vexlo server keeps a function index: for every `(team, service, name)` it has seen, the observed
callers and observed callees, counts, and up to five example calls. A function that ran has a
row; nothing in the index describes code that was never marked. Rows are kept for 90 days.

Every response body on this page was captured from a server seeded with the spec's conformance
trace, on team `fixture`. `$READ_TOKEN` holds a read token whose team-set includes `fixture`.
The three routes take `?team=`, `?environment=`, and `?environment_unset=` as on every read route
([conventions](https://docs.vexlo.ai/api/conventions.md#team-and-environment-filters)). Narrow to one team when the
token spans several: a response for a single team carries a `team` field, and a response spanning
more than one team omits it.

Counts are observed counts, not exact call counts, and they do not drift with delivery: a batch
delivered twice leaves `observed_count` and `error_count` where they were, as it leaves the
trace's own shape unchanged ([ingest](https://docs.vexlo.ai/api/ingest.md#post-/v1/records)). Every instant on
this page (`first_seen_at`, `last_seen_at`, `examples[].started_at`) is derived from the time the
server ingested the records, not from the client clock the trace's own `started_at` reports.

## GET /v1/functions

Lists functions, highest `observed_count` first.

| Parameter | Meaning |
| - | - |
| `team`, `environment`, `environment_unset` | The shared filters. |
| `service` | One service name. |
| `name` | One `module.qualname`. |
| `limit`, `cursor` | Pagination, default 50, maximum 500. |

```bash theme={null}
curl -s -H "Authorization: Bearer $READ_TOKEN" \
  "http://127.0.0.1:18200/v1/functions?team=fixture&limit=3" | jq .
```

```json theme={null}
{
  "items": [
    {
      "service": "delivery-service",
      "team": "fixture",
      "name": "delivery.api.WriteAPIResponse",
      "observed_count": 1,
      "error_count": 0,
      "first_seen_at": "2026-10-20T01:40:22.904Z",
      "last_seen_at": "2026-10-20T01:40:22.904Z",
      "is_entry_point": false
    },
    {
      "service": "delivery-service",
      "team": "fixture",
      "name": "delivery.dispatch.WriteAuditRecord",
      "observed_count": 1,
      "error_count": 0,
      "first_seen_at": "2026-10-20T01:40:22.904Z",
      "last_seen_at": "2026-10-20T01:40:22.904Z",
      "is_entry_point": false
    },
    {
      "service": "delivery-service",
      "team": "fixture",
      "name": "delivery.dispatch.SelectEligibleDasher",
      "observed_count": 1,
      "error_count": 1,
      "first_seen_at": "2026-10-20T01:40:22.904Z",
      "last_seen_at": "2026-10-20T01:40:22.904Z",
      "is_entry_point": false
    }
  ],
  "limit": 3,
  "next_cursor": "MXwxNXw"
}
```

`observed_count` and `error_count` sum across every observed caller of the function, and the two
count different units. `observed_count` counts steps, once each: a function that ran once reads 1
however many attempts its step took. `error_count` counts attempts, one for every attempt that
reported `status: "error"`. `PickBestFromCandidates`, the step retried three times with every
attempt failing, therefore reads `observed_count: 1` and `error_count: 3` on the second page
below, and `error_count` above `observed_count` is what a retried function looks like rather than
a contradiction. `is_entry_point` is `true` for a function observed opening a trace.

Every function in this trace ran once, so every row reads `observed_count: 1` and nothing on the
response orders them: the keyset tie-break among equal counts is an internal row id that no
response carries. The second page follows the cursor:

```bash theme={null}
curl -s -H "Authorization: Bearer $READ_TOKEN" \
  "http://127.0.0.1:18200/v1/functions?team=fixture&limit=3&cursor=MXwxNXw" | jq .
```

```json theme={null}
{
  "items": [
    {
      "service": "delivery-service",
      "team": "fixture",
      "name": "delivery.dispatch.PickBestFromCandidates",
      "observed_count": 1,
      "error_count": 3,
      "first_seen_at": "2026-10-20T01:40:22.904Z",
      "last_seen_at": "2026-10-20T01:40:22.904Z",
      "is_entry_point": false
    },
    {
      "service": "delivery-service",
      "team": "fixture",
      "name": "delivery.dispatch.AssignDasher",
      "observed_count": 1,
      "error_count": 1,
      "first_seen_at": "2026-10-20T01:40:22.904Z",
      "last_seen_at": "2026-10-20T01:40:22.904Z",
      "is_entry_point": false
    },
    {
      "service": "delivery-service",
      "team": "fixture",
      "name": "delivery.dispatch.ParseAvailabilityResponse",
      "observed_count": 1,
      "error_count": 0,
      "first_seen_at": "2026-10-20T01:40:22.904Z",
      "last_seen_at": "2026-10-20T01:40:22.904Z",
      "is_entry_point": false
    }
  ],
  "limit": 3,
  "next_cursor": "MXwxMnw"
}
```

`?name=` narrows the list to one function:

```bash theme={null}
curl -s -H "Authorization: Bearer $READ_TOKEN" \
  "http://127.0.0.1:18200/v1/functions?team=fixture&name=delivery.dispatch.PickBestFromCandidates" \
  | jq .
```

```json theme={null}
{
  "items": [
    {
      "service": "delivery-service",
      "team": "fixture",
      "name": "delivery.dispatch.PickBestFromCandidates",
      "observed_count": 1,
      "error_count": 3,
      "first_seen_at": "2026-10-20T01:40:22.904Z",
      "last_seen_at": "2026-10-20T01:40:22.904Z",
      "is_entry_point": false
    }
  ],
  "limit": 50,
  "next_cursor": null
}
```

The server applies `?name=` after reading one page of rows ordered by `observed_count`, so on a
service with more functions than `limit` an empty `items` alongside a `next_cursor` means only
that the row is not on this page, never that the function was not observed. When you already
hold the name, `GET /v1/functions/detail` looks it up directly and answers `observed_count: 0`
for a pair the index has never observed.

## GET /v1/functions/detail

Returns one function with its observed callers and observed callees.

| Parameter | Meaning |
| - | - |
| `team`, `environment`, `environment_unset` | The shared filters. |
| `service` | Required. A name is unique only within a service. |
| `name` | Required. The function's `module.qualname`. |

The root function of the conformance trace:

```bash theme={null}
curl -s -H "Authorization: Bearer $READ_TOKEN" \
  "http://127.0.0.1:18200/v1/functions/detail?team=fixture&service=delivery-service&name=delivery.api.AssignDasherHandler" \
  | jq .
```

```json theme={null}
{
  "service": "delivery-service",
  "team": "fixture",
  "name": "delivery.api.AssignDasherHandler",
  "observed_count": 1,
  "error_count": 1,
  "first_seen_at": "2026-10-20T01:40:22.904Z",
  "last_seen_at": "2026-10-20T01:40:22.904Z",
  "is_entry_point": true,
  "observed_callers": [
    {
      "name": null,
      "observed_count": 1,
      "first_seen_at": "2026-10-20T01:40:22.904Z",
      "last_seen_at": "2026-10-20T01:40:22.904Z"
    }
  ],
  "observed_callees": [
    {
      "name": "delivery.api.ParseAssignRequest",
      "observed_count": 1,
      "first_seen_at": "2026-10-20T01:40:22.904Z",
      "last_seen_at": "2026-10-20T01:40:22.904Z"
    },
    {
      "name": "delivery.api.ValidateAssignRequest",
      "observed_count": 1,
      "first_seen_at": "2026-10-20T01:40:22.904Z",
      "last_seen_at": "2026-10-20T01:40:22.904Z"
    },
    {
      "name": "delivery.orders.LoadOrderContext",
      "observed_count": 1,
      "first_seen_at": "2026-10-20T01:40:22.904Z",
      "last_seen_at": "2026-10-20T01:40:22.904Z"
    },
    {
      "name": "delivery.dispatch.ResolveDispatchParams",
      "observed_count": 1,
      "first_seen_at": "2026-10-20T01:40:22.904Z",
      "last_seen_at": "2026-10-20T01:40:22.904Z"
    },
    {
      "name": "delivery.dispatch.AssignDasher",
      "observed_count": 1,
      "first_seen_at": "2026-10-20T01:40:22.904Z",
      "last_seen_at": "2026-10-20T01:40:22.904Z"
    },
    {
      "name": "delivery.api.WriteAPIResponse",
      "observed_count": 1,
      "first_seen_at": "2026-10-20T01:40:22.904Z",
      "last_seen_at": "2026-10-20T01:40:22.904Z"
    }
  ]
}
```

A `null` caller `name` in `observed_callers` means the function was observed with no parent step:
as an entry point, or as an orphan whose parent record never arrived. It alone does not prove an
entry point; `is_entry_point` does. Here the two agree.

The retried step:

```bash theme={null}
curl -s -H "Authorization: Bearer $READ_TOKEN" \
  "http://127.0.0.1:18200/v1/functions/detail?team=fixture&service=delivery-service&name=delivery.dispatch.PickBestFromCandidates" \
  | jq .
```

```json theme={null}
{
  "service": "delivery-service",
  "team": "fixture",
  "name": "delivery.dispatch.PickBestFromCandidates",
  "observed_count": 1,
  "error_count": 3,
  "first_seen_at": "2026-10-20T01:40:22.904Z",
  "last_seen_at": "2026-10-20T01:40:22.904Z",
  "is_entry_point": false,
  "observed_callers": [
    {
      "name": "delivery.dispatch.SelectEligibleDasher",
      "observed_count": 1,
      "first_seen_at": "2026-10-20T01:40:22.904Z",
      "last_seen_at": "2026-10-20T01:40:22.904Z"
    }
  ],
  "observed_callees": []
}
```

The caller edge reads `observed_count: 1`, the one step, while the function's `error_count` reads
3, one for each failed attempt of it. A caller edge carries no `error_count` at all.

A pair the index has never seen answers `200` with `observed_count: 0`, empty lists, and empty
strings for both instants. It is never a `404`: "never observed" is the answer.

```bash theme={null}
curl -s -H "Authorization: Bearer $READ_TOKEN" \
  "http://127.0.0.1:18200/v1/functions/detail?team=fixture&service=delivery-service&name=delivery.api.NoSuchFunction" \
  | jq .
```

```json theme={null}
{
  "service": "delivery-service",
  "team": "fixture",
  "name": "delivery.api.NoSuchFunction",
  "observed_count": 0,
  "error_count": 0,
  "first_seen_at": "",
  "last_seen_at": "",
  "is_entry_point": false,
  "observed_callers": [],
  "observed_callees": []
}
```

Omitting `service` is `422 service_required`, and omitting `name` is `400 invalid_request`:

```http theme={null}
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json
X-Ratelimit-Limit: 20
X-Ratelimit-Remaining: 39
X-Ratelimit-Reset: 1
X-Request-Id: e38d98601063da8c
Date: Tue, 20 Oct 2026 01:44:47 GMT
Content-Length: 70

{"error":{"code":"service_required","message":"service is required"}}
```

```http theme={null}
HTTP/1.1 400 Bad Request
Content-Type: application/json
X-Ratelimit-Limit: 20
X-Ratelimit-Remaining: 39
X-Ratelimit-Reset: 1
X-Request-Id: 59389e7de1409532
Date: Tue, 20 Oct 2026 01:44:48 GMT
Content-Length: 66

{"error":{"code":"invalid_request","message":"name is required"}}
```

## GET /v1/functions/examples

Returns up to five example calls of one function, each pointing at a trace, a step, and an
attempt, with the `input` and `output` handles of that attempt.

| Parameter | Meaning |
| - | - |
| `team`, `environment`, `environment_unset` | The shared filters. `environment` filters the stored examples by the environment their trace carried, so it returns fewer than five when the examples skew toward another environment. |
| `service` | Required. |
| `name` | Required. |
| `include=values` | Replace each example's preview handles with the stored value. |
| `limit` | At most 5, default 5. There is no cursor: the index keeps at most five example ids per `(service, name)` across every environment. |

```bash theme={null}
curl -s -H "Authorization: Bearer $READ_TOKEN" \
  "http://127.0.0.1:18200/v1/functions/examples?team=fixture&service=delivery-service&name=delivery.dispatch.PickBestFromCandidates" \
  | jq .
```

```json theme={null}
{
  "function": {
    "service": "delivery-service",
    "name": "delivery.dispatch.PickBestFromCandidates"
  },
  "examples": [
    {
      "trace_id": "0f1a2b3c4d5e6f708192a3b4c5d6e7f8",
      "path": "AACAAAIAAA",
      "attempt": 0,
      "started_at": "2026-10-20T01:40:23.023Z",
      "status": "error",
      "input": {
        "state": "stored",
        "bytes_count": 116,
        "truncated": false,
        "encoding": "json",
        "preview": "{\"candidate_ids\":[\"D-101\",\"D-102\",\"D-103\",\"D-104\",\"D-105\"],\"radi"
      },
      "output": {
        "state": "",
        "truncated": false
      }
    }
  ]
}
```

The example points at attempt 0 of the step at `AACAAAIAAA` in the conformance trace. That
attempt raised, so it has no `output` slot, and the route renders one anyway with
`"state": ""`: treat an empty `state` as a slot that was not captured. `started_at` is the
trace's `first_seen_at` plus the attempt's `started_us`, an ingest-relative instant.

With `include=values`, each handle carries `value` in place of `preview`:

```bash theme={null}
curl -s -H "Authorization: Bearer $READ_TOKEN" \
  "http://127.0.0.1:18200/v1/functions/examples?team=fixture&service=delivery-service&name=delivery.dispatch.GetDashersAvailability&include=values" \
  | jq .
```

```json theme={null}
{
  "function": {
    "service": "delivery-service",
    "name": "delivery.dispatch.GetDashersAvailability"
  },
  "examples": [
    {
      "trace_id": "0f1a2b3c4d5e6f708192a3b4c5d6e7f8",
      "path": "AACAAAA",
      "attempt": 0,
      "started_at": "2026-10-20T01:40:22.919Z",
      "status": "ok",
      "input": {
        "state": "pending",
        "bytes_count": 58,
        "truncated": false,
        "encoding": "json",
        "value": "{\"radius_km\":5,\"requested_time\":\"19:30\",\"zone\":\"SF-94107\"}"
      },
      "output": {
        "state": "pending",
        "bytes_count": 58,
        "truncated": false,
        "encoding": "json",
        "value": "{\"dashers\":[],\"eligible_dashers\":0,\"query_latency_ms\":192}"
      }
    }
  ]
}
```

This is the one `?include=` in the `/v1` API, and with it the route is the second of two places a
value is served, after [`GET /v1/traces/{id}/values`](https://docs.vexlo.ai/api/traces#get-/v1/traces/id/values).
The `pending` state on both handles is the same read-side state the trace routes show for a
non-root `ok` step whose value has arrived.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.