Webhook · One endpoint · Any CI provider

Wire your CI to your Mac.

POST a small JSON payload from Bitrise, Codemagic, GitHub Actions, Xcode Cloud, or any shell script when a simulator-target build finishes. The Mac app surfaces it in seconds and (optionally) auto-launches Flow Recorder.

The endpoint

POST https://simpleappshipper.com/api/ci/build-completed
Content-Type: application/json
X-CI-Webhook-Token: <your shared secret>
X-Device-ID: <device id from your Mac app>       # optional, for anonymous flow
Authorization: Bearer <sas_session_token>        # optional, for signed-in flow

Request body

FieldTypeNotes
projectrequiredRepo name or Xcode project basename. Used to group builds.
branchoptionalGit branch name.
commit_shaoptionalFull or short SHA. Used for diffing in the Mac app.
version_stringoptionale.g. "2.4.0".
build_numberoptionale.g. "47".
artifact_urloptionalHTTPS URL to the .ipa / .pkg / .app. R2, S3, GitHub artifact, etc.
artifact_kindoptionalipa (default) · pkg · app
platformoptionalios (default) · macos · appletvos · visionos
ci_provideroptionalbitrise · codemagic · github · xcode-cloud · manual
ci_run_urloptionalLink back to the CI run for diagnostics.
statusoptionalcompleted (default) · failed · uploaded
metadataoptionalFree-form object — pass anything; stored as JSON for later display.

Response

200 OK
{
  "id": "01HV9X…",
  "accepted": true
}

Provider snippets

Bitrise (bash step)

#!/usr/bin/env bash
curl -fsS https://simpleappshipper.com/api/ci/build-completed \
  -H "Content-Type: application/json" \
  -H "X-CI-Webhook-Token: $SAS_WEBHOOK_TOKEN" \
  -H "X-Device-ID: $SAS_DEVICE_ID" \
  -d "{
    \"project\": \"$BITRISE_APP_TITLE\",
    \"branch\": \"$BITRISE_GIT_BRANCH\",
    \"commit_sha\": \"$BITRISE_GIT_COMMIT\",
    \"version_string\": \"$BITRISE_BUILD_VERSION\",
    \"build_number\": \"$BITRISE_BUILD_NUMBER\",
    \"artifact_url\": \"$BITRISE_PUBLIC_INSTALL_PAGE_URL\",
    \"ci_provider\": \"bitrise\",
    \"ci_run_url\": \"$BITRISE_BUILD_URL\"
  }"

Codemagic (codemagic.yaml)

scripts:
  - name: Notify Simple App Shipper
    script: |
      curl -fsS https://simpleappshipper.com/api/ci/build-completed \
        -H "Content-Type: application/json" \
        -H "X-CI-Webhook-Token: $SAS_WEBHOOK_TOKEN" \
        -H "X-Device-ID: $SAS_DEVICE_ID" \
        -d "{
          \"project\": \"$CM_PROJECT_NAME\",
          \"branch\": \"$CM_BRANCH\",
          \"commit_sha\": \"$CM_COMMIT\",
          \"version_string\": \"$CM_BUILD_VERSION\",
          \"build_number\": \"$CM_BUILD_NUMBER\",
          \"ci_provider\": \"codemagic\",
          \"ci_run_url\": \"$CM_BUILD_URL\"
        }"

GitHub Actions (.github/workflows/ios.yml)

- name: Notify Simple App Shipper
  if: success()
  env:
    SAS_WEBHOOK_TOKEN: ${{ '{{' }} secrets.SAS_WEBHOOK_TOKEN {{ '}}' }}
    SAS_DEVICE_ID:     ${{ '{{' }} secrets.SAS_DEVICE_ID {{ '}}' }}
  run: |
    curl -fsS https://simpleappshipper.com/api/ci/build-completed \
      -H "Content-Type: application/json" \
      -H "X-CI-Webhook-Token: $SAS_WEBHOOK_TOKEN" \
      -H "X-Device-ID: $SAS_DEVICE_ID" \
      -d "{
        \"project\": \"${{ '{{' }} github.event.repository.name {{ '}}' }}\",
        \"branch\": \"${{ '{{' }} github.ref_name {{ '}}' }}\",
        \"commit_sha\": \"${{ '{{' }} github.sha {{ '}}' }}\",
        \"ci_provider\": \"github\",
        \"ci_run_url\": \"${{ '{{' }} github.server_url {{ '}}' }}/${{ '{{' }} github.repository {{ '}}' }}/actions/runs/${{ '{{' }} github.run_id {{ '}}' }}\"
      }"

Xcode Cloud (post-build script)

Add a custom script under ci_post_xcodebuild.sh:

#!/usr/bin/env bash
curl -fsS https://simpleappshipper.com/api/ci/build-completed \
  -H "Content-Type: application/json" \
  -H "X-CI-Webhook-Token: $SAS_WEBHOOK_TOKEN" \
  -H "X-Device-ID: $SAS_DEVICE_ID" \
  -d "{
    \"project\": \"$CI_PRODUCT\",
    \"branch\": \"$CI_BRANCH\",
    \"commit_sha\": \"$CI_COMMIT\",
    \"version_string\": \"$CI_BUILD_NUMBER\",
    \"ci_provider\": \"xcode-cloud\",
    \"ci_run_url\": \"$CI_BUILD_URL\"
  }"

Anything else (curl)

The webhook is a plain HTTPS POST. Any tool that can run curl can wire to it.

What the Mac app does with these

  1. Lists recent builds in a "CI Builds" panel on the Shipment dashboard, grouped by project.
  2. Cross-references against the local XcodeBuildWatcher — when both fire for the same project, posts a single notification with one click to start Flow Recorder against the matching Simulator window.
  3. If artifact_url + artifact_kind are present and platform is macos / ios, offers a one-click "Upload to App Store Connect" action that re-uses the same altool wrapper (Transporter path) without needing to download the artifact manually.

Security