INTEGRATE

Webhooks: external events to package jobs

HTTPS trigger examples, response JSON, package matching, request failures, retries and tracing.

Examples use remoteops.example.com and fictional systems. Adapt them to your tenant.

Screen reference#

HTTPS webhook request and accepted-job response
HTTPS webhook request and accepted-job response

The example response matches the product response fields. Accepted means the saved package started, not that its endpoint action completed.

Webhook source and job status
Webhook source and job status

The triggering webhook and source IP appear on the job row. These fictional records illustrate how to follow the returned job ID.

Dispatch output and endpoint child job
Dispatch output and endpoint child job

Expand the parent job to read the dispatched result and child job ID, then inspect the endpoint job for the actual helper result.

What a RemoteOps webhook does#

An external system sends POST to https://remoteops.example.com/api/webhook?id=IDENTIFIER. RemoteOps finds saved packages with an exact matching literal webhook ID and starts them asynchronously. One identifier can match more than one package. This is a saved-workflow trigger, not a command-execution endpoint or a mechanism for passing arbitrary request-body fields into tasks.

The tenant address is illustrative. Replace it with your own tenant, not the marketing website. No portal session or administrator API key is required for this public trigger route: possession of the identifier authorises the trigger. Use a long randomly generated ID, keep it secret, and send requests only over HTTPS.

Create the package#

yaml
- webhook: doorbell_demo_REPLACE_WITH_RANDOM_ID
- timeout: 300
- task: rtsps_stream
  name: show_front_door
  agent: 'ATLAS-DESK'
  url: 'rtsps://camera.example.com:7441/front-door?enableSrtp'
  display_for_seconds: 30
  bell: true
  max_age_seconds: 60
  continue_on_error: false

Save the package as Front Door camera. Test the configured target and stream manually before enabling the external event source. The screenshot uses a fictional scene, not a live camera connection.

ID rules#

The ID is case-sensitive, starts with a letter or digit, and contains at most 128 letters, digits, dots, underscores or hyphens. Use one ID per independently controlled integration unless you deliberately want one event to fan out to multiple packages. Do not use the short demonstration identifier in production.

Call it with curl#

sh
curl --fail-with-body --connect-timeout 10 --max-time 30 -i \
  -X POST \
  'https://remoteops.example.com/api/webhook?id=doorbell_demo_REPLACE_WITH_RANDOM_ID'

The request needs no JSON body. The -i option shows the HTTP status and response headers. A network timeout can occur after RemoteOps accepted the job; do not blindly retry a workflow with external side effects.

Call it from PowerShell#

powershell
$tenant = 'https://remoteops.example.com'
$webhookId = 'doorbell_demo_REPLACE_WITH_RANDOM_ID'
$uri = "$tenant/api/webhook?id=$([Uri]::EscapeDataString($webhookId))"
$result = Invoke-RestMethod -Method Post -Uri $uri -TimeoutSec 30
$result.jobs | Select-Object packageName, id, status, error
if ($result.failed -gt 0) {
    throw 'One or more matching packages could not be started. Inspect the returned jobs.'
}

Do not print the webhook URL or identifier into shared logs. The example selects result fields rather than dumping an entire invocation URL.

Call it from Python#

python
import json
from urllib.parse import urlencode
from urllib.request import Request, urlopen

tenant = 'https://remoteops.example.com'
query = urlencode({'id': 'doorbell_demo_REPLACE_WITH_RANDOM_ID'})
request = Request(f'{tenant}/api/webhook?{query}', data=b'', method='POST')
with urlopen(request, timeout=30) as response:
    result = json.load(response)
for job in result['jobs']:
    print(job['packageName'], job['id'], job['status'])

Adapt exception handling and event-source logging for your integration. Keep IDs in protected configuration, not a public client-side script.

Understand HTTP 202 and its response#

json
{
  "webhook": "doorbell_demo_REPLACE_WITH_RANDOM_ID",
  "triggered": 1,
  "failed": 0,
  "jobs": [
    {
      "packageName": "Front Door camera",
      "id": "00000000-0000-4000-8000-000000000029",
      "status": "accepted"
    }
  ]
}
Field Meaning
webhook Matched identifier; treat response logs as potentially containing the secret
triggered Number of matching packages successfully started
failed Number of matching packages that could not be started
jobs[].packageName Saved package that matched the ID
jobs[].id Job ID, or null when an ID could not be recorded
jobs[].status Start outcome: accepted or failed
jobs[].error Present for a failed start

HTTP 202 Accepted means at least one package started. It does not mean the camera opened, an email arrived or the package completed. A multi-package result can include both accepted and failed starts; inspect every array entry.

Error handling#

Result Investigate
400 Missing or invalid identifier
404 No saved package matches the exact ID
503 No matching package could be started, or a service/storage failure prevented dispatch
TLS or network error Tenant address, HTTPS, certificate trust and event-source reachability
202 but no visible desktop action Job status, target availability, interactive user, stale-event result and stream startup

The application can still fail later after a successful 202. Use returned job IDs and portal Job History for completion. Webhook jobs include the triggering ID and the validated source IP supplied by the trusted proxy; use those details to trace an event. Do not spoof the source with an untrusted forwarded header.

Doorbell or event-relay setup#

  1. Save and test the package on a permitted test target.
  2. Generate a long ID and update the literal package metadata.
  3. Configure the event relay to POST to the tenant's HTTPS webhook URL when the doorbell is pressed.
  4. Apply source-side debounce/rate limits for repeated press/motion events.
  5. Trigger once, inspect the 202 response and then the actual Job History result.
  6. Verify the overlay closes and that old queued events are suppressed according to the freshness policy.

A doorbell with no outbound HTTPS action needs an intermediary automation/event relay. The route does not itself discover cameras, subscribe to a vendor event bus, unlock doors or transform a motion event into package inputs.

Retries and duplicate events#

There is no caller-supplied idempotency contract in this route. Repeated requests can create repeated jobs. Debounce at the event source and avoid automatic retries after ambiguous timeouts. If your workflow writes a Data Store checkpoint, design and test its concurrency behavior; an ordinary read followed by a write is not an atomic deduplication lock.

To rotate an ID, update the saved package and event-source configuration, then verify that the new ID works and the old ID no longer matches any package. Changing a package's metadata does not cancel a job that already started. Reuse of an ID across packages must be intentional.

More event-driven workflows#

For an outbound HTTPS call from a package, use the separate example in Integrations. Incoming webhook triggers and outbound API calls have different authentication, retry and response contracts.

Product screenshot