diff --git a/docs/modules/development/nav.adoc b/docs/modules/development/nav.adoc
index a04ccefb9c27..42924f58ef1e 100644
--- a/docs/modules/development/nav.adoc
+++ b/docs/modules/development/nav.adoc
@@ -70,6 +70,7 @@
*** xref:rest/emailnbi-config.adoc[]
*** xref:rest/javamail-config.adoc[]
*** xref:rest/syslognbi-config.adoc[]
+*** xref:rest/trapd-rest-api.adoc[]
*** xref:bsm/bsm-development.adoc[]
*** xref:rest/situation-feedback.adoc[]
diff --git a/docs/modules/development/pages/rest/trapd-rest-api.adoc b/docs/modules/development/pages/rest/trapd-rest-api.adoc
new file mode 100644
index 000000000000..b800e50efeec
--- /dev/null
+++ b/docs/modules/development/pages/rest/trapd-rest-api.adoc
@@ -0,0 +1,179 @@
+[[ga-events-sources-trapd-rest-api]]
+= Trapd REST API (v2)
+:description: Manage trapd configuration through the OpenNMS REST v2 API.
+
+You can view and update trapd configuration over REST.
+These endpoints are useful for automation and external configuration tooling.
+
+The Trapd REST API base path is `/api/v2/trapd`.
+
+== Endpoint overview
+
+[options="header"]
+|===
+| Method | Path | Content type | Description
+
+| `GET`
+| `/api/v2/trapd/config`
+| `application/json`
+| Get the current trapd configuration.
+
+| `PUT`
+| `/api/v2/trapd/config`
+| `application/json`
+| Replace trapd configuration using JSON payload.
+
+| `POST`
+| `/api/v2/trapd/upload`
+| `multipart/form-data`
+| Upload `trapd-configuration.xml` content as XML.
+|===
+
+== Get configuration
+
+[source, bash]
+----
+curl -u admin:admin "http://localhost:8980/opennms/api/v2/trapd/config"
+----
+
+.Example response
+[source, json]
+----
+{
+ "snmpTrapAddress": "*",
+ "snmpTrapPort": 1162,
+ "newSuspectOnTrap": false,
+ "includeRawMessage": false,
+ "threads": 0,
+ "queueSize": 10000,
+ "batchSize": 1000,
+ "batchInterval": 500,
+ "useAddressFromVarbind": true,
+ "snmpv3User": [
+ {
+ "engineId": "0x8000000001020304",
+ "securityName": "opennms",
+ "securityLevel": 3,
+ "authProtocol": "SHA",
+ "authPassphrase": "my-auth-secret",
+ "privacyProtocol": "AES",
+ "privacyPassphrase": "my-privacy-secret"
+ }
+ ]
+}
+----
+
+WARNING: The current implementation returns SNMPv3 passphrases as stored values when they are present.
+They are not masked in `GET /api/v2/trapd/config` responses.
+
+== Update configuration with JSON
+
+[source, bash]
+----
+curl -u admin:admin \
+ -H "Content-Type: application/json" \
+ -X PUT "http://localhost:8980/opennms/api/v2/trapd/config" \
+ -d '{
+ "snmpTrapAddress": "*",
+ "snmpTrapPort": 1162,
+ "newSuspectOnTrap": false,
+ "includeRawMessage": true,
+ "threads": 4,
+ "queueSize": 10000,
+ "batchSize": 1000,
+ "batchInterval": 500,
+ "useAddressFromVarbind": true,
+ "snmpv3User": [
+ {
+ "securityName": "opennms",
+ "securityLevel": 3,
+ "authProtocol": "SHA",
+ "authPassphrase": "my-auth-secret",
+ "privacyProtocol": "AES",
+ "privacyPassphrase": "my-privacy-secret"
+ }
+ ]
+ }'
+----
+
+== Upload trapd XML
+
+The multipart form field name must be `upload`.
+
+.Sample `trapd-configuration.xml` for upload
+[source, xml]
+----
+
+
+
+----
+
+You can use SCV metadata expressions for passphrases in uploaded XML (`${scv::}`).
+
+[source, bash]
+----
+curl -u admin:admin \
+ -X POST "http://localhost:8980/opennms/api/v2/trapd/upload" \
+ -F "upload=@/opt/opennms/etc/trapd-configuration.xml;type=application/xml"
+----
+
+== Validation rules
+
+The API validates both top-level trapd fields and SNMPv3 user definitions.
+
+.PUT pre-validation (service layer)
+* `snmpTrapAddress` is required for `PUT /api/v2/trapd/config`.
+* `snmpTrapPort` is required and must be between `1` and `65535`.
+* `newSuspectOnTrap` is required.
+* `threads`, `queueSize`, `batchSize`, and `batchInterval` must be `>= 0` when provided.
+
+.Additional schema validation (DAO layer, applies on persist)
+* `queueSize` must be `>= 1`.
+* `batchSize` must be `>= 1`.
+* In XML uploads, `snmp-trap-address` is optional and defaults to `*` when omitted.
+
+.SNMPv3 user fields
+* `securityName` is required.
+* `securityLevel` is required and must be `1`, `2`, or `3`.
+* Supported `authProtocol`: `MD5`, `SHA`, `SHA-224`, `SHA-256`, `SHA-512`.
+* Supported `privacyProtocol`: `DES`, `AES`, `AES192`, `AES256`.
+* `authProtocol` and `authPassphrase` must be provided together.
+* `privacyProtocol` and `privacyPassphrase` must be provided together.
+* `securityLevel=1`: no auth or privacy credentials allowed.
+* `securityLevel=2`: auth credentials required, privacy credentials not allowed.
+* `securityLevel=3`: both auth and privacy credentials are required.
+
+== Response codes
+
+[options="header"]
+|===
+| Endpoint | Success | Error responses
+
+| `GET /api/v2/trapd/config`
+| `200 OK`
+| `404 Not Found` (`Trapd configuration not found.`), `500 Internal Server Error` (`Failed to retrieve trapd configuration.`)
+
+| `PUT /api/v2/trapd/config`
+| `200 OK`
+| `400 Bad Request` (validation errors), `500 Internal Server Error` (`Failed to persist trapd configuration.`)
+
+| `POST /api/v2/trapd/upload`
+| `200 OK`
+| `400 Bad Request` (missing `upload`, invalid XML, schema validation errors), `500 Internal Server Error` (`Failed to persist trapd configuration.`)
+|===
+
+For XML-based upload, schema validation errors are returned as the response body text.
+
diff --git a/docs/modules/operation/pages/deep-dive/events/sources/snmp-traps.adoc b/docs/modules/operation/pages/deep-dive/events/sources/snmp-traps.adoc
index 940c10fe16fe..8df647b71363 100644
--- a/docs/modules/operation/pages/deep-dive/events/sources/snmp-traps.adoc
+++ b/docs/modules/operation/pages/deep-dive/events/sources/snmp-traps.adoc
@@ -6,6 +6,8 @@
{page-component-title} can receive and process SNMP traps/informs from SNMP-capable devices out of the box.
It receives SNMP traps via the xref:reference:daemons/daemon-config-files/trapd.adoc[trapd service daemon], which is enabled by default.
+To manage trapd configuration through REST, see xref:development:rest/trapd-rest-api.adoc[Trapd REST API (v2)].
+
{page-component-title} transforms these traps into events based on event definitions.
{page-component-title} includes trap definitions from many major manufacturers by default, and you can create your own event definitions.
diff --git a/docs/modules/reference/pages/daemons/daemon-config-files/trapd.adoc b/docs/modules/reference/pages/daemons/daemon-config-files/trapd.adoc
index 8468c547e55f..64568b131d3a 100644
--- a/docs/modules/reference/pages/daemons/daemon-config-files/trapd.adoc
+++ b/docs/modules/reference/pages/daemons/daemon-config-files/trapd.adoc
@@ -8,6 +8,8 @@ Based around traditional UDP-based SNMP traps, it receives traps that remote dev
It enables OpenNMS to receive SNMP traps and convert them into events and, if configured accordingly, convert those events into alarms and notifications.
Its functionality is similar to how xref:reference:daemons/daemon-config-files/syslogd.adoc[syslogd] handles syslog entries.
+You can also manage trapd configuration over REST; see xref:development:rest/trapd-rest-api.adoc[Trapd REST API (v2)].
+
Trapd supports V1 traps, V2 traps and notifications, and V3 traps and notifications.
It also accepts traps with any community name (V1, V2c).
You can use that community name in event definitions as part of a mask.
@@ -69,11 +71,26 @@ Note that for V3, you must specify the SNMPv3 credentials used to authenticate a
privacy-passphrase="super-secret" privacy-protocol="DES"/>
----
-For `privacy-protocol`, the available options are `DES`, `AES`, `AES192`, and `AES256`
-For `auth-protocol`, the available options are `MD5`, `SHA`, `SHA-224`, `SHA-256`, and `SHA-512`
+For `privacy-protocol`, the available options are `DES`, `AES`, `AES192`, and `AES256`.
+For `auth-protocol`, the available options are `MD5`, `SHA`, `SHA-224`, `SHA-256`, and `SHA-512`.
NOTE: Metadata expressions can also be used in attributes of the `trapd-configuration.xml` configuration file.
-This lets the user to also reference credentials stored in the secure credentials.
+This lets you reference credentials from the Secure Credentials Vault (SCV), including SNMPv3 passphrases.
+
+.Example using SCV metadata for SNMPv3 passphrases
+[source, xml]
+----
+
+
+
+----
+
+The SCV expression format is `${scv::}`.
+For SCV setup and management, see xref:operation:deep-dive/admin/configuration/scv-configuration.adoc[SCV configuration] and xref:operation:deep-dive/meta-data.adoc#ga-metadata-scv[secure credentials vault metadata].
== Trap metrics