Summary

This spec covers the Doorbird D2108V Video Door Station's third-party LAN control API (revision 0.36, dated 2023-11-13). The D2108V is part of the D21x family; the LAN API document explicitly lists D21x hardware with firmware 000108+ as supported. Control is exposed over HTTP/HTTPS CGI endpoints under /bha-api/, an RTSP server on port 554/8557, encrypted UDP event broadcasts on ports 6524 and 35344, and an embedded SIP client. Authentication uses HTTP Basic/Digest or session-id query parameters with DoorBird App credentials.

Transport

# Multiple transports are documented; treat as parallel interfaces. The HTTP CGI
# endpoints are the primary control surface. UDP broadcasts are unsolicited
# events. RTSP carries media. SIP carries call audio. TLS uses a self-signed
# certificate pre-installed on the device.
protocols:
  - http
  - tcp
  - udp
addressing:
  port: 80            # HTTP, plain LAN API
  base_url: "http://<device-ip>/bha-api/"
  alternate_ports:
    - 443             # HTTPS, self-signed cert
    - 554             # RTSP
    - 8557            # RTSP-over-HTTP
    - 5060            # SIP (when enable=1)
auth:
  type: basic
  scheme: "HTTP Basic or Digest (RFC 2617); alternatively plaintext query params http-user / http-password"
  notes: "Same credentials used to add the device to the DoorBird App. Excessive failed auth blocks the IP for 1 minute (HTTP 423)."

Traits

powerable: true       # inferred: restart.cgi and relay trigger commands imply the device has power management
routable: false
queryable: true       # inferred: info.cgi, sip.cgi?action=status return device state
levelable: true       # inferred: sip.cgi settings expose mic_volume and spk_volume (0-100)

Actions

- id: get_session
  label: Create temporary session ID (valid 10 minutes)
  kind: query
  command: "GET /bha-api/getsession.cgi"
  params: []

- id: invalidate_session
  label: Invalidate an existing session ID
  kind: action
  command: "GET /bha-api/getsession.cgi?invalidate=<session_id>"
  params:
    - name: session_id
      type: string
      description: The session ID to invalidate

- id: live_video
  label: Live multipart JPEG stream
  kind: action
  command: "GET /bha-api/video.cgi"
  params: []
  notes: "Returns multipart/x-mixed-replace JPEG stream, up to ~8 fps."

- id: live_image
  label: Single JPEG snapshot
  kind: query
  command: "GET /bha-api/image.cgi"
  params: []

- id: open_door
  label: Energize door opener / alarm output relay
  kind: action
  command: "GET /bha-api/open-door.cgi?r=<relay_id>"
  params:
    - name: r
      type: string
      description: "Optional. Relay to trigger: physical relay number (e.g. 1, 2) or paired IP I/O DoorController relay in form <doorcontrollerID>@<relay>. Default = physical relay 1."

- id: light_on
  label: Energize light relay
  kind: action
  command: "GET /bha-api/light-on.cgi"
  params: []

- id: history_image
  label: History image (cloud-stored)
  kind: query
  command: "GET /bha-api/history.cgi?index=<n>&event=<event>"
  params:
    - name: index
      type: integer
      description: "1..50, where 1 is the latest history image"
    - name: event
      type: string
      description: "doorbell | motionsensor (optional). Default = ring history for DoorBird, input trigger history for BirdGuard."

- id: monitor
  label: Subscribe to doorbell/motion event stream (multipart)
  kind: action
  command: "GET /bha-api/monitor.cgi?ring=doorbell[,motionsensor]"
  params:
    - name: ring
      type: string
      description: "Comma-separated event types: doorbell, motionsensor (rfid and keypad coming soon). Max 8 concurrent streams; HTTP 509 when busy."

- id: live_audio_receive
  label: Receive G.711 µ-law audio stream from device
  kind: action
  command: "GET /bha-api/audio-receive.cgi"
  params: []
  notes: "Codec G.711 µ-law, 8000 Hz sampling rate."

- id: live_audio_transmit
  label: Transmit G.711 µ-law audio to device
  kind: action
  command: "POST /bha-api/audio-transmit.cgi"
  params: []
  notes: "Content-Type: audio/basic; single transmit consumer at a time."

