Prevent Duplicate ServiceNow Ticket Creation via IDN Workflow

Hi,

We have a workflow that creates a SNOW ticket based on identity attribute changes. In a situation, the workflow is triggered multiple times with the same data resulting in duplicate tickets within a few minutes. So prior creating a tickets, Can we query servicenow from the workflow to check if the ticket already exists for the identity? Please advise how to incoporate the flag in the workflow.

Can you give more details? Why is the workflow being trigger more than once?

During workday aggregation, identity attributes were updated mutliple times consecutively with the same data in a single run that inturn caused the workflow to trigger each time the trigger logic was met.

The same attribute was updated multiple times during the same aggregation?

yes, that’s correct. The same attributes were updated mulitple times and one of them triggered the workflow

Hi @ssel

In ServiceNow, add a custom text field on the ticket table (incident / sc_req_item) called:
u_idn_dedupe_key
Make it UNIQUE (so ServiceNow rejects duplicates).

  1. In the IDN workflow, build ONE string that represents “this exact ticket”.
    Example:
    ||
    (No timestamps.)

  2. Workflow logic:
    A) SEARCH ServiceNow:
    “Do I already have a ticket where u_idn_dedupe_key = this string?”
    B) If YES → stop. Do nothing.
    C) If NO → create the ticket and set u_idn_dedupe_key = this string.

That’s it. One key per real change, one ticket max.

What exactly does this mean?

And how do subsequent workflows know how to build that same value?

By “build ONE string”, I mean: create a key that will be IDENTICAL every time the same “real-world event” happens, so I can safely dedupe on it.

Example (one ticket per identity + one attribute change):
dedupeKey = ||

Why “no timestamps”:
If you include a timestamp, the key is different on every run, so the pre-check will never find the first ticket and you’ll still get duplicates.

How other workflows “know” the same value:
They don’t “discover” it automatically — I standardize the recipe and reuse it.
so i have those options:

  1. Put the recipe in a single place (a sub-workflow or a shared step) that outputs dedupeKey, and call it from any workflow that needs the same behavior.
  2. Or simply compute the same string the same way in each workflow (same fields, same order, same delimiter), then query ServiceNow by u_idn_dedupe_key.

In ISC workflows, I can build the key with operators:

  • Trim/lowercase the pieces (optional, but helps stability)
  • Concatenate with “|” as the delimiter
    Then use HTTP Request:
  • GET Table API with sysparm_query=u_idn_dedupe_key=&sysparm_limit=1
    If a record exists: stop. If not: create + set u_idn_dedupe_key=.

The UNIQUE index on u_idn_dedupe_key is the safety net for race conditions (two runs at the same time): ServiceNow will reject the second insert.

How would this handle an identity attribute changing more than once? There are valid use cases where that would happen like department, title, etc. The way you’ve put it together, once one attribute change occurs for an identity, no subsequent ones will be allowed for that identity.

If the key is only identityId, then I’d block any later tickets for that identity which is bad approach .
Use a repeatable key like:
identityId|attributeName|newValue (optionally add effectiveDate/window if we want grouping).

Same change fired twice → same key → will skip the second create.
Attribute changes again → different key → new ticket is allowed.

This approach assumes identity attribute values never repeat after their initial change. There are plenty of valid circumstances where attribute values will change to a new value then change back to their original value. Attributes like department, job title, manager, etc. can all have this happen.

Agreed — that can happen. The key isn’t “identityId|attribute|newValue” alone if you need to distinguish repeated values.Include the event’s effective timestamp (or a change-id/window) in the key, so “back to the same value later” becomes a different key:

identityId|attributeName|newValue|effectiveDate (or |YYYYMMDDHH)

so

  • same change firing twice at the same time → same key → duplicate blocked
  • change away, then back later → different effectiveDate/window → new ticket allowed
  • if you prefer “one ticket per day/week per attribute”, use a day/week window instead.

the knob: exact change vs. change-per-window.

You said earlier not to use timestamps

Thanks for pushing on the edge cases :innocent: :innocent: I should’ve been clearer on “no timestamps”.

I meant: don’t use a “now()” timestamp that changes every run, or the lookup will never match.

If values can repeat, add a stable occurrence marker:
identityId|attribute|newValue|effectiveDate (best)
or |eventTimeBucket (minute/hour).

Same burst/retry → same key → duplicate blocked.
Same value later → different key → new ticket allowed.

How would you generate this effective date?

I you don’t “generate” an effective date in ISC.The trigger payload doesn’t include one (it’s just attribute/old/new), so the clean option is to pull the timestamp/ID of the actual change event from Identity History, then use that as the occurrence marker in the key.

My Workflow will looks like that

Trigger fires (identity + attribute + old/new)

HTTP call to /historical-identities/{identityId}/events and take the matching latest event for that change

Key = identityId|attribute|oldValue|newValue|eventId (or eventTime)

That avoids “now()” timestamps, and it also allows repeats later without blocking them.

The identity history response timestamp is iso8601 which presents the same potential matching problem as using now()

But what I’m more interested in is how can we be sure by retrieving the latest event that it matches to our workflow execution? Shouldn’t we need to do some matching on attributes changed to ensure we’re selecting the correct event?

:+1: Mark I agreed on both points.

  • ISO8601 isn’t the issue; the issue is using “now()” in the key because retries generate a different value.
  • And correcvt the “latest identity history event” isn’t safely correlatable to the workflow run unless you match on attribute + oldValue + newValue + a tight time window, which the trigger doesn’t give you cleanly.

So for this symptom , I’d keep it simple

  • baseKey = identityId|attribute|oldValue|newValue
  • before create: query SN for an open ticket with baseKey created in the last 5–10 minutes
    • exists → no-op/update
    • doesn’t → create + store baseKey

what is your insights on this ?