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

# Webhooks

# webhooks

> Manage App Store Connect webhooks for event notifications

Manage webhooks in App Store Connect to receive real-time notifications about events like subscription changes, build processing, and review updates.

## Quick Start

```bash theme={null} theme={null}
asc webhooks list --app "APP_ID"
asc webhooks create --app "APP_ID" --name "Build Updates" --url "https://example.com/webhook" --secret "secret123" --events "SUBSCRIPTION.CREATED,SUBSCRIPTION.UPDATED" --enabled true
asc webhooks serve --port 8787 --dir ./webhook-events
```

## Subcommands

* `list` - List webhooks for an app
* `get` - Get a webhook by ID
* `create` - Create a webhook
* `update` - Update a webhook
* `delete` - Delete a webhook
* `serve` - Run a local webhook receiver for testing
* `deliveries` - List webhook deliveries
* `ping` - Create a webhook ping

## Commands

### webhooks list

List webhooks for an app:

```bash theme={null} theme={null}
asc webhooks list --app "APP_ID"
asc webhooks list --app "APP_ID" --limit 10
asc webhooks list --app "APP_ID" --paginate
```

**Flags:**

* `--app` - App Store Connect app ID (or `ASC_APP_ID`)
* `--limit` - Maximum results per page (1-200)
* `--next` - Fetch next page using a links.next URL
* `--paginate` - Automatically fetch all pages
* `--output` - Output format: `json`, `table`, `markdown`
* `--pretty` - Pretty-print JSON output

### webhooks get

Get a webhook by ID:

```bash theme={null} theme={null}
asc webhooks view --webhook-id "WEBHOOK_ID"
```

**Flags:**

* `--webhook-id` - Webhook ID (required)
* `--output` - Output format: `json`, `table`, `markdown`
* `--pretty` - Pretty-print JSON output

### webhooks create

Create a webhook:

```bash theme={null} theme={null}
asc webhooks create \
  --app "APP_ID" \
  --name "Build Updates" \
  --url "https://example.com/webhook" \
  --secret "secret123" \
  --events "SUBSCRIPTION.CREATED,SUBSCRIPTION.UPDATED" \
  --enabled true
```

**Flags:**

* `--app` - App Store Connect app ID (or `ASC_APP_ID`)
* `--name` - Webhook name (required)
* `--url` - Webhook endpoint URL (required)
* `--secret` - Webhook secret (required)
* `--events` - Webhook event types, comma-separated (required)
* `--enabled` - Enable or disable the webhook: `true` or `false` (required)
* `--output` - Output format: `json`, `table`, `markdown`
* `--pretty` - Pretty-print JSON output

### webhooks update

Update a webhook:

```bash theme={null} theme={null}
asc webhooks update --webhook-id "WEBHOOK_ID" --url "https://new-url.com/webhook"
asc webhooks update --webhook-id "WEBHOOK_ID" --enabled false
```

**Flags:**

* `--webhook-id` - Webhook ID (required)
* `--name` - Webhook name
* `--url` - Webhook endpoint URL
* `--secret` - Webhook secret
* `--events` - Webhook event types, comma-separated
* `--enabled` - Enable or disable the webhook: `true` or `false`
* `--output` - Output format: `json`, `table`, `markdown`
* `--pretty` - Pretty-print JSON output

### webhooks delete

Delete a webhook:

```bash theme={null} theme={null}
asc webhooks delete --webhook-id "WEBHOOK_ID" --confirm
```

**Flags:**

* `--webhook-id` - Webhook ID (required)
* `--confirm` - Confirm deletion (required)
* `--output` - Output format: `json`, `table`, `markdown`
* `--pretty` - Pretty-print JSON output

### webhooks serve

Run a local webhook receiver for testing and automation:

```bash theme={null} theme={null}
asc webhooks serve --port 8787
asc webhooks serve --port 8787 --dir ./webhook-events
asc webhooks serve --port 8787 --exec "./scripts/on-webhook.sh"
```

**Flags:**

* `--host` - Host to bind the local webhook receiver (default: `127.0.0.1`)
* `--port` - Port to bind the local webhook receiver (0-65535, default: `8787`)
* `--dir` - Optional directory to write one JSON payload file per event
* `--exec` - Optional command to execute per event (payload JSON is piped on stdin)
* `--output` - Output format: `text` (default), `json`
* `--max-body-bytes` - Maximum accepted request body size in bytes (default: 1048576)