- id: info
  label: Get device info / firmware version / relay list
  kind: query
  command: "GET /bha-api/info.cgi"
  params: []

- id: list_favorites
  label: List configured favorites (SIP and HTTP targets)
  kind: query
  command: "GET /bha-api/favorites.cgi"
  params: []

- id: add_or_change_favorite
  label: Add or update a favorite
  kind: action
  command: "GET /bha-api/favorites.cgi?action=save&type=<type>&title=<title>&value=<value>&id=<id>"
  params:
    - name: action
      type: string
      description: "Fixed value 'save'"
    - name: type
      type: string
      description: "sip | http"
    - name: title
      type: string
      description: "Name or short description"
    - name: value
      type: string
      description: "URL (incl. protocol + user credentials if needed) or SIP target"
    - name: id
      type: integer
      description: "Optional. ID of favorite to change; omit to add new."

- id: delete_favorite
  label: Delete a favorite
  kind: action
  command: "GET /bha-api/favorites.cgi?action=remove&type=<type>&id=<id>"
  params:
    - name: action
      type: string
      description: "Fixed value 'remove'"
    - name: type
      type: string
      description: "sip | http"
    - name: id
      type: integer
      description: "ID of the favorite to delete"

- id: list_schedules
  label: List configured schedules
  kind: query
  command: "GET /bha-api/schedule.cgi"
  params: []

- id: add_or_update_schedule
  label: Add or update a schedule entry (JSON body)
  kind: action
  command: "POST /bha-api/schedule.cgi"
  params:
    - name: input
      type: string
      description: "doorbell | motion | rfid | fingerprint"
    - name: param
      type: string
      description: "Doorbell number, transponder id, fingerprint id (empty for motion)"
    - name: output
      type: string
      description: "JSON array of output actions (event=notify|sip|relay|http, param=favorite-id or relay-number, schedule=once|from-to|weekdays)"

- id: delete_schedule
  label: Delete a schedule entry
  kind: action
  command: "GET /bha-api/schedule.cgi?action=remove&input=<input>&param=<param>"
  params:
    - name: action
      type: string
      description: "Fixed value 'remove'"
    - name: input
      type: string
      description: "doorbell | motion | rfid"
    - name: param
      type: string
      description: "Doorbell number, RFID transponder id, etc."

- id: restart
  label: Restart the device
  kind: action
  command: "GET /bha-api/restart.cgi"
  params: []

- id: rtsp_live_video
  label: RTSP live video (H.264)
  kind: action
  command: "rtsp://<device-ip>:554/mpeg/media.amp"
  params: []
  notes: "Path variants: /mpeg/720p/media.amp (firmware 129+), /mpeg/1080p/media.amp (D11x only). RTSP-over-HTTP available on TCP 8557. Requires standard RTSP authentication."

- id: sip_register
  label: Register with SIP proxy
  kind: action
  command: "GET /bha-api/sip.cgi?action=registration&user=<user>&password=<password>&url=<url>"
  params:
    - name: user
      type: string
      description: "Authentication user for the SIP proxy"
    - name: password
      type: string
      description: "Authentication password for the SIP proxy"
    - name: url
      type: string
      description: "IP or hostname of the SIP proxy"

- id: sip_makecall
  label: Manually initiate a SIP call
  kind: action
  command: "GET /bha-api/sip.cgi?action=makecall&url=<url>"
  params:
    - name: url
      type: string
      description: "SIP URL to call"

- id: sip_hangup
  label: Hang up current SIP call
  kind: action
  command: "GET /bha-api/sip.cgi?action=hangup"
  params: []

