Company

Events categorised under company level will be triggered when any action performed on company. e.g. If new brand is created.

Tax rule

This event is generated when a company Tax Rule or one of its versions is created, updated, or deleted, and when a scheduled Tax Rule Version becomes live at its applicable_date. Each event carries the complete Tax Rule aggregate, so a consumer can replace its stored copy rather than merge. Silverbolt mutations and Triggerhappy activations are delivered through the fynd-json-fdk-webhook-tax-rule-event Kafka topic. The webhook event name and payload key remain tax_rule.

Events
company/tax_rule/create/v1
# This event is triggered when a company Tax Rule is created
company/tax_rule/update/v1
# This event is triggered when a company Tax Rule or one of its versions is updated, and when a scheduled version becomes live
company/tax_rule/delete/v1
# This event is triggered when a company Tax Rule is deleted

Tax Rule/tax_rule/create/v1

This event is triggered when a company Tax Rule is created

Payload
Hide
company_id
integer
Required
Company ID for which this event is triggered
contains
array of string
Required
Keys present at the root level of the payload object
event
object
Required
Show
payload
object
Required
Show
Payload Schema JSON
1{
2 "type": "object",
3 "required": [
4 "company_id",
5 "contains",
6 "event",
7 "payload"
8 ],
9 "properties": {
10 "company_id": {
11 "type": "integer",
12 "description": "Company ID for which this event is triggered"
13 },
14 "contains": {
15 "type": "array",
16 "description": "Keys present at the root level of the payload object",
17 "items": {
18 "type": "string"
19 }
20 },
21 "event": {
22 "type": "object",
23 "required": [
24 "created_timestamp",
25 "event_id",
26 "eventId",
27 "name",
28 "trace_id",
29 "type",
30 "version"
31 ],
32 "properties": {
33 "category": {
34 "type": "string",
35 "description": "Optional event category. Company Tax Rule events belong to the company category"
36 },
37 "created_timestamp": {
38 "type": "integer",
39 "description": "Event generation timestamp in epoch milliseconds"
40 },
41 "id": {
42 "type": "string",
43 "description": "Legacy event identifier, when supplied by the webhook infrastructure"
44 },
45 "event_id": {
46 "type": "string",
47 "format": "uuid",
48 "description": "Unique identifier for this emission. A redelivery of unchanged state is a distinct event with a distinct event_id, so use payload.tax_rule.snapshot_hash for duplicate detection."
49 },
50 "eventId": {
51 "type": "string",
52 "format": "uuid",
53 "description": "Canonical camelCase form of event_id"
54 },
55 "name": {
56 "type": "string",
57 "enum": [
58 "tax_rule"
59 ],
60 "description": "Name of the event"
61 },
62 "trace_id": {
63 "type": "array",
64 "description": "Internal trace identifiers for Fynd Platform services",
65 "items": {
66 "type": "string"
67 }
68 },
69 "type": {
70 "type": "string",
71 "enum": [
72 "create",
73 "update",
74 "delete"
75 ],
76 "description": "Tax Rule action that triggered the event"
77 },
78 "version": {
79 "type": "string",
80 "enum": [
81 "1"
82 ],
83 "description": "Version of the event contract"
84 }
85 }
86 },
87 "payload": {
88 "type": "object",
89 "additionalProperties": false,
90 "required": [
91 "tax_rule"
92 ],
93 "properties": {
94 "tax_rule": {
95 "type": "object",
96 "additionalProperties": false,
97 "required": [
98 "tax_rule_id",
99 "company_id",
100 "status",
101 "versions",
102 "live_versions",
103 "snapshot_hash",
104 "snapshot_revision"
105 ],
106 "properties": {
107 "_id": {
108 "type": "string",
109 "description": "MongoDB identifier of the Tax Rule"
110 },
111 "tax_rule_id": {
112 "type": "string",
113 "description": "Canonical identifier of the company Tax Rule referenced by products"
114 },
115 "company_id": {
116 "type": "integer",
117 "description": "Company that owns the Tax Rule"
118 },
119 "name": {
120 "type": "string",
121 "description": "Tax Rule name"
122 },
123 "description": {
124 "type": "string",
125 "description": "Tax Rule description"
126 },
127 "is_default": {
128 "type": "boolean",
129 "description": "Whether this is the company's default Tax Rule"
130 },
131 "status": {
132 "type": "string",
133 "enum": [
134 "ACTIVE",
135 "INACTIVE",
136 "DELETED"
137 ],
138 "description": "Current status of the Tax Rule"
139 },
140 "country_iso": {
141 "type": "string",
142 "description": "ISO country code associated with the Tax Rule, when present"
143 },
144 "admin_tax_rule": {
145 "type": [
146 "string",
147 "null"
148 ],
149 "description": "Identifier of the source admin Tax Rule, when this is a company copy"
150 },
151 "created_on": {
152 "type": "string",
153 "format": "date-time",
154 "description": "Timestamp when the Tax Rule was created"
155 },
156 "modified_on": {
157 "type": "string",
158 "format": "date-time",
159 "description": "Timestamp when the Tax Rule was last modified"
160 },
161 "versions": {
162 "type": "array",
163 "description": "Every persisted Tax Rule Version, across every scope (COUNTRY, REGION, STORE, CUSTOM). A Tax Rule can have multiple versions live at once, one per scope bucket. Use this list only if you need to resolve the applicable version at your own point-of-sale instant (compare applicable_date against your own clock, per scope); for \"what applies right now\" use live_versions instead, which is already resolved for you.",
164 "items": {
165 "type": "object",
166 "additionalProperties": false,
167 "required": [
168 "_id",
169 "rule_id",
170 "status",
171 "components"
172 ],
173 "properties": {
174 "_id": {
175 "type": "string",
176 "description": "MongoDB identifier of the Tax Rule Version"
177 },
178 "rule_id": {
179 "type": "string",
180 "description": "Identifier of the parent Tax Rule"
181 },
182 "company_id": {
183 "type": "integer",
184 "description": "Company associated with the Tax Rule Version, when present"
185 },
186 "status": {
187 "type": "string",
188 "enum": [
189 "ACTIVE",
190 "INACTIVE",
191 "DELETED"
192 ],
193 "description": "Persisted status of the Tax Rule Version"
194 },
195 "version_status": {
196 "type": "string",
197 "enum": [
198 "LIVE",
199 "FUTURE",
200 "PAST"
201 ],
202 "description": "Derived lifecycle status relative to the applicable date, when present"
203 },
204 "applicable_date": {
205 "type": [
206 "string",
207 "null"
208 ],
209 "format": "date-time",
210 "description": "Date and time from which this version can be applied"
211 },
212 "scope": {
213 "type": "string",
214 "enum": [
215 "COUNTRY",
216 "REGION",
217 "STORE",
218 "CUSTOM"
219 ],
220 "description": "Tax applicability scope for this version"
221 },
222 "region_code": {
223 "type": "string",
224 "x-not-enum": true,
225 "description": "Configured region identifier for a region-scoped version"
226 },
227 "store_ids": {
228 "type": "array",
229 "description": "Store identifiers for a store-scoped version",
230 "items": {
231 "type": "integer"
232 }
233 },
234 "custom_conditions": {
235 "type": "object",
236 "additionalProperties": false,
237 "properties": {},
238 "x-tax-rule-reject-unknown": true,
239 "description": "Reserved for a supported custom-condition grammar. Current Tax Rule write APIs support COUNTRY, REGION and STORE scopes; no owned CUSTOM condition grammar exists. Only an empty object is supported here. A persisted nonempty condition blocks publication and retains retry intent. Conditions must never be dropped or silently converted to {}."
240 },
241 "region": {
242 "type": [
243 "object",
244 "null"
245 ],
246 "additionalProperties": false,
247 "properties": {
248 "name": {
249 "type": [
250 "string",
251 "null"
252 ],
253 "description": "Display name of the configured region"
254 },
255 "slug": {
256 "type": [
257 "string",
258 "null"
259 ],
260 "description": "Slug of the configured region"
261 },
262 "areas": {
263 "type": [
264 "array",
265 "null"
266 ],
267 "description": "Area identifiers or area details belonging to the region",
268 "items": {
269 "anyOf": [
270 {
271 "type": "string"
272 },
273 {
274 "type": "object",
275 "additionalProperties": false,
276 "properties": {
277 "country": {
278 "description": "Country identifier or resolved public country details",
279 "anyOf": [
280 {
281 "type": "string"
282 },
283 {
284 "type": "object",
285 "additionalProperties": false,
286 "properties": {
287 "uid": {
288 "type": "string"
289 },
290 "display_name": {
291 "type": [
292 "string",
293 "null"
294 ]
295 },
296 "iso2": {
297 "type": [
298 "string",
299 "null"
300 ]
301 },
302 "iso3": {
303 "type": [
304 "string",
305 "null"
306 ]
307 }
308 }
309 }
310 ]
311 },
312 "regions": {
313 "type": "array",
314 "items": {
315 "anyOf": [
316 {
317 "type": "string"
318 },
319 {
320 "type": "object",
321 "additionalProperties": false,
322 "properties": {
323 "uid": {
324 "type": "string"
325 },
326 "display_name": {
327 "type": [
328 "string",
329 "null"
330 ]
331 },
332 "sub_type": {
333 "type": "string",
334 "x-not-enum": true
335 },
336 "parent_id": {
337 "type": "array",
338 "items": {
339 "type": "string"
340 }
341 }
342 }
343 }
344 ]
345 }
346 }
347 }
348 }
349 ]
350 }
351 }
352 }
353 },
354 "stores": {
355 "type": "array",
356 "description": "Present when scope is STORE and each store_id could be resolved. Omitted (not an empty array) if resolution failed or found no match -- store_ids remains the source of truth either way.",
357 "items": {
358 "type": "object",
359 "additionalProperties": false,
360 "properties": {
361 "id": {
362 "type": "integer",
363 "description": "Store identifier, matching an entry in the parent's store_ids"
364 },
365 "name": {
366 "type": [
367 "string",
368 "null"
369 ],
370 "description": "Store name"
371 },
372 "display_name": {
373 "type": [
374 "string",
375 "null"
376 ],
377 "description": "Store display name"
378 },
379 "address": {
380 "type": [
381 "object",
382 "null"
383 ],
384 "additionalProperties": false,
385 "description": "Public store address fields from the owned location model. Arbitrary address_meta, actor identity and internal store configuration are not part of the Tax Rule webhook contract.",
386 "properties": {
387 "address_type": {
388 "type": [
389 "string",
390 "null"
391 ],
392 "x-not-enum": true
393 },
394 "address1": {
395 "type": [
396 "string",
397 "null"
398 ]
399 },
400 "address2": {
401 "type": [
402 "string",
403 "null"
404 ]
405 },
406 "country": {
407 "type": [
408 "string",
409 "null"
410 ]
411 },
412 "pincode": {
413 "type": [
414 "string",
415 "integer",
416 "null"
417 ]
418 },
419 "city": {
420 "type": [
421 "string",
422 "null"
423 ]
424 },
425 "state": {
426 "type": [
427 "string",
428 "null"
429 ]
430 },
431 "state_code": {
432 "type": [
433 "string",
434 "null"
435 ],
436 "x-not-enum": true
437 },
438 "sector": {
439 "type": [
440 "string",
441 "null"
442 ]
443 },
444 "latitude": {
445 "type": [
446 "number",
447 "null"
448 ]
449 },
450 "longitude": {
451 "type": [
452 "number",
453 "null"
454 ]
455 },
456 "landmark": {
457 "type": [
458 "string",
459 "null"
460 ]
461 },
462 "country_code": {
463 "type": [
464 "string",
465 "null"
466 ],
467 "x-not-enum": true
468 }
469 }
470 }
471 }
472 }
473 },
474 "components": {
475 "type": "array",
476 "description": "Tax components. GST and CESS are represented as separate components",
477 "items": {
478 "type": "object",
479 "additionalProperties": false,
480 "required": [
481 "_id",
482 "name",
483 "slabs"
484 ],
485 "properties": {
486 "_id": {
487 "type": "string",
488 "description": "Identifier of the tax component"
489 },
490 "name": {
491 "type": "string",
492 "description": "Component name, for example GST or CESS"
493 },
494 "description": {
495 "type": "string",
496 "description": "Tax component description"
497 },
498 "slabs": {
499 "type": "array",
500 "description": "Threshold slabs for this tax component",
501 "items": {
502 "type": "object",
503 "additionalProperties": false,
504 "required": [
505 "value",
506 "rate"
507 ],
508 "properties": {
509 "value": {
510 "type": "number",
511 "description": "Threshold value at which this slab applies"
512 },
513 "rate": {
514 "type": "number",
515 "description": "Tax rate represented as a decimal, for example 0.18 means 18 percent"
516 }
517 }
518 }
519 }
520 }
521 }
522 },
523 "created_on": {
524 "type": "string",
525 "format": "date-time",
526 "description": "Timestamp when the Tax Rule Version was created"
527 },
528 "modified_on": {
529 "type": "string",
530 "format": "date-time",
531 "description": "Timestamp when the Tax Rule Version was last modified"
532 }
533 }
534 }
535 },
536 "live_versions": {
537 "type": "array",
538 "description": "The resolved winner per scope bucket (COUNTRY/REGION/STORE/CUSTOM) as of snapshot_revision, so subscribers do not need to reimplement per-scope resolution or STORE-scope shadowing themselves. This is a point-in-time answer, refreshed on every Tax Rule mutation and at scheduled activation instants through Triggerhappy. Scheduler polling, queue capacity, and delivery affect actual arrival time. Failed publications or missed activations require an explicitly invoked replay; there is no automatic Tax Rule recovery cron. A consumer needing an answer at its own exact instant can resolve from versions instead.",
539 "items": {
540 "type": "object",
541 "additionalProperties": false,
542 "required": [
543 "scope",
544 "version_id"
545 ],
546 "description": "One resolved winner for one scope bucket. A COUNTRY entry is the company-wide default; a REGION/STORE/CUSTOM entry is an override that applies in addition to (not instead of) COUNTRY -- multiple entries can be present at once, one per independently-scheduled scope.",
547 "properties": {
548 "scope": {
549 "type": "string",
550 "enum": [
551 "COUNTRY",
552 "REGION",
553 "STORE",
554 "CUSTOM"
555 ],
556 "description": "Which scope bucket this resolved version applies to"
557 },
558 "version_id": {
559 "type": "string",
560 "description": "Identifier of the winning Tax Rule Version for this bucket, matching a versions[]._id"
561 },
562 "region_code": {
563 "type": "string",
564 "x-not-enum": true,
565 "description": "Present when scope is REGION"
566 },
567 "region": {
568 "type": [
569 "object",
570 "null"
571 ],
572 "additionalProperties": false,
573 "properties": {
574 "name": {
575 "type": [
576 "string",
577 "null"
578 ],
579 "description": "Display name of the configured region"
580 },
581 "slug": {
582 "type": [
583 "string",
584 "null"
585 ],
586 "description": "Slug of the configured region"
587 },
588 "areas": {
589 "type": [
590 "array",
591 "null"
592 ],
593 "description": "Area identifiers or area details belonging to the region",
594 "items": {
595 "anyOf": [
596 {
597 "type": "string"
598 },
599 {
600 "type": "object",
601 "additionalProperties": false,
602 "properties": {
603 "country": {
604 "description": "Country identifier or resolved public country details",
605 "anyOf": [
606 {
607 "type": "string"
608 },
609 {
610 "type": "object",
611 "additionalProperties": false,
612 "properties": {
613 "uid": {
614 "type": "string"
615 },
616 "display_name": {
617 "type": [
618 "string",
619 "null"
620 ]
621 },
622 "iso2": {
623 "type": [
624 "string",
625 "null"
626 ]
627 },
628 "iso3": {
629 "type": [
630 "string",
631 "null"
632 ]
633 }
634 }
635 }
636 ]
637 },
638 "regions": {
639 "type": "array",
640 "items": {
641 "anyOf": [
642 {
643 "type": "string"
644 },
645 {
646 "type": "object",
647 "additionalProperties": false,
648 "properties": {
649 "uid": {
650 "type": "string"
651 },
652 "display_name": {
653 "type": [
654 "string",
655 "null"
656 ]
657 },
658 "sub_type": {
659 "type": "string",
660 "x-not-enum": true
661 },
662 "parent_id": {
663 "type": "array",
664 "items": {
665 "type": "string"
666 }
667 }
668 }
669 }
670 ]
671 }
672 }
673 }
674 }
675 ]
676 }
677 }
678 }
679 },
680 "store_ids": {
681 "type": "array",
682 "description": "Present when scope is STORE",
683 "items": {
684 "type": "integer"
685 }
686 },
687 "stores": {
688 "type": "array",
689 "description": "Present when scope is STORE and each store_id could be resolved",
690 "items": {
691 "type": "object",
692 "additionalProperties": false,
693 "properties": {
694 "id": {
695 "type": "integer",
696 "description": "Store identifier, matching an entry in the parent's store_ids"
697 },
698 "name": {
699 "type": [
700 "string",
701 "null"
702 ],
703 "description": "Store name"
704 },
705 "display_name": {
706 "type": [
707 "string",
708 "null"
709 ],
710 "description": "Store display name"
711 },
712 "address": {
713 "type": [
714 "object",
715 "null"
716 ],
717 "additionalProperties": false,
718 "description": "Public store address fields from the owned location model. Arbitrary address_meta, actor identity and internal store configuration are not part of the Tax Rule webhook contract.",
719 "properties": {
720 "address_type": {
721 "type": [
722 "string",
723 "null"
724 ],
725 "x-not-enum": true
726 },
727 "address1": {
728 "type": [
729 "string",
730 "null"
731 ]
732 },
733 "address2": {
734 "type": [
735 "string",
736 "null"
737 ]
738 },
739 "country": {
740 "type": [
741 "string",
742 "null"
743 ]
744 },
745 "pincode": {
746 "type": [
747 "string",
748 "integer",
749 "null"
750 ]
751 },
752 "city": {
753 "type": [
754 "string",
755 "null"
756 ]
757 },
758 "state": {
759 "type": [
760 "string",
761 "null"
762 ]
763 },
764 "state_code": {
765 "type": [
766 "string",
767 "null"
768 ],
769 "x-not-enum": true
770 },
771 "sector": {
772 "type": [
773 "string",
774 "null"
775 ]
776 },
777 "latitude": {
778 "type": [
779 "number",
780 "null"
781 ]
782 },
783 "longitude": {
784 "type": [
785 "number",
786 "null"
787 ]
788 },
789 "landmark": {
790 "type": [
791 "string",
792 "null"
793 ]
794 },
795 "country_code": {
796 "type": [
797 "string",
798 "null"
799 ],
800 "x-not-enum": true
801 }
802 }
803 }
804 }
805 }
806 },
807 "custom_conditions": {
808 "type": "object",
809 "additionalProperties": false,
810 "properties": {},
811 "x-tax-rule-reject-unknown": true,
812 "description": "Reserved for a supported custom-condition grammar. Current Tax Rule write APIs support COUNTRY, REGION and STORE scopes; no owned CUSTOM condition grammar exists. Only an empty object is supported here. A persisted nonempty condition blocks publication and retains retry intent. Conditions must never be dropped or silently converted to {}."
813 }
814 }
815 }
816 },
817 "snapshot_updated_on": {
818 "type": [
819 "string",
820 "null"
821 ],
822 "format": "date-time",
823 "description": "Latest created or modified timestamp across the Tax Rule and all its versions"
824 },
825 "snapshot_revision": {
826 "type": "integer",
827 "description": "Strictly increasing revision of this aggregate. It advances on every change to the effective state, including a scheduled version becoming live purely through the passage of time. Apply a snapshot only when its revision is greater than or equal to the one already held, so redelivery and replay cannot regress state.\nDirect scheduling reserves an increasing revision range for each source generation: every activation increases within that range, and the next mutation exceeds all previously reserved future revisions. This fences a stale job whose cancellation failed. Changed region/store enrichment also advances the reserved generation, so an older scheduled or replayed descriptor cannot overwrite its correction. The existing greater-than-or-equal comparison remains valid for duplicate snapshots. Treat the revision as an opaque integer and compare it only against another snapshot_revision for the same Tax Rule -- do not read a timestamp back out of it, and do not compare it across rules. Values are always larger than those issued by the earlier plain epoch-millisecond encoding, so a consumer holding one of those keeps accepting new events."
828 },
829 "snapshot_hash": {
830 "type": "string",
831 "description": "Hash of the delivered aggregate. Equal hashes mean the state is unchanged, so the snapshot can be skipped. Use this for duplicate detection. A scheduler retry reuses the frozen event identity, while a fresh publication or recovery may assign a new identity. Sureshot can deliver both copies; subscriber deduplication uses this hash together with per-rule revision ordering."
832 }
833 }
834 }
835 }
836 }
837 }
838}
Payload Example
1{
2 "company_id": 61,
3 "contains": [
4 "tax_rule"
5 ],
6 "event": {
7 "created_timestamp": 1758457800000,
8 "event_id": "0f7d8c1a-3b52-4f9e-9c47-2a1e6b8d4f30",
9 "eventId": "0f7d8c1a-3b52-4f9e-9c47-2a1e6b8d4f30",
10 "name": "tax_rule",
11 "trace_id": [
12 "Silverbolt.example-trace-id"
13 ],
14 "type": "create",
15 "version": "1"
16 },
17 "payload": {
18 "tax_rule": {
19 "_id": "68cf7cda35f228ee1746d8a5",
20 "tax_rule_id": "68cf7cda35f228ee1746d8a5",
21 "company_id": 61,
22 "name": "Standard GST",
23 "description": "Standard goods tax rule",
24 "status": "ACTIVE",
25 "country_iso": "IN",
26 "is_default": false,
27 "versions": [
28 {
29 "_id": "68cf7cda35f228ee1746d8a6",
30 "rule_id": "68cf7cda35f228ee1746d8a5",
31 "company_id": 61,
32 "status": "ACTIVE",
33 "version_status": "LIVE",
34 "applicable_date": "2025-09-21T00:00:00+00:00",
35 "scope": "COUNTRY",
36 "components": [
37 {
38 "_id": "68cf7cda35f228ee1746d8a7",
39 "name": "GST",
40 "description": "Goods and Services Tax",
41 "slabs": [
42 {
43 "value": 0,
44 "rate": 0.18
45 }
46 ]
47 },
48 {
49 "_id": "68cf7cda35f228ee1746d8a8",
50 "name": "CESS",
51 "slabs": [
52 {
53 "value": 0,
54 "rate": 0
55 }
56 ]
57 }
58 ]
59 }
60 ],
61 "live_versions": [
62 {
63 "scope": "COUNTRY",
64 "version_id": "68cf7cda35f228ee1746d8a6"
65 }
66 ],
67 "snapshot_updated_on": "2025-09-21T00:00:00+00:00",
68 "snapshot_revision": 1758412800000,
69 "snapshot_hash": "example-snapshot-hash"
70 }
71 }
72}

