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

# Murph agent debug calls

> Inspect recent third-party sales-agent calls, including provenance for sandbox tests and live demand

Murph agent debug calls show recent AdCP activity for storefront inventory
sources backed by third-party sales agents. Use this endpoint when you need to
understand what Apostra sent to a source, what the source returned, and
whether the call came from a sandbox test run or live buyer demand.

These rows describe observed AdCP calls. For external sales-agent sources, do
not treat an empty or failed component cache as the same evidence as a failed
live passthrough call. Cache diagnostics are about whether Apostra can reuse
raw products/components for merchandising; debug-call rows are about calls that
actually went to the source.

The response also includes `transportRequests`, a bounded and redacted 30-day
ledger of outbound transport evidence. `calls` remains the logical ADCP activity
summary, so the two counts need not match. For media-buy mutations, `groupId`
identifies the parent application operation and `debugId` identifies a child SDK
session. `physicalRequestCount` counts outbound protocol attempts;
`logicalOperationCount` counts accepted operation envelopes.

An operation stage of `mutation_not_dispatched` means Apostra stopped the
operation locally. It does not mean the remote Agent rejected the request, and
it does not prove the remote state is unchanged. A later authoritative read is
required to establish that state.

<Info>
  This endpoint is available only when Murph is enabled for the caller's
  account.
</Info>

<Info>
  Calls are an account-wide feed unless you pass `sourceId`. Always pass the
  exact Inventory Source ID before treating results as evidence for one Source;
  an unfiltered response is not Source-scoped.
</Info>

## Endpoint

`GET /api/v2/murph/agent-debug-calls`

## Request

```bash curl theme={null}
curl "https://api.apostra.com/api/v2/murph/agent-debug-calls?sourceId=retail-adcp&take=25" \
  -H "Authorization: Bearer $SCOPE3_API_KEY"
```

## Parameters

| Field             | Type    | Required | Notes                                                                                                                                                                                                                                                                                                                         |
| ----------------- | ------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `storefrontId`    | integer | No       | Limit calls to one storefront.                                                                                                                                                                                                                                                                                                |
| `sourceId`        | string  | No       | Limit calls to one storefront inventory source.                                                                                                                                                                                                                                                                               |
| `taskId`          | string  | No       | Limit calls to one AdCP task ID.                                                                                                                                                                                                                                                                                              |
| `debugId`         | string  | No       | Limit calls to one Apostra debug ID (`x-scope3-debug-id`).                                                                                                                                                                                                                                                                    |
| `dispatchGroupId` | string  | No       | Limit transport evidence to one application operation. This does not widen the customer, Source, or Storefront scope.                                                                                                                                                                                                         |
| `mediaBuyId`      | integer | No       | Limit transport evidence to one local media-buy ID.                                                                                                                                                                                                                                                                           |
| `mediaBuyIdText`  | string  | No       | Lossless decimal media-buy ID for values above JavaScript's safe integer range.                                                                                                                                                                                                                                               |
| `correlationId`   | string  | No       | Match a call by operation ID, task ID, context ID, idempotency key, traceparent, request ID, or debug ID.                                                                                                                                                                                                                     |
| `status`          | string  | No       | Limit calls to one task status, such as `COMPLETED`, `FAILED`, or `INPUT_REQUIRED`.                                                                                                                                                                                                                                           |
| `windowHours`     | integer | No       | Trailing lookback in hours, `1`–`720` (30 days). Values above `720` return `400`. Defaults to `168` (7 days) when omitted and no `from` is given. Point lookups by task, debug, dispatch group, media buy, or correlation ID are unbounded unless you pass `windowHours` or `from`. The applied window is echoed as `window`. |
| `from`            | string  | No       | ISO-8601 UTC start of a precise time range. When combined with `windowHours`, the effective start is whichever is later.                                                                                                                                                                                                      |
| `to`              | string  | No       | ISO-8601 UTC end of a precise time range. Defaults to now.                                                                                                                                                                                                                                                                    |
| `take`            | integer | No       | Maximum number of rows to return (default `25`, max `100`).                                                                                                                                                                                                                                                                   |

## Response