- id: sip_settings
  label: Configure SIP parameters
  kind: action
  command: "GET /bha-api/sip.cgi?action=settings&<parameter>=<value>"
  params:
    - name: enable
      type: integer
      description: "0..1. Enable/disable SIP registration after reboot (default 0)"
    - name: mic_volume
      type: integer
      description: "1..100. Microphone volume (default 33)"
    - name: spk_volume
      type: integer
      description: "1..100. Speaker volume (default 70)"
    - name: dtmf
      type: integer
      description: "0..1. Enable/disable DTMF support (default 0)"
    - name: autocall_doorbell_url
      type: string
      description: "DEPRECATED. Use schedule.cgi. SIP URL to call on doorbell event."
    - name: relay1_passcode
      type: integer
      description: "0..99999999. DTMF pincode to trigger the door open relay"
    - name: incoming_call_enable
      type: integer
      description: "0..1. Enable/disable incoming calls (default 0)"
    - name: incoming_call_user
      type: string
      description: "Allowed SIP user, e.g. 'sip:10.0.0.1:5060' or 'sip:user@10.0.0.2:5060'"
    - name: anc
      type: integer
      description: "0..1. Enable/disable acoustic noise cancellation (default 1)"
    - name: ring_time_limit
      type: integer
      description: "10..300. Max ringing time in seconds (default 300)"
    - name: call_time_limit
      type: integer
      description: "30..300. Max call duration in seconds (default 300)"

- id: sip_status
  label: Query current SIP status
  kind: query
  command: "GET /bha-api/sip.cgi?action=status"
  params: []
  notes: "Returns JSON with LASTERRORCODE and LASTERRORTEXT."

- id: sip_reset
  label: Reset SIP settings (keeps license)
  kind: action
  command: "GET /bha-api/sip.cgi?action=reset"
  params: []

Feedbacks

- id: info_json
  label: info.cgi JSON response
  type: object
  notes: "Fields: RETURNCODE, VERSION array with FIRMWARE / BUILD_NUMBER, PRIMARY_MAC_ADDR, RELAYS array (firmware 000108+), DEVICE-TYPE."

- id: session_json
  label: get session JSON response
  type: object
  notes: "Fields: RETURNCODE, SESSIONID, NOTIFICATION_ENCRYPTION_KEY (used to decrypt UDP events)."

- id: monitor_event_doorbell
  label: Doorbell event from monitor.cgi stream
  type: enum
  values: [H, L]
  notes: "H = high/active (doorbell pressed), L = low/inactive. Delivered as multipart sections with Content-Type: text/plain, e.g. 'doorbell:H'."

- id: monitor_event_motionsensor
  label: Motion event from monitor.cgi stream
  type: enum
  values: [H, L]

- id: history_image_jpeg
  label: History image payload
  type: binary
  notes: "Content-Type: image/jpeg"

- id: live_image_jpeg
  label: Live image payload
  type: binary
  notes: "Content-Type: image/jpeg"

- id: live_video_mjpeg
  label: Live video payload
  type: binary
  notes: "Content-Type: multipart/x-mixed-replace; boundary=<boundary>. Each section is a JPEG image."

- id: live_audio_ulaw
  label: Live audio payload (receive)
  type: binary
  notes: "G.711 µ-law, 8000 Hz sampling rate."

- id: favorites_json
  label: favorites.cgi JSON response
  type: object
  notes: "Object with 'sip' and 'http' sub-objects, each keyed by favorite id with 'title' and 'value'."

- id: schedules_json
  label: schedule.cgi JSON response
  type: object
  notes: "Array of schedule entries with input, param, output[] (each event, param, schedule)."

- id: sip_status_json
  label: sip.cgi?action=status JSON response
  type: object
  notes: "LASTERRORCODE (e.g. '200' = registered), LASTERRORTEXT."

- id: sip_reset_json
  label: sip.cgi?action=reset JSON response
  type: object

Variables

# UNRESOLVED: the source documents all device-level state via JSON-returning
# query endpoints (info.cgi, favorites.cgi, schedule.cgi, sip.cgi?action=status).
# There are no separate settable scalar parameters outside the sip settings
# query-parameter surface, which is already covered as actions above.

Events

