> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://tester.army/docs/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://tester.army/_mcp/server.

# Group Webhooks

Group webhooks let you run every test in a group with one HTTP call. Works with any CI/CD pipeline, deployment tool, or custom automation.

## Setup

1. Open your project → **Tests** tab.
2. Expand a group and click the **trigger badge** (lightning icon).
3. Toggle **Enable webhook** on. The webhook is created and activated immediately.
4. Copy the URL - the secret is shown once.

## Trigger

```bash
curl -X POST https://tester.army/api/v1/groups/webhook/{id}/{secret}
```

Enabled tests in the group are queued against the project's configured URL. Disabled tests are skipped.

### Optional body

You can pass JSON to attach commit metadata:

```bash
curl -X POST https://tester.army/api/v1/groups/webhook/{id}/{secret} \
  -H "Content-Type: application/json" \
  -d '{
    "commitSha": "abc123"
  }'
```

For stable staging, QA, or other saved targets, prefer `projectEnvironmentId`:

```bash
curl -X POST https://tester.army/api/v1/groups/webhook/{id}/{secret} \
  -H "Content-Type: application/json" \
  -d '{
    "commitSha": "abc123",
    "projectEnvironmentId": "00000000-0000-0000-0000-000000000000"
  }'
```

If you have [saved environments](/guides/environments) in the project, static
environments use their configured URL and environment-specific credential
overrides. You can copy environment IDs from **Project Settings → Test environments**
or fetch them with `GET /api/v1/projects/{projectId}`.

For one-off URLs, pass `targetUrl`. You can also set `environment` to control how
the run appears in the results list:

* `production`
* `staging`
* `preview`

If you pass `targetUrl` without `environment`, the run is marked as `preview`.
Use `environment: "staging"` for staging deployment tests.

```bash
curl -X POST https://tester.army/api/v1/groups/webhook/{id}/{secret} \
  -H "Content-Type: application/json" \
  -d '{
    "commitSha": "abc123",
    "targetUrl": "https://staging.example.com",
    "environment": "staging"
  }'
```

`environment: "staging"` only controls the Results environment label. It does
not select a saved environment row or its credential overrides.

### Choosing the run platform

Mobile tests are stored without a fixed platform, so the webhook decides which one
to run. Pass `platform` to choose it:

`platform` defaults to `ios` when omitted. An Android batch must set `"platform": "android"` —
otherwise the run is planned as iOS and any Android mobile app override fails with
`InvalidMobileApp` / "Selected mobile app was not found for this project", even though the app
exists in the dashboard.

```bash
curl -X POST https://tester.army/api/v1/groups/webhook/{id}/{secret} \
  -H "Content-Type: application/json" \
  -d '{
    "platform": "android"
  }'
```

A group cannot mix iOS and Android tests in one mobile request — split the group
or trigger one platform at a time.

### Mobile app override

You can override the app build used by mobile tests in the group. The build must match the requested run platform (`ios` or `android`), so send `platform` alongside the override for Android.

**By bundle ID** — resolves to the latest uploaded app matching that bundle identifier:

```bash
curl -X POST https://tester.army/api/v1/groups/webhook/{id}/{secret} \
  -H "Content-Type: application/json" \
  -d '{
    "platform": "ios",
    "mobile": {
      "bundleId": "com.example.app",
      "buildId": "44"
    }
  }'
```

**By app ID** — targets a specific uploaded build by its UUID (returned from the upload API):

```bash
curl -X POST https://tester.army/api/v1/groups/webhook/{id}/{secret} \
  -H "Content-Type: application/json" \
  -d '{
    "platform": "ios",
    "mobile": {
      "appId": "<YOUR APP UPLOAD ID>"
    }
  }'
```

Use `appId` when multiple builds share the same bundle ID and you need to pin a specific upload.

For an Android build, the same call with `"platform": "android"`:

```bash
curl -X POST https://tester.army/api/v1/groups/webhook/{id}/{secret} \
  -H "Content-Type: application/json" \
  -d '{
    "platform": "android",
    "mobile": {
      "appId": "<YOUR ANDROID APP UPLOAD ID>"
    }
  }'
```

**By remote artifact** — provide an HTTPS URL and filename for remote build artifacts:

```bash
curl -X POST https://tester.army/api/v1/groups/webhook/{id}/{secret} \
  -H "Content-Type: application/json" \
  -d '{
    "platform": "ios",
    "mobile": {
      "artifactUrl": "https://example.com/builds/MyApp.app.zip",
      "artifactFilename": "MyApp.app.zip",
      "buildId": "eas-982"
    }
  }'
```

For Android, pass `"platform": "android"` with an `.apk` artifact — the artifact
extension must match the requested platform.

Only one of `bundleId`, `appId`, or `artifactUrl` can be provided per request.

### Response

```json
{
  "received": true,
  "status": "queued",
  "runIds": ["uuid-1", "uuid-2"],
  "count": 2
}
```

When the batch contains mobile tests, the response includes `metadata.mobile`:

```json
{
  "received": true,
  "status": "queued",
  "runIds": ["uuid-1", "uuid-2"],
  "count": 2,
  "metadata": {
    "mobile": {
      "resolvedAppId": "11111111-1111-1111-8111-111111111111",
      "source": "app_id",
      "buildId": "44",
      "temporary": false
    }
  }
}
```

* `source: "test_default"` means each mobile test used its saved app selection.
* `source: "app_id"` means the webhook used an already uploaded project app, selected by `bundleId` or `appId`.
* `source: "artifact_url"` means TesterArmy imported the artifact for this batch.

Artifact-imported apps are temporary. They are removed automatically after every run in the webhook batch reaches a terminal state.

## Failure notifications

When a webhook-triggered batch completes and any test fails, TesterArmy sends the failure summary to connected chat providers such as [Slack](/integrations/slack) or [Discord](/integrations/discord). If no chat provider delivers, TesterArmy falls back to email.

Batches triggered with `commitSha` can still report status back through GitHub, but chat notifications remain project-level alerts for the completed batch.

## Limits

* **1 webhook per group.** The secret is shown once. If it is lost, use **Regenerate** in the group's trigger panel; the previous URL stops working immediately.
* Subject to your team's usage limits - returns `429` if exceeded.
* Webhook must be **active** to accept requests. Toggling **Enable webhook** off deactivates it (the URL is preserved); a deactivated webhook returns `403`.