Tax Rule/tax_rule/update/v1

This event is triggered when a company Tax Rule or one of its versions is updated, and when a scheduled version becomes live

Payload
Hide
company_id
integer
Required
Company ID for which this event is triggered
contains
array of string
Required
Keys present at the root level of the payload object
event
object
Required
Show
payload
object
Required
Show
Payload Schema JSON
1{
2 "type": "object",
3 "required": [
4 "company_id",
5 "contains",
6 "event",
7 "payload"
8 ],
9 "properties": {
10 "company_id": {
11 "type": "integer",
12 "description": "Company ID for which this event is triggered"
13 },
14 "contains": {
15 "type": "array",
16 "description": "Keys present at the root level of the payload object",
17 "items": {
18 "type": "string"
19 }
20 },
21 "event": {
22 "type": "object",
23 "required": [
24 "created_timestamp",
25 "event_id",
26 "eventId",
27 "name",
28 "trace_id",
29 "type",
30 "version"
31 ],
32 "properties": {
33 "category": {
34 "type": "string",
35 "description": "Optional event category. Company Tax Rule events belong to the company category"
36 },
37 "created_timestamp": {
38 "type": "integer",
39 "description": "Event generation timestamp in epoch milliseconds"
40 },
41 "id": {
42 "type": "string",
43 "description": "Legacy event identifier, when supplied by the webhook infrastructure"
44 },
45 "event_id": {
46 "type": "string",
47 "format": "uuid",
48 "description": "Unique identifier for this emission. A redelivery of unchanged state is a distinct event with a distinct event_id, so use payload.tax_rule.snapshot_hash for duplicate detection."
49 },
50 "eventId": {
51 "type": "string",
52 "format": "uuid",
53 "description": "Canonical camelCase form of event_id"
54 },
55 "name": {
56 "type": "string",
57 "enum": [
58 "tax_rule"
59 ],
60 "description": "Name of the event"
61 },
62 "trace_id": {
63 "type": "array",
64 "description": "Internal trace identifiers for Fynd Platform services",
65 "items": {
66 "type": "string"
67 }
68 },
69 "type": {
70 "type": "string",
71 "enum": [
72 "create",
73 "update",
74 "delete"
75 ],
76 "description": "Tax Rule action that triggered the event"
77 },
78 "version": {
79 "type": "string",
80 "enum": [
81 "1"
82 ],
83 "description": "Version of the event contract"
84 }
85 }
86 },
87 "payload": {
88 "type": "object",
89 "additionalProperties": false,
90 "required": [
91 "tax_rule"
92 ],
93 "properties": {
94 "tax_rule": {
95 "type": "object",
96 "additionalProperties": false,
97 "required": [
98 "tax_rule_id",
99 "company_id",
100 "status",
101 "versions",
102 "live_versions",
103 "snapshot_hash",
104 "snapshot_revision"
105 ],
106 "properties": {
107 "_id": {
108 "type": "string",
109 "description": "MongoDB identifier of the Tax Rule"
110 },
111 "tax_rule_id": {
112 "type": "string",
113 "description": "Canonical identifier of the company Tax Rule referenced by products"
114 },
115 "company_id": {
116 "type": "integer",
117 "description": "Company that owns the Tax Rule"
118 },
119 "name": {
120 "type": "string",
121 "description": "Tax Rule name"
122 },
123 "description": {
124 "type": "string",
125 "description": "Tax Rule description"
126 },
127 "is_default": {
128 "type": "boolean",
129 "description": "Whether this is the company's default Tax Rule"
130 },
131 "status": {
132 "type": "string",
133 "enum": [
134 "ACTIVE",
135 "INACTIVE",
136 "DELETED"
137 ],
138 "description": "Current status of the Tax Rule"
139 },
140 "country_iso": {
141 "type": "string",
142 "description": "ISO country code associated with the Tax Rule, when present"
143 },
144 "admin_tax_rule": {
145 "type": [
146 "string",
147 "null"
148 ],
149 "description": "Identifier of the source admin Tax Rule, when this is a company copy"
150 },
151 "created_on": {
152 "type": "string",
153 "format": "date-time",
154 "description": "Timestamp when the Tax Rule was created"
155 },
156 "modified_on": {
157 "type": "string",
158 "format": "date-time",
159 "description": "Timestamp when the Tax Rule was last modified"
160 },
161 "versions": {
162 "type": "array",
163 "description": "Every persisted Tax Rule Version, across every scope (COUNTRY, REGION, STORE, CUSTOM). A Tax Rule can have multiple versions live at once, one per scope bucket. Use this list only if you need to resolve the applicable version at your own point-of-sale instant (compare applicable_date against your own clock, per scope); for \"what applies right now\" use live_versions instead, which is already resolved for you.",
164 "items": {
165 "type": "object",
166 "additionalProperties": false,
167 "required": [
168 "_id",
169 "rule_id",
170 "status",
171 "components"
172 ],
173 "properties": {
174 "_id": {
175 "type": "string",
176 "description": "MongoDB identifier of the Tax Rule Version"
177 },
178 "rule_id": {
179 "type": "string",
180 "description": "Identifier of the parent Tax Rule"
181 },
182 "company_id": {
183 "type": "integer",
184 "description": "Company associated with the Tax Rule Version, when present"
185 },
186 "status": {
187 "type": "string",
188 "enum": [
189 "ACTIVE",
190 "INACTIVE",
191 "DELETED"
192 ],
193 "description": "Persisted status of the Tax Rule Version"
194 },
195 "version_status": {
196 "type": "string",
197 "enum": [
198 "LIVE",
199 "FUTURE",
200 "PAST"
201 ],
202 "description": "Derived lifecycle status relative to the applicable date, when present"
203 },
204 "applicable_date": {
205 "type": [
206 "string",
207 "null"
208 ],
209 "format": "date-time",
210 "description": "Date and time from which this version can be applied"
211 },
212 "scope": {
213 "type": "string",
214 "enum": [
215 "COUNTRY",
216 "REGION",
217 "STORE",
218 "CUSTOM"
219 ],
220 "description": "Tax applicability scope for this version"
221 },
222 "region_code": {
223 "type": "string",
224 "x-not-enum": true,
225 "description": "Configured region identifier for a region-scoped version"
226 },
227 "store_ids": {
228 "type": "array",
229 "description": "Store identifiers for a store-scoped version",
230 "items": {
231 "type": "integer"
232 }
233 },
234 "custom_conditions": {
235 "type": "object",
236 "additionalProperties": false,
237 "properties": {},
238 "x-tax-rule-reject-unknown": true,
239 "description": "Reserved for a supported custom-condition grammar. Current Tax Rule write APIs support COUNTRY, REGION and STORE scopes; no owned CUSTOM condition grammar exists. Only an empty object is supported here. A persisted nonempty condition blocks publication and retains retry intent. Conditions must never be dropped or silently converted to {}."
240 },
241 "region": {
242 "type": [
243 "object",
244 "null"
245 ],
246 "additionalProperties": false,
247 "properties": {
248 "name": {
249 "type": [
250 "string",
251 "null"
252 ],
253 "description": "Display name of the configured region"
254 },
255 "slug": {
256 "type": [
257 "string",
258 "null"
259 ],
260 "description": "Slug of the configured region"
261 },
262 "areas": {
263 "type": [
264 "array",
265 "null"
266 ],
267 "description": "Area identifiers or area details belonging to the region",
268 "items": {
269 "anyOf": [
270 {
271 "type": "string"
272 },
273 {
274 "type": "object",
275 "additionalProperties": false,
276 "properties": {
277 "country": {
278 "description": "Country identifier or resolved public country details",
279 "anyOf": [
280 {
281 "type": "string"
282 },
283 {
284 "type": "object",
285 "additionalProperties": false,
286 "properties": {
287 "uid": {
288 "type": "string"
289 },
290 "display_name": {
291 "type": [
292 "string",
293 "null"
294 ]
295 },
296 "iso2": {
297 "type": [
298 "string",
299 "null"
300 ]
301 },
302 "iso3": {
303 "type": [
304 "string",
305 "null"
306 ]
307 }
308 }
309 }
310 ]
311 },
312 "regions": {
313 "type": "array",
314 "items": {
315 "anyOf": [
316 {
317 "type": "string"
318 },
319 {
320 "type": "object",
321 "additionalProperties": false,
322 "properties": {
323 "uid": {
324 "type": "string"
325 },
326 "display_name": {
327 "type": [
328 "string",
329 "null"
330 ]
331 },
332 "sub_type": {
333 "type": "string",
334 "x-not-enum": true
335 },
336 "parent_id": {
337 "type": "array",
338 "items": {
339 "type": "string"
340 }
341 }
342 }
343 }
344 ]
345 }
346 }
347 }
348 }
349 ]
350 }
351 }
352 }
353 },
354 "stores": {
355 "type": "array",
356 "description": "Present when scope is STORE and each store_id could be resolved. Omitted (not an empty array) if resolution failed or found no match -- store_ids remains the source of truth either way.",
357 "items": {
358 "type": "object",
359 "additionalProperties": false,
360 "properties": {
361 "id": {
362 "type": "integer",
363 "description": "Store identifier, matching an entry in the parent's store_ids"
364 },
365 "name": {
366 "type": [
367 "string",
368 "null"
369 ],
370 "description": "Store name"
371 },
372 "display_name": {
373 "type": [
374 "string",
375 "null"
376 ],
377 "description": "Store display name"
378 },
379 "address": {
380 "type": [
381 "object",
382 "null"
383 ],
384 "additionalProperties": false,
385 "description": "Public store address fields from the owned location model. Arbitrary address_meta, actor identity and internal store configuration are not part of the Tax Rule webhook contract.",
386 "properties": {
387 "address_type": {
388 "type": [
389 "string",
390 "null"
391 ],
392 "x-not-enum": true
393 },
394 "address1": {
395 "type": [
396 "string",
397 "null"
398 ]
399 },
400 "address2": {
401 "type": [
402 "string",
403 "null"
404 ]
405 },
406 "country": {
407 "type": [
408 "string",
409 "null"
410 ]
411 },
412 "pincode": {
413 "type": [
414 "string",
415 "integer",
416 "null"
417 ]
418 },
419 "city": {
420 "type": [
421 "string",
422 "null"
423 ]
424 },
425 "state": {
426 "type": [
427 "string",
428 "null"
429 ]
430 },
431 "state_code": {
432 "type": [
433 "string",
434 "null"
435 ],
436 "x-not-enum": true
437 },
438 "sector": {
439 "type": [
440 "string",
441 "null"
442 ]
443 },
444 "latitude": {
445 "type": [
446 "number",
447 "null"
448 ]
449 },
450 "longitude": {
451 "type": [
452 "number",
453 "null"
454 ]
455 },
456 "landmark": {
457 "type": [
458 "string",
459 "null"
460 ]
461 },
462 "country_code": {
463 "type": [
464 "string",
465 "null"
466 ],
467 "x-not-enum": true
468 }
469 }
470 }
471 }
472 }
473 },
474 "components": {
475 "type": "array",
476 "description": "Tax components. GST and CESS are represented as separate components",
477 "items": {
478 "type": "object",
479 "additionalProperties": false,
480 "required": [
481 "_id",
482 "name",
483 "slabs"
484 ],
485 "properties": {
486 "_id": {
487 "type": "string",
488 "description": "Identifier of the tax component"
489 },
490 "name": {
491 "type": "string",
492 "description": "Component name, for example GST or CESS"
493 },
494 "description": {
495 "type": "string",
496 "description": "Tax component description"
497 },
498 "slabs": {
499 "type": "array",
500 "description": "Threshold slabs for this tax component",
501 "items": {
502 "type": "object",
503 "additionalProperties": false,
504 "required": [
505 "value",
506 "rate"
507 ],
508 "properties": {
509 "value": {
510 "type": "number",
511 "description": "Threshold value at which this slab applies"
512 },
513 "rate": {
514 "type": "number",
515 "description": "Tax rate represented as a decimal, for example 0.18 means 18 percent"
516 }
517 }
518 }
519 }
520 }
521 }
522 },
523 "created_on": {
524 "type": "string",
525 "format": "date-time",
526 "description": "Timestamp when the Tax Rule Version was created"
527 },
528 "modified_on": {
529 "type": "string",
530 "format": "date-time",
531 "description": "Timestamp when the Tax Rule Version was last modified"
532 }
533 }
534 }
535 },
536 "live_versions": {
537 "type": "array",
538 "description": "The resolved winner per scope bucket (COUNTRY/REGION/STORE/CUSTOM) as of snapshot_revision, so subscribers do not need to reimplement per-scope resolution or STORE-scope shadowing themselves. This is a point-in-time answer, refreshed on every Tax Rule mutation and at scheduled activation instants through Triggerhappy. Scheduler polling, queue capacity, and delivery affect actual arrival time. Failed publications or missed activations require an explicitly invoked replay; there is no automatic Tax Rule recovery cron. A consumer needing an answer at its own exact instant can resolve from versions instead.",
539 "items": {
540 "type": "object",
541 "additionalProperties": false,
542 "required": [
543 "scope",
544 "version_id"
545 ],
546 "description": "One resolved winner for one scope bucket. A COUNTRY entry is the company-wide default; a REGION/STORE/CUSTOM entry is an override that applies in addition to (not instead of) COUNTRY -- multiple entries can be present at once, one per independently-scheduled scope.",
547 "properties": {
548 "scope": {
549 "type": "string",
550 "enum": [
551 "COUNTRY",
552 "REGION",
553 "STORE",
554 "CUSTOM"
555 ],
556 "description": "Which scope bucket this resolved version applies to"
557 },
558 "version_id": {
559 "type": "string",
560 "description": "Identifier of the winning Tax Rule Version for this bucket, matching a versions[]._id"
561 },
562 "region_code": {
563 "type": "string",
564 "x-not-enum": true,
565 "description": "Present when scope is REGION"
566 },
567 "region": {
568 "type": [
569 "object",
570 "null"
571 ],
572 "additionalProperties": false,
573 "properties": {
574 "name": {
575 "type": [
576 "string",
577 "null"
578 ],
579 "description": "Display name of the configured region"
580 },
581 "slug": {
582 "type": [
583 "string",
584 "null"
585 ],
586 "description": "Slug of the configured region"
587 },
588 "areas": {
589 "type": [
590 "array",
591 "null"
592 ],
593 "description": "Area identifiers or area details belonging to the region",
594 "items": {
595 "anyOf": [
596 {
597 "type": "string"
598 },
599 {
600 "type": "object",
601 "additionalProperties": false,
602 "properties": {
603 "country": {
604 "description": "Country identifier or resolved public country details",
605 "anyOf": [
606 {
607 "type": "string"
608 },
609 {
610 "type": "object",
611 "additionalProperties": false,
612 "properties": {
613 "uid": {
614 "type": "string"
615 },
616 "display_name": {
617 "type": [
618 "string",
619 "null"
620 ]
621 },
622 "iso2": {
623 "type": [
624 "string",
625 "null"
626 ]
627 },
628 "iso3": {
629 "type": [
630 "string",
631 "null"
632 ]
633 }
634 }
635 }
636 ]
637 },
638 "regions": {
639 "type": "array",
640 "items": {
641 "anyOf": [
642 {
643 "type": "string"
644 },
645 {
646 "type": "object",
647 "additionalProperties": false,
648 "properties": {
649 "uid": {
650 "type": "string"
651 },
652 "display_name": {
653 "type": [
654 "string",
655 "null"
656 ]
657 },
658 "sub_type": {
659 "type": "string",
660 "x-not-enum": true
661 },
662 "parent_id": {
663 "type": "array",
664 "items": {
665 "type": "string"
666 }
667 }
668 }
669 }
670 ]
671 }
672 }
673 }
674 }
675 ]
676 }
677 }
678 }
679 },
680 "store_ids": {
681 "type": "array",
682 "description": "Present when scope is STORE",
683 "items": {
684 "type": "integer"
685 }
686 },
687 "stores": {
688 "type": "array",
689 "description": "Present when scope is STORE and each store_id could be resolved",
690 "items": {
691 "type": "object",
692 "additionalProperties": false,
693 "properties": {
694 "id": {
695 "type": "integer",
696 "description": "Store identifier, matching an entry in the parent's store_ids"
697 },
698 "name": {
699 "type": [
700 "string",
701 "null"
702 ],
703 "description": "Store name"
704 },
705 "display_name": {
706 "type": [
707 "string",
708 "null"
709 ],
710 "description": "Store display name"
711 },
712 "address": {
713 "type": [
714 "object",
715 "null"
716 ],
717 "additionalProperties": false,
718 "description": "Public store address fields from the owned location model. Arbitrary address_meta, actor identity and internal store configuration are not part of the Tax Rule webhook contract.",
719 "properties": {
720 "address_type": {
721 "type": [
722 "string",
723 "null"
724 ],
725 "x-not-enum": true
726 },
727 "address1": {
728 "type": [
729 "string",
730 "null"
731 ]
732 },
733 "address2": {
734 "type": [
735 "string",
736 "null"
737 ]
738 },
739 "country": {
740 "type": [
741 "string",
742 "null"
743 ]
744 },
745 "pincode": {
746 "type": [
747 "string",
748 "integer",
749 "null"
750 ]
751 },
752 "city": {
753 "type": [
754 "string",
755 "null"
756 ]
757 },
758 "state": {
759 "type": [
760 "string",
761 "null"
762 ]
763 },
764 "state_code": {
765 "type": [
766 "string",
767 "null"
768 ],
769 "x-not-enum": true
770 },
771 "sector": {
772 "type": [
773 "string",
774 "null"
775 ]
776 },
777 "latitude": {
778 "type": [
779 "number",
780 "null"
781 ]
782 },
783 "longitude": {
784 "type": [
785 "number",
786 "null"
787 ]
788 },
789 "landmark": {
790 "type": [
791 "string",
792 "null"
793 ]
794 },
795 "country_code": {
796 "type": [
797 "string",
798 "null"
799 ],
800 "x-not-enum": true
801 }
802 }
803 }
804 }
805 }
806 },
807 "custom_conditions": {
808 "type": "object",
809 "additionalProperties": false,
810 "properties": {},
811 "x-tax-rule-reject-unknown": true,
812 "description": "Reserved for a supported custom-condition grammar. Current Tax Rule write APIs support COUNTRY, REGION and STORE scopes; no owned CUSTOM condition grammar exists. Only an empty object is supported here. A persisted nonempty condition blocks publication and retains retry intent. Conditions must never be dropped or silently converted to {}."
813 }
814 }
815 }
816 },
817 "snapshot_updated_on": {
818 "type": [
819 "string",
820 "null"
821 ],
822 "format": "date-time",
823 "description": "Latest created or modified timestamp across the Tax Rule and all its versions"
824 },
825 "snapshot_revision": {
826 "type": "integer",
827 "description": "Strictly increasing revision of this aggregate. It advances on every change to the effective state, including a scheduled version becoming live purely through the passage of time. Apply a snapshot only when its revision is greater than or equal to the one already held, so redelivery and replay cannot regress state.\nDirect scheduling reserves an increasing revision range for each source generation: every activation increases within that range, and the next mutation exceeds all previously reserved future revisions. This fences a stale job whose cancellation failed. Changed region/store enrichment also advances the reserved generation, so an older scheduled or replayed descriptor cannot overwrite its correction. The existing greater-than-or-equal comparison remains valid for duplicate snapshots. Treat the revision as an opaque integer and compare it only against another snapshot_revision for the same Tax Rule -- do not read a timestamp back out of it, and do not compare it across rules. Values are always larger than those issued by the earlier plain epoch-millisecond encoding, so a consumer holding one of those keeps accepting new events."
828 },
829 "snapshot_hash": {
830 "type": "string",
831 "description": "Hash of the delivered aggregate. Equal hashes mean the state is unchanged, so the snapshot can be skipped. Use this for duplicate detection. A scheduler retry reuses the frozen event identity, while a fresh publication or recovery may assign a new identity. Sureshot can deliver both copies; subscriber deduplication uses this hash together with per-rule revision ordering."
832 }
833 }
834 }
835 }
836 }
837 }
838}
Payload Example
1{
2 "company_id": 61,
3 "contains": [
4 "tax_rule"
5 ],
6 "event": {
7 "created_timestamp": 1758457800000,
8 "event_id": "0f7d8c1a-3b52-4f9e-9c47-2a1e6b8d4f30",
9 "eventId": "0f7d8c1a-3b52-4f9e-9c47-2a1e6b8d4f30",
10 "name": "tax_rule",
11 "trace_id": [
12 "Silverbolt.example-trace-id"
13 ],
14 "type": "create",
15 "version": "1"
16 },
17 "payload": {
18 "tax_rule": {
19 "_id": "68cf7cda35f228ee1746d8a5",
20 "tax_rule_id": "68cf7cda35f228ee1746d8a5",
21 "company_id": 61,
22 "name": "Standard GST",
23 "description": "Standard goods tax rule",
24 "status": "ACTIVE",
25 "country_iso": "IN",
26 "is_default": false,
27 "versions": [
28 {
29 "_id": "68cf7cda35f228ee1746d8a6",
30 "rule_id": "68cf7cda35f228ee1746d8a5",
31 "company_id": 61,
32 "status": "ACTIVE",
33 "version_status": "LIVE",
34 "applicable_date": "2025-09-21T00:00:00+00:00",
35 "scope": "COUNTRY",
36 "components": [
37 {
38 "_id": "68cf7cda35f228ee1746d8a7",
39 "name": "GST",
40 "description": "Goods and Services Tax",
41 "slabs": [
42 {
43 "value": 0,
44 "rate": 0.18
45 }
46 ]
47 },
48 {
49 "_id": "68cf7cda35f228ee1746d8a8",
50 "name": "CESS",
51 "slabs": [
52 {
53 "value": 0,
54 "rate": 0
55 }
56 ]
57 }
58 ]
59 }
60 ],
61 "live_versions": [
62 {
63 "scope": "COUNTRY",
64 "version_id": "68cf7cda35f228ee1746d8a6"
65 }
66 ],
67 "snapshot_updated_on": "2025-09-21T00:00:00+00:00",
68 "snapshot_revision": 1758412800000,
69 "snapshot_hash": "example-snapshot-hash"
70 }
71 }
72}