# Unsolicited UDP broadcast events from the device. v2 (current) encryption
# scheme documented below; v1 (ChaCha20-Poly1305 with Argon2i) is deprecated
# per the 2023-11 revision.
- id: udp_event_v2
  label: Encrypted UDP event broadcast (v2)
  transport: udp
  address:
    ports: [6524, 35344]
    note: "Identical broadcasts sent on both ports for every user / connected device. Keep-alive broadcasts are sent every 7 seconds on the same ports and must be ignored."
  framing:
    - field: IDENT
      length: 3 bytes
      value: "0xDE 0xAD 0xBE"
    - field: VERSION
      length: 1 byte
      value: "0x02 = ChaCha20-Poly1305 (current); 0x01 deprecated"
    - field: NONCE
      length: 8 bytes
    - field: CIPHERTEXT
      length: 34 bytes (raw) / 18 bytes (after stripping 16 random bytes)
  encryption:
    algorithm: ChaCha20-Poly1305
    key_source: NOTIFICATION_ENCRYPTION_KEY from get_session response (first 32 bytes used by ChaCha20)
    rotation: "Key valid until user password changes; then re-request via getsession.cgi."
  decoded_fields:
    - field: INTERCOM_ID
      length: 6 bytes
      description: "First 6 chars of DoorBird user name. Discard packet if it does not match your user."
    - field: EVENT
      length: 8 bytes
      description: "Doorbell number or 'motion', padded with spaces."
    - field: TIMESTAMP
      length: 4 bytes
      type: uint32 unix seconds

Macros

# UNRESOLVED: no multi-step sequences are documented in the source beyond
# the implicit subscribe-then-receive pattern (GET monitor.cgi → read multipart
# sections) and the UDP event decryption setup (get_session once → decrypt
# subsequent UDP broadcasts with NOTIFICATION_ENCRYPTION_KEY).

Safety

confirmation_required_for:
  - open_door         # controls a physical relay that unlocks a door
  - restart           # disrupts any active calls or streams
  - sip_reset         # disconnects ongoing SIP call and clears configuration
interlocks: []
# UNRESOLVED: the source does not document safety interlocks, power-on
# sequencing, or fault-recovery procedures. The 503 'busy' responses (line
# busy, firmware update in progress) are documented behaviour, not interlocks.

Notes

  • Compatibility table in the source covers D10x, D20x, D21x (fw 000108+), D11x (fw 000130+), and BirdGuard B10x. The D2108V belongs to the D21x family and inherits this minimum firmware requirement; specific D2108V firmware revisions beyond 000108 are not enumerated in the source.
  • Device HTTP API caps concurrent connections to 1/second per session; repeated failed auth blocks the source IP for 1 minute (HTTP 423).
  • The DoorBird App takes precedence over LAN-API users for video/audio streams — a LAN-API stream will be interrupted if the official app opens one.
  • HTTPS uses a self-signed certificate; clients must either trust it or use --no-check-certificate style flags. Video and audio streaming are HTTP-only in the LAN and require a Session ID appended as sessionid=... so credentials are not transmitted in plaintext for those media streams.
  • RTSP server uses port 554 by default; RTSP-over-HTTP on port 8557 is available; 1080p path is restricted to D11x.
  • SIP service is "early stage" per the source; auto-hangup after 180 seconds, single simultaneous call, ≥3 seconds between SIP requests, AEC/ANC must be done client-side.
  • UDP event monitoring v2 (Nov 2023) supersedes v1 (Argon2i). The example decryption in the source uses libsodium's crypto_aead_chacha20poly1305_decrypt.

## Provenance

```yaml
source_domains:
  - doorbird.com
source_urls:
  - "https://www.doorbird.com/downloads/api_lan.pdf?rev=0.36"
retrieved_at: 2026-05-12T20:44:51.798Z
last_checked_at: 2026-09-04T22:16:55.466Z

Verification Summary

verdict: verified
checked_at: 2026-09-04T22:16:55.466Z
matched_actions: 25
action_count: 25
confidence: medium
summary: "All 25 spec actions map verbatim to CGI endpoints in the source; all transport values (80/443/554/8557/5060, /bha-api/, RFC 2617 Basic/Digest) are sourced. (5 unresolved item(s) noted in Known Gaps.)"

Known Gaps

- "D2108V-specific quirks not called out; the source covers the D21x family generally. Cloud API and remote relay scheduling behaviour for D2108V specifically are not stated."
- "the source documents all device-level state via JSON-returning"
- "no multi-step sequences are documented in the source beyond"
- "the source does not document safety interlocks, power-on"
- "Cloud API access and remote relay scheduling behaviour for the D2108V specifically are outside the scope of the LAN-2-LAN API document. D2108V-specific hardware features (display, keypad, RFID reader, fingerprint reader) and any D2108V-specific commands are not enumerated in the source beyond the D21x family compatibility note."

From the AI4AV catalog (https://ai4av.net) · ODbL-1.0