Develop a physical access control system integration with Camio quickly and easily by posting access control devices and events to the Camio API.

## Devices (badge readers)

In order for Camio to know the user's available access control devices, send a payload to [https://incoming.integrations.camio.com/pacs/devices](https://incoming.integrations.camio.com/pacs/devices) when setting up the integration and whenever the user's devices are updated. See the payload described in the [API to POST Devices](https://help.camio.com/hc/en-us/articles/4409631039892-How-do-I-create-a-Physical-Access-Control-System-integration-Developer-s-Guide#h_01HE5V7MQPT7PC82VB35B6KN39).

This way, Camio can display the available devices on the user's settings page:

**The user must select which access control devices are in view of which camera so that Camio can correlate the access control events with the associated video.**

Note that POSTs to the [https://incoming.integrations.camio.com/pacs/devices](https://incoming.integrations.camio.com/pacs/devices) endpoint overwrite the user's stored devices, but Camio won't forget currently configured devices unless the user removes them from the integration on the settings page. Remove the devices assigned to a camera by clicking the x next to the device names and hitting Save.

## Access Control Events

When a new access control event occurs, such as a door unlock, send information to [https://incoming.integrations.camio.com/pacs/webhooks](https://incoming.integrations.camio.com/pacs/webhooks). By including the user's authorization token and the access device's id, Camio matches the access control event to the user's video. Any labels you add to the video become searchable. See the payload described in the [API to POST Events](https://help.camio.com/hc/en-us/articles/4409631039892-How-do-I-create-a-Physical-Access-Control-System-integration-Developer-s-Guide#h_01HE5V9Q0XNKSZN29AYZ427TPP).

## API Calls

|     |     |
| --- | --- |
| Method + URL | Examples |
| ### Devices |  |
| **POST** [**/pacs/devices**](https://incoming.integrations.camio.com/pacs/devices) | **Payload**

```
{
  "devices": [\
    {\
      "device_id": "{{unique_id}}",\
      "device_name": "{{display_name}}"\
    },\
    ...\
  ]
}
```

**Curl**

```
curl --location --request POST 'https://incoming.integrations.camio.com/pacs/devices' \
--header 'Authorization: Bearer 42g-D0T41A5HIu4ssrlJgepKRGLgA-s' \
--header 'Content-Type: application/json' \
--data-raw '{\
    "devices": [\
        {\
            "device_id": "testDevice0129397",\
            "device_name": "Test Device"\
        },\
        ...\
    ]\
}'
```

**Response Codes**

|     |     |
| --- | --- |
| 200/204 | Success. No payload is returned. |
| 400/422 | Bad request / Malformed payload. Check that the payload you sent matches the example above. An empty payload also will return a 422. |
| 401 | Unauthorized. Most likely missing the Authorization header. |
| 405 | Method not allowed. Only supports GET and POST. |
| 500 | Server error. Something unexpected went wrong. If this does not seem to be a transient error, please contact [support@camio.com](mailto:support@camio.com) for help resolving this error. | |  
| **GET** [**/pacs/devices**](https://incoming.integrations.camio.com/pacs/devices) | **Payload**

None

**Curl**

```
curl --location --request GET 'https://incoming.integrations.camio.com/pacs/devices' \
--header 'Authorization: Bearer 42g-D0T41A5HIu4ssrlJgepKRGLgA-s'
```

**Response Codes**

|     |     |
| --- | --- |
| 200 | Success. Returns a json payload in the same format as the POST above. Ex:<br>```<br>{<br>  "readers": [<br>    {<br>      "integration_name": "pacs",<br>      "device_id": "testDevice0129397",<br>      "device_name": "Test Device"<br>    },<br>    ...<br>  ]<br>}<br>``` |
| 401 | Unauthorized. Most likely missing the Authorization header. |
| 405 | Method not allowed. Only supports GET and POST. |
| 404 | Not found. No stored devices found for the user.<br>```<br>{<br>"detail": "No devices found for {{user_id}}"<br>}<br>``` |
| 500 | Server error. Something unexpected went wrong. If this does not seem to be a transient error, please contact [support@camio.com](mailto:support@camio.com) for help resolving this error. | |  
| ### **Events** |  |
| **POST** [**/pacs/webhooks**](https://incoming.integrations.camio.com/pacs/webhooks) | **Payload**

Only **device_id**, **timestamp**, **event_type**, and **actor_id** are required.

```
{
   # Either event or events is required
   "event": {
        "device_id": {{unique_id}},
        "timestamp": {{ISO8601_datetime_UTC_string}},
        "event_type": {{valid_event_type}},
        "labels": [{{any_string}}],
        "actor_id": {{any_string}},
        "actor_name": {{any_string}},
        "actor_email": {{valid@email.com}}
   },
   "events": [\
      ... # List of access events, structured the same way as event above\
   ]
}
```

**Curl**

```
curl --location --request POST 'https://incoming.integrations.camio.com/pacs/webhooks' \
--header 'Authorization: Bearer 42g-D0T41A5HIu4ssrlJgepKRGLgA-s' \
--header 'Content-Type: application/json' \
--data-raw '{
   "event": {
      "timestamp": "2023-08-04T22:28:44.989-0000",
      "event_type": "Entry Unlocked",
      "device_id": "testDevice0129397",
      "actor_id": "T.Smith0129486",
      "actor_name": "Tester Smith",
      "actor_email": "tsmith@gmail.com",
      "labels": [\
        "South Entry",\
        "Building 5"\
      ]
   }}'
```

**Valid Event Types**

Valid event types are searchable with additional natural language queries and may go through additional analysis such as tailgating detection.

|     |
| --- |
| **event_type (not case sensitive)** |
| entry unlocked |
| forced open |
| entry ajar |

**Response Codes**

|     |     |
| --- | --- |
| 200 | Success. A payload is returned that includes the annotations that will be applied to any matching Camio events, as well as the estimated time that the annotations request will go through:<br>```<br>{<br>   "annotation_request": {<br>   "user_id": "...",<br>   "annotations": [{<br>      "timestamp": "2023-08-04T22:28:44.989000+00:00",<br>      "cameras": [{<br>        "camera_id": "...",<br>        "user_id": "..."<br>      }],<br>      "labels_to_add": [<br>        "integration:pacs",<br>        "entry.unlocked",<br>        "T.Smith0129486_entry.unlocked",<br>        "tester_smith_entry.unlocked",<br>        "tsmith@gmail.com_entry.unlocked",<br>        "pacs:entry.unlocked:2023-08-04T22:28:44.989000+00:00",<br>        "integration:pacs:2023-08-04T22:28:44.989000+00:00:Entry Unlocked:T.Smith0129486:tsmith@gmail.com:tester_smith",<br>        "T.Smith0129486",<br>        "Tester Smith",<br>        "South Entry",<br>        "Building 5"<br>      ],<br>      "labels_to_remove": []<br>   }],<br>   "create_time": "2023-08-04 22:54:29+00:00",<br>   "schedule_time": "2023-08-04 22:54:29.875997+00:00"<br>   }<br>}<br>``` |
| 400/422 | Bad request / Malformed payload. Check that the payload you sent matches the example above. An empty payload also will return a 422.<br>Common error is that the user has no camera mapped to the device_id. Make sure the user has a camera mapped to the device on their [settings page](/content/settings/integrations/pacs/index.html). <br>Response when there are no cameras mapped to the device looks like this:<br>```<br>{<br>"detail": "No annotations could be created from the events."<br>}<br>``` |
| 401 | Unauthorized. Most likely missing the Authorization header. |
| 405 | Method not allowed. Only supports POST. |
| 404 | User does not have PACS integration settings saved. |
| 500 | Server error. Something unexpected went wrong. If this does not seem to be a transient error, please contact [support@camio.com](mailto:support@camio.com) for help resolving this error. | |

## Testing Steps

1. **Create a Camio account** at [https://camio.com/app](/content/app/index.html)
2. **Register a Camio Box**to the account
   - For development, we recommend setting up a [Camio VM](https://help.camio.com/hc/en-us/articles/217375106-Can-I-run-Camio-Box-in-a-Virtual-Machine) for free
   - See [https://camio.com/start](/content/start/index.html) for other options
3. **Connect cameras** to the Camio Box on the [boxes](/content/boxes/index.html) page
4. \[Optional\] [Add a 3D grid](https://help.camio.com/hc/en-us/articles/360039048891-How-do-I-define-the-floor-plane-3D-Grid-for-object-counting-tailgating-detection-and-social-distancing-detection) on the cameras to be used for Access Control

- Follow this [guide](https://help.camio.com/hc/en-us/articles/360034450552-What-s-the-optimal-setup-for-tailgating-detection) for optimal setup
   - A 3D grid is required to perform tailgating (unauthorized entry) analysis. If your integration does not trigger tailgating analysis then you can skip this step.
5. **Generate a bearer token** on the integration [settings page](/content/settings/integrations/pacs/index.html). This token is used as authorization to store devices and write annotations for this account. Once you have the user's token, store it securely and use it with the [API calls below](https://help.camio.com/hc/en-us/articles/4409631039892-How-do-I-create-a-Physical-Access-Control-System-integration-Developer-s-Guide#h_01H7H1SC0T859FPVN1NDXTP4DK).    - If your software solution supports OAuth flows, then you can request this token via OAuth with _scope=annotations:write_
6. **Add [devices](https://help.camio.com/hc/en-us/articles/4409631039892-How-do-I-create-a-Physical-Access-Control-System-integration-Developer-s-Guide#h_01HE5V358MS41NSSPC3V5CF3HV)** to your integration
7. **Map the devices to cameras** on the [settings page](/content/settings/integrations/pacs/index.html) and hit Save
   - If you do not save your integration settings you will receive a 404 response from the [webhooks endpoint](https://help.camio.com/hc/en-us/articles/4409631039892-How-do-I-create-a-Physical-Access-Control-System-integration-Developer-s-Guide#h_01HE5V9Q0XNKSZN29AYZ427TPP)
   - With no devices mapped to cameras you will receive a 400 response from the [webhooks endpoint](https://help.camio.com/hc/en-us/articles/4409631039892-How-do-I-create-a-Physical-Access-Control-System-integration-Developer-s-Guide#h_01HE5V9Q0XNKSZN29AYZ427TPP)
8. **Send [access control event](https://help.camio.com/hc/en-us/articles/4409631039892-How-do-I-create-a-Physical-Access-Control-System-integration-Developer-s-Guide#h_01HE5V358MDRP1TQWQF596TAHY) webhooks** to Camio
9. **View results** in the [Camio app](/content/app/index.html)   - Search for "entry unlocked" or any other labels added via webhooks

## Legacy API Calls

These endpoints are deprecated in favor of the new integration server [https://incoming.integrations.camio.com](https://incoming.integrations.camio.com/) used in the examples above. These endpoints will continue to work but new features and improvements will not be added.

|     |     |
| --- | --- |
| Method + URL | Examples |
| **POST [/api/integrations/pacs/devices](/content/api/integrations/pacs/devices/index.html)**<br>**deprecated** | **Payload**

```
{
  readers: [\
    {\
      device_id: {{unique_id}},\
      device_name: {{display_name}}\
    },\
    ...\
  ]
}
```

**Curl**

```
curl --location --request POST 'https://camio.com/api/integrations/pacs/devices' \
--header 'Authorization: Bearer 42g-D0T41A5HIu4s4srlJgepKRGLgA-s' \
--header 'Content-Type: application/json' \
--data-raw '{\
    "readers": [\
         {\
             "device_id": "testDevice0129397",\
             "device_name": "Test Device"\
         },\
         ...\
    ]\
}'
```

**Response Codes**

|     |     |
| --- | --- |
| 200/204 | Success. No payload is returned. |
| 400 | Bad request / Malformed payload. Check that the payload you sent matches the example above. An empty payload also will return a 400.<br>Also returned for unsupported methods. Supported methods are GET, POST, and PUT. |
| 401 | Unauthorized. Most likely missing the Authorization header. |
| 403 | Unauthorized. Caller does not have permission to make this request. |
| 500 | Server error. Something unexpected went wrong. If this does not seem to be a transient error, please contact [support@camio.com](mailto:support@camio.com) for help resolving this error. | |
| **GET [/api/integrations/pacs/devices](/content/api/integrations/pacs/devices/index.html)**<br>**deprecated** | **Payload**

None

**Curl**

```
curl --location --request GET 'https://camio.com/api/integrations/pacs/devices' \
--header 'Authorization: Bearer 42g-D0T41A5HIu4s4srlJgepKRGLgA-s'
```

**Response Codes**

|     |     |
| --- | --- |
| 200 | Success. Returns a json payload in the same format as the POST above. Ex:<br>```<br>{<br>  "readers": [<br>    {<br>      "device_id": "testDevice0129397",<br>      "device_name": "Test Device"<br>    },<br>    ...<br>  ]<br>}<br>``` |
| 400 | Bad request. Returned for unsupported methods. Supported methods are GET, POST, and PUT. |
| 401 | Unauthorized. Most likely missing the Authorization header. |
| 404 | Not found. No stored devices found for the user. |
| 500 | Server error. Something unexpected went wrong. If this does not seem to be a transient error, please contact [support@camio.com](mailto:support@camio.com) for help resolving this error. | |
| **POST [/api/integrations/pacs/webhooks](/content/api/integrations/pacs/webhooks/index.html)**<br>**deprecated** | **Payload**

```
{
    device_id: {{unique_id}},
    timestamp: {{ISO8601_datetime_UTC_string}},
    event_type: {{valid_event_type}},
    labels: [{{any_string}}],
    actor_id: {{any_string}},
    actor_name: {{any_string}},
    actor_email: {{valid@email.com}}
}
```

**Curl**

```
curl --location --request POST 'https://camio.com/api/integrations/pacs/webhooks' \
--header 'Authorization: Bearer 42g-D0T41A5HIu4s4srlJgepKRGLgA-s' \
--header 'Content-Type: application/json' \
--data-raw '{
  "device_id": "testDevice0129397",
  "timestamp": "2021-11-01T17:30:10.000Z",
  "event_type": "Entry Unlocked",
  "labels": [\
    "South Entry",\
    "Building 5"\
  ],
  "actor_id": "T.Smith0129486",
  "actor_name": "Tester Smith",
  "actor_email": "tsmith@gmail.com"
}'
```

**Valid Event Types**

Valid event types are searchable with additional natural language queries and may go through additional analysis such as tailgating detection.

|     |
| --- |
| **event_type (not case sensitive)** |
| entry unlocked |
| forced open |
| entry ajar |

**Response Codes**

|     |     |
| --- | --- |
| 200/204 | Success. No payload is returned. |
| 400 | Bad request / Malformed payload. Check that the payload you sent matches the example above. An empty payload also will return a 400.<br>Also returned for unsupported methods. Supported methods are POST and PUT. |
| 401 | Unauthorized. Most likely missing the Authorization header. |
| 403 | Unauthorized. Caller does not have permission to make this request.<br>Also returned if the user does not have a PACS integration. |
| 404 | No camera mapped to the device_id. Make sure the user has a camera mapped to the device on their [settings page](/content/settings/integrations/pacs/index.html). |
| 500 | Server error. Something unexpected went wrong. If this does not seem to be a transient error, please contact [support@camio.com](mailto:support@camio.com) for help resolving this error. |

**required**

**at least one is required**
