openapi: 3.0.0
info:
  version: 2026.10.23
  title: Angelcam API
  contact:
    email: support@angelcam.com
  x-logo:
    url: ./assets/logo-angelcam.svg
  description: |
    Angelcam RESTful API — HTTPS only, JSON, all URLs require a trailing slash. See the [developer docs](/) for quickstart, authentication, and key concepts.
tags:
  - name: space
    x-displayName: Spaces
    description: |
      A **space** is the organisational unit in Angelcam — it owns all resources: cameras, locations, recordings, services, and billing. Every API request operates within a space context — by default the user's default space, or a specific space selected via the `X-Space-Id` header.
      See the [Key concepts guide](/guides/key-concepts/) for details on space context and permissions.
  - name: user
    x-displayName: User
  - name: camera
    x-displayName: My cameras
    description: |
      Manage your cameras and access live streams, snapshots, and recordings. Supported codecs: H.264, H.265 (experimental), MJPEG. Live streams are limited to 10 concurrent consumers per camera — use the [broadcasting service](#tag/broadcasting) for higher concurrency.
  - name: recording
    x-displayName: My cameras recording
    description: |
      Cloud Recording endpoints. Requires the Cloud Recording service to be active on the camera — otherwise all endpoints return 404.
      A camera can have multiple simultaneous recordings (e.g. continuous + event-only) with different retentions. The timeline endpoint returns _segments_ (continuous blocks of recorded video) for a given time range; maximum range per request is 24 hours.
  - name: stream-controls
    x-displayName: Recording stream controls
    description: |
      You normally don't have to know the `streamer_domain` and `stream_id` path parameter, but use the generated endpoint URLs as reported by the `stream_controls` field in a create-stream response. Those URLs correspond to the following endpoints.
      * base_url: [Recording stream info](#tag/stream-controls/GET/recording/streams/{stream_id}/)
      * play: [Play stream](#tag/stream-controls/POST/recording/streams/{stream_id}/play/)
      * pause: [Pause stream](#tag/stream-controls/POST/recording/streams/{stream_id}/pause/)
      * speed: [Set plyback stream](#tag/stream-controls/POST/recording/streams/{stream_id}/speed/)


      ## Syncing stream and timeline
      Due to various reasons, the time a user spends watching a stream doesn't necessarily have to match the time actually
      elapsed in the recorded video (i.e. a 5-minute long stream takes 6 minutes to watch on a user's slow mobile network
      connection due to lag).

      Periodically calling endpoint, [recordings stream info](#tag/stream-controls/GET/recording/streams/{stream_id}/) comes in handy in this case, because it
      synchronizes the time shown to the user in your UI, with the current time of the stream. This endpoint tells you the
      exact time where the stream is positioned at the current moment.
  - name: clip
    x-displayName: My recording clips
    description: |
      A clip is a permanent, downloadable excerpt of recorded footage. Unlike a recording stream — which is a temporary playback session — a clip is processed into a file that can be downloaded or shared with others.
      **Prerequisite:** The camera must have the Cloud Recording service active. If not, recording endpoints return 404.

      ## Creating a clip
      1. **Check available footage.** Use [`recording/{recording_id}/timeline/`](#tag/recording/GET/recording/{recording_id}/timeline/) to confirm that footage exists for the time range you want.
      2. **Submit the clip request** via [`POST cameras/{camera_id}/clips/`](#tag/clip/POST/cameras/{camera_id}/clips/) with a `name`, `start`, and `end`. The maximum clip length is **3 hours**.
      3. **Poll for completion.** Clip processing is asynchronous. Status progresses from `PENDING` → `BUILDING` → `SCREENSHOTTING` → `READY` (or `ERROR`). Poll [`cameras/{camera_id}/clips/{clip_id}/`](#tag/clip/GET/cameras/{camera_id}/clips/{clip_id}/) until the status is `READY`.
      4. **Download or share.** A `READY` clip includes a `download_url` (a time-limited direct download link) and a `sharing_token` that gives access to the clip without authentication — see Sharing a clip below.

      ## Snapshots
      During the `SCREENSHOTTING` stage a snapshot image (JPEG) is taken from the beginning of the clip and exposed in the `snapshots` field of the clip object. Use it as a thumbnail or preview — for example in a list of clips — without downloading the whole clip. The URLs are time-limited, so fetch a fresh clip object instead of caching them.

      The field is a list, but currently at most one snapshot is generated. It stays empty while the clip is still `PENDING` or `BUILDING`, and it can also stay empty on a `READY` clip if the snapshot could not be taken — a failed snapshot never fails the clip itself, so always handle an empty list.

      ## Sharing a clip
      To share a clip with someone who has no Angelcam account, use [`POST cameras/{camera_id}/clips/{clip_id}/share/`](#tag/clip/POST/cameras/{camera_id}/clips/{clip_id}/share/), which emails them a link to the clip.

      Access to such a link is granted by the clip's `sharing_token` — a secret that requires no authentication. Anyone who obtains it can watch the clip, so treat it like a password.

      **Validity.** The sharing token does not expire and cannot be given an expiration, a view limit, or a password through the API. It stays valid until you revoke it with [`POST cameras/{camera_id}/clips/{clip_id}/revoke-access/`](#tag/clip/POST/cameras/{camera_id}/clips/{clip_id}/revoke-access/), which issues a new `sharing_token` and breaks *every* link shared so far — it cannot revoke a single recipient. Deleting the clip has the same effect. If you need a link with a limited lifetime, share the `download_url` instead: its token is short-lived and a fresh one is issued every time you read the clip object.

      ## Deleting a clip
      [`DELETE cameras/{camera_id}/clips/{clip_id}/`](#tag/clip/DELETE/cameras/{camera_id}/clips/{clip_id}/) permanently removes the clip together with its video data and snapshots, and invalidates its `download_url` and `sharing_token`. The underlying recording is not affected. A clip can be deleted in any status, including while it is still being processed.

      Clips on shared cameras cannot be deleted through the `shared-cameras` endpoints.
  - name: event
    x-displayName: Events
    description: |
      Events represent detections reported by cameras or sensors — typically motion detected by a camera or a trigger from an external sensor. Events are the building blocks for [RTS incidents](#tag/incidents) and camera timeline markers.

      ## Sending events to Angelcam
      When a camera or sensor detects something, it reports it to Angelcam by calling the event endpoint with its unique `hash` (found in the Angelcam dashboard or via the [Sensor](#tag/sensor) endpoints). Use `POST /v1/events/` in all cases where possible. A `GET /v1/events/` alternative exists solely for devices that are technically incapable of making POST requests (some older cameras). The rate limit for event submission is 10 requests per minute per hash.

      ## Listing events
      Pagination for event list endpoints works differently from other list endpoints: there is no `offset` parameter. Instead:
      - Use the `next` link in the response to move to the next page. - Pagination is one-directional (forward only). - Use the `start` and `end` filters to narrow down the time range.
      Events are returned ordered by `occurred_at` (newest first).
  - name: sensor
    x-displayName: My sensors
    description: |
      With sensor endpoints you can view, manage and connect sensors to the user account.

      Sensor can be bind to one particular already connected [camera](#tag/camera) to mark received [events](#tag/event) on camera timeline. If camera that sensor is bind to has active [Cloud Recording](#tag/recording) event recording can be enabled using these endpoints. Event recording will not be applied in the case that the camera assigned to the sensor doesn't have Cloud Recording activated.

      To specify event recording length [duration](#section/Angelcam-API/Time-and-duration-formats) format must be used and currently options for recording length are limited to:
        - 30 seconds
        - 1 minute
        - 2 minutes
        - 5 minutes

      Each sensor is given a unique email and unique hash. Those can be used to send [events](#tag/event) to Angelcam.
  - name: client
    x-displayName: Clients
    description: |
      Endpoints for reseller users to manage their clients.
      A reseller can create two types of client accounts:
      * **Full account** — the client has full control over their cameras and services. * **Limited account** — the client has read-only access. They can view their cameras and streams but cannot make any changes. A client can upgrade from limited to full at any time, which also revokes the reseller's access to their space.
      A reseller automatically has access to their clients' spaces (cameras, recordings, streams). A client — whether full or limited — can revoke this access at any time.
  - name: camera-stream-detection
    x-displayName: Camera streams detection
    description: Using these endpoints you can verify if there are camera streams available on specified network address. Detection is asynchronous. For this reason there is one endpoint for initializing stream detection and one for retrieving result of detection.
  - name: arrow-clients
    x-displayName: Arrow clients
    description: |
      Manage [Arrow clients](https://github.com/angelcam/arrow-client) — pair them with your account, inspect exposed services, and send commands.
      **Pairing:** restart the device (pairing mode is active for the first 20 minutes after start), POST to `arrow-clients/` to get the UUID, then poll `arrow-clients/{uuid}/` until status is `online`.
      **Arrow proxy:** use the transparent HTTP proxy or HTTP CONNECT proxy to reach services behind an Arrow client. Both require a `Host: {SERVICE_ID}-{ARROW_UUID}` header and a `Proxy-Authorization: Bearer` token from the Arrow client detail endpoint.
  - name: angelcameras
    x-displayName: AngelCameras
    description: ''
  - name: broadcasting
    x-displayName: My cameras broadcasting
    description: |
      Endpoints for managing broadcasting settings and retrieving broadcasting streams. If a camera doesn't have the Broadcasting service activated, all camera broadcasting endpoints will return HTTP 404.

      The broadcasting service can be used whenever you need more concurrent stream consumers. It does not necessarily mean that the stream from your camera has to be public.
  - name: public-camera
    x-displayName: Public cameras
    description: |
      Endpoints for browsing cameras that are publicly accessible. A camera appears here if it has the Broadcasting service active and has been marked as public — either because it uses free public broadcasting, or because the camera owner has explicitly enabled public access.
      > **Access restricted:** These endpoints are available only to partners who have arranged access with Angelcam. Please contact [support](https://www.angelcam.com/support/) if you are interested in using them.
  - name: service
    x-displayName: Available services
    description: |
      A catalog of services available for purchase. Use these endpoints to discover service `code` values before activating a service via the [My services](#tag/active-service) endpoints.
      Services fall into two categories:
      * **Account plan** — your overall subscription level. * **Camera services** — features you enable on individual cameras. The two main camera services are **Cloud Recording** and **Broadcasting**. Activating a camera service creates an active service instance that you then [assign to a specific camera](#tag/active-service/PUT/billing/active-services/{active_service_id}/usage/).
  - name: active-service
    x-displayName: My services
    description: |
      Endpoints for managing your activated services and assigning them to cameras.
      A service must first be activated (purchased) for your account, then assigned to a specific camera before it takes effect on that camera.

      ## Service lifecycle
      1. **Find a service code.** Browse [available services](#tag/service/GET/billing/services/) to get the `code` of the service you want.
      2. **Activate the service** by calling [`POST /billing/active-services/`](#tag/active-service/POST/billing/active-services/). Provide the service `code` and a billing `period` — `P1M` for monthly or `P1Y` for annual billing.
      3. **Assign to a camera** by calling [`PUT /billing/active-services/{id}/usage/`](#tag/active-service/PUT/billing/active-services/{active_service_id}/usage/) with the `camera_id`. Set `camera_id` to `null` to unassign.
      4. **Upgrade or downgrade** at any time via [`PUT /billing/active-services/{id}/`](#tag/active-service/PUT/billing/active-services/{active_service_id}/). A downgrade takes effect at the end of the current billing period by default. Set `force_downgrade: true` to apply it immediately with prorated credit.
      5. **Cancel** via [`DELETE /billing/active-services/{id}/`](#tag/active-service/DELETE/billing/active-services/{active_service_id}/).
  - name: order
    x-displayName: My Orders
  - name: incidents
    x-displayName: Incidents
    description: |
      Endpoints for managing Real Time Security (RTS) incidents.
      An incident is a security event that has been detected and may require attention. Incidents are created automatically when sensor events or camera status changes match an active [notification rule](#tag/rts_notification_rules).
      Incidents go through the following states:
      * **Open** — the incident has been created and not yet reviewed. * **Verified** — acknowledged as a genuine security event (`verified_at` is set). * **Closed** — the incident has been resolved (`closed_at` is set). An incident can be closed without being verified first (e.g. a false alarm).
  - name: rts_messages
    x-displayName: Messages
    description: |
      Endpoints for managing notifications. Base object is message. We create a message when something important happens. For example, when a camera goes offline, when a sensor detects motion, etc. When a message is created, we can send it to user using different notification methods based on notification rules.
  - name: rts_notification_methods
    x-displayName: Notification methods
    description: |
      Manage notification methods — email and HTTP webhook. HTTP methods send a signed POST to your URL with a JSON payload on each notification. See the [Webhooks guide](/guides/webhooks/) for payload fields and signature verification.
  - name: rts_notification_rules
    x-displayName: Notification rules
    description: |
      Endpoints for managing notification rules. Notification rule is a rule that defines when and how we should send message to user. For example, we can create rule that says: "When camera goes offline, send me an email".
  - name: rts_settings
    x-displayName: Settings
    description: |
      Global Real Time Security (RTS) settings for your account.
      The main setting is `incident_ttl`, which controls how long (in [ISO 8601 duration format](#section/Angelcam-API/Time-and-duration-formats)) an open incident stays active before it is automatically closed when no new events are received.
  - name: location
    x-displayName: Locations
    description: |
      Endpoints for accessing and managing locations. Locations are used to organize cameras into groups. Every camera belongs to exactly one location, and every user has a root location whose ID is available from the [Current User Info](#tag/user) endpoint.
      Locations can be **armed** or **disarmed**. When a location is armed, Real Time Security (RTS) will generate notifications for events on cameras in that location. Each location supports scheduled arming/disarming so notifications can be active only during certain hours.
      > **Note:** Creating, editing, and deleting locations is currently only possible through the [My Angelcam](https://my.angelcam.com/) web UI. These API endpoints provide read access only.
  - name: speakers
    x-displayName: Speakers
    description: |
      Manage speakers and trigger audio playback. See the [Speakers guide](/guides/speakers/) for setup instructions, including how to configure an AngelBox as a speaker.
  - name: audio-message
    x-displayName: Audio messages
    description: |
      Endpoints for managing audio messages. Audio messages are pre-recorded audio clips that can be played through [speakers](#tag/speakers).
      Audio files are uploaded as Base64-encoded content. Supported formats: AAC (`audio/aac`), MP3 (`audio/mpeg`), WAV (`audio/wav`), OGG (`audio/ogg`), and WebM audio (`audio/webm`).
      Keep audio files short — a few seconds is ideal. Large files will increase upload time and may affect playback reliability.
  - name: recording-deprecated
    x-displayName: My cameras recording (deprecated)
    description: |
      **These endpoints are deprecated and will be removed in a future release. Use the [My cameras recording](#tag/recording) and [Recording stream controls](#tag/stream-controls) endpoints instead.**

      The legacy recording API was bound to a camera (`cameras/{camera_id}/recording/`) and could only work with a single recording per camera. The current API addresses recordings directly by `recording_id`, which allows multiple simultaneous recordings on one camera.
  - name: shared-camera
    x-displayName: Shared cameras (deprecated)
    description: |
      **These endpoints are deprecated and will be removed in a future release. Do not use them in new integrations.**

      For access to cameras which somebody shared with you. In general everything is same as in my cameras section, see above, there is only one difference. Together with cameras information you get also a camera's public page url
  - name: shared-camera-recording
    x-displayName: Shared cameras recording (deprecated)
    description: |
      **These endpoints are deprecated and will be removed in a future release. Use the [Recording](#tag/recording) and [Recording stream controls](#tag/stream-controls) endpoints instead.**

      Everything is same as in recording for my own cameras. Just replace `cameras` by `shared-cameras` in every endpoints url.
  - name: shared-camera-clip
    x-displayName: Shared recording clips (deprecated)
    description: |
      **These endpoints are deprecated and will be removed in a future release. Use the [My recording clips](#tag/clip) endpoints instead.**

      Recording clips on cameras shared with you. Everything works the same as [My recording clips](#tag/clip) — just replace `cameras` with `shared-cameras` in the endpoint URLs.

      Two operations are not available here: a clip on a shared camera cannot be deleted, and its sharing access cannot be shared by email or revoked. Those remain with the camera owner.
  - name: camera-guest
    x-displayName: Manage camera guests (deprecated)
    description: |
      **These endpoints are deprecated and will be removed in a future release. Do not use them in new integrations.**

      You can share your camera with a guest, this means, you allow guests to view stream from your camera. There is also an option to share also recordings together with live stream.

      When you adding new guest, you just need their email. Then we send them an email informing them that you share camera with them. In case when there was no account with given email we precreate an account for these guest.
x-tagGroups:
  - name: General
    tags:
      - user
      - space
      - location
  - name: Camera management
    tags:
      - camera
      - camera-stream-detection
      - arrow-clients
      - angelcameras
  - name: Recording
    tags:
      - recording
      - stream-controls
      - clip
  - name: Broadcasting
    tags:
      - broadcasting
      - public-camera
  - name: Events & Sensors
    tags:
      - event
      - sensor
  - name: Speaker management
    tags:
      - speakers
      - audio-message
  - name: RTS
    tags:
      - incidents
      - rts_settings
      - rts_messages
      - rts_notification_methods
      - rts_notification_rules
  - name: Billing
    tags:
      - service
      - active-service
      - order
  - name: Clients
    tags:
      - client
  - name: Deprecated
    tags:
      - recording-deprecated
      - shared-camera
      - shared-camera-recording
      - shared-camera-clip
      - camera-guest
servers:
  - url: 'https://api.angelcam.com/v1'
paths:
  '/angelcamera/latest-firmware/{board}/':
    get:
      operationId: angelcamera-latest-firmware-get
      summary: Get AngelCamera firmware
      description: Get the latest firmware for a given AngelCamera model.
      tags:
        - angelcameras
      security:
        - OAuth2: []
        - PersonalAccessToken: []
      parameters:
        - name: board
          in: path
          required: true
          description: AngelCamera board ID
          example: c3c9429e42c76e50f0f300267a7ac733
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AngelCameraFirmwareResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  /arrow-clients/:
    get:
      operationId: arrow-clients-list
      summary: List paired Arrow clients
      description: Get a list of Arrow clients paired with the current user account.
      tags:
        - arrow-clients
      security:
        - OAuth2:
            - arrow_client_access
        - PersonalAccessToken: []
      parameters:
        - name: mac
          in: query
          required: false
          description: |
            If set, the endpoint will return only Arrow clients with a given MAC address. You can use either the colon or the dash separated format or you can omit the separator completely.
          example: 11-22-33-aa-bb-cc
          schema:
            type: string
            format: mac
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ArrowClientsResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
    post:
      operationId: arrow-client-pairing-request
      summary: Request pairing of an Arrow client
      description: |
        Request pairing of a given Arrow client with the current user account. One of the `uuid`, `angelbox_id` or `mac` parameter is required. In case the Arrow client has been paired already, the API will check if the current user can access the client. If the user can access the client, the API will respond with UUID of the client (i.e. the standard response). Otherwise, the API will respond with "Permission Denied".

        Pairing via MAC address is only available upon request, otherwise API responds with "Permission Denied". When using MAC there will be MAC adress in the response instead of UUID.
      tags:
        - arrow-clients
      security:
        - OAuth2:
            - arrow_client_manage
        - PersonalAccessToken: []
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                uuid:
                  type: string
                  format: uuid
                  description: UUID of the paired Arrow client
                angelbox_id:
                  type: string
                  description: AngelBox ID
                mac:
                  type: string
                  format: MAC address
                  description: MAC address of the Arrow client
              example:
                uuid: 75b62326-eca3-4424-ab68-48e7da47e847
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ArrowClientPairingResponse'
        '400':
          $ref: '#/components/responses/Error400InvalidBody'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/arrow-clients/{mac}/':
    get:
      operationId: arrow-client-detail-mac
      summary: Arrow client detail (MAC address pairing)
      description: 'Get detailed information about a given Arrow client, it can be used **just during the paring process via MAC address**. When you know uuid of the client, use [Arrow client detail API endpoint](#tag/arrow-clients/GET/arrow-clients/{uuid}/) endpoint instead.'
      tags:
        - arrow-clients
      security:
        - OAuth2:
            - arrow_client_access
        - PersonalAccessToken: []
      parameters:
        - $ref: '#/components/parameters/arrowClientMAC'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ArrowClientDetailObject'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/arrow-clients/{uuid}/':
    get:
      operationId: arrow-client-detail
      summary: Arrow client detail
      description: Get detailed information about a given Arrow client.
      tags:
        - arrow-clients
      security:
        - OAuth2:
            - arrow_client_access
        - PersonalAccessToken: []
      parameters:
        - $ref: '#/components/parameters/arrowClientId'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ArrowClientDetailObject'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
    delete:
      operationId: arrow-client-unpair
      summary: Unpair Arrow client
      tags:
        - arrow-clients
      parameters:
        - $ref: '#/components/parameters/arrowClientId'
      security:
        - OAuth2:
            - arrow_client_manage
        - PersonalAccessToken: []
      responses:
        '204':
          description: No content
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/arrow-clients/{uuid}/reset-service-table/':
    post:
      operationId: arrow-client-reset-service-table
      summary: Reset service table
      description: |
        Remove all automatically discovered and/or custom services from the client's service table.
      tags:
        - arrow-clients
      security:
        - OAuth2:
            - arrow_client_manage
        - PersonalAccessToken: []
      parameters:
        - $ref: '#/components/parameters/arrowClientId'
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                full:
                  type: boolean
                  description: |
                    When `true`, all non-static services will be removed. Otherwise, only discovered services will be removed.
                  example: false
      responses:
        '204':
          $ref: '#/components/responses/EmptyResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
        '502':
          $ref: '#/components/responses/Error502BadGateway'
  '/arrow-clients/{uuid}/scan-network/':
    post:
      operationId: arrow-client-scan-network
      summary: Scan network
      description: |
        Trigger a scan of the local network that the Arrow client is connected to. The scan discovers cameras and other services available on that network.

        The scan runs asynchronously — this endpoint returns immediately. To check whether the scan is still in progress, poll the [Arrow client detail](#tag/arrow-clients/GET/arrow-clients/{uuid}/) endpoint and inspect the `scanning` field. Discovered services appear in the [Arrow client services](#tag/arrow-clients/GET/arrow-clients/{uuid}/services/) list once the scan completes.

        The API responds with 502 Bad Gateway if the Arrow client is offline or unreachable.
      tags:
        - arrow-clients
      security:
        - OAuth2:
            - arrow_client_manage
        - PersonalAccessToken: []
      parameters:
        - $ref: '#/components/parameters/arrowClientId'
      responses:
        '204':
          $ref: '#/components/responses/EmptyResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
        '502':
          $ref: '#/components/responses/Error502BadGateway'
  '/arrow-clients/{uuid}/services/':
    get:
      operationId: arrow-client-services
      summary: List Arrow services
      description: Get a list of services visible and available to a given Arrow client.
      tags:
        - arrow-clients
      security:
        - OAuth2:
            - arrow_client_access
        - PersonalAccessToken: []
      parameters:
        - $ref: '#/components/parameters/arrowClientId'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ArrowClientServicesResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
    post:
      operationId: add-arrow-service
      summary: Add Arrow service
      description: |
        Add a custom service to the Arrow client service table.

        This method is supported only if the `add_custom_service` capability is
        signaled by the Arrow client. It can be used to access IP cameras in
        the target network if the automatic service discovery does not find
        them. The Arrow client will verify that the IP address belongs to the
        same local network it is connected to. Other IP addresses will be
        rejected for security reasons.
      tags:
        - arrow-clients
      security:
        - OAuth2:
            - arrow_client_manage
        - PersonalAccessToken: []
      parameters:
        - $ref: '#/components/parameters/arrowClientId'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ArrowClientAddServiceRequest'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ArrowClientAddServiceResponse'
        '400':
          $ref: '#/components/responses/Error400InvalidBody'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
        '405':
          $ref: '#/components/responses/Error405MethodNotAllowed'
        '502':
          $ref: '#/components/responses/Error502BadGateway'
  '/arrow-clients/{uuid}/services/{service_id}/':
    get:
      operationId: arrow-client-service-detail
      summary: Retrieve Arrow service
      description: Get details about a service visible and available to a given Arrow client.
      tags:
        - arrow-clients
      security:
        - OAuth2:
            - arrow_client_access
        - PersonalAccessToken: []
      parameters:
        - $ref: '#/components/parameters/arrowClientId'
        - $ref: '#/components/parameters/arrowClientServiceId'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ArrowServiceObject'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
    delete:
      operationId: arrow-client-service-delete
      summary: Delete Arrow service
      description: |
        Delete given Arrow service from the client's service table.

        Note that it is only possible to delete services that were added via the [corresponding API call](#tag/arrow-clients/POST/arrow-clients/{uuid}/services/). If the same service was also discovered by the network scanner, it will remain available as long as it is still visible for the network scanner.
      tags:
        - arrow-clients
      security:
        - OAuth2:
            - arrow_client_manage
        - PersonalAccessToken: []
      parameters:
        - $ref: '#/components/parameters/arrowClientId'
        - $ref: '#/components/parameters/arrowClientServiceId'
      responses:
        '204':
          $ref: '#/components/responses/EmptyResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
        '502':
          $ref: '#/components/responses/Error502BadGateway'
  /audio-messages/:
    get:
      operationId: audio-message-list
      summary: Retrieve audio messages
      tags:
        - audio-message
      parameters:
        - name: limit
          in: query
          required: false
          description: 'Limit result set. Example: `1`.'
          schema:
            type: integer
            minimum: 1
        - name: offset
          in: query
          required: false
          description: 'Return results starting at `offset`. Example: `10`.'
          schema:
            type: integer
            minimum: 1
      security:
        - OAuth2:
            - audio_message_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: Audio message list.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AudioMessageListResponse'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
    post:
      operationId: create-audio-messages
      summary: Create a new audio message
      tags:
        - audio-message
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AudioMessageWriteObject'
      security:
        - OAuth2:
            - audio_message_manage
        - PersonalAccessToken: []
      responses:
        '201':
          description: Newly created audio message object.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AudioMessageObject'
        '400':
          $ref: '#/components/responses/Error400InvalidBody'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
  '/audio-messages/{message_id}/':
    parameters:
      - $ref: '#/components/parameters/messageId'
    get:
      operationId: audio-message-detail
      summary: Retrieve audio message
      tags:
        - audio-message
      security:
        - OAuth2:
            - audio_message_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: Audio message.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AudioMessageObject'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
    put:
      operationId: update-audio-message
      summary: Update existing audio message
      tags:
        - audio-message
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AudioMessageWriteObject'
      security:
        - OAuth2:
            - audio_message_manage
        - PersonalAccessToken: []
      responses:
        '200':
          description: Updated audio message object.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AudioMessageObject'
        '400':
          $ref: '#/components/responses/Error400InvalidBody'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  /billing/active-services/:
    get:
      operationId: my-services
      summary: Retrieve list of my services
      tags:
        - active-service
      parameters:
        - name: type
          in: query
          required: false
          description: Filtering by service type
          schema:
            type: string
      security:
        - OAuth2:
            - active_services_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: Returns list of my active services.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ActiveServiceListResponse'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
    post:
      operationId: activate-service
      summary: Activate new service
      tags:
        - active-service
      description: |
        Purchase and activate a new service for your account. After activation, [assign the service to a camera](#tag/active-service/PUT/billing/active-services/{active_service_id}/usage/) using the returned active service `id`.
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - code
                - period
              properties:
                code:
                  type: string
                  description: 'Code of service, this code together with type is unique identifier of service'
                  example: 3-days
                period:
                  type: string
                  format: duration
                  description: 'Billing period — `P1M` for monthly, `P1Y` for annual.'
                  enum:
                    - P1M
                    - P1Y
              example:
                code: 3-days
                period: P1M
      security:
        - OAuth2:
            - active_services_manage
        - PersonalAccessToken: []
      responses:
        '201':
          description: Newly activated service
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ActiveServiceObject'
        '400':
          $ref: '#/components/responses/Error400InvalidBody'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
  '/billing/active-services/{active_service_id}/':
    get:
      operationId: my-service-detail
      summary: Retrieve my service detail
      tags:
        - active-service
      parameters:
        - $ref: '#/components/parameters/activeServiceId'
      security:
        - OAuth2:
            - active_services_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: Returns detail of my active service.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ActiveServiceObject'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
    put:
      operationId: my-service-update
      summary: Change service
      tags:
        - active-service
      parameters:
        - $ref: '#/components/parameters/activeServiceId'
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - code
                - period
              properties:
                code:
                  type: string
                  description: 'Code of service, this code together with type is unique identifier of service'
                  example: 3-days
                period:
                  type: string
                  format: duration
                  enum:
                    - P1M
                    - P1Y
                force_downgrade:
                  type: boolean
                  default: false
                  description: |
                    If set to false, the downgrade occurs after the current period concludes. If set to true, the downgrade happens immediately, applying the prorated price of the current service towards the new service. Should the prorated price exceed the cost of the new service, the new service will be extended for a period that matches the full price value.
              example:
                code: 3days
                period: P1M
      security:
        - OAuth2:
            - active_services_manage
        - PersonalAccessToken: []
      responses:
        '201':
          description: Newly activated service
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ActiveServiceObject'
        '400':
          $ref: '#/components/responses/Error400InvalidBody'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
    delete:
      operationId: my-service-cancel
      summary: Cancel active service
      tags:
        - active-service
      parameters:
        - $ref: '#/components/parameters/activeServiceId'
      security:
        - OAuth2:
            - active_services_manage
        - PersonalAccessToken: []
      responses:
        '204':
          $ref: '#/components/responses/EmptyResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/billing/active-services/{active_service_id}/usage/':
    get:
      operationId: my-service-usage-detail
      summary: Retrieve my service usage detail
      tags:
        - active-service
      parameters:
        - $ref: '#/components/parameters/activeServiceId'
      security:
        - OAuth2:
            - active_services_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: Returns detail of my active service usage.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ActiveServiceUsageObject'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
    put:
      operationId: my-service-usage-update
      summary: Change service usage
      tags:
        - active-service
      description: |
        Assign this active service to a camera, or unassign it by setting `camera_id` to `null`. A service must be assigned to a camera before it takes effect on that camera.
      parameters:
        - $ref: '#/components/parameters/activeServiceId'
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - camera_id
              properties:
                camera_id:
                  type: integer
                  description: 'ID of the camera to be used for the service, if null, the service will be unassigned'
                  example: 3
                  nullable: true
              example:
                camera_id: 3
      security:
        - OAuth2:
            - active_services_manage
        - PersonalAccessToken: []
      responses:
        '200':
          description: Returns detail of my active service usage.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ActiveServiceUsageObject'
        '400':
          $ref: '#/components/responses/Error400InvalidBody'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  /billing/orders/:
    get:
      operationId: orders
      summary: Retrieve list of orders
      tags:
        - order
      parameters:
        - name: state
          in: query
          required: false
          description: Filtering by order state
          schema:
            type: string
            enum:
              - purchase
              - unpaid
              - pending-payment
              - canceled
              - paid
      security:
        - OAuth2:
            - orders_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: Returns list of orders.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrderListResponse'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
  '/billing/orders/{order_id}/':
    get:
      operationId: order-detail
      summary: Retrieve order detail
      tags:
        - order
      parameters:
        - $ref: '#/components/parameters/orderId'
      security:
        - OAuth2:
            - orders_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: Returns list of available services.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrderObject'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/billing/orders/{order_id}/items/':
    get:
      operationId: order-items
      summary: Retrieve list of items on order
      tags:
        - order
      parameters:
        - $ref: '#/components/parameters/orderId'
      security:
        - OAuth2:
            - orders_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: Returns list of order items.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrderItemListResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  /billing/services/:
    get:
      operationId: services
      summary: Retrieve list of available services
      tags:
        - service
      parameters:
        - name: type
          in: query
          required: false
          description: Filtering by service type
          schema:
            type: string
      security:
        - OAuth2:
            - services_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: Returns list of available services.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceListResponse'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
  /cameras/:
    get:
      operationId: my-cameras-list
      summary: Retrieve camera list
      tags:
        - camera
      parameters:
        - name: limit
          in: query
          required: false
          description: 'Limit result set. Example: `1`.'
          schema:
            type: integer
            minimum: 1
        - name: offset
          in: query
          required: false
          description: 'Return results starting at `offset`. Example: `10`.'
          schema:
            type: integer
            minimum: 1
        - name: refresh_rate
          in: query
          required: false
          description: 'Set a maximum number of frames per second sent in an MJPEG stream. For example, if you want to get an MJPEG stream with frame sent every 10 seconds, use value 0.1.'
          schema:
            type: number
            format: float
            minimum: 0
        - name: max_width
          in: query
          required: false
          description: Maximum frame width for the MJPEG stream and LIVE SNAPSHOT.
          schema:
            type: integer
            minimum: 1
        - name: max_height
          in: query
          required: false
          description: Maximum frame height for the MJPEG stream and LIVE SNAPSHOT.
          schema:
            type: integer
            minimum: 1
        - $ref: '#/components/parameters/streamExpiresAt'
        - name: has_guests
          in: query
          required: false
          description: '1 for retrieving list of cameras that have been shared with someone, 0 for retrieving list of cameras that have not been shared with anyone. Leaving parameter empty will return list of all user cameras.'
          schema:
            type: boolean
        - name: tags
          in: query
          required: false
          description: 'Filter cameras by tags. Multiple tags can be specified by separating them with a comma. When using multiple tags, any camera that has at least one of the specified tags will be returned.'
          schema:
            type: string
          example: 'tag1,tag2'
        - name: ids
          in: query
          required: false
          description: Filter cameras by IDs. Multiple IDs can be specified by separating them with a comma.
          schema:
            type: string
          example: '1,2,3'
        - name: location_id
          in: query
          required: false
          description: Filter cameras by location ID. Only cameras belonging to the specified location will be returned.
          schema:
            type: integer
            minimum: 1
          example: 1
      security:
        - OAuth2:
            - camera_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: Returns camera list.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CameraListResponse'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
    post:
      operationId: connect-cameras
      summary: Connect new camera
      tags:
        - camera
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - name
                - type
                - url
                - connection_type
              properties:
                name:
                  type: string
                  description: Camera name
                type:
                  type: string
                  enum:
                    - h264
                    - h265
                    - mjpeg
                  description: Camera type. We currently support H.264/H.265 over RTSP and MJPEG over HTTP cameras.
                connection_type:
                  type: string
                  enum:
                    - direct
                    - arrow
                  description: |
                    How is the camera connected to Angelcam. The `direct` connection means that the camera stream is available on a public IP address. The `arrow` option can be used for connecting cameras that can be accessed via an Arrow client. Please note that cameras connected via an Arrow client use URL in a specific format. You will need to use the [stream detection](#tag/camera-stream-detection) endpoints to obtain the URL first.
                url:
                  type: string
                  format: url
                  description: |
                    Complete URL of a camera stream. H.264 and H.265 cameras must use "rtsp" scheme, for MJPEG cameras it's allowed to use "http" and "https" schemes. The "https" scheme is valid only for cameras using the `direct` connection type.
                enable_status_checks:
                  type: boolean
                  default: true
                  description: Enable periodic online/offline checks for the camera.
                enable_periodical_snapshots:
                  type: boolean
                  default: true
                  description: Refresh camera snapshot automatically once every 24h.
                tags:
                  type: array
                  items:
                    type: string
                  description: List of tags assigned to the camera. Tags can be used for filtering.
              example:
                name: My brand new shiny camera
                type: h264
                connection_type: direct
                url: 'rtsp://username:password@175.36.248.73:554/live.sdp'
      security:
        - OAuth2:
            - camera_create
        - PersonalAccessToken: []
      responses:
        '201':
          description: Newly created camera object
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CameraObject'
        '400':
          $ref: '#/components/responses/Error400InvalidBody'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
  /cameras/stream-detection/:
    post:
      operationId: stream-detection-start
      summary: Start stream detection
      description: |
        Retrieve `session_id` which can be used for [querying stream detection result](#tag/camera-stream-detection/GET/cameras/stream-detection/{session_id}/).
      tags:
        - camera-stream-detection
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                address:
                  type: string
                  description: |
                    Various address types can be used. Valid examples: `my-camera.my-site.com/feed`, `http://test:test@my-camera.my-site.com:80/feed?show=1`, `rtsp://site.domain.com/camera1`, `132.45.32.21`. As you can see from examples `address` can optionally contain information about `port`, `username` and `password`. In such cases these fields can be omitted from request body. The `arrow_service` field must not be present if the `address` field is being used.
                arrow_service:
                  type: object
                  properties:
                    arrow_client:
                      type: string
                      format: uuid
                      description: Arrow client UUID
                    service_id:
                      type: string
                      description: Arrow service ID
                  description: |
                    Use this field for stream detection via an Arrow client. The `path` field can be used to request detection on a specific endpoint in addition to all endpoints tested by the stream detector service. The `address` field must not be present if the `arrow_service` field is being used.
                path:
                  type: string
                  description: Stream path (if not given in the address field).
                port:
                  type: integer
                  minimum: 1
                  maximum: 65535
                  description: If port is not specified all reasonable ports will be tested.
                username:
                  type: string
                password:
                  type: string
              example:
                address: 'http://test:test@my-camera.my-site.com:80/feed?show=1'
      security:
        - OAuth2:
            - streams_detect
        - PersonalAccessToken: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CameraStartStreamDetectionResponse'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
  '/cameras/stream-detection/{session_id}/':
    get:
      operationId: stream-detection-result
      summary: Retrieve stream detection result
      tags:
        - camera-stream-detection
      parameters:
        - $ref: '#/components/parameters/sessionId'
      security:
        - OAuth2:
            - streams_detect
        - PersonalAccessToken: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CameraStreamDetectionResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
  '/cameras/{camera_id}/':
    get:
      operationId: my-cameras-detail
      summary: Retrieve camera
      tags:
        - camera
      parameters:
        - $ref: '#/components/parameters/cameraId'
        - name: refresh_rate
          in: query
          required: false
          description: 'Set a maximum number of frames per second sent in an MJPEG stream. For example, if you want to get an MJPEG stream with frame sent every 10 seconds, use value 0.1.'
          schema:
            type: number
            format: float
            minimum: 0
        - name: max_width
          in: query
          required: false
          description: Maximum frame width for the MJPEG stream and LIVE SNAPSHOT.
          schema:
            type: integer
            minimum: 1
        - name: max_height
          in: query
          required: false
          description: Maximum frame height for the MJPEG stream and LIVE SNAPSHOT.
          schema:
            type: integer
            minimum: 1
        - $ref: '#/components/parameters/streamExpiresAt'
      security:
        - OAuth2:
            - camera_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: Camera object
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CameraObject'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
    put:
      operationId: my-cameras-update
      summary: Update camera
      tags:
        - camera
      parameters:
        - $ref: '#/components/parameters/cameraId'
      requestBody:
        content:
          application/json:
            schema:
              type: object
              title: camera
              properties:
                name:
                  type: string
                  description: Camera name
                type:
                  type: string
                  enum:
                    - h264
                    - h265
                    - mjpeg
                  description: Camera type. We currently support H.264/H.265 over RTSP and MJPEG over HTTP cameras.
                connection_type:
                  type: string
                  enum:
                    - direct
                    - arrow
                  description: |
                    How is the camera connected to Angelcam. The `direct` connection means that the camera stream is available on a public IP address. The `arrow` option can be used for connecting cameras that can be accessed via an Arrow client. Please note that cameras connected via an Arrow client use URL in a specific format. You will need to use the [stream detection](#tag/camera-stream-detection) endpoints to obtain the URL first.
                url:
                  type: string
                  format: url
                  description: |
                    Complete URL of a camera stream. H.264 and H.265 cameras must use "rtsp" scheme, for MJPEG cameras it's allowed to use "http" and "https" schemes. The "https" scheme is valid only for cameras using the `direct` connection type.
                enable_status_checks:
                  type: boolean
                  description: Enable periodic online/offline checks for the camera.
                enable_periodical_snapshots:
                  type: boolean
                  description: Refresh camera snapshot automatically once every 24h.
                tags:
                  type: array
                  items:
                    type: string
                  description: List of tags assigned to the camera. Tags can be used for filtering.
              example:
                name: My updated shiny camera
                type: h264
                url: 'rtsp://username:password@175.36.248.73:554/live.sdp'
      security:
        - OAuth2:
            - camera_manage
        - PersonalAccessToken: []
      responses:
        '200':
          description: Camera object
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CameraObject'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
    delete:
      operationId: my-cameras-remove
      summary: Remove camera
      tags:
        - camera
      parameters:
        - $ref: '#/components/parameters/cameraId'
      security:
        - OAuth2:
            - camera_delete
        - PersonalAccessToken: []
      responses:
        '204':
          description: No content
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/cameras/{camera_id}/broadcasting/':
    get:
      operationId: my-cameras-broadcasting-info
      summary: General broadcasting information
      tags:
        - broadcasting
      parameters:
        - $ref: '#/components/parameters/cameraId'
      security:
        - OAuth2:
            - broadcasting_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: Returns general broadcasting information.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BroadcastingResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/cameras/{camera_id}/broadcasting/start/':
    post:
      operationId: my-cameras-broadcasting-start
      summary: Start public broadcasting on given camera
      tags:
        - broadcasting
      parameters:
        - $ref: '#/components/parameters/cameraId'
      security:
        - OAuth2:
            - broadcasting_start_stop
        - PersonalAccessToken: []
      responses:
        '204':
          $ref: '#/components/responses/EmptyResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/cameras/{camera_id}/broadcasting/stop/':
    post:
      operationId: my-cameras-broadcasting-stop
      summary: Stop public broadcasting on given camera
      tags:
        - broadcasting
      parameters:
        - $ref: '#/components/parameters/cameraId'
      security:
        - OAuth2:
            - broadcasting_start_stop
        - PersonalAccessToken: []
      responses:
        '204':
          $ref: '#/components/responses/EmptyResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/cameras/{camera_id}/clips/':
    get:
      operationId: my-cameras-clips-list
      summary: Retrieve camera clips list
      tags:
        - clip
      description: Retrieves the list of recording clips of given camera
      security:
        - OAuth2:
            - recording_clips_access
        - PersonalAccessToken: []
      parameters:
        - $ref: '#/components/parameters/cameraId'
        - name: created_by
          in: query
          required: false
          description: Filter results only to clips created by given users. A comma separated list of user IDs is expected. No whitespace characters are permited. The asterisk (`*`) character can be used to list all clips. By default the endpoint returns only clips created by the current user.
          example: '1,2,3'
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ClipListResponse'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
    post:
      operationId: my-cameras-clips-create
      summary: Create clip
      tags:
        - clip
      description: |
        Request creation of a recording clip for the given camera. Clip processing is **asynchronous** — the response will have status `PENDING`. Poll `cameras/{camera_id}/clips/{clip_id}/` until status reaches `READY` or `ERROR`. The maximum clip length is 3 hours.
      parameters:
        - $ref: '#/components/parameters/cameraId'
      requestBody:
        content:
          application/json:
            schema:
              type: object
              title: clip
              required:
                - name
                - start
                - end
              properties:
                name:
                  type: string
                  description: Clip name
                start:
                  type: string
                  format: date-time
                  description: Start time of clip (ISO 8601)
                end:
                  type: string
                  format: date-time
                  description: End time of clip (ISO 8601)
                recording:
                  type: string
                  format: uuid
                  description: 'Optional recording_id; if not specified, continuous recording will be used'
              example:
                name: Frontdoor loitering
                start: '2017-01-01T00:00:00.000Z'
                end: '2017-01-01T00:25:00.000Z'
      security:
        - OAuth2:
            - recording_clips_access
            - recording_clips_create
        - PersonalAccessToken: []
      responses:
        '201':
          description: Clip request was received and clip processing will start
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ClipObject'
        '400':
          description: 'The request is invalid. Common reasons: no recording footage exists for the requested time range, or the requested clip length exceeds the 3 hour maximum.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400Invalid'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
  '/cameras/{camera_id}/clips/{clip_id}/':
    get:
      operationId: my-cameras-clips-detail
      summary: Retrieve a single clip
      tags:
        - clip
      description: Retrieves the details of a recording clip
      parameters:
        - $ref: '#/components/parameters/cameraId'
        - $ref: '#/components/parameters/clipId'
      security:
        - OAuth2:
            - recording_clips_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ClipObject'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
    delete:
      operationId: my-cameras-clips-delete
      summary: Delete a clip
      tags:
        - clip
      description: |
        Permanently deletes a recording clip, including its video data and snapshots. Once deleted, the clip's `download_url` and `sharing_token` stop working. A clip can be deleted in any status, including while it is still being processed.

        Deleting a clip does not affect the underlying recording — only the clip itself is removed.
      parameters:
        - $ref: '#/components/parameters/cameraId'
        - $ref: '#/components/parameters/clipId'
      security:
        - OAuth2:
            - recording_clips_delete
        - PersonalAccessToken: []
      responses:
        '204':
          $ref: '#/components/responses/EmptyResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/cameras/{camera_id}/clips/{clip_id}/share/':
    post:
      operationId: my-cameras-clips-share
      summary: Share a clip via email
      tags:
        - clip
      description: |
        Sends an email with a link to the clip to the given address. The link contains the clip's `sharing_token`, so the recipient does not need an Angelcam account. The link stays valid until the token is revoked via [`revoke-access`](#tag/clip/POST/cameras/{camera_id}/clips/{clip_id}/revoke-access/) or the clip is deleted — it has no expiration of its own.
      parameters:
        - $ref: '#/components/parameters/cameraId'
        - $ref: '#/components/parameters/clipId'
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - email
              properties:
                email:
                  type: string
                  format: email
      security:
        - OAuth2:
            - recording_clips_share
        - PersonalAccessToken: []
      responses:
        '204':
          $ref: '#/components/responses/EmptyResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/cameras/{camera_id}/clips/{clip_id}/revoke-access/':
    post:
      operationId: my-cameras-clips-revoke-access
      summary: Revoke clip sharing access
      tags:
        - clip
      description: |
        Revokes all previously shared links to the clip by generating a new `sharing_token`. Any link that was sent out earlier — including links from clip share emails — stops working immediately.

        The clip itself is not affected and can be shared again; the new `sharing_token` is returned by the clip detail endpoint.
      parameters:
        - $ref: '#/components/parameters/cameraId'
        - $ref: '#/components/parameters/clipId'
      security:
        - OAuth2:
            - recording_clips_share
        - PersonalAccessToken: []
      responses:
        '204':
          $ref: '#/components/responses/EmptyResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/cameras/{camera_id}/clips/{clip_id}/stream/':
    get:
      operationId: my-cameras-clips-stream
      summary: Retrieve a clip stream
      tags:
        - clip
      description: Retrieves stream of a recording clip
      parameters:
        - $ref: '#/components/parameters/cameraId'
        - $ref: '#/components/parameters/clipId'
        - name: start
          in: query
          required: true
          description: 'Start time of a stream. Example: `2016-03-19T08:00:00Z`.'
          example: '2017-01-01T00:00:00.000Z'
          schema:
            type: string
            format: date-time
      security:
        - OAuth2:
            - recording_clips_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecordingStreamResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/cameras/{camera_id}/events/':
    get:
      operationId: camera-events
      summary: Retrieve camera event list
      tags:
        - event
      description: Retrieves list of events belonging to the specified camera
      parameters:
        - $ref: '#/components/parameters/cameraId'
        - name: start
          in: query
          description: 'Example: `2017-03-07T14:00:00Z`.'
          required: false
          schema:
            type: string
            format: date-time
        - name: end
          in: query
          description: 'Example: `2017-03-07T16:00:00Z`.'
          required: false
          schema:
            type: string
            format: date-time
        - name: limit
          in: query
          description: 'Limit result set. Example: `1`.'
          required: false
          schema:
            type: integer
            minimum: 1
      security:
        - OAuth2:
            - event_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EventListResponse'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/cameras/{camera_id}/guests/':
    get:
      deprecated: true
      operationId: my-cameras-guests
      summary: Retrieve camera guests list
      tags:
        - camera-guest
      parameters:
        - $ref: '#/components/parameters/cameraId'
        - name: limit
          in: query
          required: false
          description: 'Limit result set. Example: `1`.'
          schema:
            type: integer
            minimum: 1
        - name: offset
          in: query
          required: false
          description: 'Return results starting at `offset`. Example: `10`.'
          schema:
            type: integer
            minimum: 1
      security:
        - OAuth2:
            - camera_guest_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: Returns camera guests list.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CameraGuestListResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
    post:
      deprecated: true
      operationId: my-cameras-guest-create
      summary: Create camera guest
      tags:
        - camera-guest
      parameters:
        - $ref: '#/components/parameters/cameraId'
      requestBody:
        content:
          application/json:
            schema:
              type: object
              title: guest
              required:
                - email
              properties:
                email:
                  type: string
                  format: email
                permissions:
                  $ref: '#/components/schemas/CameraGuestPermissionObject'
      security:
        - OAuth2:
            - camera_guest_manage
        - PersonalAccessToken: []
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CameraGuestObject'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/cameras/{camera_id}/guests/{guest_id}/':
    get:
      deprecated: true
      operationId: my-cameras-guest
      summary: Retrieve camera guest
      tags:
        - camera-guest
      parameters:
        - $ref: '#/components/parameters/cameraId'
        - $ref: '#/components/parameters/guestId'
      security:
        - OAuth2:
            - camera_guest_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: Camera guest object
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CameraGuestObject'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
    put:
      deprecated: true
      operationId: my-cameras-guest-update
      summary: Update camera guest
      tags:
        - camera-guest
      parameters:
        - $ref: '#/components/parameters/cameraId'
        - $ref: '#/components/parameters/guestId'
      requestBody:
        content:
          application/json:
            schema:
              type: object
              title: guest
              properties:
                permissions:
                  $ref: '#/components/schemas/CameraGuestPermissionObject'
      security:
        - OAuth2:
            - camera_guest_manage
        - PersonalAccessToken: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CameraGuestObject'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '404':
          $ref: '#/components/responses/Error404NotFound'
    delete:
      deprecated: true
      operationId: my-cameras-guest-remove
      summary: Remove camera guest
      tags:
        - camera-guest
      parameters:
        - $ref: '#/components/parameters/cameraId'
        - $ref: '#/components/parameters/guestId'
      security:
        - OAuth2:
            - camera_guest_manage
        - PersonalAccessToken: []
      responses:
        '204':
          description: No content
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/cameras/{camera_id}/recording/':
    get:
      deprecated: true
      operationId: my-cameras-recording-info-deprecated
      summary: General recording information
      description: |
        **This endpoint is deprecated and will be removed in the future. Use [this endpoint](#tag/recording/GET/recording/{recording_id}/) instead.**
      tags:
        - recording-deprecated
      parameters:
        - $ref: '#/components/parameters/cameraId'
      security:
        - OAuth2:
            - recording_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: Returns general recording information.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecordingResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/cameras/{camera_id}/recording/download/':
    get:
      deprecated: true
      operationId: my-cameras-recording-download-deprecated
      summary: Download a given recording section
      tags:
        - recording-deprecated
      description: |
        This endpoint will construct a download URL for a specified recording section of a given camera. If there are no records within the section, the download URL will be still returned, however, the URL will respond with HTTP 404. If there are any gaps within the specified recording section, they will be skipped.

        Please keep in mind that the maximum downloadable length is 3 hours.

        **This endpoint is deprecated and will be removed in the future. Use [this endpoint](#tag/recording/GET/recording/{recording_id}/download/) instead.**
      parameters:
        - $ref: '#/components/parameters/cameraId'
        - name: start
          in: query
          required: true
          description: 'Start time of the download. Example: `2016-03-19T08:00:00Z`.'
          example: '2017-01-01T00:00:00.000Z'
          schema:
            type: string
            format: date-time
        - name: end
          in: query
          required: true
          description: 'End time of the download. Example: `2016-03-19T14:00:00Z.`'
          example: '2017-01-01T00:10:00.000Z'
          schema:
            type: string
            format: date-time
        - name: filename
          in: query
          required: false
          description: |
            Filename suggestion for the download. The filename extension will be added automatically.
          example: clip
          schema:
            type: string
      security:
        - OAuth2:
            - recording_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecordingDownloadResponse'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/cameras/{camera_id}/recording/start/':
    post:
      deprecated: true
      operationId: my-cameras-recording-start-deprecated
      summary: Start recording on given camera
      description: |
        **This endpoint is deprecated and will be removed in the future. Use [this endpoint](#tag/recording/POST/recording/{recording_id}/start/) instead.**
      tags:
        - recording-deprecated
      parameters:
        - $ref: '#/components/parameters/cameraId'
        - name: duration
          in: query
          description: Time in seconds after which recording will be stopped. In case multiple auto stop recording requests are received on same camera the one which ends later will be applied. If this endpoint is called without this parameter recording will not be stopped automatically and if there's scheduled auto stop it will be canceled.
          example: 30
          schema:
            type: integer
            minimum: 30
            maximum: 1800
      security:
        - OAuth2:
            - recording_start_stop
        - PersonalAccessToken: []
      responses:
        '204':
          $ref: '#/components/responses/EmptyResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/cameras/{camera_id}/recording/stop/':
    post:
      deprecated: true
      operationId: my-cameras-recording-stop-deprecated
      summary: Stop recording on given camera
      description: |
        **This endpoint is deprecated and will be removed in the future. Use [this endpoint](#tag/recording/POST/recording/{recording_id}/stop/) instead.**
      tags:
        - recording-deprecated
      parameters:
        - $ref: '#/components/parameters/cameraId'
      security:
        - OAuth2:
            - recording_start_stop
        - PersonalAccessToken: []
      responses:
        '204':
          $ref: '#/components/responses/EmptyResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/cameras/{camera_id}/recording/stream/':
    get:
      deprecated: true
      operationId: my-cameras-recording-stream-deprecated
      summary: Create and return recorded stream for a specified time
      description: |
        **This endpoint is deprecated and will be removed in the future. Use [this endpoint](#tag/recording/GET/recording/{recording_id}/stream/) instead.**
      tags:
        - recording-deprecated
      parameters:
        - $ref: '#/components/parameters/cameraId'
        - name: start
          in: query
          required: true
          description: 'Start time of a stream. Example: `2016-03-19T08:00:00Z`.'
          example: '2017-01-01T00:00:00.000Z'
          schema:
            type: string
            format: date-time
        - name: end
          in: query
          required: false
          description: |
            End time of a stream. If missing, stream will play till the very end of recorded footage. Example: `2016-03-19T14:00:00Z.`
          example: '2017-01-01T00:10:00.000Z'
          schema:
            type: string
            format: date-time
      security:
        - OAuth2:
            - recording_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecordingStreamResponse'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/cameras/{camera_id}/recording/timeline/':
    get:
      deprecated: true
      operationId: my-cameras-recording-timeline-deprecated
      summary: Retrieve timeline of records for given camera
      tags:
        - recording-deprecated
      description: |
        Please keep in mind that maximum length of timeline is 1 day.

        **This endpoint is deprecated and will be removed in the future. Use [this endpoint](#tag/recording/GET/recording/{recording_id}/timeline/) instead.**
      parameters:
        - $ref: '#/components/parameters/cameraId'
        - name: start
          in: query
          required: true
          description: 'Start time of a timeline. Example: `2016-03-19T08:00:00Z`.'
          example: '2017-01-01T00:00:00.000Z'
          schema:
            type: string
            format: date-time
        - name: end
          in: query
          required: true
          description: 'End time of a timeline. Example: `2016-03-19T14:00:00Z.`'
          example: '2017-01-01T00:10:00.000Z'
          schema:
            type: string
            format: date-time
      security:
        - OAuth2:
            - recording_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecordingTimelineResponse'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/cameras/{camera_id}/recordings/':
    get:
      operationId: my-cameras-recordings-list
      summary: Retrieve recordings on a given camera
      tags:
        - recording
      parameters:
        - $ref: '#/components/parameters/cameraId'
      security:
        - OAuth2:
            - recording_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: Returns general recording information.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecordingListResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  /clients/:
    get:
      operationId: my-clients-list
      summary: Retrieve clients list
      tags:
        - client
      parameters:
        - name: limit
          in: query
          required: false
          description: 'Limit result set. Example: `1`.'
          schema:
            type: integer
            minimum: 1
        - name: offset
          in: query
          required: false
          description: 'Return results starting at `offset`. Example: `10`.'
          schema:
            type: integer
            minimum: 1
      security:
        - OAuth2:
            - client_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: Returns client list.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ClientListResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
    post:
      operationId: create-client
      summary: Creates new client account
      description: |
        Creates a new client account. After successful creation client receives an email with link for account activation.
      tags:
        - client
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - first_name
                - last_name
                - email
              properties:
                first_name:
                  type: string
                  description: Clients first name
                last_name:
                  type: string
                  description: Clients last name
                email:
                  type: string
                  format: email
                  description: Clients email
                phone:
                  type: string
                  description: Clients phone number
                invoice_to:
                  type: string
                  enum:
                    - me
                    - client
                  default: me
                  description: All services are invoice to reseller (me) or directly to client.
                limited_account:
                  type: boolean
                  default: false
                  description: |
                    Limited clients cannot connect new cameras or purchase any services, by themselves.
                allowed_access:
                  type: boolean
                  default: true
                  description: |
                    This option can be used to give away access to the client user account. A client action is required in order to get the access again.
                activated:
                  type: boolean
                  default: false
                  description: |
                    Create the client account as already activated (i.e. do not send the activation email). A special permission is required for the reseller account in order to use this option.
                password:
                  type: string
                  description: |
                    Create the client account with a given default password. A special permission is required for the reseller account in order to use this option.
              example:
                first_name: Joe
                last_name: Parker
                email: joe@angelcam.com
                phone: +1 111 222 333
                invoice_to: me
                limited_account: false
      security:
        - OAuth2:
            - client_create
        - PersonalAccessToken: []
      responses:
        '201':
          description: Newly created client object
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ClientObject'
        '400':
          $ref: '#/components/responses/Error400InvalidBody'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
  '/clients/{client_id}/':
    get:
      operationId: my-client-detail
      summary: Retrieve client
      tags:
        - client
      parameters:
        - $ref: '#/components/parameters/clientId'
      security:
        - OAuth2:
            - client_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: Client object
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ClientObject'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
    put:
      operationId: update-client
      summary: Update client account
      tags:
        - client
      parameters:
        - $ref: '#/components/parameters/clientId'
      requestBody:
        content:
          application/json:
            schema:
              type: object
              title: client
              properties:
                first_name:
                  type: string
                  description: Clients first name
                last_name:
                  type: string
                  description: Clients last name
                phone:
                  type: string
                  description: Clients phone number
                invoice_to:
                  type: string
                  enum:
                    - me
                    - client
                  description: All services are invoice to reseller (me) or directly to client.
                limited_account:
                  type: boolean
                  description: |
                    Limited clients cannot connect new cameras or purchase any services, by themselves.
                allowed_access:
                  type: boolean
                  description: |
                    This option can be used to give away access to the client user account. A client action is required in order to get the access again. (It is only possible to change this value from true to false using this endpoint.)
                password:
                  type: string
                  description: |
                    Set password for the client account. A special permission is required for the reseller account in order to use this option.
              example:
                first_name: Joe
                last_name: Parker
                phone: +1 111 222 333
                invoice_to: client
                limited_account: false
      security:
        - OAuth2:
            - client_manage
        - PersonalAccessToken: []
      responses:
        '200':
          description: Client object
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ClientObject'
        '400':
          $ref: '#/components/responses/Error400InvalidBody'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
  '/clients/{client_id}/invite/':
    post:
      operationId: my-client-invite
      summary: Resend invitation email
      description: |
        For resending an invitation email. This is useful in case when client does not receive the first invitation email,
         so client get new chance to activate their account and set a password.
      tags:
        - client
      parameters:
        - $ref: '#/components/parameters/clientId'
      security:
        - OAuth2:
            - client_create
        - PersonalAccessToken: []
      responses:
        '204':
          $ref: '#/components/responses/EmptyResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  /events/:
    post:
      operationId: events-create
      summary: Create event
      tags:
        - event
      description: |
        This endpoint has rate limiting in place. The endpoint will accept at most 10 requests per minute
        for a given hash (see [Nuts and bolts](#section/Angelcam-API/Nuts-and-bolts) for more details).
      requestBody:
        content:
          application/json:
            schema:
              type: object
              title: event
              required:
                - hash
              properties:
                hash:
                  type: string
                  description: |
                    Event API hash (a unique token for each sensor found in My Angelcam dashboard or obtained
                    via Sensor Resource) - used to authenticate the request and pair the event with corresponding
                    sensor.
                title:
                  type: string
                occurred_at:
                  type: string
                  format: datetime
              example:
                hash: 50yxnlu2o2
      security: []
      responses:
        '201':
          description: Event was received
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EventObject'
        '400':
          description: The event hash is invalid or there's another error in the request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400Invalid'
        '429':
          description: The rate limit has been reached
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429TooManyRequests'
    get:
      operationId: events-create-get
      summary: Create event by get request
      tags:
        - event
      description: |
        In cases when it's not possible to send post request we allowed to create event by GET request. In general you should avoid using this method and rather prefer creating events via POST request.
      parameters:
        - name: hash
          in: query
          required: true
          description: |
            Event API hash (a unique token for each camera found in My Angelcam dashboard or obtained
            via Camera Resource) - used to authenticate the request and pair the event with corresponding
            camera.
          example: 50yxnlu2o2
          schema:
            type: string
        - name: title
          in: query
          required: false
          schema:
            type: string
      security: []
      responses:
        '201':
          description: Event was received
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EventObject'
        '400':
          description: The event hash is invalid or there's another error in the request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400Invalid'
        '429':
          description: The rate limit has been reached
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429TooManyRequests'
  /locations/:
    get:
      operationId: locations-list
      summary: Retrieve location list
      tags:
        - location
      parameters:
        - name: limit
          in: query
          required: false
          description: 'Limit result set. Example: `1`.'
          schema:
            type: integer
            minimum: 1
        - name: offset
          in: query
          required: false
          description: 'Return results starting at `offset`. Example: `10`.'
          schema:
            type: integer
            minimum: 1
      security:
        - OAuth2:
            - locations_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: Returns location list.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LocationListResponse'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
  '/locations/{location_id}/':
    get:
      operationId: location-detail
      summary: Retrieve location details
      tags:
        - location
      parameters:
        - $ref: '#/components/parameters/locationId'
      security:
        - OAuth2:
            - locations_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: Returns location details.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LocationObject'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  /me/:
    get:
      operationId: me
      summary: Current user info
      tags:
        - user
      security:
        - OAuth2:
            - user_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserMeResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
    delete:
      operationId: me-delete
      summary: Delete current user
      tags:
        - user
      security:
        - OAuth2:
            - user_delete
        - PersonalAccessToken: []
      responses:
        '204':
          $ref: '#/components/responses/EmptyResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
  /public-cameras/:
    get:
      operationId: public-cameras-list
      summary: Retrieve public camera list
      tags:
        - public-camera
      parameters:
        - name: limit
          in: query
          required: false
          description: 'Limit result set. Example: `1`.'
          schema:
            type: integer
            minimum: 1
        - name: offset
          in: query
          required: false
          description: 'Return results starting at `offset`. Example: `10`.'
          schema:
            type: integer
            minimum: 1
        - name: online
          in: query
          required: false
          description: '`1` for filtering only cameras that are online. `0` for filtering only cameras that are offline. Be aware that you cannot fully rely on this filtering. The camera status is checked every 10 minutes. Therefore the real status of camera can differ from API status.'
          schema:
            type: boolean
      security:
        - OAuth2:
            - public_cameras_access
      responses:
        '200':
          description: Returns public camera list.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicCameraListResponse'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
  '/public-cameras/{camera_id}/':
    get:
      operationId: public-cameras-detail
      summary: Retrieve public camera
      tags:
        - public-camera
      parameters:
        - $ref: '#/components/parameters/sharedCameraId'
      security:
        - OAuth2:
            - public_cameras_access
      responses:
        '200':
          description: Camera object
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicCameraObject'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/recording/stream/{streamer_name}/{streamer_id}/':
    get:
      deprecated: true
      operationId: my-cameras-recordings-stream-info
      summary: Retrieve recording stream info
      description: |
        **This endpoint is deprecated and will be removed in the future. Use [this endpoint](#tag/stream-controls/GET/recording/streams/{stream_id}/) instead.**
      tags:
        - recording-deprecated
      security:
        - OAuth2:
            - recording_access
        - PersonalAccessToken: []
      parameters:
        - name: streamer_name
          in: path
          required: true
          description: Streamer server name.
          example: rec-streamer-eu-central-1
          schema:
            type: string
        - name: streamer_id
          in: path
          required: true
          description: Stream ID.
          example: 61c59a859e9244a19713fdfec6e50184
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecordingStreamInfoResponseDeprecated'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/recording/streams/{stream_id}/':
    get:
      servers:
        - url: 'https://{streamer_domain}'
          variables:
            streamer_domain:
              default: rec-streamer-eu-central-1.angelcam.com
              description: Streamer server name.
      operationId: recordings-stream-info
      summary: Retrieve recording stream info
      tags:
        - stream-controls
      security: []
      parameters:
        - name: stream_id
          in: path
          required: true
          description: Stream ID.
          example: 63d57a30-e167-4b39-b098-102ab99e136d
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecordingStreamInfoResponse'
        '404':
          description: Not Found
  '/recording/streams/{stream_id}/pause/':
    post:
      servers:
        - url: 'https://{streamer_domain}'
          variables:
            streamer_domain:
              default: rec-streamer-eu-central-1.angelcam.com
              description: Streamer server name.
      operationId: recordings-stream-pause
      summary: Pause recording stream
      tags:
        - stream-controls
      security: []
      parameters:
        - name: stream_id
          in: path
          required: true
          description: Stream ID.
          example: 63d57a30-e167-4b39-b098-102ab99e136d
          schema:
            type: string
      responses:
        '204':
          $ref: '#/components/responses/EmptyResponse'
        '404':
          description: Not Found
  '/recording/streams/{stream_id}/play/':
    post:
      servers:
        - url: 'https://{streamer_domain}'
          variables:
            streamer_domain:
              default: rec-streamer-eu-central-1.angelcam.com
              description: Streamer server name.
      operationId: recordings-stream-play
      summary: Play recording stream
      tags:
        - stream-controls
      security: []
      parameters:
        - name: stream_id
          in: path
          required: true
          description: Stream ID.
          example: 63d57a30-e167-4b39-b098-102ab99e136d
          schema:
            type: string
      responses:
        '204':
          $ref: '#/components/responses/EmptyResponse'
        '404':
          description: Not Found
  '/recording/streams/{stream_id}/speed/':
    post:
      servers:
        - url: 'https://{streamer_domain}'
          variables:
            streamer_domain:
              default: rec-streamer-eu-central-1.angelcam.com
              description: Streamer server name.
      operationId: recordings-stream-speed
      summary: Set playback speed
      description: |
        If you're looking to modify the playback speed in your application, there's an essential step that you need to keep in mind. You must send a request to our streaming service via this endpoint to prepare the HLS playlist at the desired speed.

        Keep in mind, however, that altering the playback speed does not only change how fast the video plays, but also affects the bitrate. For instance, if you increase the playback speed to twice (2x) the normal speed, the bitrate will also double. The implications of this are significant. A higher bitrate requires faster internet speeds to maintain smooth playback. So, if your users do not have a fast enough internet connection, they might experience buffering or interruptions during playback.
      tags:
        - stream-controls
      security: []
      parameters:
        - name: stream_id
          in: path
          required: true
          description: Stream ID.
          example: 63d57a30-e167-4b39-b098-102ab99e136d
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              type: object
              title: speed
              required:
                - speed
              properties:
                speed:
                  type: number
                  enum:
                    - 1
                    - 2
                    - 4
                    - 8
                    - 16
      responses:
        '204':
          $ref: '#/components/responses/EmptyResponse'
        '400':
          description: Bad Request
        '404':
          description: Not Found
  '/recording/{recording_id}/':
    get:
      operationId: my-cameras-recording-info
      summary: General recording information
      tags:
        - recording
      parameters:
        - $ref: '#/components/parameters/recordingId'
      security:
        - OAuth2:
            - recording_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: Returns general recording information.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecordingResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/recording/{recording_id}/download/':
    get:
      operationId: my-cameras-recording-download
      summary: Download a given recording section
      tags:
        - recording
      description: |
        This endpoint will construct a download URL for a specified recording section of a given camera. If there are no records within the section, the download URL will be still returned, however, the URL will respond with HTTP 404. If there are any gaps within the specified recording section, they will be skipped.

        Please keep in mind that the maximum downloadable length is 3 hours.
      parameters:
        - $ref: '#/components/parameters/recordingId'
        - name: start
          in: query
          required: true
          description: 'Start time of the download. Example: `2016-03-19T08:00:00Z`.'
          example: '2017-01-01T00:00:00.000Z'
          schema:
            type: string
            format: date-time
        - name: end
          in: query
          required: true
          description: 'End time of the download. Example: `2016-03-19T14:00:00Z.`'
          example: '2017-01-01T00:10:00.000Z'
          schema:
            type: string
            format: date-time
        - name: filename
          in: query
          required: false
          description: |
            Filename suggestion for the download. The filename extension will be added automatically.
          example: clip
          schema:
            type: string
      security:
        - OAuth2:
            - recording_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecordingDownloadResponse'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/recording/{recording_id}/snapshot/':
    get:
      operationId: my-cameras-recording-snapshot
      summary: Retrieve recording snapshot URL at a specified time
      tags:
        - recording
      parameters:
        - $ref: '#/components/parameters/recordingId'
        - name: datetime
          in: query
          required: true
          description: 'Time at which to retrieve snapshot. Example: `2016-03-19T08:00:00Z`.'
          example: '2017-01-01T00:00:00.000Z'
          schema:
            type: string
            format: date-time
      security:
        - OAuth2:
            - recording_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  url:
                    type: string
                    format: uri
                    description: URL of the snapshot image
                required:
                  - url
                example:
                  url: 'https://dsw4ncxjbie85.cloudfront.net/snapshot/157/h8yeodu1mrjtiiok.jpg'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/recording/{recording_id}/start/':
    post:
      operationId: my-cameras-recording-start
      summary: Start recording
      tags:
        - recording
      description: |
        ### Event recording

        If you only wish to record events instead of 24/7 coverage, you can use a combination of the `start_from` and `stop_at` or `duration` parameters. Setting `start_from` a few seconds before now will ensure that any buffered media starting from the given timestamp will be recorded. Note that this means that Angelcam Cloud is already connected to the media source (e.g. IP camera) or that the media source itself is able to hold media in an internal buffer for some amount of time (RTSP/2.0 media source with Time-Duration media property is required).

        The `stop_at` or `duration` parameters can be used then to stop the recording automatically at some point. To extend a recording, call this endpoint repeatedly with the same `duration` parameter or with an increased `stop_at` parameter. For example, let's assume that the current time is `2024-07-10 10:00:00.000Z`. Calling this endpoint with `start_from=2024-07-10T09:59:30.000Z` and `duration=60` will tell Angelcam Cloud to record all available media starting from 30 seconds ago and to keep recording until 60 seconds from now. Calling this endpoint again after 30 seconds with the same parameters will extend the recording duration to 90 seconds from now.
      parameters:
        - $ref: '#/components/parameters/recordingId'
        - name: start_from
          in: query
          description: 'All available media starting from a given timestamp will be recorded. This also includes any media buffered by Angelcam Cloud infrastructure and the media source itself (e.g. IP camera). This parameter becomes handy in situations when you only want to record certain events but you need the recording to start a few seconds before the event itself. If this endpoint is called without this parameter, only media generated after the recording start command are recorded.'
          example: '2024-07-10T00:00:00.000Z'
          schema:
            type: string
            format: date-time
        - name: stop_at
          in: query
          description: 'Time at which the recording will be stopped. In case multiple auto-stop recording requests are received on the same recording, the one which ends later will be applied. If this endpoint is called without this parameter, the recording will not be stopped automatically, and if there''s a scheduled auto stop, it will be canceled. This parameter is mutually exclusive with the `duration` parameter.'
          example: '2024-07-10T00:01:00.000Z'
          schema:
            type: string
            format: date-time
        - name: duration
          in: query
          description: 'Time in seconds after which the recording will be stopped (counting from the moment the request is received by Angelcam API). In case multiple auto-stop recording requests are received on the same recording, the one that ends later will be applied. If this endpoint is called without this parameter, the recording will not be stopped automatically, and if there''s a scheduled auto stop, it will be canceled. This parameter is mutually exclusive with the `stop_at` parameter.'
          example: 30
          schema:
            type: integer
            minimum: 30
            maximum: 1800
      security:
        - OAuth2:
            - recording_start_stop
        - PersonalAccessToken: []
      responses:
        '204':
          $ref: '#/components/responses/EmptyResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/recording/{recording_id}/stop/':
    post:
      operationId: my-cameras-recording-stop
      summary: Stop recording
      tags:
        - recording
      parameters:
        - $ref: '#/components/parameters/recordingId'
      security:
        - OAuth2:
            - recording_start_stop
        - PersonalAccessToken: []
      responses:
        '204':
          $ref: '#/components/responses/EmptyResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/recording/{recording_id}/stream/':
    get:
      operationId: my-cameras-recording-stream
      summary: Create and return recorded stream for a specified time
      tags:
        - recording
      parameters:
        - $ref: '#/components/parameters/recordingId'
        - name: start
          in: query
          required: true
          description: 'Start time of a stream. Example: `2016-03-19T08:00:00Z`.'
          example: '2017-01-01T00:00:00.000Z'
          schema:
            type: string
            format: date-time
        - name: end
          in: query
          required: false
          description: |
            End time of a stream. If missing, stream will play till the very end of recorded footage. Example: `2016-03-19T14:00:00Z.`
          example: '2017-01-01T00:10:00.000Z'
          schema:
            type: string
            format: date-time
      security:
        - OAuth2:
            - recording_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecordingStreamResponse'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/recording/{recording_id}/timeline/':
    get:
      operationId: my-cameras-recording-timeline
      summary: Retrieve timeline of records for given recording
      tags:
        - recording
      description: |
        Please keep in mind that maximum length of timeline is 1 day.
      parameters:
        - $ref: '#/components/parameters/recordingId'
        - name: start
          in: query
          required: true
          description: 'Start time of a timeline. Example: `2016-03-19T08:00:00Z`.'
          example: '2017-01-01T00:00:00.000Z'
          schema:
            type: string
            format: date-time
        - name: end
          in: query
          required: true
          description: 'End time of a timeline. Example: `2016-03-19T14:00:00Z.`'
          example: '2017-01-01T00:10:00.000Z'
          schema:
            type: string
            format: date-time
      security:
        - OAuth2:
            - recording_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecordingTimelineResponse'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  /rts/:
    get:
      operationId: rts-settings-retrieve
      summary: RTS settings
      tags:
        - rts_settings
      security:
        - OAuth2:
            - rts_settings_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RTSSettingsObject'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
    put:
      operationId: rts-settings-update
      summary: Update RTS settings
      tags:
        - rts_settings
      security:
        - OAuth2:
            - rts_settings_manage
        - PersonalAccessToken: []
      requestBody:
        content:
          application/json:
            schema:
              type: object
              title: RTS settings
              properties:
                incident_ttl:
                  type: string
                  enum:
                    - PT1M
                    - PT3M
                    - PT5M
                    - PT10M
                    - PT30M
                    - PT1H
                  description: ISO 8601 duration format. The value represents the minimal delay between two events triggered by the same sensor that has to pass before Angelcam sends another notification to the user.
              example:
                incident_ttl: PT1M
      responses:
        '200':
          description: RTSSettings object
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RTSSettingsObject'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
  /rts/arm/:
    post:
      operationId: rts-arm
      summary: Arm RTS
      tags:
        - rts_settings
      parameters:
        - name: location_id
          in: query
          required: false
          description: Location ID to arm.
          schema:
            type: integer
            minimum: 1
          example: 1
        - name: delay
          in: query
          required: false
          description: 'Arming delay in seconds. If specified, the location will be armed after the specified delay.'
          schema:
            type: integer
            minimum: 0
          example: 30
      security:
        - OAuth2:
            - rts_arming_manage
        - PersonalAccessToken: []
      responses:
        '204':
          $ref: '#/components/responses/EmptyResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
  /rts/disarm/:
    post:
      operationId: rts-disarm
      summary: Disarm RTS
      tags:
        - rts_settings
      parameters:
        - name: location_id
          in: query
          required: false
          description: Location ID to disarm.
          schema:
            type: integer
            minimum: 1
          example: 1
        - name: delay
          in: query
          required: false
          description: 'Disarming delay in seconds. If specified, the location will be disarmed after the specified delay.'
          schema:
            type: integer
            minimum: 0
          example: 30
      security:
        - OAuth2:
            - rts_arming_manage
        - PersonalAccessToken: []
      responses:
        '204':
          $ref: '#/components/responses/EmptyResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
  /rts/incidents/:
    get:
      operationId: incidents
      summary: Retrieve incidents
      tags:
        - incidents
      description: Retrieves list of user incidents
      parameters:
        - name: limit
          in: query
          required: false
          description: 'Limit result set. Example: `1`.'
          schema:
            type: integer
            minimum: 1
        - name: offset
          in: query
          required: false
          description: 'Return results starting at `offset`. Example: `10`.'
          schema:
            type: integer
            minimum: 1
        - name: start
          in: query
          description: 'Example: `2017-03-07T14:00:00Z`.'
          required: false
          schema:
            type: string
            format: date-time
        - name: end
          in: query
          description: 'Example: `2017-03-07T16:00:00Z`.'
          required: false
          schema:
            type: string
            format: date-time
        - name: ordering
          in: query
          description: 'Orderign of results, based on `created_at` field. Default: desc'
          required: false
          schema:
            type: string
            enum:
              - asc
              - desc
      security:
        - OAuth2:
            - incidents_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IncidentListResponse'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/rts/incidents/{incident_id}/':
    get:
      operationId: rts-incident-detail
      summary: Retrieve incident detail
      description: Retrieve incident detail
      tags:
        - incidents
      security:
        - OAuth2:
            - incidents_access
        - PersonalAccessToken: []
      parameters:
        - $ref: '#/components/parameters/incidentId'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IncidentObject'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  /rts/messages/:
    get:
      operationId: rts-messages
      summary: Retrieve messages
      tags:
        - rts_messages
      description: Retrieves list of user messages
      parameters:
        - name: limit
          in: query
          required: false
          description: 'Limit result set. Example: `1`.'
          schema:
            type: integer
            minimum: 1
        - name: next
          in: query
          required: false
          description: 'Cursor for the next page, taken from `next` field of a previous response.'
          schema:
            type: string
            format: uri
      security:
        - OAuth2:
            - messages_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessageListResponse'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  /rts/messages/set-all-read/:
    post:
      operationId: rts-message-set-all-read
      summary: Set all messages as read
      description: Set all messages as read
      tags:
        - rts_messages
      security:
        - OAuth2:
            - messages_manage
        - PersonalAccessToken: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  set_as_read_count:
                    type: number
                    description: Number of messages which were marked as read
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
  /rts/messages/unread-count/:
    get:
      operationId: rts-message-unread-count
      summary: Retrieve unread messages count
      description: Retrieve unread messages count
      tags:
        - rts_messages
      security:
        - OAuth2:
            - messages_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  unread_count:
                    type: number
                    description: Unread messages count
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
  '/rts/messages/{message_id}/':
    get:
      operationId: rts-message-detail
      summary: Retrieve message detail
      description: Retrieve message detail
      tags:
        - rts_messages
      security:
        - OAuth2:
            - messages_access
        - PersonalAccessToken: []
      parameters:
        - $ref: '#/components/parameters/messageId'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessageObject'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
    put:
      operationId: rts-message-update
      summary: Update message
      description: Update messages
      tags:
        - rts_messages
      security:
        - OAuth2:
            - messages_manage
        - PersonalAccessToken: []
      parameters:
        - $ref: '#/components/parameters/messageId'
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                is_read:
                  type: boolean
                  description: Was message read by user?
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessageObject'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  /rts/notifications/methods/:
    get:
      operationId: rts-notifications-methods
      summary: Retrieve notifications methods
      tags:
        - rts_notification_methods
      description: Retrieves list of user notification methods
      parameters:
        - name: limit
          in: query
          required: false
          description: 'Limit result set. Example: `1`.'
          schema:
            type: integer
            minimum: 1
        - name: offset
          in: query
          required: false
          description: 'Return results starting at `offset`. Example: `10`.'
          schema:
            type: integer
            minimum: 0
      security:
        - OAuth2:
            - notifications_methods_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NotificationMethodListResponse'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
    post:
      operationId: rts-notification-method-create
      summary: Create notification method
      description: Create notification method
      tags:
        - rts_notification_methods
      security:
        - OAuth2:
            - notifications_methods_manage
        - PersonalAccessToken: []
      requestBody:
        content:
          application/json:
            schema:
              oneOf:
                - $ref: '#/components/schemas/HttpNotificationMethodChangeObject'
                - $ref: '#/components/schemas/EmailNotificationMethodChangeObject'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/HttpNotificationMethodObject'
                  - $ref: '#/components/schemas/EmailNotificationMethodObject'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
  '/rts/notifications/methods/{method_id}/':
    get:
      operationId: rts-notification-method-detail
      summary: Retrieve notification method detail
      description: Retrieve notification method detail
      tags:
        - rts_notification_methods
      security:
        - OAuth2:
            - notifications_methods_access
        - PersonalAccessToken: []
      parameters:
        - $ref: '#/components/parameters/notificationMethodId'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/HttpNotificationMethodObject'
                  - $ref: '#/components/schemas/EmailNotificationMethodObject'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
    put:
      operationId: rts-notification-method-update
      summary: Update notification method
      description: Update notification method
      tags:
        - rts_notification_methods
      security:
        - OAuth2:
            - notifications_methods_manage
        - PersonalAccessToken: []
      parameters:
        - $ref: '#/components/parameters/notificationMethodId'
      requestBody:
        content:
          application/json:
            schema:
              oneOf:
                - $ref: '#/components/schemas/HttpNotificationMethodChangeObject'
                - $ref: '#/components/schemas/EmailNotificationMethodChangeObject'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/HttpNotificationMethodObject'
                  - $ref: '#/components/schemas/EmailNotificationMethodObject'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  /rts/notifications/rules/:
    get:
      operationId: rts-notifications-rules
      summary: Retrieve notifications rules
      tags:
        - rts_notification_rules
      description: Retrieves list of user notification rules
      parameters:
        - name: limit
          in: query
          required: false
          description: 'Limit result set. Example: `1`.'
          schema:
            type: integer
            minimum: 1
        - name: offset
          in: query
          required: false
          description: 'Return results starting at `offset`. Example: `10`.'
          schema:
            type: integer
            minimum: 0
      security:
        - OAuth2:
            - notifications_rules_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NotificationRuleListResponse'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
    post:
      operationId: rts-notification-rule-create
      summary: Create notification rule
      description: Create notification rule
      tags:
        - rts_notification_rules
      security:
        - OAuth2:
            - notifications_rules_manage
        - PersonalAccessToken: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NotificationRuleChangeObject'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NotificationRuleObject'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
  '/rts/notifications/rules/{rule_id}/':
    get:
      operationId: rts-notification-rule-detail
      summary: Retrieve notification rule detail
      description: Retrieve notification rule detail
      tags:
        - rts_notification_rules
      security:
        - OAuth2:
            - notifications_rules_access
        - PersonalAccessToken: []
      parameters:
        - $ref: '#/components/parameters/notificationRuleId'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NotificationRuleObject'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
    put:
      operationId: rts-notification-rule-update
      summary: Update notification rule
      description: Update notification rule
      tags:
        - rts_notification_rules
      security:
        - OAuth2:
            - notifications_rules_manage
        - PersonalAccessToken: []
      parameters:
        - $ref: '#/components/parameters/notificationRuleId'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NotificationRuleChangeObject'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NotificationRuleObject'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  /sensors/:
    get:
      operationId: my-sensors-list
      summary: Retrieve sensor list
      tags:
        - sensor
      parameters:
        - name: limit
          in: query
          required: false
          description: 'Limit result set. Example: `1`.'
          schema:
            type: integer
            minimum: 1
        - name: offset
          in: query
          required: false
          description: 'Return results starting at `offset`. Example: `10`.'
          schema:
            type: integer
            minimum: 1
      security:
        - OAuth2:
            - sensor_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: Returns sensor list.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SensorListResponse'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
    post:
      operationId: connect-sensors
      summary: Connect new sensor
      tags:
        - sensor
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - name
                - type
              properties:
                name:
                  type: string
                  description: Sensor name
                type:
                  type: string
                  enum:
                    - motion
                    - camera_motion
                    - door_window
                    - smoke
                    - fire
                    - glass_break
                    - shock_vibration
                    - water
                    - perimeter_entry
                  description: Sensor type
                placement:
                  type: string
                  enum:
                    - indoors
                    - outdoors
                  description: Sensor placement
                manufacturer:
                  type: string
                  description: Sensor manufacturer
                model:
                  type: string
                  description: Sensor model
                note:
                  type: string
                  description: Any note related to sensor
                enabled:
                  type: boolean
                  description: Defaults to True. Indicates if sensor is enabled or not. If disabled then all events from the sensor are ignored.
                override_arming:
                  type: boolean
                  description: 'Defaults to False. If enabled, an event received from the sensor will always trigger an incident regardless of the arming settings.'
                camera:
                  type: integer
                  minimum: 1
                  description: Camera ID sensor is bind to
                enable_cloud_recording_for:
                  type: string
                  format: duration
                  enum:
                    - PT30S
                    - PT1M
                    - PT2M
                    - PT5M
                  description: Duration of event Recording triggered by an event from this sensor. This setting is applied only if sensor has an assigned camera with active Cloud Recording.
                incident_delay:
                  type: string
                  format: duration
                  description: 'A delay before RTS incident is triggered. If the location is disarmed during this period, no incident is forwarded. However the video from the binded camera is recorded. PT0S means no delay and PT3M is the max.'
              example:
                name: My brand new sensor
                type: smoke
      security:
        - OAuth2:
            - sensor_manage
        - PersonalAccessToken: []
      responses:
        '201':
          description: Newly created sensor object
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SensorObject'
        '400':
          $ref: '#/components/responses/Error400InvalidBody'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
  '/sensors/{sensor_id}/':
    get:
      operationId: my-sensors-detail
      summary: Retrieve sensor
      tags:
        - sensor
      parameters:
        - $ref: '#/components/parameters/sensorId'
      security:
        - OAuth2:
            - sensor_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: Sensor object
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SensorObject'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
    put:
      operationId: my-sensors-update
      summary: Update sensor
      tags:
        - sensor
      parameters:
        - $ref: '#/components/parameters/sensorId'
      requestBody:
        content:
          application/json:
            schema:
              type: object
              title: sensor
              properties:
                name:
                  type: string
                  description: Sensor name
                type:
                  type: string
                  enum:
                    - motion
                    - camera_motion
                    - door_window
                    - smoke
                    - fire
                    - glass_break
                    - shock_vibration
                    - water
                    - perimeter_entry
                  description: Sensor type
                placement:
                  type: string
                  enum:
                    - indoors
                    - outdoors
                  description: Sensor placement
                manufacturer:
                  type: string
                  description: Sensor manufacturer
                model:
                  type: string
                  description: Sensor model
                note:
                  type: string
                  description: Any note related to sensor
                enabled:
                  type: boolean
                  description: Defaults to True. Indicates if sensor is enabled or not. If disabled then all events from the sensor are ignored.
                override_arming:
                  type: boolean
                  description: 'Defaults to False. If enabled, an event received from the sensor will always trigger an incident regardless of the arming settings.'
                camera:
                  type: integer
                  minimum: 1
                  description: Camera ID sensor is bind to
                enable_cloud_recording_for:
                  type: string
                  format: duration
                  enum:
                    - PT30S
                    - PT1M
                    - PT2M
                    - PT5M
                  description: Duration of event Recording triggered by an event from this sensor. This setting is applied only if sensor has an assigned camera with active Cloud Recording.
                incident_delay:
                  type: string
                  format: duration
                  description: 'A delay before RTS incident is triggered. If the location is disarmed during this period, no incident is forwarded. However the video from the binded camera is recorded. PT0S means no delay and PT3M is the max.'
              example:
                name: My updated shiny sensor
                type: smoke
                camera: 24
                enable_cloud_recording_for: PT1M
                incident_delay: PT0S
      security:
        - OAuth2:
            - sensor_manage
        - PersonalAccessToken: []
      responses:
        '200':
          description: Sensor object
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SensorObject'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
    delete:
      operationId: my-sensors-remove
      summary: Remove sensor
      tags:
        - sensor
      parameters:
        - $ref: '#/components/parameters/sensorId'
      security:
        - OAuth2:
            - sensor_manage
        - PersonalAccessToken: []
      responses:
        '204':
          description: No content
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  /spaces/:
    get:
      operationId: list-spaces
      summary: List spaces
      tags:
        - space
      description: |
        Returns all spaces the authenticated user belongs to. Use the `is_default` flag to identify the user's default space. To operate within a specific space, pass the `X-Space-Id` request header with the desired space ID.
      security:
        - OAuth2:
            - space_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: List of spaces the user belongs to.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SpaceObject'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
  '/spaces/{space_id}/':
    get:
      operationId: get-space
      summary: Get space detail
      tags:
        - space
      description: |
        Returns details of a specific space. The authenticated user must be a member of that space.
      security:
        - OAuth2:
            - space_access
        - PersonalAccessToken: []
      parameters:
        - name: space_id
          in: path
          required: true
          description: ID of the space.
          schema:
            type: integer
          example: 7
      responses:
        '200':
          description: Space detail.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SpaceObject'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          description: Space not found or the user is not a member.
  '/spaces/{space_id}/permissions/':
    get:
      operationId: get-space-permissions
      summary: Get space permissions
      tags:
        - space
      description: |
        Returns all permissions the authenticated user has within the given space. The user must be a member of that space. Includes both permissions assigned directly to the user and those inherited through group membership.
        Each permission entry may be scoped to the whole space, a specific location, or a specific camera. See the [Spaces section](#tag/space) for the full list of permission slugs and scoping rules.
      security:
        - OAuth2:
            - space_permissions_access
        - PersonalAccessToken: []
      parameters:
        - name: space_id
          in: path
          required: true
          description: ID of the space.
          schema:
            type: integer
          example: 7
      responses:
        '200':
          description: Permissions for the given space.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SpacePermissionsObject'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          description: Space not found or the user is not a member.
  /shared-cameras/:
    get:
      deprecated: true
      operationId: shared-cameras-list
      summary: Retrieve shared camera list
      tags:
        - shared-camera
      parameters:
        - name: limit
          in: query
          required: false
          description: 'Limit result set. Example: `1`.'
          schema:
            type: integer
            minimum: 1
        - name: offset
          in: query
          required: false
          description: 'Return results starting at `offset`. Example: `10`.'
          schema:
            type: integer
            minimum: 1
        - name: refresh_rate
          in: query
          required: false
          description: 'Set a maximum number of keyframes sent in MJPEG stream per second. For example if you want to have MJPEG stream with keyframe sent every 10 seconds, post value 0.1.'
          schema:
            type: number
            format: float
            minimum: 0
        - name: max_width
          in: query
          required: false
          description: Maximum width of MJPEG stream and LIVE SNAPSHOT.
          schema:
            type: integer
            minimum: 1
        - name: max_height
          in: query
          required: false
          description: Maximum height of MJPEG stream and LIVE SNAPSHOT.
          schema:
            type: integer
            minimum: 1
      security:
        - OAuth2:
            - camera_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: Returns shared camera list.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SharedCameraListResponse'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
  '/shared-cameras/{camera_id}/':
    get:
      deprecated: true
      operationId: shared-cameras-detail
      summary: Retrieve shared camera
      tags:
        - shared-camera
      parameters:
        - $ref: '#/components/parameters/sharedCameraId'
        - name: refresh_rate
          in: query
          required: false
          description: 'Set a maximum number of keyframes sent in MJPEG stream per second. For example if you want to have MJPEG stream with keyframe sent every 10 seconds, post value 0.1.'
          schema:
            type: number
            format: float
            minimum: 0
        - name: max_width
          in: query
          required: false
          description: Maximum width of MJPEG stream and LIVE SNAPSHOT.
          schema:
            type: integer
            minimum: 1
        - name: max_height
          in: query
          required: false
          description: Maximum height of MJPEG stream and LIVE SNAPSHOT.
          schema:
            type: integer
            minimum: 1
      security:
        - OAuth2:
            - camera_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: Camera object
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SharedCameraObject'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
    delete:
      deprecated: true
      operationId: shared-cameras-remove
      summary: Remove shared camera
      tags:
        - shared-camera
      parameters:
        - $ref: '#/components/parameters/sharedCameraId'
      security:
        - OAuth2:
            - camera_manage
        - PersonalAccessToken: []
      responses:
        '204':
          description: No content
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/shared-cameras/{camera_id}/clips/':
    get:
      deprecated: true
      operationId: shared-cameras-clips-list
      summary: Retrieve camera clips list
      tags:
        - shared-camera-clip
      description: Retrieve a list of recording clips for a given shared camera
      security:
        - OAuth2:
            - recording_clips_access
        - PersonalAccessToken: []
      parameters:
        - $ref: '#/components/parameters/cameraId'
        - name: created_by
          in: query
          required: false
          description: Filter results only to clips created by given users. A comma separated list of user IDs is expected. No whitespace characters are permited. The asterisk (`*`) character can be used to list all clips. By default the endpoint returns only clips created by the current user.
          example: '1,2,3'
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SharedCameraClipListResponse'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
    post:
      deprecated: true
      operationId: shared-cameras-clips-create
      summary: Create clip
      tags:
        - shared-camera-clip
      description: Create a recording clip on a given shared camera
      parameters:
        - $ref: '#/components/parameters/cameraId'
      requestBody:
        content:
          application/json:
            schema:
              type: object
              title: clip
              required:
                - name
                - start
                - end
              properties:
                name:
                  type: string
                  description: Clip name
                start:
                  type: string
                  format: date-time
                  description: Start time of clip (ISO 8601)
                end:
                  type: string
                  format: date-time
                  description: End time of clip (ISO 8601)
              example:
                name: Frontdoor loitering
                start: '2017-01-01T00:00:00.000Z'
                end: '2017-01-01T00:25:00.000Z'
      security:
        - OAuth2:
            - recording_clips_access
            - recording_clips_create
        - PersonalAccessToken: []
      responses:
        '201':
          description: Clip request was received and clip processing will start
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SharedCameraClipObject'
        '400':
          description: 'No recording data exists for given timeframe, requested clip lenght exceeds 3 hours or there''s another error in the request'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400Invalid'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
  '/shared-cameras/{camera_id}/clips/{clip_id}/':
    get:
      deprecated: true
      operationId: shared-cameras-clips-detail
      summary: Retrieve a single clip
      tags:
        - shared-camera-clip
      description: Retrieves the details for a given recording clip
      parameters:
        - $ref: '#/components/parameters/cameraId'
        - $ref: '#/components/parameters/clipId'
      security:
        - OAuth2:
            - recording_clips_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SharedCameraClipObject'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/shared-cameras/{camera_id}/clips/{clip_id}/stream/':
    get:
      deprecated: true
      operationId: shared-cameras-clips-stream
      summary: Retrieve a clip stream
      tags:
        - shared-camera-clip
      description: Retrieves stream of a recording clip
      parameters:
        - $ref: '#/components/parameters/cameraId'
        - $ref: '#/components/parameters/clipId'
        - name: start
          in: query
          required: true
          description: 'Start time of a stream. Example: `2016-03-19T08:00:00Z`.'
          example: '2017-01-01T00:00:00.000Z'
          schema:
            type: string
            format: date-time
      security:
        - OAuth2:
            - recording_clips_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecordingStreamResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/shared-cameras/{camera_id}/recording/':
    get:
      deprecated: true
      operationId: shared-cameras-recordings-info
      summary: General shared recording information
      tags:
        - shared-camera-recording
      parameters:
        - $ref: '#/components/parameters/sharedCameraId'
      security:
        - OAuth2:
            - recording_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: Returns general recording information.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecordingResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/shared-cameras/{camera_id}/recording/stream/':
    get:
      deprecated: true
      operationId: shared-cameras-recordings-stream
      summary: Retrieve recording stream for shared camera
      description: Create and return recorded stream of shared camera for a specified time
      tags:
        - shared-camera-recording
      parameters:
        - $ref: '#/components/parameters/sharedCameraId'
        - name: start
          in: query
          required: true
          description: 'Start time of a stream. Example: `2016-03-19T08:00:00Z`.'
          example: '2017-01-01T00:00:00.000Z'
          schema:
            type: string
            format: date-time
        - name: end
          in: query
          required: false
          description: |
            End time of a stream. If missing, stream will play till the very end of recorded footage. Example: `2016-03-19T14:00:00Z.`
          example: '2017-01-01T00:10:00.000Z'
          schema:
            type: string
            format: date-time
      security:
        - OAuth2:
            - recording_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecordingStreamResponse'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/shared-cameras/{camera_id}/recording/timeline/':
    get:
      deprecated: true
      operationId: shared-cameras-recordings-timeline
      summary: Retrieve timeline of records for given shared camera
      tags:
        - shared-camera-recording
      description: |
        Please keep in mind that maximum length of timeline is 1 day.
      parameters:
        - $ref: '#/components/parameters/sharedCameraId'
        - name: start
          in: query
          required: true
          description: 'Start time of a timeline. Example: `2016-03-19T08:00:00Z`.'
          example: '2017-01-01T00:00:00.000Z'
          schema:
            type: string
            format: date-time
        - name: end
          in: query
          required: true
          description: 'End time of a timeline. Example: `2016-03-19T14:00:00Z.`'
          example: '2017-01-01T00:10:00.000Z'
          schema:
            type: string
            format: date-time
      security:
        - OAuth2:
            - recording_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecordingTimelineResponse'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  /speakers/:
    get:
      operationId: speaker-list
      summary: Retrieve speaker list
      tags:
        - speakers
      parameters:
        - name: limit
          in: query
          required: false
          description: 'Limit result set. Example: `1`.'
          schema:
            type: integer
            minimum: 1
        - name: offset
          in: query
          required: false
          description: 'Return results starting at `offset`. Example: `10`.'
          schema:
            type: integer
            minimum: 1
      security:
        - OAuth2:
            - speaker_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: List of speakers.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SpeakerListResponse'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
    post:
      operationId: connect-speakers
      summary: Connect new speaker
      tags:
        - speakers
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SpeakerObject'
      security:
        - OAuth2:
            - speaker_manage
        - PersonalAccessToken: []
      responses:
        '201':
          description: Newly created speaker object.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SpeakerObject'
        '400':
          $ref: '#/components/responses/Error400InvalidBody'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
  '/speakers/{speaker_id}/':
    parameters:
      - $ref: '#/components/parameters/speakerId'
    get:
      operationId: speaker-detail
      summary: Retrieve speaker detail
      tags:
        - speakers
      security:
        - OAuth2:
            - speaker_access
        - PersonalAccessToken: []
      responses:
        '200':
          description: Speaker.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SpeakerObject'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
    put:
      operationId: update-speaker
      summary: Update existing speaker
      tags:
        - speakers
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SpeakerObject'
      security:
        - OAuth2:
            - speaker_manage
        - PersonalAccessToken: []
      responses:
        '200':
          description: Updated speaker object.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SpeakerObject'
        '400':
          $ref: '#/components/responses/Error400InvalidBody'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/speakers/{speaker_id}/play/':
    parameters:
      - $ref: '#/components/parameters/speakerId'
    post:
      operationId: audio-playback-start
      summary: Start audio playback
      tags:
        - speakers
      security:
        - OAuth2:
            - audio_messages_play
        - PersonalAccessToken: []
      description: |
        Play a given audio message or return a WebRTC signaling URL if no message ID is given.

        ### Live audio playback using WebRTC

        Every [WebRTC signaling](#section/Angelcam-API/WebRTC-signaling) session for live audio playback starts by sending an SDP offer from the client to the corresponding Angelcam server followed by one or more local ICE candidates. The server then responds with an SDP answer followed by one or more of its local ICE candidates. The candidate exchange should conclude by sending a `null` candidate by each side to the other peer to signal that there are no more local ICE candidates. There is no lock-step mechanism for sending the ICE candidates. All available local candidates should be sent to the other peer immediately after sending the SDP offer/answer.

        #### STUN/TURN servers

        No external STUN or TURN servers are required as all Angelcam servers have a public IP address and, therefore, the `host` ICE candidates on the server side are always reachable. The client's server-reflexive candidates, if needed, are then discovered once the client contacts the server via the server's `host` candidates.
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                message:
                  type: integer
                  nullable: true
                  description: audio message ID
                repeat:
                  type: boolean
                  default: false
                  description: repeat the audio message
                stop_after:
                  type: integer
                  nullable: true
                  description: Duration in seconds after which the playback will automatically stop. This is required when repeat is `true` to prevent infinite playback.
      responses:
        '200':
          description: WebRTC signaling URL.
          content:
            application/json:
              schema:
                type: object
                properties:
                  webrtc_signaling_url:
                    type: string
                    format: url
                    description: WebRTC signaling URL
                    example: 'wss://m1-eu1.angelcam.com/speakers/123/web-rtc/'
                required:
                  - webrtc_signaling_url
        '204':
          $ref: '#/components/responses/EmptyResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
        '503':
          $ref: '#/components/responses/Error503ServiceUnavailable'
  '/speakers/{speaker_id}/stop/':
    parameters:
      - $ref: '#/components/parameters/speakerId'
    post:
      operationId: audio-playback-stop
      summary: Stop audio playback
      tags:
        - speakers
      security:
        - OAuth2:
            - audio_messages_play
        - PersonalAccessToken: []
      responses:
        '204':
          $ref: '#/components/responses/EmptyResponse'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
  '/speakers/{speaker_id}/test/':
    parameters:
      - $ref: '#/components/parameters/speakerId'
    get:
      operationId: speaker-test
      summary: Test speaker connection
      description: |
        On success, the endpoint returns HTTP 204; otherwise, HTTP 400 with a detail about the connection issue is returned.

        _Note that this is just a connectivity test. Successful connectivity test does not mean that the speaker itself works (i.e. that it's able to play audio)._
      tags:
        - speakers
      security:
        - OAuth2:
            - speaker_access
        - PersonalAccessToken: []
      responses:
        '204':
          $ref: '#/components/responses/EmptyResponse'
        '400':
          $ref: '#/components/responses/Error400InvalidParams'
        '401':
          $ref: '#/components/responses/Error401Unauthorized'
        '403':
          $ref: '#/components/responses/Error403PermissionDenied'
        '404':
          $ref: '#/components/responses/Error404NotFound'
components:
  schemas:
    ActiveServiceListResponse:
      type: object
      title: Active service list
      properties:
        count:
          type: integer
          description: Count of all services
        next:
          format: uri
          description: Next page from pagination
          nullable: true
          type: string
        previous:
          format: uri
          description: Previous page from pagination
          nullable: true
          type: string
        results:
          type: array
          description: List of services available for user
          items:
            $ref: '#/components/schemas/ActiveServiceObject'
      required:
        - count
        - next
        - previous
        - results
    ActiveServiceObject:
      type: object
      title: Service object
      properties:
        id:
          type: integer
        current_service:
          $ref: '#/components/schemas/ServiceObject'
          description: Current service
          nullable: true
        renew_service:
          $ref: '#/components/schemas/ServiceObject'
          description: Pending service (the service that will be activated at the next renewal)
          nullable: true
        renew_period:
          type: string
          format: duration
          example: P1M
          nullable: true
        valid_until:
          type: string
          format: datetime
        in_use:
          type: boolean
          description: Says if service is in use for example by a camera
        usage_detail:
          $ref: '#/components/schemas/UsageDetailObject'
      required:
        - id
        - current_service
        - renew_service
        - renew_period
        - valid_until
        - in_use
        - usage_detail
    ActiveServiceUsageObject:
      type: object
      title: Service object
      properties:
        id:
          type: integer
        in_use:
          type: boolean
          description: Says if service is in use for example by a camera
        usage_detail:
          $ref: '#/components/schemas/UsageDetailObject'
          nullable: true
      required:
        - id
        - in_use
        - usage_detail
    AngelCameraFirmwareResponse:
      type: object
      title: AngelCamera firmware
      properties:
        board:
          type: string
          description: AngelCamera board ID
        model:
          type: string
          description: AngelCamera model name
        version:
          type: string
          description: Firmware version
        image:
          type: string
          format: url
          description: Firmware image URL
        changelog:
          type: string
          description: Changelog
      required:
        - board
        - model
        - version
        - image
        - changelog
      example:
        board: c3c9429e42c76e50f0f300267a7ac733
        model: AngelCamera One
        version: 1.20.0
        image: 'https://download.angelcam.com/angelcamera/c3c9429e42c76e50f0f300267a7ac733/fw-1.20.0.img'
        changelog: ''
    ApplicationObject:
      type: object
      properties:
        code:
          type: string
          enum:
            - LSA
            - CRA
            - VVA
            - VPA
            - TLA
      required:
        - code
      example:
        code: LSA
    ArrowClientAddServiceRequest:
      type: object
      title: New Arrow service
      properties:
        type:
          type: string
          enum:
            - http
            - rtsp
          description: Type of the target service
        ip:
          type: string
          description: local IP address
        port:
          type: integer
          description: service port
      required:
        - type
        - ip
        - port
      example:
        type: rtsp
        ip: 192.168.1.100
        port: 554
    ArrowClientAddServiceResponse:
      type: object
      title: Arrow client add service response
      properties:
        service_id:
          type: string
          description: Arrow service ID
      required:
        - service_id
      example:
        service_id: abcd
    ArrowClientDetailObject:
      type: object
      title: Arrow client
      properties:
        uuid:
          type: string
          format: uuid
          description: UUID of the Arrow client
          nullable: true
        mac:
          type: string
          format: mac
          description: MAC address of the device running the Arrow client
          nullable: true
        ip:
          type: string
          description: Public IP address of the device running the Arrow client
        status:
          type: string
          enum:
            - online
            - offline
            - not_paired
          description: |
            Current availability of the Arrow client. The `not_paired` value means that there is an active pairing request for this client, however, the client has not reached Angelcam servers yet.
        scanning:
          type: boolean
          description: |
            True if the client is currently scanning the target network, false otherwise
        proxy:
          type: object
          description: |
            Arrow proxy addresses and credentials (see
            [the description](#tag/arrow-clients/Arrow-proxy) for more details)
          properties:
            connect:
              type: object
              description: HTTP CONNECT proxy addresses
              properties:
                http:
                  type: string
                  description: HTTP address of the Arrow proxy
                https:
                  type: string
                  description: HTTPS address of the Arrow proxy
            transparent:
              type: object
              description: Transparent HTTP proxy addresses
              properties:
                http:
                  type: string
                  description: HTTP address of the Arrow proxy
                https:
                  type: string
                  description: HTTPS address of the Arrow proxy
            token:
              type: string
              description: Arrow proxy access token
        capabilities:
          type: object
          description: Features supported by the Arrow client
          properties:
            add_custom_service:
              type: boolean
              description: True if adding custom services via API is supported.
      required:
        - uuid
        - mac
        - status
      example:
        uuid: 75b62326-eca3-4424-ab68-48e7da47e847
        mac: '12:34:56:78:9a:bc'
        ip: 1.1.1.1
        status: online
        scanning: true
        proxy:
          connect:
            http: 'm1-eu1.angelcam.com:8920'
            https: 'm1-eu1.angelcam.com:8940'
          transparent:
            http: 'm1-eu1.angelcam.com:8921'
            https: 'm1-eu1.angelcam.com:8941'
          token: xxx.yyy.zzz
        capabilities:
          add_custom_service: true
    ArrowClientListObject:
      type: object
      title: Paired Arrow client
      properties:
        uuid:
          type: string
          format: uuid
          description: UUID of the Arrow client
        mac:
          type: string
          format: mac
          description: MAC address of the device running the Arrow client
        ip:
          type: string
          description: Public IP address of the device running the Arrow client
      required:
        - uuid
        - mac
        - ip
      example:
        uuid: 75b62326-eca3-4424-ab68-48e7da47e847
        mac: '12:34:56:78:9a:bc'
        ip: 1.1.1.1
    ArrowClientPairingResponse:
      type: object
      title: Arrow client pairing response
      properties:
        uuid:
          type: string
          format: uuid
          description: UUID of the paired Arrow client
        mac:
          type: string
          format: MAC address
          description: MAC address of the paired Arrow client
      example:
        uuid: 75b62326-eca3-4424-ab68-48e7da47e847
    ArrowClientServicesResponse:
      type: object
      title: A list of Arrow services
      properties:
        count:
          type: integer
          description: Number of all services
        next:
          format: uri
          description: Next page from pagination
          nullable: true
          type: string
        previous:
          format: uri
          description: Previous page from pagination
          nullable: true
          type: string
        results:
          type: array
          description: A list of Arrow services
          items:
            $ref: '#/components/schemas/ArrowServiceObject'
      required:
        - count
        - next
        - previous
        - results
    ArrowClientsResponse:
      type: object
      title: A list of Arrow clients
      properties:
        count:
          type: integer
          description: Number of all clients
        next:
          format: uri
          description: Next page from pagination
          nullable: true
          type: string
        previous:
          format: uri
          description: Previous page from pagination
          nullable: true
          type: string
        results:
          type: array
          description: A list of Arrow clients
          items:
            $ref: '#/components/schemas/ArrowClientListObject'
      required:
        - count
        - next
        - previous
        - results
    ArrowServiceObject:
      type: object
      title: Arrow service
      properties:
        id:
          type: string
          description: Arrow service ID
        type:
          type: string
          enum:
            - http
            - rtsp
          description: Type of the service.
        mac:
          type: string
          format: mac
          description: |
            MAC address of the device providing this service. The MAC address will be valid only for services discovered via the network scan. In all other cases, it will be a fake MAC address starting with `FF:FF` prefix.
        ip:
          type: string
          description: |
            IP address used by the corresponding Arrow client to connect to the service (i.e. local IP address of the service).
        port:
          type: integer
          description: |
            Port number used by the corresponding Arrow client to connect to the service (i.e. the port which the service is listening on).
        flags:
          type: object
          description: Service flags.
          properties:
            static:
              type: boolean
              description: 'If `true`, the service is fixed and cannot be deleted.'
            discovered:
              type: boolean
              description: 'If `true`, the service was discovered by the network scanner.'
            custom:
              type: boolean
              description: 'If `true`, the service was added manually using the API.'
          required:
            - static
            - discovered
            - custom
        hints:
          type: object
          description: |
            Various hints that may help with service identification. Please note that the hints are best-effort only. They may not be always correct.
          properties:
            camera:
              type: boolean
              description: |
                If `true`, the service appears to be an RTSP server of an IP camera or an HTTP server of an IP camera providing an MJPEG stream.
            locked:
              type: boolean
              description: |
                The field is present only if the `camera` field is `true` and it indicates that the service may require authentication.
            stream:
              type: string
              nullable: true
              description: |
                The field is present only if the `camera` field is `true` and it indicates that there is likely a video stream on the given endpoint.
          required:
            - camera
        camera_ids:
          type: array
          items:
            type: integer
          description: A list of cameras (their IDs) which use this service.
      required:
        - id
        - type
        - mac
        - ip
        - port
        - camera_ids
      example:
        id: 21af
        type: rtsp
        mac: 'ff:ff:7f:00:00:01'
        ip: 127.0.0.1
        port: 554
        hints:
          camera: true
          locked: true
          stream: null
        flags:
          static: false
          discovered: true
          custom: false
        camera_ids: []
    AudioMessageListResponse:
      type: object
      title: Audio Message list
      properties:
        count:
          type: integer
          description: Count of audio messages
        next:
          format: uri
          description: Next page from pagination
          nullable: true
          type: string
        previous:
          format: uri
          description: Previous page from pagination
          nullable: true
          type: string
        results:
          type: array
          description: List of audio messages
          items:
            $ref: '#/components/schemas/AudioMessageObject'
      required:
        - count
        - next
        - previous
        - results
    AudioMessageObject:
      type: object
      title: Audio message object
      properties:
        id:
          type: integer
          minimum: 1
          description: Audio message ID
        name:
          type: string
          description: Audio message name
        message:
          type: string
          format: url
          description: URL where the audio message content can be downloaded
      required:
        - id
        - name
        - message
      example:
        id: 157
        name: Alarm
        message: 'https://example.com/alarm.mp3'
    AudioMessageWriteObject:
      type: object
      title: Audio message object
      properties:
        name:
          type: string
          description: Audio message name
        message:
          type: string
          format: base64
          description: 'Base64-encoded audio file. Supported formats: `audio/aac`, `audio/mpeg` (MP3), `audio/wav`, `audio/ogg`, `audio/webm`. Keep files short — a few seconds is ideal for reliable playback.'
      required:
        - name
        - message
      example:
        id: 157
        name: Alarm
        message: dGhlIGF1ZGlvIGZpbGUgY29udGVudCBnb2VzIGhlcmU=
    BroadcastingResponse:
      type: object
      title: Broadcasting information
      required:
        - enabled
        - public_page
        - streams
      properties:
        enabled:
          type: boolean
          description: 'True if the public broadcasting is enabled for this camera, false otherwise This settings affects only the public page and the HTML embed code.'
        public_page:
          type: boolean
          description: 'True if the public page (i.e. xyz.click2stream.com) is enabled for this camera, false otherwise.'
        streams:
          type: array
          nullable: true
          items:
            $ref: '#/components/schemas/StreamObject'
          description: 'Available broadcasting streams or `null` if the current broadcasting service plan does not allow broadcasting via API. [Read about stream URLs expirations.](http://help.angelcam.com/en/articles/3952149-how-to-deal-with-stream-url-expiration)'
      example:
        enabled: true
        public_page: false
        streams:
          - format: mjpeg
            url: 'http://e1.angelcam.com/stream/81/stream.mjpeg?token=eyJ0aW1lIjogMTQ5NjkzNDYyODE5NjIxOCwgInRpbWVvdXQiOiAzNjAwLCAiYWxpYXMiOiAiODEifQ==.85b552be2b7f0abaa0a3b5b4f412877f8af92f691c7d0c6db6b8c517ea8f921c'
          - format: mp4
            url: 'http://e1.angelcam.com/stream/81/stream.mp4?token=eyJ0aW1lIjogMTQ5NjkzNDYyODE5NjMxNiwgInRpbWVvdXQiOiAzNjAwLCAiYWxpYXMiOiAiODEifQ==.b5b4cf405cf054701a75b359f4069d2af8a102c5ffd8f33cbb560a4638c7cb71'
          - format: mpegts
            url: 'http://e1.angelcam.com/stream/81/stream.ts?token=eyJ0aW1lIjogMTQ5NjkzNDYyODE5NjMxNiwgInRpbWVvdXQiOiAzNjAwLCAiYWxpYXMiOiAiODEifQ==.b5b4cf405cf054701a75b359f4069d2af8a102c5ffd8f33cbb560a4638c7cb71'
          - format: hls
            url: 'http://e1.angelcam.com/stream/81/playlist.m3u8?token=eyJ0aW1lIjogMTQ5NjkzNDYyODE5NjQwMSwgInRpbWVvdXQiOiAzNjAwLCAiYWxpYXMiOiAiODEifQ==.8ac35b434e768e8f10161b2d74da492f5fd8a8c115c18cbb421017665acd908a'
    CameraGuestListResponse:
      type: object
      deprecated: true
      title: Camera guests list
      properties:
        count:
          type: integer
          description: Count of all camera guests
        next:
          format: uri
          description: Next page from pagination
          nullable: true
          type: string
        previous:
          format: uri
          description: Previous page from pagination
          nullable: true
          type: string
        results:
          type: array
          description: List of camera guests
          items:
            $ref: '#/components/schemas/CameraGuestObject'
      required:
        - count
        - next
        - previous
        - results
    CameraGuestObject:
      type: object
      deprecated: true
      title: Guest object
      properties:
        id:
          type: integer
          description: Guest id
        first_name:
          description: Guest's first or given name.
          nullable: true
          type: string
        last_name:
          description: Guest's last or family name.
          nullable: true
          type: string
        email:
          type: string
          format: email
          description: Guest's email.
        permissions:
          $ref: '#/components/schemas/CameraGuestPermissionObject'
      required:
        - email
        - permissions
      example:
        id: 35
        first_name: Saint
        last_name: Michael
        email: michael@angelcam.com
        permisions:
          can_view_rec: true
          can_create_clips: false
          can_view_all_clips: false
          share_notifications: false
    CameraGuestPermissionObject:
      type: object
      deprecated: true
      title: Guest permission
      properties:
        can_view_rec:
          type: boolean
          description: The guest can view camera recordings.
          x-example: false
        can_create_clips:
          type: boolean
          description: The guest can create clips and view clips created by themselves. This option also implies `can_view_rec`.
          x-example: false
        can_view_all_clips:
          type: boolean
          description: The guest can view clips created by any user.
          x-example: false
        share_notifications:
          type: boolean
          description: Share RTS notifications for a given camera.
          x-example: false
    CameraListResponse:
      type: object
      title: Camera list
      properties:
        count:
          type: integer
          description: Count of all cameras
        next:
          format: uri
          description: Next page from pagination
          nullable: true
          type: string
        previous:
          format: uri
          description: Previous page from pagination
          nullable: true
          type: string
        results:
          type: array
          description: List of cameras owned by the user
          items:
            $ref: '#/components/schemas/CameraObject'
      required:
        - count
        - next
        - previous
        - results
    CameraObject:
      type: object
      title: Camera object
      properties:
        id:
          type: integer
          minimum: 1
          description: Camera ID
        name:
          type: string
          description: Camera name
        location:
          description: ID of the location the camera belongs to
          nullable: true
          type: integer
        site:
          description: 'ID of the location the camera belongs to. **Deprecated:** use `location` instead.'
          deprecated: true
          nullable: true
          type: integer
        type:
          type: string
          enum:
            - h264
            - h265
            - mjpeg
          description: Camera type
        snapshot:
          $ref: '#/components/schemas/SnapshotObject'
        status:
          type: string
          enum:
            - offline
            - online
            - unknown
        event_api_hash:
          type: string
          description: Event API hash - unique token for posting events to camera timeline from embedded devices without authentication (do not disclose)
        live_snapshot:
          format: uri
          description: Live snapshot URL
          nullable: true
          type: string
        streams:
          type: array
          items:
            $ref: '#/components/schemas/StreamObject'
          description: 'Available camera streams. [Read about stream URLs expirations.](http://help.angelcam.com/en/articles/3952149-how-to-deal-with-stream-url-expiration) Please note that the amount of stream consumers per camera is limited to 10 concurrent consumers. Angelcam web app and Angelcam mobile app also count to this limit. Recording is excluded. If you need more concurrent stream consumers, use the broadcasting service.'
        applications:
          type: array
          items:
            $ref: '#/components/schemas/ApplicationObject'
        low_latency_enabled:
          type: boolean
          description: 'Indicates if user enabled [low latency streaming](http://help.angelcam.com/en/articles/372634-enabling-low-latency-streaming) in camera settings.'
        audio_enabled:
          type: boolean
          description: Indicates if audio is enabled for given camera.
        enable_status_checks:
          type: boolean
          description: Indicates if periodic online/offline checks for the camera are enabled.
        enable_periodical_snapshots:
          type: boolean
          description: Indicates if camera snapshot is being refreshed automatically once every 24h.
        tags:
          type: array
          items:
            type: string
          description: List of tags assigned to the camera. Tags can be used for filtering.
      required:
        - id
        - name
        - location
        - site
        - type
        - snapshot
        - status
        - live_snapshot
        - streams
        - applications
        - low_latency_enabled
        - audio_enabled
        - enable_status_checks
        - enable_periodical_snapshots
        - tags
      example:
        id: 157
        name: Parkside Office
        location: 1
        site: 1
        type: h264
        snapshot:
          url: 'https://dsw4ncxjbie85.cloudfront.net/snapshot/81/y8jol6kbn0ol1gh2.jpg'
          created_at: '2017-03-29T15:41:39.000Z'
        status: online
        live_snapshot: 'http://m1.angelcam.com/stream/81/snapshot.jpg?token=eyJ0aW1lIjogMTQ5NjkzNDYyODE5NjIxOCwgInRpbWVvdXQiOiAzNjAwLCAiYWxpYXMiOiAiODEifQ==.85b552be2b7f0abaa0a3b5b4f412877f8af92f691c7d0c6db6b8c517ea8f921c'
        streams:
          - format: mjpeg
            url: 'http://m1.angelcam.com/stream/81/stream.mjpeg?token=eyJ0aW1lIjogMTQ5NjkzNDYyODE5NjIxOCwgInRpbWVvdXQiOiAzNjAwLCAiYWxpYXMiOiAiODEifQ==.85b552be2b7f0abaa0a3b5b4f412877f8af92f691c7d0c6db6b8c517ea8f921c'
            refresh_rate: 0.1
          - format: mp4
            url: 'http://m1.angelcam.com/stream/81/stream.mp4?token=eyJ0aW1lIjogMTQ5NjkzNDYyODE5NjMxNiwgInRpbWVvdXQiOiAzNjAwLCAiYWxpYXMiOiAiODEifQ==.b5b4cf405cf054701a75b359f4069d2af8a102c5ffd8f33cbb560a4638c7cb71'
          - format: mpegts
            url: 'http://m1.angelcam.com/stream/81/stream.ts?token=eyJ0aW1lIjogMTQ5NjkzNDYyODE5NjMxNiwgInRpbWVvdXQiOiAzNjAwLCAiYWxpYXMiOiAiODEifQ==.b5b4cf405cf054701a75b359f4069d2af8a102c5ffd8f33cbb560a4638c7cb71'
          - format: hls
            url: 'http://m1.angelcam.com/stream/81/playlist.m3u8?token=eyJ0aW1lIjogMTQ5NjkzNDYyODE5NjQwMSwgInRpbWVvdXQiOiAzNjAwLCAiYWxpYXMiOiAiODEifQ==.8ac35b434e768e8f10161b2d74da492f5fd8a8c115c18cbb421017665acd908a'
        applications:
          - LSA
          - CRA
        low_latency_enabled: false
        audio_enabled: true
        enable_status_checks: true
        enable_periodical_snapshots: true
        tags:
          - office
          - entrance
    CameraStartStreamDetectionResponse:
      type: object
      title: Camera Start Stream Detection Response
      properties:
        session_id:
          type: string
      required:
        - session_id
    CameraStreamDetectionPreview:
      type: object
      title: Camera preview
      description: Camera preview that can be used to access the underlying stream in various ways. The preview is available only for 20 minutes.
      properties:
        live_snapshot:
          type: string
          format: url
          description: A URL that can be used to retrieve a snapshot from the camera
        streams:
          type: array
          description: A list of streams available for the preview
          items:
            $ref: '#/components/schemas/CameraStreamDetectionPreviewStream'
      required:
        - live_snapshot
        - streams
    CameraStreamDetectionPreviewStream:
      type: object
      title: Camera preview stream
      properties:
        format:
          type: string
          enum:
            - hls
            - mjpeg
            - mp4
          description: Stream type
        url:
          type: string
          format: url
          description: Stream URL
      required:
        - format
        - url
    CameraStreamDetectionResponse:
      type: object
      title: Camera Result Stream Detection Response
      properties:
        status:
          type: string
          enum:
            - ok
            - in-progress
            - error
          description: Result status
        streams:
          type: array
          description: A list of detected streams
          items:
            $ref: '#/components/schemas/CameraStreamDetectionStream'
        error:
          type: string
          description: Error information
      required:
        - status
      example:
        status: ok
        streams:
          - url: 'rtsp://1.2.3.4/main'
            type: h264
            preview:
              live_snapshot: 'http://m1.angelcam.com/stream/81/snapshot.jpg?token=eyJ0aW1lIjogMTQ5NjkzNDYyODE5NjIxOCwgInRpbWVvdXQiOiAzNjAwLCAiYWxpYXMiOiAiODEifQ==.85b552be2b7f0abaa0a3b5b4f412877f8af92f691c7d0c6db6b8c517ea8f921c'
              streams:
                - format: mjpeg
                  url: 'http://m1.angelcam.com/stream/81/stream.mjpeg?token=eyJ0aW1lIjogMTQ5NjkzNDYyODE5NjIxOCwgInRpbWVvdXQiOiAzNjAwLCAiYWxpYXMiOiAiODEifQ==.85b552be2b7f0abaa0a3b5b4f412877f8af92f691c7d0c6db6b8c517ea8f921c'
                - format: mp4
                  url: 'http://m1.angelcam.com/stream/81/stream.mp4?token=eyJ0aW1lIjogMTQ5NjkzNDYyODE5NjMxNiwgInRpbWVvdXQiOiAzNjAwLCAiYWxpYXMiOiAiODEifQ==.b5b4cf405cf054701a75b359f4069d2af8a102c5ffd8f33cbb560a4638c7cb71'
                - format: hls
                  url: 'http://m1.angelcam.com/stream/81/playlist.m3u8?token=eyJ0aW1lIjogMTQ5NjkzNDYyODE5NjQwMSwgInRpbWVvdXQiOiAzNjAwLCAiYWxpYXMiOiAiODEifQ==.8ac35b434e768e8f10161b2d74da492f5fd8a8c115c18cbb421017665acd908a'
    CameraStreamDetectionStream:
      type: object
      title: Detected stream
      properties:
        url:
          type: string
          format: url
          description: URL of the detected stream. This is the URL that should be used to create a new camera.
        type:
          type: string
          enum:
            - h264
            - h265
            - mjpeg
          description: Camera type
        preview:
          $ref: '#/components/schemas/CameraStreamDetectionPreview'
      required:
        - url
        - type
        - preview
    ClientListResponse:
      type: object
      title: Client list
      properties:
        count:
          type: integer
          description: Count of client
        next:
          format: uri
          description: Next page from pagination
          nullable: true
          type: string
        previous:
          format: uri
          description: Previous page from pagination
          nullable: true
          type: string
        results:
          type: array
          description: List of clients of reseller
          items:
            $ref: '#/components/schemas/ClientObject'
      required:
        - count
        - next
        - previous
        - results
    ClientObject:
      type: object
      title: Client object
      properties:
        id:
          type: integer
          minimum: 1
          description: Client ID
        first_name:
          type: string
          description: Clients first name
        last_name:
          type: string
          description: Clients last name
        email:
          type: string
          format: email
          description: Clients email
        phone:
          description: Clients phone number
          nullable: true
          type: string
        invoice_to:
          type: string
          enum:
            - me
            - client
          description: All services are invoice to reseller (me) or directly to client.
        limited_account:
          type: boolean
          description: |
            Limited clients cannot connect new cameras or purchase any services, by themselves.
        allowed_access:
          type: boolean
          description: |
            This field indicates if reseller can access clients cameras. Defualt is true, but client can refuse access.
        activated_at:
          format: datetime
          description: 'Datetime, when client activated their account, or null in a case when the account is not activated yet at all.'
          nullable: true
          type: string
      required:
        - id
        - first_name
        - last_name
        - email
        - phone
        - invoice_to
        - limited_account
        - allowed_access
        - activated_at
      example:
        id: 42
        first_name: Joe
        last_name: Parker
        email: joe@angelcam.com
        phone: +1 111 222 333
        invoice_to: client
        limited_account: false
        allowed_access: true
        confiremd_at: null
    ClipListResponse:
      type: object
      title: Clip list
      properties:
        count:
          type: integer
          minimum: 0
          description: Count of all clips
        next:
          format: uri
          description: Next page from pagination
          nullable: true
          type: string
        previous:
          format: uri
          description: Previous page from pagination
          nullable: true
          type: string
        results:
          type: array
          description: List of clips for the camera
          items:
            $ref: '#/components/schemas/ClipObject'
      required:
        - count
        - next
        - previous
        - results
      example:
        count: 10
        next: null
        previous: null
        results:
          - id: b9aad334-07ba-4660-9f18-041875ec1ea4
            created_by: 1
            name: Frontdoor loitering
            status: READY
            sharing_token: cd13975b-0b08-48f5-bd39-3f7d2a0c935a
            start: '2017-01-01T00:00:20.000Z'
            end: '2017-01-01T00:25:20.000Z'
            created_at: '2017-02-01T02:37:21.000Z'
            download_url: 'https://rust-streamer-us-west-2-07489f9b03f198b91.angelcam.com/clips/b986b0c8-05c2-4c59-8fdd-8afd7bbfa2bf/download/?start=2019%2D12%2D09T14%3A19%3A59%2B00%3A00&end=2019%2D12%2D09T14%3A20%3A29%2B00%3A00&token=eyJ0aW1lIjoxNTc2NzUyMzY3LCJ0aW1lb3V0IjoxMjAwfQ%3D%3D%2E1c5903efe76af570bea4ef5edf49c39f5afc1ce2c1aaf79e85ad5d140c8c3f42&filename=Frontdoor%20loitering'
    ClipObject:
      type: object
      title: Clip object
      properties:
        id:
          type: string
          minimum: 1
          description: Clip UUID
        created_by:
          type: integer
          description: User who created the clip
        created_at:
          type: string
          minimum: 1
          description: Time when the clip was created
        name:
          type: string
          minimum: 1
          description: Clip name
        status:
          type: string
          description: Status of clip processing
          enum:
            - PENDING
            - BUILDING
            - SCREENSHOTTING
            - READY
            - ERROR
        start:
          type: string
          minimum: 1
          description: Start time of the clip
        end:
          type: string
          minimum: 1
          description: End time of the clip
        sharing_token:
          type: string
          description: Security token for sharing the clip without authentication (UUID)
        snapshots:
          type: array
          description: 'List of URLs of snapshot images (JPEG) taken from the beginning of the clip. The snapshots are generated automatically during clip processing and can be used as a thumbnail/preview of the clip. The list is empty until the clip reaches the `SCREENSHOTTING` stage, and it may stay empty if the snapshot could not be taken. The URLs contain a security token valid for a limited time.'
          items:
            type: string
            format: uri
        download_url:
          type: string
          description: 'URL for download of the clip as TS/MP4 file (TS for HLS cameras, MP4 for MJPEG cameras). The URL contains security token valid for a limited time.'
      required:
        - id
        - created_by
        - created_at
        - download_url
        - end
        - name
        - sharing_token
        - snapshots
        - start
        - status
      example:
        id: b9aad334-07ba-4660-9f18-041875ec1ea4
        created_by: 1
        name: Frontdoor loitering
        status: READY
        sharing_token: cd13975b-0b08-48f5-bd39-3f7d2a0c935a
        start: '2017-01-01T00:00:20.000Z'
        end: '2017-01-01T00:25:20.000Z'
        created_at: '2017-02-01T02:37:21.000Z'
        snapshots:
          - 'https://recording-us-west-2.s3.amazonaws.com/clips/b9aad334-07ba-4660-9f18-041875ec1ea4.jpg?AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&Signature=NpgCO4tLYjQmhLpq7QgCGkl6EXAMPLE%3D&Expires=1576753567'
        download_url: 'https://rust-streamer-us-west-2-07489f9b03f198b91.angelcam.com/clips/b986b0c8-05c2-4c59-8fdd-8afd7bbfa2bf/download/?start=2019%2D12%2D09T14%3A19%3A59%2B00%3A00&end=2019%2D12%2D09T14%3A20%3A29%2B00%3A00&token=eyJ0aW1lIjoxNTc2NzUyMzY3LCJ0aW1lb3V0IjoxMjAwfQ%3D%3D%2E1c5903efe76af570bea4ef5edf49c39f5afc1ce2c1aaf79e85ad5d140c8c3f42&filename=Frontdoor%20loitering'
    EmailNotificationMethodChangeObject:
      type: object
      title: Email notification object
      properties:
        name:
          type: string
          description: notification method name
        type:
          type: string
          enum:
            - email
          description: notification method type
        email:
          type: string
          format: email
          description: email address
      required:
        - type
        - email
      example:
        name: My email
        type: email
        email: email@example.com
    EmailNotificationMethodObject:
      type: object
      title: Email notification object
      properties:
        id:
          type: integer
          minimum: 1
          description: notification method ID
        name:
          type: string
          description: notification method name
        type:
          type: string
          enum:
            - email
          description: notification method type
        email:
          type: string
          format: email
          description: email address
      required:
        - id
        - name
        - type
        - email
      example:
        id: 85
        name: My email
        type: email
        email: email@example.com
    Error400Invalid:
      allOf:
        - $ref: '#/components/schemas/ErrorGeneric'
      title: Error 400 Bad Request
      example:
        title: invalid
        detail: Invalid hash
        status: 400
    Error400InvalidParams:
      type: object
      title: Error 400 Invalid Parameters
      properties:
        title:
          type: string
        detail:
          type: object
        status:
          type: integer
      required:
        - title
        - detail
        - status
      example:
        title: invalid
        detail:
          - refresh_rate:
              - valid number is required.
              - Ensure this value is greater than 0.
          - max_width:
              - valid number is required.
              - Ensure this value is greater than or equal to 1.
        status: 400
    Error401Unauthorized:
      allOf:
        - $ref: '#/components/schemas/ErrorGeneric'
      title: Error 401 Unauthorized
      example:
        title: not_authenticated
        detail: Authentication credentials were not provided
        status: 401
    Error403PermissionDenied:
      allOf:
        - $ref: '#/components/schemas/ErrorGeneric'
      title: Error 403 Permission Denied
      example:
        title: permission_denied
        detail: You do not have permission to perform this action.
        status: 403
    Error404NotFound:
      allOf:
        - $ref: '#/components/schemas/ErrorGeneric'
      title: Error 404 Not Found
      example:
        title: not_found
        detail: Not Found
        status: 404
    Error405MethodNotAllowed:
      allOf:
        - $ref: '#/components/schemas/ErrorGeneric'
      title: Error 405 Method Not Allowed
      example:
        title: method_not_allowed
        detail: Method Not Allowed
        status: 405
    Error429TooManyRequests:
      allOf:
        - $ref: '#/components/schemas/ErrorGeneric'
      title: Error 429 Too Many Requests
      example:
        title: rate_limited
        detail: The rate limit has been reached
        status: 429
    Error502BadGateway:
      allOf:
        - $ref: '#/components/schemas/ErrorGeneric'
      title: Error 502 Bad Gateway
      example:
        title: bad_gateway
        detail: Bad Gateway
        status: 502
    Error503ServiceUnavailable:
      allOf:
        - $ref: '#/components/schemas/ErrorGeneric'
      title: Error 502 Bad Gateway
      example:
        title: bad_gateway
        detail: Bad Gateway
        status: 502
    ErrorGeneric:
      type: object
      title: Error object
      properties:
        title:
          type: string
        detail:
          type: string
        status:
          type: integer
      required:
        - title
        - detail
        - status
    EventListResponse:
      type: object
      title: Event list
      properties:
        count:
          type: integer
          minimum: 0
          description: Count of all events
        next:
          format: uri
          description: Next page from pagination
          nullable: true
          type: string
        previous:
          description: Previous page from pagination
          type: string
          nullable: true
        results:
          type: array
          description: List of events owned by the user
          items:
            $ref: '#/components/schemas/EventObject'
      required:
        - count
        - next
        - previous
        - results
    EventObject:
      type: object
      title: Event object
      properties:
        camera:
          description: Camera ID
          nullable: true
          type: integer
        location:
          description: Location ID
          nullable: true
          type: integer
        site:
          description: 'Location ID. **Deprecated:** use `location` instead.'
          deprecated: true
          nullable: true
          type: integer
        title:
          description: Event title
          nullable: true
          type: string
        category:
          type: string
          description: event category
        source:
          type: string
          description: Name of event source
        occurred_at:
          type: string
          format: datetime
          description: Time when event occurred or was received by Angelcam
        received_at:
          type: string
          format: datetime
          description: Time when event was received by Angelcam
      required:
        - camera
        - location
        - site
        - title
        - category
        - source
        - received_at
        - occurred_at
      example:
        title: Door open
        camera: 20
        location: null
        site: null
        source: smtp
        category: motion_detected
        received_at: '2018-10-24T11:21:59.000Z'
        occurred_at: '2018-10-24T11:21:39.000Z'
    HttpNotificationMethodChangeObject:
      type: object
      title: Http notification object
      properties:
        name:
          type: string
          description: notification method name
        type:
          type: string
          enum:
            - http
          description: notification method type
        http_method:
          type: string
          enum:
            - GET
            - POST
            - PUT
          description: HTTP method
          default: POST
        url:
          type: string
          format: uri
          description: 'URL to send the notification to, can be local when Arrow client is used'
        arrow_client:
          type: string
          format: uuid
          description: Arrow client UUID we want to send the notification through
          nullable: true
        signature_private_key:
          type: string
          description: Private key to sign the notification
          default: randomly generated
      required:
        - type
        - url
      example:
        name: My server
        type: http
        http_method: POST
        url: 'https://example.com/notify'
        signature_private_key: CHDFXB3CLXSJ8JjHh3xY8SSNJyjTmGB4jdz7reLm6cVW8ammg4
    HttpNotificationMethodObject:
      type: object
      title: Http notification object
      properties:
        id:
          type: integer
          minimum: 1
          description: notification method ID
        name:
          type: string
          description: notification method name
        type:
          type: string
          enum:
            - http
          description: notification method type
        http_method:
          type: string
          enum:
            - GET
            - POST
            - PUT
          description: HTTP method
        url:
          type: string
          format: uri
          description: 'URL to send the notification to, can be local when Arrow client is used'
        arrow_client:
          type: string
          format: uuid
          description: Arrow client UUID we want to send the notification through
          nullable: true
        signature_private_key:
          type: string
          description: Private key to sign the notification
          default: randomly generated
      required:
        - id
        - name
        - http_method
        - type
        - url
        - arrow_client
        - signature_private_key
      example:
        id: 85
        name: My server
        type: http
        http_method: POST
        url: 'https://example.com/notify'
        signature_private_key: CHDFXB3CLXSJ8JjHh3xY8SSNJyjTmGB4jdz7reLm6cVW8ammg4
    IncidentListResponse:
      type: object
      title: Incident list
      properties:
        count:
          type: integer
          minimum: 0
          description: Count of all incidents
        next:
          format: uri
          description: Next page from pagination
          nullable: true
          type: string
        previous:
          format: uri
          description: Previous page from pagination
          nullable: true
          type: string
        results:
          type: array
          description: List of incidents
          items:
            $ref: '#/components/schemas/IncidentObject'
      required:
        - count
        - next
        - previous
        - results
      example:
        count: 10
        next: null
        previous: null
        results:
          - id: 1
            created_at: '2019-08-09T13:23:23.000Z'
            verified_at: '2019-08-09T13:23:58.000Z'
            closed_at: null
            first_event_occurred_at: '2019-08-09T13:23:20.000Z'
            last_event_occurred_at: '2019-08-09T13:25:16.000Z'
            event_count: 5
            incident_sharing_url: www.example.com
            snapshot:
              url: 'https://dsw4ncxjbie85.cloudfront.net/snapshot/81/y8jol6kbn0ol1gh2.jpg'
              created_at: '2019-08-09T13:23:24.000Z'
    IncidentObject:
      type: object
      title: Incident object
      properties:
        id:
          type: number
          minimum: 1
          description: Incident ID
        created_at:
          type: string
          description: 'Time when incident was created, format `%Y-%m-%dT%H:%M:%SZ`'
        verified_at:
          type: string
          nullable: true
          description: 'Time when incident was verified, format `%Y-%m-%dT%H:%M:%SZ`'
        closed_at:
          type: string
          nullable: true
          description: 'Time when incident was closed, format `%Y-%m-%dT%H:%M:%SZ`'
        first_event_occurred_at:
          type: string
          nullable: true
          description: 'Time when first event (triggering one) occured, format `%Y-%m-%dT%H:%M:%SZ`'
        last_event_occurred_at:
          type: string
          nullable: true
          description: 'Time when last event durign of incident occured, format `%Y-%m-%dT%H:%M:%SZ`'
        event_count:
          type: number
          minimum: 1
          description: Number of events during incident
        incident_sharing_url:
          type: string
          nullable: true
          description: URL that can be used for incident verification by third parties. The URL leads to a web page where all cameras from the affected location can be viewed (live streams + the last two hours of recording). The URL is valid for one hour after the corresponding incident is created. This field will be `null` if the URL is no longer valid.
        snapshot:
          $ref: '#/components/schemas/SnapshotObject'
      required:
        - id
        - created_at
        - verified_at
        - closed_at
        - first_event_occurred_at
        - last_event_occurred_at
        - event_count
        - incident_sharing_url
        - snapshot
      example:
        id: 1
        created_at: '2019-08-09T13:23:23.000Z'
        verified_at: '2019-08-09T13:23:58.000Z'
        closed_at: null
        first_event_occurred_at: '2019-08-09T13:23:20.000Z'
        last_event_occurred_at: '2019-08-09T13:25:16.000Z'
        event_count: 5
        incident_sharing_url: www.example.com
        snapshot:
          url: 'https://dsw4ncxjbie85.cloudfront.net/snapshot/81/y8jol6kbn0ol1gh2.jpg'
          created_at: '2019-08-09T13:23:24.000Z'
    LocationListResponse:
      type: object
      title: Location list
      properties:
        count:
          type: integer
          description: Total number of locations
          example: 2
        next:
          format: uri
          description: Next page from pagination
          nullable: true
          type: string
        previous:
          format: uri
          description: Previous page from pagination
          nullable: true
          type: string
        results:
          type: array
          description: List of locations
          items:
            $ref: '#/components/schemas/LocationObject'
      required:
        - count
        - next
        - previous
        - results
      example:
        count: 2
        next: null
        previous: null
        results:
          - id: 1
            name: My house
            description: Main bedroom
            is_armed: true
            next_arming: '2025-06-28T23:03:00Z'
            next_disarming: null
            cameras_count: 3
    LocationObject:
      type: object
      title: Location object
      properties:
        id:
          type: integer
          description: Location ID
        name:
          type: string
          description: Location name
        description:
          type: string
          nullable: true
          description: Location description/note
        is_armed:
          type: boolean
          description: Whether the location is currently armed
        next_arming:
          type: string
          format: date-time
          nullable: true
          description: Next scheduled arming time
        next_disarming:
          type: string
          format: date-time
          nullable: true
          description: Next scheduled disarming time
        cameras_count:
          type: integer
          description: Number of cameras associated with this location
      required:
        - id
        - name
        - is_armed
        - next_arming
        - next_disarming
        - cameras_count
      example:
        id: 1
        name: My house
        description: Main bedroom
        is_armed: true
        next_arming: '2025-06-28T23:03:00Z'
        next_disarming: null
        cameras_count: 3
    MessageListResponse:
      type: object
      title: Message list
      properties:
        count:
          type: integer
          minimum: 0
          description: Count of all messages
        next:
          format: uri
          description: Next page from pagination
          nullable: true
          type: string
        previous:
          format: uri
          description: Previous page from pagination
          nullable: true
          type: string
        results:
          type: array
          description: List of messages
          items:
            $ref: '#/components/schemas/MessageObject'
      required:
        - count
        - next
        - previous
        - results
      example:
        count: 10
        next: null
        previous: null
        results:
          - id: 1
            created_at: '2019-08-09T13:23:23Z'
            title: Sensor My Sensor detected motion
            type: my_incident
            short_message: Your sensor with name My Sensor detected motion.
            long_message: Your sensor with name My Sensor detected motion. Find out more at <url>.
            is_read: false
            image: 'https://s3.us-west-2.amazonaws.com/rec-prod.us-west-2.angelcam.com/c/944c8ee2-0230-4dbf-b03d-de09dc4a79da.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJ6CMNV7APGJB5JYQ%2F20180416%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20180416T093432Z&X-Amz-Expires=86400&X-Amz-Signature=40b3701f85114ed22f76a97e6b0c099b1dc7301645bd2db8380c5fa824c59455&X-Amz-SignedHeaders=host&response-content-disposition=attachment%3B%20filename%3D%22Frontdoor%20loitering.jpg%22'
            action_url: 'https://my.angelcam.com/camera/1/'
            action_label: Show camera
            show_detail: false
    MessageObject:
      type: object
      title: Message object
      properties:
        id:
          type: number
          minimum: 1
          description: Message ID
        created_at:
          type: string
          description: 'Time when message was created, format `%Y-%m-%dT%H:%M:%SZ`'
        title:
          type: string
          description: Message title
        type:
          type: string
          description: Message type. Can be used to decide for instance priority of the message.
          enum:
            - my_incident
            - shared_incident
            - arming
            - trigger_action
            - open_incident_verification
            - verify_incident
            - close_incident
            - arrow_status_online
            - arrow_status_offline
            - camera_status_online
            - camera_status_offline
        short_message:
          type: string
          description: Short version of message. Use short version for example in notification list
        long_message:
          type: string
          description: More detailed version of message. Use long version in message detail or when sending via e-mail.
        is_read:
          type: boolean
          description: Whether message was read by user.
        read_at:
          type: string
          description: 'Time when message was read, format `%Y-%m-%dT%H:%M:%SZ`'
        image:
          type: string
          description: URL of image that is related to the message.
        action_url:
          type: string
          description: URL to a particular screen in webapp or mobile app that is related to this message. Required when `show_detail == false`
        action_label:
          type: string
          description: Label for button that should redirect to action_url
        show_detail:
          type: boolean
          description: Whether to show detail of message or redirect user directly to `action_url`
        incident_sharing_url:
          type: string
          description: URL that can be used for incident verification by third parties. The URL leads to a web page where all cameras from the affected location can be viewed (live streams + the last two hours of recording). The URL is valid for one hour after the corresponding incident is created. This field will be `null` if the message type isn't `my_incident` or if the URL is no longer valid.
      required:
        - id
        - created_at
        - title
        - type
        - is_read
        - short_message
        - long_message
        - show_detail
      example:
        id: 1
        created_at: '2019-08-09T13:23:23.000Z'
        title: Sensor My Sensor detected motion
        type: my_incident
        short_message: Your sensor with name My Sensor detected motion.
        long_message: Your sensor with name My Sensor detected motion. Find out more at <url>.
        is_read: false
        read_at: '2019-08-09T13:23:30.000Z'
        image: 'https://s3.us-west-2.amazonaws.com/rec-prod.us-west-2.angelcam.com/c/944c8ee2-0230-4dbf-b03d-de09dc4a79da.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJ6CMNV7APGJB5JYQ%2F20180416%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20180416T093432Z&X-Amz-Expires=86400&X-Amz-Signature=40b3701f85114ed22f76a97e6b0c099b1dc7301645bd2db8380c5fa824c59455&X-Amz-SignedHeaders=host&response-content-disposition=attachment%3B%20filename%3D%22Frontdoor%20loitering.jpg%22'
        action_url: 'https://my.angelcam.com/camera/1/'
        action_label: Show camera
        show_detail: false
        incident_sharing_url: null
    NotificationMethodListResponse:
      type: object
      title: Notification method list
      properties:
        count:
          type: integer
          minimum: 0
          description: Count of all notifications methods
        next:
          format: uri
          description: Next page from pagination
          nullable: true
          type: string
        previous:
          format: uri
          description: Previous page from pagination
          nullable: true
          type: string
        results:
          type: array
          description: List of notification methods
          items:
            oneOf:
              - $ref: '#/components/schemas/HttpNotificationMethodObject'
              - $ref: '#/components/schemas/EmailNotificationMethodObject'
      required:
        - count
        - next
        - previous
        - results
      example:
        count: 10
        next: null
        previous: null
        results:
          - id: 85
            name: My Email
            type: email
            email: email@example.com
          - id: 254
            name: My Server
            type: http
            http_method: POST
            url: 'https://example.com/notify'
            signature_private_key: CHDFXB3CLXSJ8JjHh3xY8SSNJyjTmGB4jdz7reLm6cVW8ammg4
    NotificationRuleChangeObject:
      type: object
      title: Http notification rule object
      properties:
        notification_method:
          type: integer
          description: notification method ID
        message_type:
          type: string
          enum:
            - my_incident
            - shared_incident
            - arming
            - trigger_action
            - open_incident_verification
            - verify_incident
            - close_incident
            - arrow_status_online
            - arrow_status_offline
            - camera_status_online
            - camera_status_offline
          description: message type to send notification for
        allowed_cameras:
          type: array
          items:
            type: integer
            description: |
              List of camera IDs that are allowed to send notifications.
              Allowed only for `camera_status_online` and `camera_status_offline` message types.
              When empty, all cameras are allowed.
        allowed_arrow_clients:
          type: array
          items:
            type: string
            format: uuid
            description: |
              List of Arrow client UUIDs that are allowed to send notifications.
              Allowed only for `arrow_status_online` and `arrow_status_offline` message types.
              When empty, all Arrow clients are allowed.
      required:
        - notification_method
        - message_type
      example:
        id: 85
        notification_method: 254
        message_type: camera_status_online
        allowed_cameras:
          - 1
          - 2
          - 3
    NotificationRuleListResponse:
      type: object
      title: Notification rule list
      properties:
        count:
          type: integer
          minimum: 0
          description: Count of all notifications rules
        next:
          format: uri
          description: Next page from pagination
          nullable: true
          type: string
        previous:
          format: uri
          description: Previous page from pagination
          nullable: true
          type: string
        results:
          type: array
          description: List of notification rules
          items:
            $ref: '#/components/schemas/NotificationRuleObject'
      required:
        - count
        - next
        - previous
        - results
      example:
        count: 10
        next: null
        previous: null
        results:
          - id: 85
            notification_method: 254
            message_type: camera_status_online
            allowed_cameras:
              - 1
              - 2
              - 3
    NotificationRuleObject:
      type: object
      title: Http notification rule object
      properties:
        id:
          type: integer
          minimum: 1
          description: notification rule ID
        notification_method:
          type: integer
          description: notification method ID
        message_type:
          type: string
          enum:
            - my_incident
            - shared_incident
            - arming
            - trigger_action
            - open_incident_verification
            - verify_incident
            - close_incident
            - arrow_status_online
            - arrow_status_offline
            - camera_status_online
            - camera_status_offline
          description: message type to send notification for
        allowed_cameras:
          type: array
          items:
            type: integer
            description: |
              List of camera IDs that are allowed to send notifications.
              Allowed only for `camera_status_online` and `camera_status_offline` message types.
              When empty, all cameras are allowed.
        allowed_arrow_clients:
          type: array
          items:
            type: string
            format: uuid
            description: |
              List of Arrow client UUIDs that are allowed to send notifications.
              Allowed only for `arrow_status_online` and `arrow_status_offline` message types.
              When empty, all Arrow clients are allowed.
      required:
        - id
        - notification_method
        - message_type
      example:
        id: 85
        notification_method: 254
        message_type: camera_status_online
        allowed_cameras:
          - 1
          - 2
          - 3
    OrderItemListResponse:
      type: object
      title: Order list
      properties:
        count:
          type: integer
          description: Count of all services
        next:
          format: uri
          description: Next page from pagination
          nullable: true
          type: string
        previous:
          format: uri
          description: Previous page from pagination
          nullable: true
          type: string
        results:
          type: array
          description: List of orders
          items:
            $ref: '#/components/schemas/OrderItemObject'
      required:
        - count
        - next
        - previous
        - results
    OrderItemObject:
      type: object
      title: Order item object
      properties:
        service:
          $ref: '#/components/schemas/ServiceObject'
        period_from:
          type: string
          format: datetime
          example: '2017-01-01T00:00:20.000Z'
        period_until:
          type: string
          nullable: true
          format: datetime
          example: '2017-02-01T00:00:20.000Z'
        full_price:
          type: string
          format: number
          description: Decimal price in USD
          example: 3.99
        price:
          type: string
          format: number
          description: Decimal price in USD
          example: 3.99
        currency:
          type: string
          description: Currency of the service
          example: USD
        type:
          type: string
          description: Type of item
          enum:
            - receivable
            - refund
      required:
        - service
        - period_from
        - period_until
        - full_price
        - price
        - currency
        - type
    OrderListResponse:
      type: object
      title: Order list
      properties:
        count:
          type: integer
          description: Count of all services
        next:
          format: uri
          description: Next page from pagination
          nullable: true
          type: string
        previous:
          format: uri
          description: Previous page from pagination
          nullable: true
          type: string
        results:
          type: array
          description: List of orders
          items:
            $ref: '#/components/schemas/OrderObject'
      required:
        - count
        - next
        - previous
        - results
    OrderObject:
      type: object
      title: Order object
      properties:
        id:
          type: integer
          description: Order id
          example: 1
        closed_at:
          type: string
          format: datetime
          description: Date when order was closed
          example: '2017-01-01T00:00:20.000Z'
        paid_at:
          type: string
          nullable: true
          format: datetime
          description: Date when order was paid
          example: '2017-01-01T00:00:20.000Z'
        due_at:
          type: string
          nullable: true
          format: datetime
          description: Date when order is due
          example: '2017-01-01T00:00:20.000Z'
        total_price:
          type: string
          format: number
          description: Decimal price in USD
          example: 3.99
        currency:
          type: string
          description: Currency of the order
          example: USD
      required:
        - id
        - closed_at
        - paid_at
        - due_at
        - total_price
        - currency
    OwnerObject:
      type: object
      title: Owner object
      properties:
        first_name:
          type: string
          description: User's first or given name.
        last_name:
          type: string
          description: User's last or family name.
        email:
          type: string
          format: email
          description: User's email.
      required:
        - email
      example:
        first_name: John
        last_name: Appleseed
        email: john@apple.com
    PriceObject:
      type: object
      title: Price object
      properties:
        period:
          type: string
          format: duration
          description: Period of time
          example: P1M
        price:
          type: string
          format: number
          description: Decimal price in USD
          example: 3.99
    PublicCameraListResponse:
      type: object
      title: Public Camera list
      properties:
        count:
          type: integer
          description: Count of all public cameras
        next:
          format: uri
          description: Next page from pagination
          nullable: true
          type: string
        previous:
          format: uri
          description: Previous page from pagination
          nullable: true
          type: string
        results:
          type: array
          description: List of public cameras
          items:
            $ref: '#/components/schemas/PublicCameraObject'
      required:
        - count
        - next
        - previous
        - results
    PublicCameraObject:
      type: object
      title: Public camera object
      properties:
        id:
          type: integer
          minimum: 1
          description: Camera ID
        name:
          type: string
          description: Camera name
        type:
          type: string
          enum:
            - h264
            - h265
            - mjpeg
          description: Camera type
        status:
          type: string
          enum:
            - offline
            - online
            - unknown
        live_snapshot:
          format: uri
          description: Live snapshot URL
          nullable: true
          type: string
        public_page_url:
          format: uri
          description: Public page URL
          nullable: true
          type: string
        streams:
          type: array
          items:
            $ref: '#/components/schemas/StreamObject'
          description: 'Available broadcasting streams. [Read about stream URLs expirations.](http://help.angelcam.com/en/articles/3952149-how-to-deal-with-stream-url-expiration)'
      required:
        - id
        - name
        - type
        - status
        - live_snapshot
        - public_page_url
        - streams
      example:
        id: 157
        name: Parkside Office
        type: h264
        status: online
        live_snapshot: 'http://m1.angelcam.com/stream/81/snapshot.jpg?token=eyJ0aW1lIjogMTQ5NjkzNDYyODE5NjIxOCwgInRpbWVvdXQiOiAzNjAwLCAiYWxpYXMiOiAiODEifQ==.85b552be2b7f0abaa0a3b5b4f412877f8af92f691c7d0c6db6b8c517ea8f921c'
        public_page_url: 'https://some.url/camera/4564'
        streams:
          - format: mjpeg
            url: 'http://e1.angelcam.com/stream/81/stream.mjpeg?token=eyJ0aW1lIjogMTQ5NjkzNDYyODE5NjIxOCwgInRpbWVvdXQiOiAzNjAwLCAiYWxpYXMiOiAiODEifQ==.85b552be2b7f0abaa0a3b5b4f412877f8af92f691c7d0c6db6b8c517ea8f921c'
          - format: mp4
            url: 'http://e1.angelcam.com/stream/81/stream.mp4?token=eyJ0aW1lIjogMTQ5NjkzNDYyODE5NjMxNiwgInRpbWVvdXQiOiAzNjAwLCAiYWxpYXMiOiAiODEifQ==.b5b4cf405cf054701a75b359f4069d2af8a102c5ffd8f33cbb560a4638c7cb71'
          - format: mpegts
            url: 'http://e1.angelcam.com/stream/81/stream.ts?token=eyJ0aW1lIjogMTQ5NjkzNDYyODE5NjMxNiwgInRpbWVvdXQiOiAzNjAwLCAiYWxpYXMiOiAiODEifQ==.b5b4cf405cf054701a75b359f4069d2af8a102c5ffd8f33cbb560a4638c7cb71'
          - format: hls
            url: 'http://e1.angelcam.com/stream/81/playlist.m3u8?token=eyJ0aW1lIjogMTQ5NjkzNDYyODE5NjQwMSwgInRpbWVvdXQiOiAzNjAwLCAiYWxpYXMiOiAiODEifQ==.8ac35b434e768e8f10161b2d74da492f5fd8a8c115c18cbb421017665acd908a'
    RTSSettingsObject:
      type: object
      title: RTS Settings object
      properties:
        incident_ttl:
          type: string
          enum:
            - PT1M
            - PT3M
            - PT5M
            - PT10M
            - PT30M
            - PT1H
          description: ISO 8601 duration format. The value represents the minimal delay between two events triggered by the same sensor that has to pass before Angelcam sends another notification to the user.
        is_armed:
          type: boolean
          description: If set to `false` user will not reveive any notifications about sensor events. This field shows global state.
          deprecated: true
        next_arming:
          type: string
          format: date-time
          nullable: true
          description: Next scheduled global arming time.
          deprecated: true
        next_disarming:
          type: string
          format: date-time
          nullable: true
          description: Next scheduled global disarming time.
          deprecated: true
      required:
        - incident_ttl
        - is_armed
        - next_arming
        - next_disarming
      example:
        incident_ttl: PT1M
        is_armed: true
        next_arming: '2025-06-28T23:03:00Z'
        next_disarming: null
    RecordingDownloadResponse:
      type: object
      title: Recording download
      properties:
        url:
          type: string
          format: url
          description: Download URL
      example:
        url: 'https://rust-streamer-eu-central-1-07489f9b03f198b91.angelcam.com/recordings/7e65d945-fffc-42e7-b78d-dd6f5cea91ee/download/?start=2019%2D09%2D30T07%3A23%3A14%2E932%2B00%3A00&end=2019%2D09%2D30T07%3A53%3A57%2E016%2B00%3A00&token=eyJ0aW1lIjoxNTY5ODU3NjgzLCJ0aW1lb3V0IjoxMjAwfQ%3D%3D%2E020b136d5da0d9518ed5428bfa01cadab1a139bf1e4f8e64a726fe3dfd40e541&filename=clip'
    RecordingListResponse:
      type: object
      title: Recording list
      properties:
        count:
          type: integer
          description: Recording count
        next:
          format: uri
          description: Next page from pagination
          nullable: true
          type: string
        previous:
          format: uri
          description: Previous page from pagination
          nullable: true
          type: string
        results:
          type: array
          description: List of recordings on a given camera
          items:
            $ref: '#/components/schemas/RecordingResponse'
      required:
        - count
        - next
        - previous
        - results
    RecordingPlanObject:
      type: object
      title: Recording plan description
      properties:
        code:
          type: string
          description: Plan identifier
        retention:
          type: string
          description: Recording retention
        price:
          type: string
          format: decimal
          description: Price of the plan
        billing_period:
          type: string
          enum:
            - month
            - year
          description: |
            It specifies a time period for the price field. The purpose of this field is just to fix the cost
            in time. It does not necessarily mean that the price will be charged every billing period.
      required:
        - code
        - retention
        - price
        - billing_period
      example:
        code: cra-3days-monthly-v2
        retention: P3D
        price: '3.99'
        billing_period: month
    RecordingPlansResponse:
      type: object
      title: Recording plans
      properties:
        count:
          type: integer
          minimum: 0
          description: Number of all plans
        next:
          format: uri
          description: Next page from pagination
          nullable: true
          type: string
        previous:
          format: uri
          description: Previous page from pagination
          nullable: true
          type: string
        results:
          type: array
          description: A list of recording plans
          items:
            $ref: '#/components/schemas/RecordingPlanObject'
      required:
        - count
        - next
        - previous
        - results
      example:
        count: 16
        next: null
        previous: null
        results:
          - code: cra-3days-monthly-v2
            retention: P3D
            price: '3.99'
            billing_period: month
          - code: cra-7days-monthly-v2
            retention: P7D
            price: '5.99'
            billing_period: month
          - code: cra-30days-monthly-v2
            retention: P30D
            price: '13.99'
            billing_period: month
          - code: cra-60days-monthly-v2
            retention: P60D
            price: '18.99'
            billing_period: month
          - code: cra-3months-monthly-v2
            retention: P90D
            price: '24.99'
            billing_period: month
          - code: cra-6months-monthly-v2
            retention: P180D
            price: '39.99'
            billing_period: month
          - code: cra-3days-yearly-v2
            retention: P3D
            price: '47.88'
            billing_period: year
          - code: cra-1year-monthly-v2
            retention: P365D
            price: '69.99'
            billing_period: month
          - code: cra-7days-yearly-v2
            retention: P7D
            price: '71.88'
            billing_period: year
          - code: cra-2years-monthly-v2
            retention: P730D
            price: '129.99'
            billing_period: month
          - code: cra-30days-yearly-v2
            retention: P30D
            price: '167.88'
            billing_period: year
          - code: cra-60days-yearly-v2
            retention: P60D
            price: '227.88'
            billing_period: year
          - code: cra-3months-yearly-v2
            retention: P90D
            price: '299.88'
            billing_period: year
          - code: cra-6months-yearly-v2
            retention: P180D
            price: '479.88'
            billing_period: year
          - code: cra-1year-yearly-v2
            retention: P365D
            price: '839.88'
            billing_period: year
          - code: cra-2years-yearly-v2
            retention: P730D
            price: '1559.88'
            billing_period: year
    RecordingResponse:
      type: object
      title: Recording information
      required:
        - id
        - status
        - retention
        - deactivated_at
      properties:
        id:
          type: string
          format: uuid
          description: Recording ID
        status:
          type: string
          enum:
            - READY
            - CONNECTING
            - RECORDING
            - STOPPING
            - ERROR
          description: |
            Recording status values have the following meaning:
            * `READY` - Not recording (recording is ready to be started)
            * `CONNECTING` - Recorder is trying to connect to the stream (this usually indicates camera connectivity problems; the recorder keeps trying to connect).
            * `RECORDING` - Recorder is connected to the stream and records are being created
            * `STOPPING` - Recording is stopping
            * `ERROR` - Error occurred when recording (this indicates a possible issue with Angelcam infrastructure)
        retention:
          description: |
            Retention period in ISO 8601 duration format tells how long in past we store the footage. Example: P7D means 7 days.
          nullable: true
          type: string
        record_queue_capacity:
          description: |
            Capacity of the record queue in seconds, maxium amount of seconds to be recorded in total, unlimited if null
          nullable: true
          type: number
        deactivated_at:
          type: string
          format: datetime
          nullable: true
          description: 'Datetime when recording service has been deactivated, if null then recording is active.'
        recording_start:
          type: string
          format: datetime
          nullable: true
          description: 'Recording footage start datetime, if null there is no recording footage'
        recording_end:
          type: string
          format: datetime
          nullable: true
          description: 'Recording footage end datetime, if null there is no recording footage'
      example:
        id: df5fcd78-6114-4750-b23a-cec3c3febc5b
        status: RECORDING
        retention: P7D
        deactivated_at: null
        record_queue_capacity: null
        recording_start: '2024-05-02T10:32:11.000Z'
        recording_end: '2024-05-07T16:58:7.5400Z'
    RecordingStreamInfoResponse:
      type: object
      title: Recording stream information
      properties:
        current_position:
          type: string
          format: date-time
          description: Current time in a stream.
        speed:
          type: number
          description: 'Speed of the stream playback, 1 means the original speed'
      example:
        current_time: '2024-01-16T00:00:59.146606443+00:00'
        speed: 1
    RecordingStreamInfoResponseDeprecated:
      type: object
      title: Recording stream information
      properties:
        current_time:
          type: string
          format: date-time
          description: Current time in a stream.
      example:
        current_time: '2017-01-01T00:00:00.000Z'
    RecordingStreamResponse:
      type: object
      title: Recording stream object
      properties:
        url:
          type: string
          description: URL of a stream.
          example: |
            https://rec-streamer-eu-central-1.angelcam.com/streams/cefa6471a38f469585b46675fc992614/playlist.m3u8
        format:
          type: string
          enum:
            - hls
            - mjpeg
          description: Stream format.
          example: hls
        stream_info:
          deprecated: true
          type: string
          description: URL of a recorded stream info endpoint.
          example: 'https://api.angelcam.com/v1/recording/stream/rec-streamer-eu-central-1/cefa6471a38f469585b46675fc992614/'
        stream_controls:
          type: object
          description: |
            Links allowing to synchronize and control stream playback. See [more](#tag/stream-controls).
          properties:
            base_url:
              type: string
              description: URL for retrieving the current stream position and playback speed.
              example: |
                https://rec-streamer-eu-central-1.angelcam.com/recording/streams/cefa6471a38f469585b46675fc992614/
            play:
              type: string
              description: URL for resuming the stream playback.
              example: |
                https://rec-streamer-eu-central-1.angelcam.com/recording/streams/cefa6471a38f469585b46675fc992614/play/
            pause:
              type: string
              description: URL for pausing the stream playback.
              example: |
                https://rec-streamer-eu-central-1.angelcam.com/recording/streams/cefa6471a38f469585b46675fc992614/pause/
            speed:
              type: string
              description: URL for changing the stream playback speed.
              example: |
                https://rec-streamer-eu-central-1.angelcam.com/recording/streams/cefa6471a38f469585b46675fc992614/speed/
      example:
        url: 'https://rec-streamer-eu-central-1.angelcam.com/streams/df0600b7487a44d480217db7713720d3/playlist.m3u8'
        format: hls
        stream_controls:
          base_url: 'https://rec-streamer-eu-central-1.angelcam.com/recording/streams/df0600b7487a44d480217db7713720d3/'
          play: 'https://rec-streamer-eu-central-1.angelcam.com/recording/streams/df0600b7487a44d480217db7713720d3/play/'
          pause: 'https://rec-streamer-eu-central-1.angelcam.com/recording/streams/df0600b7487a44d480217db7713720d3/pause/'
          speed: 'https://rec-streamer-eu-central-1.angelcam.com/recording/streams/df0600b7487a44d480217db7713720d3/speed/'
    RecordingTimelineResponse:
      type: object
      title: Recording timeline object
      properties:
        start:
          type: string
          format: date-time
          description: |
            Start time of timeline (the value you entered in the query parameter). Example: `2017-01-01T00:00:00Z`.
        end:
          type: string
          format: date-time
          description: |
            End time of timeline (the value you entered in the query parameter). Example: `2017-01-01T00:00:00Z`.
        segments:
          type: array
          description: Array of recording segments.
          items:
            $ref: '#/components/schemas/SegmentObject'
      example:
        start: '2017-01-01T00:00:00.000Z'
        end: '2017-01-01T03:32:19.000Z'
        segments:
          - start: '2017-06-09T00:00:18.000Z'
            end: '2017-06-09T03:25:28.000Z'
          - start: '2017-06-09T04:19:42.000Z'
            end: '2017-06-09T010:39:31Z'
    AccessAssignmentObject:
      type: object
      title: Access assignment
      description: |
        A single permission grant within a space. The scope of the permission is determined by which fields are set:
        - **Space-level** (`location_id` and `camera_id` are null): the permission applies across the entire space. - **Location-level** (`location_id` is set, `camera_id` is null): the permission applies to a specific location. Used for `location.*` slugs. - **Camera-level** (`location_id` and `camera_id` are both set): the permission applies to a specific camera. Used for `camera.*` slugs.
      required:
        - permission
      properties:
        permission:
          type: string
          description: Permission slug.
          example: camera.view
          enum:
            - space.admin
            - space.limited_client
            - space.billing
            - camera.notifications.status
            - location.notifications.incident
            - location.notifications.other
            - location.access
            - location.view
            - location.arming
            - location.manage
            - camera.view
            - camera.manage
            - camera.recording.view
            - camera.recording.manage
            - camera.clip.view
            - camera.clip.manage
            - camera.clip.create
            - camera.broadcasting.manage
            - camera.timelapse.manage
        location_id:
          type: integer
          nullable: true
          description: |
            When set, the permission is scoped to this location. Always present for `location.*` and `camera.*` slugs.
          example: 12
        camera_id:
          type: integer
          nullable: true
          description: |
            When set, the permission is scoped to this camera. Always present for `camera.*` slugs, together with `location_id`.
          example: null
      example:
        permission: camera.view
        location_id: 12
        camera_id: 345
    SegmentObject:
      type: object
      title: Segment object
      properties:
        start:
          type: string
          format: date-time
          description: 'Start of record segment. Example: `2017-01-01T00:00:00Z`.'
        end:
          type: string
          format: date-time
          description: 'End of record segment. Example: `2017-01-01T00:00:00Z`.'
    SensorListResponse:
      type: object
      title: My sensors list
      properties:
        count:
          type: integer
          description: Count of all sensors
        next:
          format: uri
          description: Next page from pagination
          nullable: true
          type: string
        previous:
          format: uri
          description: Previous page from pagination
          nullable: true
          type: string
        results:
          type: array
          description: List of sensors owned by the user
          items:
            $ref: '#/components/schemas/SensorObject'
      required:
        - count
        - next
        - previous
        - results
    SensorObject:
      type: object
      title: Sensor object
      properties:
        id:
          type: integer
          minimum: 1
          description: Sensor ID
        user:
          type: integer
          minimum: 1
          description: User ID
        name:
          type: string
          description: Sensor name
        type:
          type: string
          enum:
            - motion
            - camera_motion
            - door_window
            - smoke
            - fire
            - glass_break
            - shock_vibration
            - water
            - perimeter_entry
          description: Sensor type
        placement:
          type: string
          enum:
            - indoors
            - outdoors
          description: Sensor placement
        manufacturer:
          type: string
          description: Sensor manufacturer
        model:
          type: string
          description: Sensor model
        note:
          type: string
          description: Any note related to sensor
        hash:
          type: string
          description: Event API hash (a unique token for each sensor)
        email:
          type: string
          description: Unique email address that can be used to receive events from this sensor by Angelcam
        enabled:
          type: boolean
          description: Defaults to True. Indicates if sensor is enabled or not. If disabled then all events from this sensor are ignored.
        override_arming:
          type: boolean
          description: 'Defaults to False. If enabled, an event received from the sensor will always trigger an incident regardless of the arming settings.'
        camera:
          type: integer
          minimum: 1
          description: Camera ID sensor is bind to
        enable_cloud_recording_for:
          type: string
          format: duration
          enum:
            - PT30S
            - PT1M
            - PT2M
            - PT5M
          description: Duration of event Recording triggered by an event from this sensor. This setting is applied only if sensor has an assigned camera with active Cloud Recording.
        incident_delay:
          type: string
          format: duration
          description: 'A delay before RTS incident is triggered. If the location is disarmed during this period, no incident is forwarded. However the video from the binded camera is recorded. PT0S means no delay and PT3M is the max.'
        created_at:
          type: string
          description: DateTime when sensor was created
        updated_at:
          type: string
          description: DateTime when sensor was last updated
        events_count_ifttt:
          type: integer
          description: Total count of events received from this sensor via IFTTT
        events_count_email:
          type: integer
          description: Total count of events received from this sensor via email
        events_count_api:
          type: integer
          description: Total count of events received from this sensor via API
      required:
        - id
        - user
        - name
        - type
        - placement
        - manufacturer
        - model
        - note
        - hash
        - email
        - enabled
        - override_arming
        - camera
        - enable_cloud_recording_for
        - incident_delay
        - created_at
        - updated_at
        - events_count_ifttt
        - events_count_email
        - events_count_api
      example:
        id: 34
        user: 4
        name: Front door sensor
        type: motion
        placement: indoors
        manufacturer: SensorsX
        model: XTF-666
        note: Testing this sensor
        hash: dy3ovys2ol
        email: dy3ovys2ol@angel.cam
        enabled: true
        override_arming: false
        camera: 32
        enable_cloud_recording_for: PT1M
        incident_delay: PT0S
        created_at: '2019-09-24T13:16:23.899357+02:00'
        updated_at: '2019-09-24T13:16:23.899384+02:00'
        events_count_ifttt: 0
        events_count_email: 0
        events_count_api: 5
    ServiceListResponse:
      type: object
      title: Service list
      properties:
        count:
          type: integer
          description: Count of all services
        next:
          format: uri
          description: Next page from pagination
          nullable: true
          type: string
        previous:
          format: uri
          description: Previous page from pagination
          nullable: true
          type: string
        results:
          type: array
          description: List of services available for user
          items:
            $ref: '#/components/schemas/ServiceWithPriceObject'
      required:
        - count
        - next
        - previous
        - results
    ServiceObject:
      type: object
      title: Service object
      properties:
        type:
          type: string
          description: Type of service
          enum:
            - cloud-recording
            - broadcasting
            - timelapse
            - user-service
            - event-recording
            - live-view
          example: cloud-recording
        code:
          type: string
          description: 'Code of service, this code together with type is unique identifier of service'
          example: 3-days
      required:
        - type
        - code
    ServiceWithPriceObject:
      type: object
      title: Service object
      properties:
        type:
          type: string
          description: Type of service
          enum:
            - cloud-recording
            - broadcasting
            - timelapse
            - user-service
            - event-recording
            - live-view
          example: cloud-recording
        code:
          type: string
          description: 'Code of service, this code together with type is unique identifier of service'
          example: 3-days
        name:
          type: string
          description: Human readable name of service
          example: 3 days
        prices:
          type: array
          items:
            $ref: '#/components/schemas/PriceObject'
          description: Service prices
        currency:
          type: string
          description: Currency of the service
          example: USD
      required:
        - type
        - code
        - name
        - prices
        - currency
    SharedApplicationObject:
      type: object
      properties:
        code:
          type: string
          enum:
            - CRA
      required:
        - code
      example:
        code: CRA
    SpaceObject:
      type: object
      title: Space
      properties:
        id:
          type: integer
          description: Space ID.
          example: 7
        name:
          type: string
          description: Display name of the space.
          example: My Organisation
        is_default:
          type: boolean
          description: Whether this is the user's default space.
          example: true
        owner_email:
          type: string
          format: email
          nullable: true
          readOnly: true
          description: Email address of the space owner.
          example: owner@example.com
        owner_first_name:
          type: string
          nullable: true
          readOnly: true
          description: First name of the space owner.
          example: Jane
        owner_last_name:
          type: string
          nullable: true
          readOnly: true
          description: Last name of the space owner.
          example: Doe
      required:
        - id
        - name
        - is_default
      example:
        id: 7
        name: My Organisation
        is_default: true
        owner_email: owner@example.com
        owner_first_name: Jane
        owner_last_name: Doe
    SpacePermissionsObject:
      type: object
      title: Space permissions
      properties:
        assignments:
          type: array
          description: |
            All permissions effective for the authenticated user in the active space. Includes both directly assigned permissions and those inherited through group membership.
          items:
            $ref: '#/components/schemas/AccessAssignmentObject'
      required:
        - assignments
      example:
        assignments:
          - permission: camera.view
            location_id: 12
            camera_id: 345
          - permission: location.access
            location_id: 12
            camera_id: null
    SharedCameraClipListResponse:
      type: object
      title: Clip list
      properties:
        count:
          type: integer
          minimum: 0
          description: Count of all clips
        next:
          format: uri
          description: Next page from pagination
          nullable: true
          type: string
        previous:
          format: uri
          description: Previous page from pagination
          nullable: true
          type: string
        results:
          type: array
          description: List of clips for the camera
          items:
            $ref: '#/components/schemas/SharedCameraClipObject'
      required:
        - count
        - next
        - previous
        - results
      example:
        count: 10
        next: null
        previous: null
        results:
          - id: b9aad334-07ba-4660-9f18-041875ec1ea4
            created_by: 1
            name: Frontdoor loitering
            status: READY
            start: '2017-01-01T00:00:20.000Z'
            end: '2017-01-01T00:25:20.000Z'
            created_at: '2017-02-01T02:37:21.000Z'
            download_url: 'https://rust-streamer-us-west-2-07489f9b03f198b91.angelcam.com/clips/b986b0c8-05c2-4c59-8fdd-8afd7bbfa2bf/download/?start=2019%2D12%2D09T14%3A19%3A59%2B00%3A00&end=2019%2D12%2D09T14%3A20%3A29%2B00%3A00&token=eyJ0aW1lIjoxNTc2NzUyMzY3LCJ0aW1lb3V0IjoxMjAwfQ%3D%3D%2E1c5903efe76af570bea4ef5edf49c39f5afc1ce2c1aaf79e85ad5d140c8c3f42&filename=Frontdoor%20loitering'
    SharedCameraClipObject:
      type: object
      title: Clip object
      properties:
        id:
          type: string
          minimum: 1
          description: Clip UUID
        created_by:
          type: integer
          description: User who created the clip
        created_at:
          type: string
          minimum: 1
          description: Time when the clip was created
        name:
          type: string
          minimum: 1
          description: Clip name
        status:
          type: string
          description: Status of clip processing
          enum:
            - PENDING
            - BUILDING
            - SCREENSHOTTING
            - READY
            - ERROR
        start:
          type: string
          minimum: 1
          description: Start time of the clip
        end:
          type: string
          minimum: 1
          description: End time of the clip
        snapshots:
          type: array
          description: 'List of URLs of snapshot images (JPEG) taken from the beginning of the clip. The snapshots are generated automatically during clip processing and can be used as a thumbnail/preview of the clip. The list is empty until the clip reaches the `SCREENSHOTTING` stage, and it may stay empty if the snapshot could not be taken. The URLs contain a security token valid for a limited time.'
          items:
            type: string
            format: uri
        download_url:
          type: string
          description: 'URL for download of the clip as TS/MP4 file (TS for HLS cameras, MP4 for MJPEG cameras). The URL contains security token valid for a limited time.'
      required:
        - id
        - created_by
        - created_at
        - download_url
        - end
        - name
        - snapshots
        - start
        - status
      example:
        id: b9aad334-07ba-4660-9f18-041875ec1ea4
        created_by: 1
        name: Frontdoor loitering
        status: READY
        start: '2017-01-01T00:00:20.000Z'
        end: '2017-01-01T00:25:20.000Z'
        created_at: '2017-02-01T02:37:21.000Z'
        snapshots:
          - 'https://recording-us-west-2.s3.amazonaws.com/clips/b9aad334-07ba-4660-9f18-041875ec1ea4.jpg?AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&Signature=NpgCO4tLYjQmhLpq7QgCGkl6EXAMPLE%3D&Expires=1576753567'
        download_url: 'https://rust-streamer-us-west-2-07489f9b03f198b91.angelcam.com/clips/b986b0c8-05c2-4c59-8fdd-8afd7bbfa2bf/download/?start=2019%2D12%2D09T14%3A19%3A59%2B00%3A00&end=2019%2D12%2D09T14%3A20%3A29%2B00%3A00&token=eyJ0aW1lIjoxNTc2NzUyMzY3LCJ0aW1lb3V0IjoxMjAwfQ%3D%3D%2E1c5903efe76af570bea4ef5edf49c39f5afc1ce2c1aaf79e85ad5d140c8c3f42&filename=Frontdoor%20loitering'
    SharedCameraListResponse:
      type: object
      title: Shared Camera list
      properties:
        count:
          type: integer
          description: Count of all shared cameras
        next:
          format: uri
          description: Next page from pagination
          nullable: true
          type: string
        previous:
          format: uri
          description: Previous page from pagination
          nullable: true
          type: string
        results:
          type: array
          description: List of cameras shared with the user
          items:
            $ref: '#/components/schemas/SharedCameraObject'
      required:
        - count
        - next
        - previous
        - results
    SharedCameraObject:
      type: object
      title: Shared camera object
      properties:
        id:
          type: integer
          minimum: 1
          description: Camera ID
        name:
          type: string
          description: Camera name
        type:
          type: string
          enum:
            - h264
            - h265
            - mjpeg
          description: Camera type
        snapshot:
          $ref: '#/components/schemas/SnapshotObject'
        status:
          type: string
          enum:
            - offline
            - online
            - unknown
        live_snapshot:
          format: uri
          description: Live snapshot URL
          nullable: true
          type: string
        streams:
          type: array
          items:
            $ref: '#/components/schemas/StreamObject'
          description: Available camera streams
        applications:
          type: array
          deprecated: true
          description: Use `has_recording` and `has_notifications` fields
          items:
            $ref: '#/components/schemas/SharedApplicationObject'
        owner:
          $ref: '#/components/schemas/OwnerObject'
        has_recording:
          type: boolean
          description: Indicates whether the user to whom the camera is shared can access camera recordings
        has_notifications:
          type: boolean
          description: Indicates whether the user to whom the camera is shared will receive notifications (eg. security alerts) related to the camera
      required:
        - id
        - name
        - type
        - snapshot
        - status
        - live_snapshot
        - streams
        - applications
        - owner
        - has_recording
        - has_notifications
      example:
        id: 157
        name: Parkside Office
        type: h264
        snapshot:
          url: 'https://dsw4ncxjbie85.cloudfront.net/snapshot/81/y8jol6kbn0ol1gh2.jpg'
          created_at: '2017-03-29T15:41:39.000Z'
        status: online
        live_snapshot: 'http://m1.angelcam.com/stream/81/snapshot.jpg?token=eyJ0aW1lIjogMTQ5NjkzNDYyODE5NjIxOCwgInRpbWVvdXQiOiAzNjAwLCAiYWxpYXMiOiAiODEifQ==.85b552be2b7f0abaa0a3b5b4f412877f8af92f691c7d0c6db6b8c517ea8f921c'
        streams:
          - format: mjpeg
            url: 'http://m1.angelcam.com/stream/81/stream.mjpeg?token=eyJ0aW1lIjogMTQ5NjkzNDYyODE5NjIxOCwgInRpbWVvdXQiOiAzNjAwLCAiYWxpYXMiOiAiODEifQ==.85b552be2b7f0abaa0a3b5b4f412877f8af92f691c7d0c6db6b8c517ea8f921c'
            refresh_rate: 0.1
          - format: mp4
            url: 'http://m1.angelcam.com/stream/81/stream.mp4?token=eyJ0aW1lIjogMTQ5NjkzNDYyODE5NjMxNiwgInRpbWVvdXQiOiAzNjAwLCAiYWxpYXMiOiAiODEifQ==.b5b4cf405cf054701a75b359f4069d2af8a102c5ffd8f33cbb560a4638c7cb71'
          - format: hls
            url: 'http://m1.angelcam.com/stream/81/playlist.m3u8?token=eyJ0aW1lIjogMTQ5NjkzNDYyODE5NjQwMSwgInRpbWVvdXQiOiAzNjAwLCAiYWxpYXMiOiAiODEifQ==.8ac35b434e768e8f10161b2d74da492f5fd8a8c115c18cbb421017665acd908a'
        applications:
          - CRA
        owner:
          email: john@apple.com
          first_name: John
          last_name: Appleseed
        has_recording: false
        has_notifications: true
    SnapshotObject:
      title: Snapshot object
      properties:
        url:
          format: uri
          description: URL of the snapshot image
          nullable: true
          type: string
        created_at:
          type: string
          format: date-time
          description: The date and time when the snapshot was created for the first time
      required:
        - url
        - created_at
      example:
        url: 'https://dsw4ncxjbie85.cloudfront.net/snapshot/157/h8yeodu1mrjtiiok.jpg'
        created_at: '2017-03-31T12:29:10.000Z'
      description: Snapshot is created by Angelcam when certain types of events are received
      nullable: true
      type: object
    SpeakerListResponse:
      type: object
      title: Speaker list
      properties:
        count:
          type: integer
          description: Count of speakers
        next:
          format: uri
          description: Next page from pagination
          nullable: true
          type: string
        previous:
          format: uri
          description: Previous page from pagination
          nullable: true
          type: string
        results:
          type: array
          description: List of speakers
          items:
            $ref: '#/components/schemas/SpeakerObject'
      required:
        - count
        - next
        - previous
        - results
    SpeakerObject:
      type: object
      title: Speaker object
      properties:
        id:
          type: integer
          minimum: 1
          description: Speaker ID
          readOnly: true
        name:
          type: string
          description: Speaker name
        setup:
          type: string
          enum:
            - arrow
          description: Speaker connection type
        protocol:
          type: string
          enum:
            - basic
          description: Audio protocol
        arrow_client:
          type: string
          format: uuid
          description: 'UUID of arrow client client used for speaker connection, required when setup=arrow'
          nullable: true
        arrow_service_id:
          type: string
          description: 'hexadecimal id of arrow service, can contain leading zeros, required when setup=arrow'
          nullable: true
        endpoint:
          type: string
          format: uri
          description: Endpoint URL for the speaker
          example: /api/v1/audio/play
        username:
          type: string
        password:
          type: string
          writeOnly: true
      required:
        - id
        - name
        - setup
        - protocol
        - endpoint
      example:
        id: 157
        name: Angelbox Speaker
        setup: arrow
        protocol: basic
        arrow_client: 75b62326-eca3-4424-ab68-48e7da47e847
        arrow_service_id: 00af
        endpoint: /api/v1/audio/play
    StreamObject:
      type: object
      properties:
        url:
          type: string
          format: uri
          description: Stream URL
        format:
          type: string
          enum:
            - hls
            - mp4
            - mpegts
            - mjpeg
        refresh_rate:
          type: number
          format: float
          description: Stream refresh rate
      required:
        - url
        - format
      example:
        url: 'http://m2-eu1.angelcam.com/stream/157/stream.mjpeg?token=eyJ0aW1lIjogMTQ5NjkzNDYyODE4Mjc3OCwgInRpbWVvdXQiOiAzNjAwLCAiYWxpYXMiOiAiMTU3In0%3D.d365e2a6fbdfae0bfa5b27175a6ea57de1ae31844fdcd22ff5f56da10a970d65'
        format: mjpeg
    UsageDetailObject:
      type: object
      title: Usage detail
      description: In case of camera service show info for what camera the service is used.
      properties:
        camera_id:
          type: integer
        camera_name:
          type: string
    UserMeResponse:
      type: object
      title: User object
      properties:
        id:
          type: integer
          minimum: 0
          description: User ID.
        first_name:
          type: string
          description: User's first or given name.
        last_name:
          type: string
          description: User's last or family name.
        email:
          type: string
          format: email
          description: User's email.
        phone:
          description: User's phone.
          nullable: true
          type: string
        root_site:
          type: integer
          minimum: 1
          description: Root site ID for current user
        my_cameras_count:
          type: integer
          description: Count of user cameras
        shared_cameras_count:
          type: integer
          description: Count of cameras shared with user
        total_cameras_count:
          type: integer
          description: Sum of count of user cameras + cameras shared with user
        cameras_with_guests_count:
          type: integer
          description: Count of user cameras that have been shared with others
        require_qualification:
          type: boolean
          description: 'true if the user hasn''t filled in the qualification form, false otherwise'
        available_features:
          type: object
          description: Features available to the user
          properties:
            live_view:
              type: boolean
              description: 'true if the live-view feature is available to the user, false otherwise'
      required:
        - id
        - email
      example:
        id: 2929
        first_name: John
        last_name: Appleseed
        email: john@apple.com
        phone: +123 558 951 14
        root_site: 1
        my_cameras_count: 3
        shared_cameras_count: 2
        total_cameras_count: 5
        cameras_with_guests_count: 1
        require_qualification: false
        available_features:
          live_view: true
  parameters:
    activeServiceId:
      name: active_service_id
      in: path
      required: true
      description: Active service ID
      example: 3
      schema:
        type: integer
        minimum: 1
    arrowClientId:
      name: uuid
      in: path
      required: true
      description: Arrow client UUID
      example: c95227c4-218c-4dee-899d-f3fa2ce9c39b
      schema:
        type: string
        format: uuid
    arrowClientMAC:
      name: mac
      in: path
      required: true
      description: Arrow client MAC address
      example: '12:34:56:78:90:AB'
      schema:
        type: string
        format: MAC address
    arrowClientServiceId:
      name: service_id
      in: path
      required: true
      description: Arrow client service ID
      example: 1ab2
      schema:
        type: string
        format: hex
    cameraId:
      name: camera_id
      in: path
      required: true
      description: Camera ID
      example: 3
      schema:
        type: integer
        minimum: 1
    clientDeviceId:
      name: device_id
      in: path
      required: true
      description: Device ID
      example: 1
      schema:
        type: integer
        minimum: 1
    clientId:
      name: client_id
      in: path
      required: true
      description: Client ID
      example: 6
      schema:
        type: integer
        minimum: 1
    clipId:
      name: clip_id
      in: path
      required: true
      description: Clip UUID
      example: cd13975b-0b08-48f5-bd39-3f7d2a0c935a
      schema:
        type: string
        format: uuid
    guestId:
      name: guest_id
      in: path
      required: true
      description: Guest ID
      example: 4
      schema:
        type: integer
        minimum: 1
    incidentId:
      name: incident_id
      in: path
      required: true
      description: Incident ID
      example: 3
      schema:
        type: integer
        minimum: 1
    locationId:
      name: location_id
      in: path
      required: true
      description: Location ID
      example: 1
      schema:
        type: integer
        minimum: 1
    messageId:
      name: message_id
      in: path
      required: true
      description: Message ID
      example: 3
      schema:
        type: integer
        minimum: 1
    notificationMethodId:
      name: method_id
      in: path
      required: true
      description: Notification method ID
      example: 3
      schema:
        type: integer
        minimum: 1
    notificationRuleId:
      name: rule_id
      in: path
      required: true
      description: Notification rule ID
      example: 3
      schema:
        type: integer
        minimum: 1
    orderId:
      name: order_id
      in: path
      required: true
      description: Order ID
      example: 3
      schema:
        type: integer
        minimum: 1
    recordingId:
      name: recording_id
      in: path
      required: true
      description: Recording UUID
      example: cd13975b-0b08-48f5-bd39-3f7d2a0c935a
      schema:
        type: string
        format: uuid
    sensorId:
      name: sensor_id
      in: path
      required: true
      description: Sensor ID
      example: 3
      schema:
        type: integer
        minimum: 1
    speakerId:
      name: speaker_id
      in: path
      required: true
      description: Speaker ID
      example: 1
      schema:
        type: integer
        minimum: 1
    sessionId:
      name: session_id
      in: path
      required: true
      description: |
        `session_id` that you received from [start stream detection endpoint](#tag/camera-stream-detection/POST/cameras/stream-detection/)
      example: c95227c4-218c-4dee-899d-f3fa2ce9c39b
      schema:
        type: string
        format: uuid
    sharedCameraId:
      name: camera_id
      in: path
      required: true
      description: Camera ID
      example: 21
      schema:
        type: integer
        minimum: 1
    streamExpiresAt:
      name: stream_expires_at
      in: query
      required: false
      description: |
        Date and time when the returned camera streams should stop. By default, the returned streams have no expiration allowing the consumer to pull them indefinitely.
            
        Do not confuse this with expiration of the stream URLs themselves. The stream URLs have a short expiration in order to minimize the risk of leaking and this behavior cannot be changed. However, once a stream URL is used to establish a connection, the returned stream can be pulled indefinitely unless the `stream_expires_at` parameter is used.
      example: 2999-12-12T00%3A00%3A00Z
      schema:
        type: string
        format: date-time
  responses:
    EmptyResponse:
      description: Empty response.
    Error400InvalidBody:
      description: Body payload is invalid.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error400InvalidParams'
    Error400InvalidParams:
      description: Query params are invalid.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error400InvalidParams'
    Error401Unauthorized:
      description: Missing or invalid authorization.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error401Unauthorized'
    Error403PermissionDenied:
      description: Missing permission.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error403PermissionDenied'
    Error404NotFound:
      description: The specified resource was not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error404NotFound'
    Error405MethodNotAllowed:
      description: The specified method is not allowed for the resource
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error405MethodNotAllowed'
    Error502BadGateway:
      description: Unable to contact the target gateway.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error502BadGateway'
    Error503ServiceUnavailable:
      description: Service unavailable
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error503ServiceUnavailable'
  headers:
    ExpiresAfter:
      description: date in UTC when token expires
      schema:
        type: string
        format: date-time
  securitySchemes:
    OAuth2:
      type: oauth2
      description: |
        Use the authorization code flow with PKCE (`code_challenge_method=S256`). Confidential applications authenticate with a client secret; public applications (mobile, desktop and single-page apps) have no client secret. See the [Authentication guide](/guides/authentication/) for full documentation.
      flows:
        authorizationCode:
          authorizationUrl: 'https://my.angelcam.com/oauth/authorize/'
          tokenUrl: 'https://my.angelcam.com/oauth/token/'
          scopes:
            user_access: Permission to access user information
            user_delete: Permission to delete the current user account
            camera_access: Permission to list cameras and to get details of a specific camera
            camera_create: Permission to create cameras
            camera_manage: Permission to update cameras
            camera_delete: Permission to delete cameras
            camera_guest_access: Permission to access camera guest
            camera_guest_manage: Permission to manage camera guest
            public_cameras_access: Permission to access public cameras
            arrow_client_access: Permission to access Arrow clients
            arrow_client_manage: Permission to manage Arrow clients
            event_access: Permission to access events
            recording_access: Permission to access camera recordings
            recording_start_stop: Permission to start and stop recording on camera
            recording_clips_access: Permission to access recording clips
            recording_clips_create: Permission to create recording clips
            recording_clips_delete: Permission to delete recording clips
            recording_clips_share: Permission to share recording clips
            sensor_access: Permission to list sensors and to get details of a specific sensor
            sensor_manage: 'Permission to create, update and delete sensors'
            broadcasting_access: Permission to see general broadcasting information and access broadcasting streams
            broadcasting_start_stop: Permission to start and stop public broadcasting on camera
            client_access: Permission to list resellers clients and get details of a specific client
            client_create: Permission to create client account
            client_manage: Permission to update clients detail
            streams_detect: Permission to detect camera streams
            locations_access: Permission to access locations
            services_access: Permission to access available services
            trials_access: Permission to access available trials
            trials_activate: Permission to activate a trial
            active_services_access: Permission to access active services
            active_services_manage: Permission to manage active services
            orders_access: Permission to access orders
            messages_access: Permission to access RTS messages
            messages_manage: Permission to manage RTS messages
            incidents_access: Permission to access Incidents
            space_access: Permission to list and activate spaces
            space_permissions_access: Permission to view space permissions
        password:
          tokenUrl: 'https://api.angelcam.com/oauth/token/'
          scopes:
            user_access: Permission to access user information
            user_delete: Permission to delete the current user account
            camera_access: Permission to list cameras and to get details of a specific camera
            camera_create: Permission to create cameras
            camera_manage: Permission to update cameras
            camera_delete: Permission to delete cameras
            camera_guest_access: Permission to access camera guest
            camera_guest_manage: Permission to manage camera guest
            arrow_client_access: Permission to access Arrow clients
            arrow_client_manage: Permission to manage Arrow clients
            event_access: Permission to access events
            recording_access: Permission to access camera recordings
            recording_start_stop: Permission to start and stop recording on camera
            recording_clips_access: Permission to access recording clips
            recording_clips_create: Permission to create recording clips
            recording_clips_delete: Permission to delete recording clips
            recording_clips_share: Permission to share recording clips
            sensor_access: Permission to list sensors and to get details of a specific sensor
            sensor_manage: 'Permission to create, update and delete sensors'
            broadcasting_access: Permission to see general broadcasting information and access broadcasting streams
            broadcasting_start_stop: Permission to start and stop public broadcasting on camera
            client_access: Permission to list resellers clients and get details of a specific client
            client_create: Permission to create client account
            client_manage: Permission to update clients detail
            streams_detect: Permission to detect camera streams
            locations_access: Permission to access locations
            services_access: Permission to access available services
            trials_access: Permission to access available trials
            trials_activate: Permission to activate a trial
            active_services_access: Permission to access active services
            active_services_manage: Permission to manage active services
            orders_access: Permission to access orders
            messages_access: Permission to access RTS messages
            messages_manage: Permission to manage RTS messages
            rts_settings_access: Permission to access RTS settings
            rts_settings_manage: Permission to manage RTS settings
            rts_arming_manage: Permission to arm and disarm RTS
            incidents_access: Permission to access Incidents
            space_access: Permission to list and activate spaces
            space_permissions_access: Permission to view space permissions
    PersonalAccessToken:
      type: apiKey
      in: header
      name: Authorization
      description: |
        Enter your token as: `PersonalAccessToken {your-token}`