**Features:**

* Accepts webhook POSTs at `http://host:port/`
* Validates JSON payloads
* Writes timestamped payload files when `--dir` is set
* Executes custom scripts with `--exec` (payload on stdin)
* Queue-based processing with 4 concurrent workers
* Configurable request body size limits

**Example startup output:**

```bash theme={null} theme={null}
$ asc webhooks serve --port 8787 --dir ./webhook-events
Listening for webhook events on http://127.0.0.1:8787
```

**Event file naming:**

Files are written as `{timestamp}-{index}-{event-type}.json`:

```
20260304T123456.789012345Z-000001-subscription_created.json
20260304T123501.234567890Z-000002-subscription_updated.json
```

### webhooks deliveries

List webhook deliveries:

```bash theme={null} theme={null}
asc webhooks deliveries --webhook-id "WEBHOOK_ID" --created-after "2026-01-01T00:00:00Z"
asc webhooks deliveries --webhook-id "WEBHOOK_ID" --limit 10
asc webhooks deliveries --webhook-id "WEBHOOK_ID" --paginate
```

**Flags:**

* `--webhook-id` - Webhook ID (required)
* `--created-after` - Filter deliveries created after or equal to a timestamp
* `--created-before` - Filter deliveries created before a timestamp
* `--limit` - Maximum results per page (1-200)
* `--next` - Fetch next page using a links.next URL
* `--paginate` - Automatically fetch all pages
* `--output` - Output format: `json`, `table`, `markdown`
* `--pretty` - Pretty-print JSON output

**Note:** Either `--created-after` or `--created-before` is required (mutually exclusive).

### webhooks deliveries links

List webhook delivery relationships:

```bash theme={null} theme={null}
asc webhooks deliveries links --webhook-id "WEBHOOK_ID"
asc webhooks deliveries links --webhook-id "WEBHOOK_ID" --paginate
```

**Flags:**

* `--webhook-id` - Webhook ID (required)
* `--limit` - Maximum results per page (1-200)
* `--next` - Fetch next page using a links.next URL
* `--paginate` - Automatically fetch all pages
* `--output` - Output format: `json`, `table`, `markdown`
* `--pretty` - Pretty-print JSON output

### webhooks deliveries redeliver

Redeliver a webhook delivery:

```bash theme={null} theme={null}
asc webhooks deliveries redeliver --delivery-id "DELIVERY_ID"
```

**Flags:**

* `--delivery-id` - Webhook delivery ID (required)
* `--output` - Output format: `json`, `table`, `markdown`
* `--pretty` - Pretty-print JSON output

### webhooks ping

Create a webhook ping:

```bash theme={null} theme={null}
asc webhooks ping --webhook-id "WEBHOOK_ID"
```

**Flags:**

* `--webhook-id` - Webhook ID (required)
* `--output` - Output format: `json`, `table`, `markdown`
* `--pretty` - Pretty-print JSON output

## Event Types

Common webhook event types:

* `SUBSCRIPTION.CREATED`
* `SUBSCRIPTION.UPDATED`
* `SUBSCRIPTION.RENEWED`
* `SUBSCRIPTION.EXPIRED`
* `BUILD.PROCESSING`
* `BUILD.PROCESSED`
* `VERSION.REVIEW_STATUS_CHANGED`

See the [App Store Connect API documentation](https://developer.apple.com/documentation/appstoreconnectapi/app_store_connect_api_webhooks) for a complete list.

## Local Testing Workflow

1. Start the local webhook receiver:
   ```bash theme={null} theme={null}
   asc webhooks serve --port 8787 --dir ./webhook-events
   ```

2. Use a tunnel service (ngrok, Cloudflare Tunnel) to expose the local server:
   ```bash theme={null} theme={null}
   ngrok http 8787
   ```

3. Create a webhook in App Store Connect pointing to the tunnel URL:
   ```bash theme={null} theme={null}
   asc webhooks create \
     --app "APP_ID" \
     --name "Test Webhook" \
     --url "https://abc123.ngrok.io" \
     --secret "test-secret" \
     --events "SUBSCRIPTION.CREATED" \
     --enabled true
   ```

4. Trigger events in App Store Connect and watch the local receiver log incoming events

5. Clean up:
   ```bash theme={null} theme={null}
   asc webhooks delete --webhook-id "WEBHOOK_ID" --confirm
   ```
