Linking findings to your own systems
When your SOAR opens an incident for a finding, record its id back against the
finding. Without that the link runs one way — your incident knows its
SecureSight id, and SecureSight knows nothing about your incident — so
"is this already being worked?" is a lookup in the other system every time.
PUT /v1/threats/{threat_id}/external-references/{system}
Content-Type: application/json
{ "external_id": "INC-42", "url": "https://xsoar.example.com/#/incident/42" }
204 No Content on success. The reference then comes back on every read:
"external_references": [
{
"system": "xsoar",
"external_id": "INC-42",
"url": "https://xsoar.example.com/#/incident/42",
"linked_at": "2026-09-15T12:00:00Z"
}
]
Retries are safe, and there is no idempotency key
{system} is the key. Writing the same one again replaces the link rather
than adding a second, so a playbook that retries after a timeout cannot create
duplicates. You do not need to send an idempotency key and there is none to
send.
That is a property of every write in v1, not just this one:
| Operation | Why a retry is safe |
|---|---|
PUT /v1/threats/{id}/external-references/{system} |
Upsert keyed on system |
PATCH /v1/threats/{id} |
Sets the status to a value; setting it twice is the same state |
POST /v1/threats/{id}/update-note |
Replaces the note; it does not append |
None of them accumulates on replay. Retry with backoff and stop worrying about exactly-once.
One difference worth knowing: the status and note writes are sent upstream exactly once and never retried automatically, because a replay there costs a duplicate audit entry even though the end state is the same. If one of those times out, the outcome is unknown and re-sending is your call. The external-reference write is retried for you, because a replay of it reaches the same single link.
One reference per system
Use different {system} values to link the same finding into several tools at
once:
PUT /v1/threats/{id}/external-references/xsoar → INC-42
PUT /v1/threats/{id}/external-references/servicenow → TICKET-9
Sending a different external_id for the same {system} is how you move
a link — for example when an incident is merged into another. There is no
partial update: the last write for a system wins.
{system} is your name for the system, not ours. We do not validate it against
a list, because we do not know what you run.
What you cannot set
linked_at is stamped by the platform. It is rejected in the request body
(422) rather than ignored, because a caller-supplied timestamp would be the
only field in the record that could disagree with what actually happened.
After the write
A successful write bumps the threat's updated_at, so the threat appears on
your next delta poll. Like the note write, it reaches the
stream asynchronously — an immediate read-back may briefly show the previous
state.
A {threat_id} your organization has no threat for returns 404, and nothing
is written.
Not yet supported
There is no unlink. Removing a reference — when an incident is closed or created in error — is not in v1; overwrite it with the correct value instead. Tell us if you need the delete and we will prioritise it.