CouponsCouponExpiredPayload coupons.coupon.expired@1
Generated at from
openvibe-contracts v0.34.2 and
openvibe-sdk v0.5.0.
- Version
- 1.0.0
- Owner
- coupons
- Visibility
- first-party
- Status
- active
- Compatibility
- backward
- Schema
https://openvibe.network/contracts/events/payloads/coupons.coupon.expired.v1.json
coupons.coupon.expired v1 (OpenVibe.Coupons server/domain/coupons.js recompute, payload from lifecyclePayload). A code's status became expired, in the transaction that recorded it: the sweep (server/worker.js, every COUPONS_SWEEP_INTERVAL_MS) saw its known expiry pass (reason expiry), a recompute for other work found it past its expiry first (evidence, report or decay), or staff or a service marked it expired (staff, service:<client>[:<note>]). Active lists do not wait for this event: they filter on expires_at at query time. When the code was in Search, a coupons.index_document.deleted tombstone and the merchant's updated document follow in the same transaction. Envelope: subject { type: coupon, id: cpn_… }, visibility public when the code was publicly listed before the change, otherwise internal, priority important (not set: the Events default), actor service:coupons. No known consumers.
Fields
| Field | Type | Required | Description | Constraints |
|---|---|---|---|---|
merchant_id | string | yes | The merchant the code belongs to. |
|
status | const | yes |
| |
confidence | number | null | yes | Report confidence at the time (rounded to 2 decimals); null = no counted report in the last 30 days. |
|
review_state | enum | yes |
| |
expires_at | string | null | yes | The known expiry that passed; null when staff or a service marked a code of unknown expiry expired. |
|
canonical_url | string | yes | The code's page on Coupons (<origin>/c/<coupon id>); it stays up, noindex. |
|
previous_status | enum | yes | Status before; a disabled code has to be re-enabled before it can be marked expired. |
|
reason | one of | yes | expiry, evidence, report, decay, staff, or service:<client>[:<note>]. |
Examples
From the contract's own test fixtures: valid ones validate, rejected ones must fail.
Valid: staff-marked
{
"merchant_id": "mer_01K5R7A1B2C3D4E5F6G7H8J9KM",
"status": "expired",
"confidence": 0.71,
"review_state": "published",
"expires_at": null,
"canonical_url": "https://openvibe.coupons/c/cpn_01K5R8Z3Q4M2N7P9T1V6W8X0YA",
"previous_status": "reported_working",
"reason": "staff"
}Valid: sweep
{
"merchant_id": "mer_01K5R7A1B2C3D4E5F6G7H8J9KM",
"status": "expired",
"confidence": null,
"review_state": "published",
"expires_at": "2026-09-22T23:59:59.999Z",
"canonical_url": "https://openvibe.coupons/c/cpn_01K5R8Z3Q4M2N7P9T1V6W8X0YA",
"previous_status": "unknown",
"reason": "expiry"
}Rejected: from-disabled
{
"merchant_id": "mer_01K5R7A1B2C3D4E5F6G7H8J9KM",
"status": "expired",
"confidence": null,
"review_state": "published",
"expires_at": "2026-09-22T23:59:59.999Z",
"canonical_url": "https://openvibe.coupons/c/cpn_01K5R8Z3Q4M2N7P9T1V6W8X0YA",
"previous_status": "disabled",
"reason": "expiry"
}Rejected: missing-previous-status
{
"merchant_id": "mer_01K5R7A1B2C3D4E5F6G7H8J9KM",
"status": "expired",
"confidence": null,
"review_state": "published",
"expires_at": "2026-09-22T23:59:59.999Z",
"canonical_url": "https://openvibe.coupons/c/cpn_01K5R8Z3Q4M2N7P9T1V6W8X0YA",
"reason": "expiry"
}Rejected: wrong-status
{
"merchant_id": "mer_01K5R7A1B2C3D4E5F6G7H8J9KM",
"status": "disabled",
"confidence": null,
"review_state": "published",
"expires_at": "2026-09-22T23:59:59.999Z",
"canonical_url": "https://openvibe.coupons/c/cpn_01K5R8Z3Q4M2N7P9T1V6W8X0YA",
"previous_status": "unknown",
"reason": "expiry"
}Validate
const contracts = require('openvibe-contracts');
contracts.validate('coupons.coupon.expired@1', value); // { valid, errors: [{ path, message }] }