```json theme={null}
{
  "calls": [
    {
      "id": 98765,
      "storefrontId": 42,
      "sourceId": "retail-adcp",
      "sourceName": "Retail AdCP Agent",
      "agentId": "agent_retail",
      "agentName": "Retail AdCP Agent",
      "operationId": "op_456",
      "contextId": "ctx_789",
      "idempotencyKey": "murph-test-abc",
      "debugId": null,
      "traceparent": null,
      "requestId": null,
      "taskId": "task_123",
      "taskStatus": "FAILED",
      "rawTaskStatus": "create_media_buy rejected",
      "tool": "create_media_buy",
      "activityType": "RESPONSE",
      "rawActivityType": "response",
      "payload": {
        "error": "Billing field is required."
      },
      "userEmail": "s***@example.com",
      "initiatorEmail": "s***@example.com",
      "origin": {
        "kind": "sandbox_test",
        "testRunUid": "550e8400-e29b-41d4-a716-446655440001",
        "testRunStatus": "failed",
        "testRunToolName": "create_media_buy",
        "testRunCreatedAt": "2026-06-18T12:45:00Z"
      },
      "timestamp": "2026-06-18T12:45:30Z"
    }
  ],
  "window": {
    "hours": 168,
    "requestedHours": null,
    "startedAt": "2026-06-11T12:45:30Z",
    "endedAt": "2026-06-18T12:45:30Z"
  },
  "transportRequests": {
    "unavailable": false,
    "totalCount": 2,
    "sourceAttributedCount": 1,
    "sharedAgentCount": 1,
    "displayedCount": 1,
    "hasMore": true,
    "retentionDays": 30,
    "requests": [
      {
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "observedAt": "2026-06-18T12:45:30Z",
        "completedAt": "2026-06-18T12:45:31Z",
        "groupId": "dbg_550e8400-e29b-41d4-a716-446655440000",
        "attributionScope": "source",
        "origin": null,
        "destinationOrigin": null,
        "dispatchState": "remote_responded",
        "provenance": "remote_agent",
        "requestKind": "adcp_tool",
        "httpMethod": "POST",
        "adcpTool": "get_products",
        "protocolMethod": "tools/call",
        "outcome": "succeeded",
        "httpStatus": 200,
        "latencyMs": 120,
        "errorClass": null,
        "failureDomain": "none",
        "instrumentationGap": false,
        "requestHeaders": {},
        "requestBody": null,
        "requestBodyTruncated": false,
        "responseHeaders": {},
        "responseBody": null,
        "responseBodyTruncated": false,
        "statusText": null,
        "replayOfTransportRequestId": null,
        "replayEligible": false,
        "accountId": null,
        "mediaBuyId": null
      }
    ]
  }
}
```

## Transport attempts

`transportRequests` is optional while API and UI deployments roll out
independently. Current API responses include it, but clients must continue to
work when an older response does not. It is additive to `calls`; it does not
change the logical call history.

When `transportRequests.unavailable` is `true`, the transport-ledger lookup
was unavailable. The `calls` array is still returned, and the transport counts
and `requests` array are empty. Retry the request later if you need transport
attempt evidence.

| Field                                           | Type                           | Notes                                                                                                                                                                                                                                                  |
| ----------------------------------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `transportRequests`                             | object \| omitted              | Bounded physical transport-attempt evidence. Omitted only for backward compatibility with an older response.                                                                                                                                           |
| `transportRequests.unavailable`                 | boolean                        | `true` means transport evidence could not be read. Logical calls remain available.                                                                                                                                                                     |
| `transportRequests.totalCount`                  | integer                        | All matching transport attempts retained for the requested time range, before the response limit is applied.                                                                                                                                           |
| `transportRequests.sourceAttributedCount`       | integer                        | Matching attempts tied directly to an inventory source.                                                                                                                                                                                                |
| `transportRequests.sharedAgentCount`            | integer                        | Matching account-wide attempts tied to a shared Agent source rather than a single inventory source.                                                                                                                                                    |
| `transportRequests.displayedCount`              | integer                        | Number of attempt rows returned in `transportRequests.requests`.                                                                                                                                                                                       |
| `transportRequests.hasMore`                     | boolean                        | `true` when additional matching attempts exist beyond the returned rows.                                                                                                                                                                               |
| `transportRequests.retentionDays`               | integer                        | Days that transport-attempt evidence is retained.                                                                                                                                                                                                      |
| `transportRequests.requests`                    | array                          | Bounded attempt records with timing, attribution, dispatch, protocol, outcome, and replay metadata.                                                                                                                                                    |
| `transportRequests.requests[].attributionScope` | `"source"` \| `"agent_global"` | `source` is directly attributed to an inventory source. `agent_global` is shared-Agent/account-wide evidence. In an unfiltered account-wide feed it can relate to more than one source; pass `sourceId` before treating it as evidence for one source. |
| `transportRequests.requests[].observedAt`       | string                         | When Apostra observed the transport attempt.                                                                                                                                                                                                           |
| `transportRequests.requests[].outcome`          | string                         | Recorded transport outcome: `started`, `succeeded`, `http_error`, or `transport_error`.                                                                                                                                                                |
| `transportRequests.requests[].failureDomain`    | string                         | Recorded failure category, when any.                                                                                                                                                                                                                   |

