---
title: "Onboard Integration Cameras"
method: POST
path: "/parents/{parent_id}/integrations/{integration_id}/onboard"
tags: ["integrations"]
---

# Onboard Integration Cameras

`POST /parents/{parent_id}/integrations/{integration_id}/onboard`

## Request

- Base URL: `https://api.verdun.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.verdun.ai/parents/{parent_id}/integrations/{integration_id}/onboard`
- Auth: HTTP bearer

## Path parameters

- `parent_id` string, required
- `integration_id` string, required

## Request body

- OnboardIntegrationCamerasRequest: Bulk-onboard selected vendor devices into one Verdun site. NOTE WHAT IS ABSENT: there is no `rtsp_url` field, and there never should be. A bridge-fed camera's source address is derived server-side from the deployment's bridge template — a client-supplied address would let the caller point a monitored camera at a host of its choosing.
  - `site_id` string, uuid, required: The Verdun site the cameras are created under. Must belong to the client in the path.
  - `devices` OnboardIntegrationDevice[], required: Vendor devices to onboard.
    - `device_id` string, required: The VENDOR's camera id, as returned by GET /parents/{parent_id}/integrations/{integration_id}/cameras.
    - `camera_label` string, nullable: Display label; defaults to the name the vendor reports for the device.
    - `camera_id` string, nullable: Verdun camera_id; defaults to a slug of the label, uniquified within the site.
  - `defaults` OnboardIntegrationDefaults
    - `ingest_mode` 'continuous' | 'motion_clip'
    - `motion_config` object, nullable: Extensible motion settings with bounded known keys (timings, thresholds, detector geometry/rate and RTSP buffer mode); see app/services/motion_config_validation.py. Unknown keys are preserved.
    - `analytics_provider` 'none' | 'deepalert'
    - `analytics_config` object, nullable: Opaque per-vendor analytics settings interpreted by the ingestor.

## Response `200`

Successful Response

- OnboardIntegrationCamerasResponse: PARTIAL SUCCESS IS THE CONTRACT — read `results`, not the status code. The call commits per device, so a 200 can describe any mix of created, failed and skipped. This mirrors the NVR bulk-onboard contract exactly.
  - `results` OnboardIntegrationResult[], required: Per-device outcome, in request order.
    - `device_id` string, required: The vendor's camera id this result is for.
    - `status` 'created' | 'failed' | 'skipped_already_onboarded', required: What happened to this device.
    - `camera_id` string, nullable: The created camera's camera_id (slug), when created.
    - `camera_uuid` string, uuid, nullable: The created camera's UUID, when created.
    - `kvs_stream_name` string, nullable: The created camera's KVS stream name, when created.
    - `error` string, nullable: Failure detail, when failed. Sanitized — never carries the vendor API key.
    - `assigned_site` boolean: True when creating this camera also ASSIGNED its site to the connection (the site had no connection of this provider yet). False otherwise, including every non-created row.
  - `created` integer, required: Number of cameras created.
  - `failed` integer, required: Number of devices that failed.
  - `skipped` integer, required: Number of devices skipped because they were already onboarded.

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/verdun/apis/verdun-api.md) - [All operations](https://skmtc.dev/verdun/apis/verdun-api/llms.txt) - [OpenAPI document](https://skmtc.dev/verdun/apis/verdun-api/revisions/a19366be50a3?raw)
