CouponsCouponCreatedPayload coupons.coupon.created@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.created.v1.json
coupons.coupon.created v1 (OpenVibe.Coupons server/domain/coupons.js submit and importFromSource, payload from lifecyclePayload). A new code was recorded, in the transaction that inserted it: submitted by a member, by staff or by an AI extraction run (POST /api/v1/coupons/submit or the site form), or imported from an OpenVibe.Sources item (origin source). Submitting a code the merchant already has adds evidence and emits no created event. A new code always starts with status unknown and confidence null: a submission can never carry a status or a confidence. AI-extracted codes, imported codes (unless COUPONS_SOURCES_AUTO_PUBLISH is true and the merchant is active) and codes for a pending merchant start with review_state pending. Left out on purpose: the code text, title, description and restrictions (Search gets them from coupons.index_document.*) and who submitted it (submitters stay inside Coupons). Envelope: subject { type: coupon, id: cpn_… }, visibility public when the new code is publicly listed (published, merchant active, not expired), 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 | Every new code starts unknown; only people's reports can move it to reported_working or reported_failed. |
|
confidence | null | yes | Always null at creation: no counted report yet. | |
review_state | enum | yes | pending = waits for staff review (AI-extracted, imported without auto-publish, or merchant pending); published = eligible for active results. |
|
expires_at | string | null | yes | Known expiry (UTC; a date-only expiry is 23:59:59.999Z of that day). null = expiry unknown, never defaulted. |
|
canonical_url | string | yes | The code's page on Coupons (<origin>/c/<coupon id>). |
|
origin | enum | yes | How the code arrived: a member's or a staff member's submission, an OpenVibe.Sources import, or an AI extraction run (X-OV-Origin: ai). |
|
Examples
From the contract's own test fixtures: valid ones validate, rejected ones must fail.
Valid: ai-pending-dated
{
"merchant_id": "mer_01K5R7A1B2C3D4E5F6G7H8J9KM",
"status": "unknown",
"confidence": null,
"review_state": "pending",
"expires_at": "2026-10-31T23:59:59.999Z",
"canonical_url": "https://openvibe.coupons/c/cpn_01K5R9B2C3D4E5F6G7H8J9K0MN",
"origin": "ai"
}Valid: member-published
{
"merchant_id": "mer_01K5R7A1B2C3D4E5F6G7H8J9KM",
"status": "unknown",
"confidence": null,
"review_state": "published",
"expires_at": null,
"canonical_url": "https://openvibe.coupons/c/cpn_01K5R8Z3Q4M2N7P9T1V6W8X0YA",
"origin": "member"
}Rejected: missing-origin
{
"merchant_id": "mer_01K5R7A1B2C3D4E5F6G7H8J9KM",
"status": "unknown",
"confidence": null,
"review_state": "published",
"expires_at": null,
"canonical_url": "https://openvibe.coupons/c/cpn_01K5R8Z3Q4M2N7P9T1V6W8X0YA"
}Rejected: names-submitter
{
"merchant_id": "mer_01K5R7A1B2C3D4E5F6G7H8J9KM",
"status": "unknown",
"confidence": null,
"review_state": "published",
"expires_at": null,
"canonical_url": "https://openvibe.coupons/c/cpn_01K5R8Z3Q4M2N7P9T1V6W8X0YA",
"origin": "member",
"created_by": "usr_01K5R5E4F3G2H1J0K9M8N7P6QR"
}Rejected: with-confidence
{
"merchant_id": "mer_01K5R7A1B2C3D4E5F6G7H8J9KM",
"status": "reported_working",
"confidence": 0.99,
"review_state": "published",
"expires_at": null,
"canonical_url": "https://openvibe.coupons/c/cpn_01K5R8Z3Q4M2N7P9T1V6W8X0YA",
"origin": "member"
}Validate
const contracts = require('openvibe-contracts');
contracts.validate('coupons.coupon.created@1', value); // { valid, errors: [{ path, message }] }