The authorised REST response and Diagnostics Calls UI can include captured
transport detail, such as request and response headers or bodies. Treat those
fields as diagnostic records for authorised operators. Murph's tool response
uses only structural transport metadata and does not send those captured values
into model context.

| Field                     | Type                                                           | Notes                                                                                                                                                                                                                                        |
| ------------------------- | -------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `window.hours`            | number \| null                                                 | Trailing hours actually covered (`endedAt` − `startedAt`); may be fractional for a precise sub-hour `from`/`to` range. `null` only for an unbounded point lookup (a `taskId`/`debugId`/`correlationId` lookup with no `windowHours`/`from`). |
| `window.requestedHours`   | integer \| null                                                | The `windowHours` you asked for, or `null` if none was supplied. Compare against `window.hours` to see whether the lookback was narrowed.                                                                                                    |
| `window.startedAt`        | string \| null                                                 | Inclusive lower bound applied to the lookup. `null` means unbounded start.                                                                                                                                                                   |
| `window.endedAt`          | string                                                         | Inclusive upper bound applied to the lookup (your `to`, or now).                                                                                                                                                                             |
| `timestamp`               | string                                                         | When Apostra observed the request, response, webhook, or status activity.                                                                                                                                                                    |
| `userEmail`               | string \| null                                                 | Redacted email on the activity row when available.                                                                                                                                                                                           |
| `initiatorEmail`          | string \| null                                                 | Redacted email for the user who initiated the call. For sandbox tests, this is the Murph test-run user when the call can be matched to a test run.                                                                                           |
| `origin.kind`             | `"sandbox_test"` \| `"live_demand"`                            | `sandbox_test` means the call was linked to a Murph sandbox test run or uses Murph's sandbox test idempotency marker. `live_demand` means no sandbox test provenance was found, so treat it as non-test demand traffic.                      |
| `origin.testRunUid`       | string \| null                                                 | Test-run UID when the call can be matched to a Murph sandbox test run.                                                                                                                                                                       |
| `origin.testRunStatus`    | `"passed"` \| `"partial"` \| `"failed"` \| `"planned"` \| null | Status of the matched sandbox test run.                                                                                                                                                                                                      |
| `origin.testRunToolName`  | string \| null                                                 | Test-run tool name when available.                                                                                                                                                                                                           |
| `origin.testRunCreatedAt` | string \| null                                                 | Creation timestamp for the matched sandbox test run.                                                                                                                                                                                         |

## Provenance

Use `origin.kind` before interpreting a failure:

* `sandbox_test` calls were created by a technical validation flow. A failed
  sandbox call usually means the source or adapter needs setup, protocol, or
  credential work before launch.
* `live_demand` calls were not matched to Murph sandbox test metadata. Treat
  them as actual demand or other non-test traffic unless you have separate
  evidence that the caller was testing manually.

When `origin.kind` is `sandbox_test`, `initiatorEmail` identifies the redacted
test-run user when that user is available. When the test-run join is not
available, Murph falls back to the redacted activity-row user email.

## Errors

* `400 VALIDATION_ERROR` — invalid query parameter.
* `401 UNAUTHORIZED` — missing or invalid bearer token.
* `403 FORBIDDEN` — Murph is not enabled for the caller's account.

See [Errors](/v2/reference/errors) for the full error contract.
