---
title: "Create Integration"
method: POST
path: "/parents/{parent_id}/integrations"
tags: ["integrations"]
---

# Create Integration

`POST /parents/{parent_id}/integrations`

## 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`
- Auth: HTTP bearer

## Path parameters

- `parent_id` string, required

## Request body

- CreateIntegrationRequest
  - `provider` 'verkada' | 'turing' | 'avertx', required
  - `label` string, required: Operator-facing name for this connection. Unique per client and provider (compared trimmed and case-insensitively).
  - `api_key` string, password, required: Provider credential: a Verkada API key, or a Turing Vision third-party access token. WRITE-ONLY: stored in Secrets Manager and never returned by any endpoint, log line, or activity-log entry. Mint a dedicated, view-only credential for Verdun rather than reusing an administrative one.
  - `org_id` string, nullable: Provider organization id. NOT a secret — stored in the clear for display, and also inside the credential secret. Optional at this layer, and NOT required by every provider: Verkada scopes every stream URL by org and rejects a connection without one, while a Turing access token is already org-scoped and takes no org parameter on any endpoint.
  - `username` string, nullable: AvertX only, and required for it: the AvertX Connect sign-in email of the Verdun user the customer added to their account (Manage Users). With provider=avertx, `api_key` is that user's PASSWORD and `org_id` is the account's company code (the `cm=` value in connect.avertx.com URLs, e.g. `Z6WQ7G`). Not a secret; stored inside the credential secret. Ignored by Verkada and Turing.
  - `command_short_name` string, nullable: The vendor console's organization short name (the subdomain in https://<short-name>.command.verkada.com/...). Owner-entered and never fetched from the provider. Lowercase letters, digits and hyphens only. Send null or an empty string to clear it.
  - `site_ids` string[]: Sites to assign this connection to on creation, in the same transaction. Every site must be a live site of this client and none may already use a connection of this provider. Duplicates are ignored.

## Response `200`

Successful Response

- SiteIntegrationResponse: One cloud-VMS connection. There is deliberately NO api_key field and NO secret_arn field. The key never leaves Secrets Manager, and the ARN is an internal handle with no client-facing use (the same omission as NvrResponse / the speaker responses). Because FastAPI serializes through this model, a field that somehow appeared in the service dict would be dropped here rather than reaching a client — a second layer under to_dict_complete's omission, and the property the router leak test pins.
  - `id` string, uuid, required: The integration record ID.
  - `parent_id` string, uuid, required: The client this connection belongs to. The credential is client-level; WHICH SITES it serves is `site_ids`.
  - `provider` 'verkada' | 'turing' | 'avertx', required
  - `label` string, required: Operator-facing name for this connection.
  - `external_org_id` string, nullable: Provider organization id (non-secret), for display.
  - `command_short_name` string, nullable: The vendor console's organization short name (the subdomain in https://<short-name>.command.verkada.com/...). Owner-entered, never fetched from the provider, and used only to build an operator's deep link. A Verkada concept: providers whose console has no such deep link leave it null.
  - `status` 'active' | 'error', required
  - `last_verified_at` string, date-time, nullable: When the connection last tested successfully.
  - `last_error` string, nullable: Most recent connection-test failure, sanitized and truncated. Never contains a credential.
  - `site_ids` string[]: The live sites this connection is assigned to, ordered by id. Empty means UNASSIGNED: the connection is listed and manageable but no site uses it yet. Absent from payloads of older servers (read as empty).
  - `created_at` string, date-time, required: When the connection was created.
  - `updated_at` string, date-time, nullable: When the connection was last modified.

## 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/00252d8227c1?raw)