Tax Rule/tax_rule/delete/v1

This event is triggered when a company Tax Rule is deleted

Payload
Hide
company_id
integer
Required
Company ID for which this event is triggered
contains
array of string
Required
Keys present at the root level of the payload object
event
object
Required
Show
payload
object
Required
Show
Payload Schema JSON
1{
2 "type": "object",
3 "required": [
4 "company_id",
5 "contains",
6 "event",
7 "payload"
8 ],
9 "properties": {
10 "company_id": {
11 "type": "integer",
12 "description": "Company ID for which this event is triggered"
13 },
14 "contains": {
15 "type": "array",
16 "description": "Keys present at the root level of the payload object",
17 "items": {
18 "type": "string"
19 }
20 },
21 "event": {
22 "type": "object",
23 "required": [
24 "created_timestamp",
25 "event_id",
26 "eventId",
27 "name",
28 "trace_id",
29 "type",
30 "version"
31 ],
32 "properties": {
33 "category": {
34 "type": "string",
35 "description": "Optional event category. Company Tax Rule events belong to the company category"
36 },
37 "created_timestamp": {
38 "type": "integer",
39 "description": "Event generation timestamp in epoch milliseconds"
40 },
41 "id": {
42 "type": "string",
43 "description": "Legacy event identifier, when supplied by the webhook infrastructure"
44 },
45 "event_id": {
46 "type": "string",
47 "format": "uuid",
48 "description": "Unique identifier for this emission. A redelivery of unchanged state is a distinct event with a distinct event_id, so use payload.tax_rule.snapshot_hash for duplicate detection."
49 },
50 "eventId": {
51 "type": "string",
52 "format": "uuid",
53 "description": "Canonical camelCase form of event_id"
54 },
55 "name": {
56 "type": "string",
57 "enum": [
58 "tax_rule"
59 ],
60 "description": "Name of the event"
61 },
62 "trace_id": {
63 "type": "array",
64 "description": "Internal trace identifiers for Fynd Platform services",
65 "items": {
66 "type": "string"
67 }
68 },
69 "type": {
70 "type": "string",
71 "enum": [
72 "create",
73 "update",
74 "delete"
75 ],
76 "description": "Tax Rule action that triggered the event"
77 },
78 "version": {
79 "type": "string",
80 "enum": [
81 "1"
82 ],
83 "description": "Version of the event contract"
84 }
85 }
86 },
87 "payload": {
88 "type": "object",
89 "additionalProperties": false,
90 "required": [
91 "tax_rule"
92 ],
93 "properties": {
94 "tax_rule": {
95 "type": "object",
96 "additionalProperties": false,
97 "required": [
98 "tax_rule_id",
99 "company_id",
100 "status",
101 "versions",
102 "live_versions",
103 "snapshot_hash",
104 "snapshot_revision"
105 ],
106 "properties": {
107 "_id": {
108 "type": "string",
109 "description": "MongoDB identifier of the Tax Rule"
110 },
111 "tax_rule_id": {
112 "type": "string",
113 "description": "Canonical identifier of the company Tax Rule referenced by products"
114 },
115 "company_id": {
116 "type": "integer",
117 "description": "Company that owns the Tax Rule"
118 },
119 "name": {
120 "type": "string",
121 "description": "Tax Rule name"
122 },
123 "description": {
124 "type": "string",
125 "description": "Tax Rule description"
126 },
127 "is_default": {
128 "type": "boolean",
129 "description": "Whether this is the company's default Tax Rule"
130 },
131 "status": {
132 "type": "string",
133 "enum": [
134 "ACTIVE",
135 "INACTIVE",
136 "DELETED"
137 ],
138 "description": "Current status of the Tax Rule"
139 },
140 "country_iso": {
141 "type": "string",
142 "description": "ISO country code associated with the Tax Rule, when present"
143 },
144 "admin_tax_rule": {
145 "type": [
146 "string",
147 "null"
148 ],
149 "description": "Identifier of the source admin Tax Rule, when this is a company copy"
150 },
151 "created_on": {
152 "type": "string",
153 "format": "date-time",
154 "description": "Timestamp when the Tax Rule was created"
155 },
156 "modified_on": {
157 "type": "string",
158 "format": "date-time",
159 "description": "Timestamp when the Tax Rule was last modified"
160 },
161 "versions": {
162 "type": "array",
163 "description": "Every persisted Tax Rule Version, across every scope (COUNTRY, REGION, STORE, CUSTOM). A Tax Rule can have multiple versions live at once, one per scope bucket. Use this list only if you need to resolve the applicable version at your own point-of-sale instant (compare applicable_date against your own clock, per scope); for \"what applies right now\" use live_versions instead, which is already resolved for you.",
164 "items": {
165 "type": "object",
166 "additionalProperties": false,
167 "required": [
168 "_id",
169 "rule_id",
170 "status",
171 "components"
172 ],
173 "properties": {
174 "_id": {
175 "type": "string",
176 "description": "MongoDB identifier of the Tax Rule Version"
177 },
178 "rule_id": {
179 "type": "string",
180 "description": "Identifier of the parent Tax Rule"
181 },
182 "company_id": {
183 "type": "integer",
184 "description": "Company associated with the Tax Rule Version, when present"
185 },
186 "status": {
187 "type": "string",
188 "enum": [
189 "ACTIVE",
190 "INACTIVE",
191 "DELETED"
192 ],
193 "description": "Persisted status of the Tax Rule Version"
194 },
195 "version_status": {
196 "type": "string",
197 "enum": [
198 "LIVE",
199 "FUTURE",
200 "PAST"
201 ],
202 "description": "Derived lifecycle status relative to the applicable date, when present"
203 },
204 "applicable_date": {
205 "type": [
206 "string",
207 "null"
208 ],
209 "format": "date-time",
210 "description": "Date and time from which this version can be applied"
211 },
212 "scope": {
213 "type": "string",
214 "enum": [
215 "COUNTRY",
216 "REGION",
217 "STORE",
218 "CUSTOM"
219 ],
220 "description": "Tax applicability scope for this version"
221 },
222 "region_code": {
223 "type": "string",
224 "x-not-enum": true,
225 "description": "Configured region identifier for a region-scoped version"
226 },
227 "store_ids": {
228 "type": "array",
229 "description": "Store identifiers for a store-scoped version",
230 "items": {
231 "type": "integer"
232 }
233 },
234 "custom_conditions": {
235 "type": "object",
236 "additionalProperties": false,
237 "properties": {},
238 "x-tax-rule-reject-unknown": true,
239 "description": "Reserved for a supported custom-condition grammar. Current Tax Rule write APIs support COUNTRY, REGION and STORE scopes; no owned CUSTOM condition grammar exists. Only an empty object is supported here. A persisted nonempty condition blocks publication and retains retry intent. Conditions must never be dropped or silently converted to {}."
240 },
241 "region": {
242 "type": [
243 "object",
244 "null"
245 ],
246 "additionalProperties": false,
247 "properties": {
248 "name": {
249 "type": [
250 "string",
251 "null"
252 ],
253 "description": "Display name of the configured region"
254 },
255 "slug": {
256 "type": [
257 "string",
258 "null"
259 ],
260 "description": "Slug of the configured region"
261 },
262 "areas": {
263 "type": [
264 "array",
265 "null"
266 ],
267 "description": "Area identifiers or area details belonging to the region",
268 "items": {
269 "anyOf": [
270 {
271 "type": "string"
272 },
273 {
274 "type": "object",
275 "additionalProperties": false,
276 "properties": {
277 "country": {
278 "description": "Country identifier or resolved public country details",
279 "anyOf": [
280 {
281 "type": "string"
282 },
283 {
284 "type": "object",
285 "additionalProperties": false,
286 "properties": {
287 "uid": {
288 "type": "string"
289 },
290 "display_name": {
291 "type": [
292 "string",
293 "null"
294 ]
295 },
296 "iso2": {
297 "type": [
298 "string",
299 "null"
300 ]
301 },
302 "iso3": {
303 "type": [
304 "string",
305 "null"
306 ]
307 }
308 }
309 }
310 ]
311 },
312 "regions": {
313 "type": "array",
314 "items": {
315 "anyOf": [
316 {
317 "type": "string"
318 },
319 {
320 "type": "object",
321 "additionalProperties": false,
322 "properties": {
323 "uid": {
324 "type": "string"
325 },
326 "display_name": {
327 "type": [
328 "string",
329 "null"
330 ]
331 },
332 "sub_type": {
333 "type": "string",
334 "x-not-enum": true
335 },
336 "parent_id": {
337 "type": "array",
338 "items": {
339 "type": "string"
340 }
341 }
342 }
343 }
344 ]
345 }
346 }
347 }
348 }
349 ]
350 }
351 }
352 }
353 },
354 "stores": {
355 "type": "array",
356 "description": "Present when scope is STORE and each store_id could be resolved. Omitted (not an empty array) if resolution failed or found no match -- store_ids remains the source of truth either way.",
357 "items": {
358 "type": "object",
359 "additionalProperties": false,
360 "properties": {
361 "id": {
362 "type": "integer",
363 "description": "Store identifier, matching an entry in the parent's store_ids"
364 },
365 "name": {
366 "type": [
367 "string",
368 "null"
369 ],
370 "description": "Store name"
371 },
372 "display_name": {
373 "type": [
374 "string",
375 "null"
376 ],
377 "description": "Store display name"
378 },
379 "address": {
380 "type": [
381 "object",
382 "null"
383 ],
384 "additionalProperties": false,
385 "description": "Public store address fields from the owned location model. Arbitrary address_meta, actor identity and internal store configuration are not part of the Tax Rule webhook contract.",
386 "properties": {
387 "address_type": {
388 "type": [
389 "string",
390 "null"
391 ],
392 "x-not-enum": true
393 },
394 "address1": {
395 "type": [
396 "string",
397 "null"
398 ]
399 },
400 "address2": {
401 "type": [
402 "string",
403 "null"
404 ]
405 },
406 "country": {
407 "type": [
408 "string",
409 "null"
410 ]
411 },
412 "pincode": {
413 "type": [
414 "string",
415 "integer",
416 "null"
417 ]
418 },
419 "city": {
420 "type": [
421 "string",
422 "null"
423 ]
424 },
425 "state": {
426 "type": [
427 "string",
428 "null"
429 ]
430 },
431 "state_code": {
432 "type": [
433 "string",
434 "null"
435 ],
436 "x-not-enum": true
437 },
438 "sector": {
439 "type": [
440 "string",
441 "null"
442 ]
443 },
444 "latitude": {
445 "type": [
446 "number",
447 "null"
448 ]
449 },
450 "longitude": {
451 "type": [
452 "number",
453 "null"
454 ]
455 },
456 "landmark": {
457 "type": [
458 "string",
459 "null"
460 ]
461 },
462 "country_code": {
463 "type": [
464 "string",
465 "null"
466 ],
467 "x-not-enum": true
468 }
469 }
470 }
471 }
472 }
473 },
474 "components": {
475 "type": "array",
476 "description": "Tax components. GST and CESS are represented as separate components",
477 "items": {
478 "type": "object",
479 "additionalProperties": false,
480 "required": [
481 "_id",
482 "name",
483 "slabs"
484 ],
485 "properties": {
486 "_id": {
487 "type": "string",
488 "description": "Identifier of the tax component"
489 },
490 "name": {
491 "type": "string",
492 "description": "Component name, for example GST or CESS"
493 },
494 "description": {
495 "type": "string",
496 "description": "Tax component description"
497 },
498 "slabs": {
499 "type": "array",
500 "description": "Threshold slabs for this tax component",
501 "items": {
502 "type": "object",
503 "additionalProperties": false,
504 "required": [
505 "value",
506 "rate"
507 ],
508 "properties": {
509 "value": {
510 "type": "number",
511 "description": "Threshold value at which this slab applies"
512 },
513 "rate": {
514 "type": "number",
515 "description": "Tax rate represented as a decimal, for example 0.18 means 18 percent"
516 }
517 }
518 }
519 }
520 }
521 }
522 },
523 "created_on": {
524 "type": "string",
525 "format": "date-time",
526 "description": "Timestamp when the Tax Rule Version was created"
527 },
528 "modified_on": {
529 "type": "string",
530 "format": "date-time",
531 "description": "Timestamp when the Tax Rule Version was last modified"
532 }
533 }
534 }
535 },
536 "live_versions": {
537 "type": "array",
538 "description": "The resolved winner per scope bucket (COUNTRY/REGION/STORE/CUSTOM) as of snapshot_revision, so subscribers do not need to reimplement per-scope resolution or STORE-scope shadowing themselves. This is a point-in-time answer, refreshed on every Tax Rule mutation and at scheduled activation instants through Triggerhappy. Scheduler polling, queue capacity, and delivery affect actual arrival time. Failed publications or missed activations require an explicitly invoked replay; there is no automatic Tax Rule recovery cron. A consumer needing an answer at its own exact instant can resolve from versions instead.",
539 "items": {
540 "type": "object",
541 "additionalProperties": false,
542 "required": [
543 "scope",
544 "version_id"
545 ],
546 "description": "One resolved winner for one scope bucket. A COUNTRY entry is the company-wide default; a REGION/STORE/CUSTOM entry is an override that applies in addition to (not instead of) COUNTRY -- multiple entries can be present at once, one per independently-scheduled scope.",
547 "properties": {
548 "scope": {
549 "type": "string",
550 "enum": [
551 "COUNTRY",
552 "REGION",
553 "STORE",
554 "CUSTOM"
555 ],
556 "description": "Which scope bucket this resolved version applies to"
557 },
558 "version_id": {
559 "type": "string",
560 "description": "Identifier of the winning Tax Rule Version for this bucket, matching a versions[]._id"
561 },
562 "region_code": {
563 "type": "string",
564 "x-not-enum": true,
565 "description": "Present when scope is REGION"
566 },
567 "region": {
568 "type": [
569 "object",
570 "null"
571 ],
572 "additionalProperties": false,
573 "properties": {
574 "name": {
575 "type": [
576 "string",
577 "null"
578 ],
579 "description": "Display name of the configured region"
580 },
581 "slug": {
582 "type": [
583 "string",
584 "null"
585 ],
586 "description": "Slug of the configured region"
587 },
588 "areas": {
589 "type": [
590 "array",
591 "null"
592 ],
593 "description": "Area identifiers or area details belonging to the region",
594 "items": {
595 "anyOf": [
596 {
597 "type": "string"
598 },
599 {
600 "type": "object",
601 "additionalProperties": false,
602 "properties": {
603 "country": {
604 "description": "Country identifier or resolved public country details",
605 "anyOf": [
606 {
607 "type": "string"
608 },
609 {
610 "type": "object",
611 "additionalProperties": false,
612 "properties": {
613 "uid": {
614 "type": "string"
615 },
616 "display_name": {
617 "type": [
618 "string",
619 "null"
620 ]
621 },
622 "iso2": {
623 "type": [
624 "string",
625 "null"
626 ]
627 },
628 "iso3": {
629 "type": [
630 "string",
631 "null"
632 ]
633 }
634 }
635 }
636 ]
637 },
638 "regions": {
639 "type": "array",
640 "items": {
641 "anyOf": [
642 {
643 "type": "string"
644 },
645 {
646 "type": "object",
647 "additionalProperties": false,
648 "properties": {
649 "uid": {
650 "type": "string"
651 },
652 "display_name": {
653 "type": [
654 "string",
655 "null"
656 ]
657 },
658 "sub_type": {
659 "type": "string",
660 "x-not-enum": true
661 },
662 "parent_id": {
663 "type": "array",
664 "items": {
665 "type": "string"
666 }
667 }
668 }
669 }
670 ]
671 }
672 }
673 }
674 }
675 ]
676 }
677 }
678 }
679 },
680 "store_ids": {
681 "type": "array",
682 "description": "Present when scope is STORE",
683 "items": {
684 "type": "integer"
685 }
686 },
687 "stores": {
688 "type": "array",
689 "description": "Present when scope is STORE and each store_id could be resolved",
690 "items": {
691 "type": "object",
692 "additionalProperties": false,
693 "properties": {
694 "id": {
695 "type": "integer",
696 "description": "Store identifier, matching an entry in the parent's store_ids"
697 },
698 "name": {
699 "type": [
700 "string",
701 "null"
702 ],
703 "description": "Store name"
704 },
705 "display_name": {
706 "type": [
707 "string",
708 "null"
709 ],
710 "description": "Store display name"
711 },
712 "address": {
713 "type": [
714 "object",
715 "null"
716 ],
717 "additionalProperties": false,
718 "description": "Public store address fields from the owned location model. Arbitrary address_meta, actor identity and internal store configuration are not part of the Tax Rule webhook contract.",
719 "properties": {
720 "address_type": {
721 "type": [
722 "string",
723 "null"
724 ],
725 "x-not-enum": true
726 },
727 "address1": {
728 "type": [
729 "string",
730 "null"
731 ]
732 },
733 "address2": {
734 "type": [
735 "string",
736 "null"
737 ]
738 },
739 "country": {
740 "type": [
741 "string",
742 "null"
743 ]
744 },
745 "pincode": {
746 "type": [
747 "string",
748 "integer",
749 "null"
750 ]
751 },
752 "city": {
753 "type": [
754 "string",
755 "null"
756 ]
757 },
758 "state": {
759 "type": [
760 "string",
761 "null"
762 ]
763 },
764 "state_code": {
765 "type": [
766 "string",
767 "null"
768 ],
769 "x-not-enum": true
770 },
771 "sector": {
772 "type": [
773 "string",
774 "null"
775 ]
776 },
777 "latitude": {
778 "type": [
779 "number",
780 "null"
781 ]
782 },
783 "longitude": {
784 "type": [
785 "number",
786 "null"
787 ]
788 },
789 "landmark": {
790 "type": [
791 "string",
792 "null"
793 ]
794 },
795 "country_code": {
796 "type": [
797 "string",
798 "null"
799 ],
800 "x-not-enum": true
801 }
802 }
803 }
804 }
805 }
806 },
807 "custom_conditions": {
808 "type": "object",
809 "additionalProperties": false,
810 "properties": {},
811 "x-tax-rule-reject-unknown": true,
812 "description": "Reserved for a supported custom-condition grammar. Current Tax Rule write APIs support COUNTRY, REGION and STORE scopes; no owned CUSTOM condition grammar exists. Only an empty object is supported here. A persisted nonempty condition blocks publication and retains retry intent. Conditions must never be dropped or silently converted to {}."
813 }
814 }
815 }
816 },
817 "snapshot_updated_on": {
818 "type": [
819 "string",
820 "null"
821 ],
822 "format": "date-time",
823 "description": "Latest created or modified timestamp across the Tax Rule and all its versions"
824 },
825 "snapshot_revision": {
826 "type": "integer",
827 "description": "Strictly increasing revision of this aggregate. It advances on every change to the effective state, including a scheduled version becoming live purely through the passage of time. Apply a snapshot only when its revision is greater than or equal to the one already held, so redelivery and replay cannot regress state.\nDirect scheduling reserves an increasing revision range for each source generation: every activation increases within that range, and the next mutation exceeds all previously reserved future revisions. This fences a stale job whose cancellation failed. Changed region/store enrichment also advances the reserved generation, so an older scheduled or replayed descriptor cannot overwrite its correction. The existing greater-than-or-equal comparison remains valid for duplicate snapshots. Treat the revision as an opaque integer and compare it only against another snapshot_revision for the same Tax Rule -- do not read a timestamp back out of it, and do not compare it across rules. Values are always larger than those issued by the earlier plain epoch-millisecond encoding, so a consumer holding one of those keeps accepting new events."
828 },
829 "snapshot_hash": {
830 "type": "string",
831 "description": "Hash of the delivered aggregate. Equal hashes mean the state is unchanged, so the snapshot can be skipped. Use this for duplicate detection. A scheduler retry reuses the frozen event identity, while a fresh publication or recovery may assign a new identity. Sureshot can deliver both copies; subscriber deduplication uses this hash together with per-rule revision ordering."
832 }
833 }
834 }
835 }
836 }
837 }
838}
Payload Example
1{
2 "company_id": 61,
3 "contains": [
4 "tax_rule"
5 ],
6 "event": {
7 "created_timestamp": 1758457800000,
8 "event_id": "0f7d8c1a-3b52-4f9e-9c47-2a1e6b8d4f30",
9 "eventId": "0f7d8c1a-3b52-4f9e-9c47-2a1e6b8d4f30",
10 "name": "tax_rule",
11 "trace_id": [
12 "Silverbolt.example-trace-id"
13 ],
14 "type": "create",
15 "version": "1"
16 },
17 "payload": {
18 "tax_rule": {
19 "_id": "68cf7cda35f228ee1746d8a5",
20 "tax_rule_id": "68cf7cda35f228ee1746d8a5",
21 "company_id": 61,
22 "name": "Standard GST",
23 "description": "Standard goods tax rule",
24 "status": "ACTIVE",
25 "country_iso": "IN",
26 "is_default": false,
27 "versions": [
28 {
29 "_id": "68cf7cda35f228ee1746d8a6",
30 "rule_id": "68cf7cda35f228ee1746d8a5",
31 "company_id": 61,
32 "status": "ACTIVE",
33 "version_status": "LIVE",
34 "applicable_date": "2025-09-21T00:00:00+00:00",
35 "scope": "COUNTRY",
36 "components": [
37 {
38 "_id": "68cf7cda35f228ee1746d8a7",
39 "name": "GST",
40 "description": "Goods and Services Tax",
41 "slabs": [
42 {
43 "value": 0,
44 "rate": 0.18
45 }
46 ]
47 },
48 {
49 "_id": "68cf7cda35f228ee1746d8a8",
50 "name": "CESS",
51 "slabs": [
52 {
53 "value": 0,
54 "rate": 0
55 }
56 ]
57 }
58 ]
59 }
60 ],
61 "live_versions": [
62 {
63 "scope": "COUNTRY",
64 "version_id": "68cf7cda35f228ee1746d8a6"
65 }
66 ],
67 "snapshot_updated_on": "2025-09-21T00:00:00+00:00",
68 "snapshot_revision": 1758412800000,
69 "snapshot_hash": "example-snapshot-hash"
70 }
71 }
72}