# list_deploy_hook_calls

Source: https://modulify.ai/docs/api/deploy-hooks/list-deploy-hook-calls

Lists the calls made to a site's deploy hooks, 30 to a page.

- Title: List deploy hook calls
- Scope: `config:read`
- Access: Read only
- Endpoint: `POST /v1/list_deploy_hook_calls`

Pass the returned `nextCursor` back as `cursor` for the next page. It is null once there is nothing more. This is the tool to reach for when someone asks why a hook did not start a build.

Each call carries its `Source`, which is `url` for the URL itself, `dashboard`, `chat`, `mcp`, or `api` for a call made through the HTTP API. It also carries the caller's IP address and user agent, or the member who called it.

`Outcome` says what the call did. `started` started a build, and `already-building` arrived while a build was running, so it started nothing and queued nothing, which is not an error.

`disabled` hit a hook that is turned off, and `refused` means the publish was refused, with the reason in `Reason`. `rate-limited` means the hook was called more than 10 times in a minute, and only the first refused call of such a burst is logged. `failed` means something went wrong starting the build.

`Deployment` is the build a call started or joined, with its `Status`, so a call that started a build can still point at a publish that failed later. Calls are kept until the log is cleared. See [Deploy hooks](https://modulify.ai/docs/automations/deploy-hooks#read-the-call-log).

## Request

Call it with a `POST` to `https://api.modulify.ai/v1/list_deploy_hook_calls`, sending the inputs below as a JSON object. The token needs the `config:read` scope.

It only reads and changes nothing, so retrying it is safe.

```bash
curl -X POST https://api.modulify.ai/v1/list_deploy_hook_calls \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"projectId":"PROJECT_ID"}'
```

Over MCP, the same method is the [list_deploy_hook_calls tool](https://modulify.ai/docs/mcp/deploy-hooks/list-deploy-hook-calls).

## Inputs

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `projectId` | string | Yes | The site id. |
| `hookId` | string | No | Only calls to this one hook, by its id from `list_deploy_hooks`. Leave it out for the calls to every hook on the site. |
| `outcome` | string | No | Which calls to keep, `all`, `started`, `already-building`, or `rejected` for every call that started nothing for another reason (`disabled`, `refused`, `rate-limited` and `failed`). Defaults to `all`. |
| `sort` | string | No | `newest` first, the default, or `oldest` to walk the log forward from the beginning. |
| `cursor` | string | No | The `nextCursor` from the previous page. Leave it out for the first page. |

## Response

Every call answers with the [JSON envelope](https://modulify.ai/docs/api/requests-and-responses#the-response) of `success`, `message`, `data`, `code` and `version`. `data` holds the result described above, and on a method that returns a total, `count` carries it. The [response headers](https://modulify.ai/docs/api/requests-and-responses#headers-on-every-method-call) carry the call's `X-Request-Id` and what is left of your per-minute budget in `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset`. [Errors](https://modulify.ai/docs/api/errors) explains every status code a call can answer with.