diff --git a/.gitignore b/.gitignore index e43b0f9..ba0d7d0 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .DS_Store +.cursor/* diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 4af227f..0000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,3 +0,0 @@ -# Contributing to the specification - -TBD diff --git a/GOVERNANCE.md b/GOVERNANCE.md new file mode 100644 index 0000000..1633f2d --- /dev/null +++ b/GOVERNANCE.md @@ -0,0 +1,359 @@ +# Beckn Protocol Governance Model (2.x) + +**Status:** Draft +**Applies to:** Beckn Protocol (Core), Domain Specifications, and Open Networks built using Beckn + +--- + +## 0. Notice + +This document is part of the **Governance Model of the Beckn Protocol** and is the **highest-precedence governance artifact** for specification evolution and interpretation. + +All other documents (e.g., attribution guidelines, contribution guidelines, style guide, domain charters, network publishing guides, implementation guides) are **derived artifacts**. + +When any derived artifact conflicts with this document, **this document prevails**. + +## 1. Purpose and non-goals + +### 1.1 Purpose + +Establish a governance framework that is: + +- **Lightweight:** minimal roles and minimal ceremony. +- **Airtight:** unambiguous precedence, decision rules, compatibility rules, and dispute handling. +- **Composable:** explicitly supports the reality of **Core → Domain → Network** evolution without breaking interoperability. + +### 1.2 Non-goals + +This governance model does not aim to: + +- create membership structures, gatekeeping, or bureaucracy; +- force every network to move at the pace of core/domain; + +## 2. The Beckn credo (constitutional intent) + +Beckn is an open protocol designed to create an interoperable value exchange layer on the internet across diverse actors and ecosystems—globally, across domains, and across regions—while preserving agency, choice, and competition. + +Governance exists to protect: +- interoperability, +- user and participant safety (security, privacy, consent), +- predictable evolution, +- and the long-term coherence of the protocol. + +## 3. Constitutional principles + +These principles are the primary basis for approving changes, resolving ambiguity, and interpreting disputes. + +### 3.1 Interoperability-first + +Any change that reduces interoperability is presumed harmful unless a compelling, globally-relevant justification and migration path exists. + +### 3.2 Abstraction over specificity + +Core remains domain-agnostic. Domain and network specificity belongs in the appropriate layer. + +### 3.3 Optimal ignorance + +If a feature is not required to achieve interoperability, it should not be standardized in the core. Prefer extension mechanisms and profiles when feasible. + +### 3.4 Security by design + +Changes must not introduce avoidable security vulnerabilities, ambiguity around trust, or unsafe defaults. + +### 3.5 Privacy and consent by default + +Changes must not weaken privacy expectations or expand data collection without explicit, scoped rationale and safeguards. + +### 3.6 Scalability neutrality + +The protocol should remain viable across scales—from small deployments to large ecosystems—without requiring centralized control. + +### 3.7 Reusability before novelty + +Prefer general patterns that can be reused across domains and regions over one-off solutions. + +### 3.8 Unification over forced standardization + +Aim to unify patterns and meaning while allowing diversity through profiles and extensions, instead of imposing rigid, premature uniformity. + +### 3.9 Dependency over duplication (2.x emphasis) + +Prefer **upstream dependencies** (versioned references, overlays, profiles) over copying, forking, and rebranding upstream content. This reduces drift and preserves interoperability. + +### 3.10 Automation-first governance (2.x emphasis) + +If a rule can be validated, it should be enforced through tooling/CI rather than social process. + +## 4. Scope and layering (Core → Domain → Network) + +### 4.1 Core + +The global, domain-agnostic protocol contract: verbs, baseline schemas, semantics, normative behaviors, and conformance rules. + +### 4.2 Domain + +Domain specializations: domain vocabulary bindings, domain IGs, domain-level conformance guidance, and recommended workflows. + +### 4.3 Network + +Network-specific constraints and additions: regional policy requirements, identifiers, compliance constraints, stricter validation rules, and network-specific implementation guidance. + +**Key constraint:** Network rules MUST NOT silently alter core semantics. Networks may constrain (be stricter than) the domain/core, but must not contradict core conformance. + +## 5. Artifact hierarchy and precedence + +### 5.1 Normative vs informative + +- **Normative** text uses MUST/SHOULD/MAY and defines conformance. +- **Informative** text includes examples, diagrams, tutorials, and explanatory material unless explicitly declared normative. + +### 5.2 Precedence order (highest → lowest) + +1. **Governance Model (this document)** +2. **Core Specification (normative sections)** +3. **Domain Charters and Domain Specifications (normative sections)** +4. **Network Profiles and Network Conformance Rules (normative within that network)** +5. **Implementation Guides, examples, tutorials (informative unless declared normative)** + +### 5.3 Conflict handling + +If two artifacts conflict: +1) follow precedence order; +2) if still ambiguous, apply **constitutional principles**; +3) final interpretation authority lies with the **Core Working Group** (Section 6). + +## 6. Roles (minimal and accountable) + +### 6.1 Core Working Group (CWG) + +**Mandate:** protect constitutional principles and decide final interpretations. + +**Responsibilities:** +- approve governance amendments; +- appoint and remove Editors; +- arbitrate disputes escalated beyond Editors; +- ratify major releases (as defined in Section 9); +- publish binding interpretations when ambiguity arises. + +**Size:** 5 stewards (default), adjustable only by governance amendment. + +**Term:** 2 years, rolling/staggered when possible. + +**Transparency:** all decisions must be documented publicly with rationale, except sensitive disclosures (Section 11). + +### 6.2 Editors + +**Mandate:** maintain coherence and quality of the specification. + +**Responsibilities:** +- merge changes that meet requirements; +- ensure changelogs, migration notes, and conformance impact are included; +- enforce process gates and CI requirements; +- maintain release readiness and documentation hygiene. + +### 6.3 Release Captain (per release) + +Time-bounded role responsible for: +- coordinating release checklist completion; +- publishing release artifacts; +- ensuring validation and migration material is complete. + +### 6.4 Domain Stewards (per domain) + +Domains follow this governance model, adapted through a **Domain Charter** that must remain consistent with this document. + +--- + +## 7. Selection, rotation, and removal (lightweight but real) + +### 7.1 CWG selection (default mechanism) + +- A public call for nominations is opened. +- Nominations must include: + - statement of intent, + - relevant experience, + - disclosure of conflicts of interest (employment, advisory roles, major commercial dependencies). +- The CWG selects candidates via rough consensus; if contested, a 2/3 CWG vote applies. +- A time-boxed public objection window is provided before finalizing appointments. + +### 7.2 Removal + +A steward/editor may be removed for: +- sustained inactivity, +- repeated bypassing of governance gates, +- serious misconduct (as defined by the project’s Code of Conduct), +- undisclosed conflicts of interest that materially affect trust. + +Removal requires: +- documented rationale, +- an opportunity to respond, +- CWG vote (2/3). + +--- + +## 8. Decision-making + +### 8.1 Default: rough consensus + recorded objections + +A decision passes when: +- objections are addressed, or +- objections are recorded with rationale and the decision proceeds with documented tradeoffs. + +### 8.2 Fallback: time-boxed vote + +If consensus stalls: +- Editors or CWG may call a vote with a defined deadline. +- Vote outcomes and rationale must be documented in the issue/PR. + +### 8.3 Interpretation authority + +When ambiguity exists in the spec: +- Editors attempt resolution using principles; +- unresolved disputes escalate to CWG; +- CWG interpretations are binding until superseded by a release. + +--- + +## 9. Specification change lifecycle (simple, enforceable) + +### 9.1 Stages + +1. **Proposal** (issue/RFC with use case + motivation) +2. **Draft** (PR with working text/schema + examples) +3. **Candidate** (passes validation + includes migration notes if needed) +4. **Release** (tagged and published) +5. **Deprecated** (sunset clock starts) +6. **Removed** (major versions only) + +### 9.2 Minimum requirements for normative changes + +Any normative change MUST include: +- clear statement of **conformance impact**; +- **compatibility classification** (patch/minor/major); +- updated or new machine-verifiable examples when applicable; +- security/privacy implications (even if “no impact”, explicitly stated). + +### 9.3 Optional maturity labels (for clarity, not ceremony) + +Governance tooling MAY use labels such as: +- `proposal`, `draft`, `candidate`, `released`, `deprecated`, `removed`. + +--- + +## 10. Versioning, compatibility, and deprecation + +### 10.1 Semantic versioning (SemVer) + +- **PATCH**: clarifications, fixes, non-breaking tightening with explicit rationale. +- **MINOR**: backward-compatible additions. +- **MAJOR**: breaking changes, removals, or semantic shifts. + +### 10.2 Deprecation policy (airtight rule) + +Deprecations MUST specify: +- replacement guidance; +- migration plan (or “no migration possible” with rationale); +- earliest version where removal may occur (MAJOR only). + +--- + +## 11. Core–Domain–Network interaction rules (2.x foundation) + +### 11.1 Networks publish profiles, overlays, and extensions—not forks + +Networks SHOULD publish: +- **Network Profile**: the subset/constraints of core+domain they adopt, plus stricter validations. +- **Overlays/Addenda**: network-specific guidance layered atop domain IGs. +- **Extensions**: network-specific fields using approved extension containers or namespaces. +- **Pinned dependencies**: exact upstream versions used (core + domain). + +### 11.2 Upstreaming classification (fast, explicit) + +Changes discovered in networks/domains should be categorized as: +- **Core-candidate** (domain-agnostic, broadly reusable), +- **Domain-candidate** (sector-wide), +- **Network-only** (regional/policy/operational constraints). + +### 11.3 Constraint rule + +Networks may be **stricter** than domain/core, but must not: +- contradict core semantics, +- redefine core meanings incompatibly, +- claim core conformance while violating core requirements. + +--- + +## 12. Attribution, licensing, and redistribution (constitutional framing) + +Attribution and licensing are governance concerns because they affect trust, reuse, and interoperability. + +Minimum expectations for derived works: +- preserve upstream license notices; +- include a `NOTICE` artifact listing upstream dependencies and versions; +- ensure documentation sites and compiled outputs visibly credit upstream sources. + +(Operational details live in derived “Attribution Guidelines”, which must not conflict with this model.) + +--- + +## 13. Transparency and confidentiality + +The process should be transparent by default. + +Exceptions: +- sensitive customer/partner information, +- security vulnerabilities prior to coordinated disclosure, +- legal or privacy-sensitive content. + +If discussion happens privately, the final decision MUST be published with an anonymized rationale. + +--- + +## 14. Enforcement (automation-first) + +To keep governance lightweight and real: + +- Normative PRs MUST pass automated validation (schemas, examples, conformance rules) where applicable. +- Editors MUST refuse merges that omit required change metadata. +- Repeated bypassing of gates triggers escalation to CWG. + +--- + +## 15. Amendments to this governance model + +Because this document is constitutional: + +- Amendments require: + - written proposal, + - documented rationale tied to principles, + - a time-boxed public review window, + - CWG approval (2/3 minimum). +- Amendment history MUST be maintained in a changelog section or linked artifact. + +--- + +## 16. Derived governance artifacts (registry) + +The following documents are derived from (and subordinate to) this model: + +- Attribution Guidelines +- Contribution Guidelines +- Style Guide +- Release Guide / Checklist +- Domain Charter Template +- Network Profile Publishing Guide +- Code of Conduct (if adopted) + +Each derived document MUST include the Notice statement defined in Section 0. + +--- + +## 17. Key changes from Governance 1.x (summary) + +- Governance is now explicitly **constitutional**: precedence and interpretation are formal. +- The **Core → Domain → Network** layering is first-class and rules are explicit. +- Roles are compressed into a minimal set (CWG, Editors, Release Captain, Domain Stewards). +- Change lifecycle is tied to **enforceable gates** (validation + migration + conformance impact). +- Dependency-over-duplication is elevated as a governance principle to reduce drift and preserve interoperability. +- Deprecation and removal rules are formalized (sunset clocks; removal via major versions only). +- Automation-first enforcement is emphasized to reduce human bureaucracy. diff --git a/README.md b/README.md index 9a7f0dd..144d238 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,20 @@ -# Beckn Protocol v2.0.0 (Release Candidate) -This repository contains the release candidate of the latest major version release of Beckn Protocol - v2.0.0, defining a JSON-LD and schema.org-aligned core schema, updated APIs, and reference flows for the next generation of Beckn networks. It introduces a catalog-first Catalog Discovery Service (CDS) (replacing the Beckn Gateway for discovery), a DeDi-compliant Network Registry, and a modular “core + schema packs” model to enable strong design-time and run-time composability and global semantic interoperability. +# Beckn Protocol Version 2 +This repository contains the the latest major version release of Beckn Protocol - Version 2, defining a JSON-LD and schema.org-aligned core schema, updated APIs, and reference flows for the next generation of Beckn networks. It introduces a catalog-first Catalog Discovery Service (CDS) (replacing the Beckn Gateway for discovery), a DeDi-compliant Network Registry, and a modular “core + schema packs” model to enable strong design-time and run-time composability and global semantic interoperability. + +TODO: Add version history table ## 1. High-level goals of v2 Beckn v2 reorganizes the protocol around: - **Global semantic interoperability** via JSON-LD and deep alignment with schema.org and other globally interoperable linked data schemas. - Design-time composability: modular core + pluggable domain-specific “schema”. -- **Run-time composability**: independent but interoperable actors (BAP, BPP, CDS, Registry, Agents) that can be recombined without changing the core. +- **Run-time composability**: independent but interoperable actors (BAP, BPP, CDS, Registry) that can be recombined without changing the core. - **Registry and discovery modernization**: - BG → CDS: Beckn Gateway is replaced by a Catalog Discovery Service (CDS). - Legacy Registry → DeDi-compliant Registry: Network Registry becomes compliant with the Decentralized Directory (DeDi) protocol.  -## 2. Schema changes: from v1.x to v2 +## 2. Schema changes: from v1 to v2 ### 2.1 From OpenAPI/JSON Schema to JSON-LD + schema.org diff --git a/api/README.md b/api/README.md new file mode 100644 index 0000000..905b2c4 --- /dev/null +++ b/api/README.md @@ -0,0 +1,4 @@ +# Beckn Protocol 2.0 API Specification + +> Note: All release candidate versions of the protocol can be found under specific folders named `v2-rc*` to avoid any downstream impact. However, these folders are only temporary and will be removed upon release of a minor version of the specification. The long term support (LTS) version of the API specs can be found in the beckn.yaml file in this folder. + diff --git a/api/beckn.yaml b/api/beckn.yaml deleted file mode 100644 index 7b2486c..0000000 --- a/api/beckn.yaml +++ /dev/null @@ -1,1688 +0,0 @@ -openapi: 3.1.1 -info: - title: Beckn Protocol API - description: | - A unified OpenAPI specification for the Beckn Protocol covering: - - Discovery: Search and discover items across multiple schemas - - Transaction: Order lifecycle (select, init, confirm, update, cancel, status, track, support, rating) - - Catalog Publish: Asynchronous catalog ingestion for Discovery Service - - This specification combines the Discovery API, Transaction API, and Catalog Publish API into a single comprehensive document. - version: 2.0.0 - contact: - name: Beckn Protocol - url: https://becknprotocol.io - license: - name: MIT - url: https://opensource.org/licenses/MIT - -servers: - - url: https://staging-api.becknprotocol.io - description: Staging server - - url: http://localhost:8080 - description: Local development server - -paths: - /beckn/discover: - get: - summary: Discover items across multiple schemas - description: | - Search and discover items across any schemas in Beckn Schema registry. Supports text search, JSONPath-based filtering (RFC 9535), or both together with automatic schema adaptation. This endpoint may return either an **ACK/NACK** confirming receipt/validation or a synchronous **DiscoverResponse** providing discovery results in catalog format. Networks may still choose to deliver results asynchronously via **/beckn/on_discover**. - operationId: discoverItems - tags: [Discovery] - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/DiscoverRequest' - examples: - structured_query: - $ref: '#/components/examples/discover_structured_query' - natural_language: - $ref: '#/components/examples/discover_natural_language' - grocery_search: - $ref: '#/components/examples/discover_grocery_search' - combined_search: - $ref: '#/components/examples/discover_combined_search' - multi_schema_search: - $ref: '#/components/examples/discover_multi_schema_search' - responses: - '200': - description: ACK — received the discover request (validation passed) - content: - application/json: - schema: - oneOf: - - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/AckResponse' - - $ref: '#/components/schemas/DiscoverResponse' - examples: - discover_electronics_catalog: - $ref: '#/components/examples/on_discover_electronics_catalog' - discover_grocery_catalog: - $ref: '#/components/examples/on_discover_grocery_catalog' - success_ack: - $ref: '#/components/examples/ack_success' - '400': - $ref: '#/components/responses/Ack400' - '500': - $ref: '#/components/responses/Ack500' - /beckn/on_discover: - post: - summary: On Discover response with catalog data - description: | - Callback endpoint that provides the actual discovery results in catalog format. This endpoint is called by the BPP to return the search results after processing the discover request. **This endpoint returns only an ACK/NACK** confirming receipt and validation of the catalog payload. - operationId: onDiscoverItems - tags: [Discovery] - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/DiscoverResponse' - examples: - electronic_items_catalog: - $ref: '#/components/examples/on_discover_electronics_catalog' - grocery_items_catalog: - $ref: '#/components/examples/on_discover_grocery_catalog' - responses: - '200': - description: ACK — received catalog data for the corresponding discover request - content: - application/json: - schema: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/AckResponse' - examples: - success_ack: - $ref: '#/components/examples/ack_success' - '400': - $ref: '#/components/responses/Ack400' - '500': - $ref: '#/components/responses/Ack500' - /beckn/discover/browser-search: - get: - summary: Browser-friendly search API - description: | - URL-based search API for browser navigation and direct links using JSONPath expressions. - Response format is determined by the Accept header: - - Accept: text/html → Returns browser-friendly HTML page (default) - - Accept: application/json → Returns structured JSON data in same format as structured query API - - Supports complex filtering via URL-encoded JSONPath expressions. - Generic search across all entity types (items, providers, catalogs) based on filter criteria. - operationId: browserSearch - tags: [Browser Search] - parameters: - - name: Accept - in: header - required: false - schema: - type: string - enum: ["text/html", "application/json"] - default: "text/html" - description: | - Response format preference. - - Accept: text/html → Returns browser-friendly HTML page (default) - - Accept: application/json → Returns structured JSON data in same format as structured query API - examples: - default: - value: "text/html" - - name: filters - in: query - required: false - schema: - type: string - description: URL-encoded JSONPath expression for complex filtering - examples: - sample: - value: "%24%5B%3F%28%40.price%20%3C%3D%201000%20%26%26%20%40.brand%20%3D%3D%20%27Premium%20Tech%27%29%5D" - responses: - '200': - description: Successful search response - content: - text/html: - schema: - type: string - examples: - html_example: - summary: Browser-friendly HTML page - value: | - Search Results - Premium Tech Electronics | Beckn Catalog - Search - - # Premium Tech Electronics Store - - High-quality electronics and gaming equipment - - Available from Jan 27, 2025 to Dec 31, 2026 - - ## Premium Gaming Laptop Pro - - High-performance gaming laptop with RTX graphics - - ★★★★★ 4.8 (156 reviews) - - $1,499.99 USD - - Brand: Premium Tech - - ID: laptop-item-001 - - © 2024 Beckn Catalog. Powered by Beckn Protocol. - application/json: - schema: - $ref: '#/components/schemas/DiscoverResponse' - examples: - electronic_items: - $ref: '#/components/examples/browser_search_electronic_items' - '400': - description: Bad request - Invalid parameters - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - examples: - invalid_entity_type: - summary: Invalid entity type error - description: Error when entity_type is missing or invalid - value: - error: - code: "INVALID_ENTITY_TYPE" - message: "entity_type is required and must be one of: item, provider, catalog" - '404': - description: No results found - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - examples: - no_results: - summary: No results found error - description: Error when no items match the search criteria - value: - error: - code: "NO_RESULTS_FOUND" - message: "No items found matching the specified criteria" - details: - search_criteria: - entity_type: "item" - category: "electric_vehicles" - price_max: 50000 - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - /beckn/select: - post: - summary: "Buyer selects items/offers — returns priced order" - requestBody: - required: true - content: - application/json: - schema: - type: object - required: - - context - - message - properties: - context: - allOf: - - $ref: '#/components/schemas/TransactionContext' - - type: object - properties: - action: - const: select - message: - type: object - required: - - order - properties: - order: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Order' - responses: - '200': - $ref: '#/components/responses/Ack200' - '400': - $ref: '#/components/responses/Ack400' - '500': - $ref: '#/components/responses/Ack500' - /beckn/on_select: - post: - summary: Provider returns priced order (quote) - requestBody: - required: true - content: - application/json: - schema: - type: object - required: - - context - - message - properties: - context: - allOf: - - $ref: '#/components/schemas/TransactionContext' - - type: object - properties: - action: - const: on_select - message: - type: object - required: - - order - properties: - order: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Order' - responses: - '200': - $ref: '#/components/responses/Ack200' - '400': - $ref: '#/components/responses/Ack400' - '500': - $ref: '#/components/responses/Ack500' - /beckn/init: - post: - summary: Initialize order (party details, fulfillment mode, payment intent) - requestBody: - required: true - content: - application/json: - schema: - type: object - required: - - context - - message - properties: - context: - allOf: - - $ref: '#/components/schemas/TransactionContext' - - type: object - properties: - action: - const: init - message: - type: object - required: - - order - properties: - order: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Order' - responses: - '200': - $ref: '#/components/responses/Ack200' - '400': - $ref: '#/components/responses/Ack400' - '500': - $ref: '#/components/responses/Ack500' - /beckn/on_init: - post: - summary: Provider echoes initialized order (with refs populated) - requestBody: - required: true - content: - application/json: - schema: - type: object - required: - - context - - message - properties: - context: - allOf: - - $ref: '#/components/schemas/TransactionContext' - - type: object - properties: - action: - const: on_init - message: - type: object - required: - - order - properties: - order: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Order' - responses: - '200': - $ref: '#/components/responses/Ack200' - '400': - $ref: '#/components/responses/Ack400' - '500': - $ref: '#/components/responses/Ack500' - /beckn/confirm: - post: - summary: Confirm order (final selections; payment/fulfillment committed) - requestBody: - required: true - content: - application/json: - schema: - type: object - required: - - context - - message - properties: - context: - allOf: - - $ref: '#/components/schemas/TransactionContext' - - type: object - properties: - action: - const: confirm - message: - type: object - required: - - order - properties: - order: - allOf: - - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Order' - responses: - '200': - $ref: '#/components/responses/Ack200' - '400': - $ref: '#/components/responses/Ack400' - '500': - $ref: '#/components/responses/Ack500' - /beckn/on_confirm: - post: - summary: Provider returns confirmed order - requestBody: - required: true - content: - application/json: - schema: - type: object - required: - - context - - message - properties: - context: - allOf: - - $ref: '#/components/schemas/TransactionContext' - - type: object - properties: - action: - const: on_confirm - message: - type: object - required: - - order - properties: - order: - allOf: - - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Order' - - type: object - required: - - beckn:id - responses: - '200': - $ref: '#/components/responses/Ack200' - '400': - $ref: '#/components/responses/Ack400' - '500': - $ref: '#/components/responses/Ack500' - /beckn/status: - post: - summary: Fetch order status by id - requestBody: - required: true - content: - application/json: - schema: - type: object - required: - - context - - message - properties: - context: - allOf: - - $ref: '#/components/schemas/TransactionContext' - - type: object - properties: - action: - const: status - message: - type: object - required: - - order - properties: - order: - oneOf: - - type: object - additionalProperties: false - required: - - beckn:id - properties: - beckn:id: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Order/properties/beckn:id' - - allOf: - - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Order' - - type: object - required: - - beckn:id - responses: - '200': - $ref: '#/components/responses/Ack200' - '400': - $ref: '#/components/responses/Ack400' - '500': - $ref: '#/components/responses/Ack500' - /beckn/on_status: - post: - summary: Provider returns current order (or tracking via fulfillment packs) - requestBody: - required: true - content: - application/json: - schema: - type: object - required: - - context - - message - properties: - context: - allOf: - - $ref: '#/components/schemas/TransactionContext' - - type: object - properties: - action: - const: on_status - message: - type: object - properties: - order: - allOf: - - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Order' - - type: object - required: - - beckn:id - anyOf: - - required: - - order - - required: [] - responses: - '200': - $ref: '#/components/responses/Ack200' - '400': - $ref: '#/components/responses/Ack400' - '500': - $ref: '#/components/responses/Ack500' - /beckn/update: - post: - summary: Request order mutation (replace, cancel line, address change, etc.) - requestBody: - required: true - content: - application/json: - schema: - type: object - required: - - context - - message - properties: - context: - allOf: - - $ref: '#/components/schemas/TransactionContext' - - type: object - properties: - action: - const: update - message: - type: object - required: - - order - properties: - order: - allOf: - - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Order' - - type: object - required: - - beckn:id - responses: - '200': - $ref: '#/components/responses/Ack200' - '400': - $ref: '#/components/responses/Ack400' - '500': - $ref: '#/components/responses/Ack500' - /beckn/on_update: - post: - summary: Provider returns mutated order - requestBody: - required: true - content: - application/json: - schema: - type: object - required: - - context - - message - properties: - context: - allOf: - - $ref: '#/components/schemas/TransactionContext' - - type: object - properties: - action: - const: on_update - message: - type: object - required: - - order - properties: - order: - allOf: - - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Order' - - type: object - required: - - beckn:id - responses: - '200': - $ref: '#/components/responses/Ack200' - '400': - $ref: '#/components/responses/Ack400' - '500': - $ref: '#/components/responses/Ack500' - /beckn/cancel: - post: - summary: Request to cancel an order - requestBody: - required: true - content: - application/json: - schema: - type: object - required: - - context - - message - properties: - context: - allOf: - - $ref: '#/components/schemas/TransactionContext' - - type: object - properties: - action: - const: cancel - message: - type: object - required: - - order - properties: - order: - oneOf: - - type: object - additionalProperties: false - required: - - beckn:id - properties: - beckn:id: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Order/properties/beckn:id' - beckn:orderItems: - type: array - minItems: 1 - items: - oneOf: - - type: object - required: - - beckn:orderedItem - properties: - beckn:orderedItem: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Item/properties/beckn:id' - beckn:lineId: - type: string - description: Unique line id within order - beckn:quantity: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Quantity' - - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/OrderItem' - - allOf: - - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Order' - - type: object - required: - - beckn:id - responses: - '200': - $ref: '#/components/responses/Ack200' - '400': - $ref: '#/components/responses/Ack400' - '500': - $ref: '#/components/responses/Ack500' - /beckn/on_cancel: - post: - summary: Provider returns cancelled order (may reflect refund/payment update via PaymentRef) - requestBody: - required: true - content: - application/json: - schema: - type: object - required: - - context - - message - properties: - context: - allOf: - - $ref: '#/components/schemas/TransactionContext' - - type: object - properties: - action: - const: on_cancel - message: - type: object - required: - - order - properties: - order: - allOf: - - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Order' - - type: object - required: - - beckn:id - responses: - '200': - $ref: '#/components/responses/Ack200' - '400': - $ref: '#/components/responses/Ack400' - '500': - $ref: '#/components/responses/Ack500' - /beckn/support: - post: - summary: Request support details for an entity (order/item/provider/etc.) - requestBody: - required: true - content: - application/json: - schema: - type: object - required: [context, message] - properties: - context: - allOf: - - $ref: '#/components/schemas/TransactionContext' - - type: object - properties: - action: - const: support - message: - type: object - required: [refId, refType] - properties: - refId: - type: string - description: ID of the entity for which support is requested (order/item/fulfillment/provider/agent). # legacy kept minimal - refType: - type: string - description: Entity type for which support is requested. - enum: [ORDER, FULFILLMENT, ITEM, PROVIDER, AGENT, OTHER] - support: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/SupportInfo' - responses: - '200': - $ref: '#/components/responses/Ack200' - '400': - $ref: '#/components/responses/Ack400' - '500': - $ref: '#/components/responses/Ack500' - /beckn/on_support: - post: - summary: Provider returns support details - requestBody: - required: true - content: - application/json: - schema: - type: object - required: [context, message] - properties: - context: - allOf: - - $ref: '#/components/schemas/TransactionContext' - - type: object - properties: - action: - const: on_support - message: - type: object - required: [support] - properties: - support: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/SupportInfo' - responses: - '200': - $ref: '#/components/responses/Ack200' - '400': - $ref: '#/components/responses/Ack400' - '500': - $ref: '#/components/responses/Ack500' - /beckn/track: - post: - summary: Request tracking handle/link for an active order/fulfillment - requestBody: - required: true - content: - application/json: - schema: - type: object - required: [context, message] - properties: - context: - allOf: - - $ref: '#/components/schemas/TransactionContext' - - type: object - properties: - action: - const: track - message: - type: object - required: - - tracking - properties: - tracking: - type: object - required: - - id - properties: - id: - type: string - description: Tracking identifier - callbackUrl: - type: string - format: uri - description: Optional callback URL for streaming tracking coordinates/updates - mode_hint: - type: string - description: Optional delivery mode for the tracking handle. - enum: [link_only, deep_link, webhook, ws_handle] - responses: - '200': - $ref: '#/components/responses/Ack200' - '400': - $ref: '#/components/responses/Ack400' - '500': - $ref: '#/components/responses/Ack500' - /beckn/on_track: - post: - summary: Provider returns tracking handle/link and status - requestBody: - required: true - content: - application/json: - schema: - type: object - required: [context, message] - properties: - context: - allOf: - - $ref: '#/components/schemas/TransactionContext' - - type: object - properties: - action: - const: on_track - message: - type: object - required: - - tracking - properties: - tracking: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/TrackAction' - responses: - '200': - $ref: '#/components/responses/Ack200' - '400': - $ref: '#/components/responses/Ack400' - '500': - $ref: '#/components/responses/Ack500' - /beckn/rating: - post: - summary: Submit a rating (optionally with feedback) for an entity - requestBody: - required: true - content: - application/json: - schema: - type: object - required: [context, message] - properties: - context: - allOf: - - $ref: '#/components/schemas/TransactionContext' - - type: object - properties: - action: - const: rating - message: - ratings: - type: array - items: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/RatingInput' - responses: - '200': - $ref: '#/components/responses/Ack200' - '400': - $ref: '#/components/responses/Ack400' - '500': - $ref: '#/components/responses/Ack500' - /beckn/on_rating: - post: - summary: Provider acknowledges/returns rating receipt (optional aggregate snapshot) - requestBody: - required: true - content: - application/json: - schema: - type: object - required: [context, message] - properties: - context: - allOf: - - $ref: '#/components/schemas/TransactionContext' - - type: object - properties: - action: - const: on_rating - message: - type: object - properties: - received: - type: boolean - default: true - aggregate: - type: object - description: Optional current aggregate rating snapshot. - properties: - count: - type: integer - minimum: 0 - value: - type: number - minimum: 0 - best: - type: number - minimum: 0 - worst: - type: number - minimum: 0 - feedbackForm: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Form' - description: Optional feedback form for additional detailed feedback collection - responses: - '200': - $ref: '#/components/responses/Ack200' - '400': - $ref: '#/components/responses/Ack400' - '500': - $ref: '#/components/responses/Ack500' - /beckn/catalog/publish: - post: - summary: Publish one or more catalogs for indexing - description: | - BPP submits catalogs to be indexed. Returns **ACK** immediately if accepted for processing. - The detailed per-catalog processing result arrives later via **/on_catalog_publish**. - operationId: publishCatalogs - tags: [Catalog Publish] - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/CatalogPublishRequest' - examples: - publish_basic: - summary: Minimal publish - value: - context: - version: "2.0.0" - action: "catalog_publish" - timestamp: "2025-09-01T10:30:00+05:30" - message_id: "u-req-123" - transaction_id: "u-txn-123" - bap_id: "bpp.example.com" - bap_uri: "https://bpp.example.com/callbacks" # where /on_catalog_publish is exposed - ttl: "PT30S" - catalogs: - - "@context": "https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/EvChargingOffer/v1/context.jsonld" - "@type": "beckn:Catalog" - "beckn:id": "catalog-001" - "beckn:descriptor": {"@type": "beckn:Descriptor", "schema:name": "BPP Test Catalog"} - "beckn:items": [] - responses: - '200': - $ref: '#/components/responses/Ack200' - '400': - $ref: '#/components/responses/Ack400' - '500': - $ref: '#/components/responses/Ack500' - /beckn/catalog/on_publish: - post: - summary: Callback with catalog publish processing results - description: | - Discovery Service calls back with per-catalog processing results (accepted/rejected, errors, derived stats). - The receiver should respond with an **AckResponse**. - operationId: onCatalogPublish - tags: [Catalog Publish] - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/CatalogPublishResponse' - examples: - results_basic: - summary: Example processing results - value: - context: - version: "2.0.0" - action: "on_catalog_publish" - timestamp: "2025-09-01T10:31:05+05:30" - message_id: "u-resp-123" - transaction_id: "u-txn-123" - bpp_id: "discovery-indexer.example.com" - bpp_uri: "https://discovery-indexer.example.com" - ttl: "PT30S" - message: - results: - - catalog_id: "catalog-001" - status: "ACCEPTED" - item_count: 42 - warnings: - - code: "NON_NORMALIZED_BRAND" - message: "Some brand values were normalized" - - catalog_id: "catalog-002" - status: "REJECTED" - error: - code: "INVALID_ITEM" - message: "Invalid item payload at index 3" - paths: "catalogs[1].items[3]" - responses: - '200': - $ref: '#/components/responses/Ack200' - '400': - $ref: '#/components/responses/Ack400' - '500': - $ref: '#/components/responses/Ack500' -components: - schemas: - DiscoverRequest: - type: object - required: [context] - properties: - context: - allOf: - - $ref: '#/components/schemas/DiscoveryContext' - - type: object - properties: - action: - type: string - enum: [discover] - message: - type: object - description: Discover payload containing search criteria - properties: - text_search: - type: string - description: Free text search query for items - example: "gaming laptop premium tech" - filters: - type: object - description: Filter criteria for items - properties: - type: - type: string - enum: [jsonpath] - default: jsonpath - description: Type of filter expression - expression: - type: string - description: Filter expression based on the specified type - example: "$[?(@.rating.value >= 4.0 && @.electronic.brand.name == 'Premium Tech')]" - required: [type, expression] - spatial: - type: array - description: Optional array of spatial constraints (CQL2-JSON semantics). - items: - $ref: '#/components/schemas/SpatialConstraint' - media_search: - $ref: '#/components/schemas/MediaSearch' - anyOf: - - required: [text_search] - - required: [filters] - - required: [spatial] - - required: [filters, spatial] - DiscoverResponse: - type: object - required: [context, message] - properties: - context: - allOf: - - $ref: '#/components/schemas/DiscoveryContext' - - type: object - properties: - action: - type: string - enum: [on_discover] - message: - type: object - properties: - catalogs: - type: array - description: Array of catalogs containing items - items: - $ref: '#/components/schemas/Catalog' - DiscoveryContext: - allOf: - - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications/refs/heads/master/api/transaction/build/transaction.yaml#/components/schemas/Context' - - type: object - description: Beckn Context extended for Discovery. - properties: - schema_context: - type: array - items: - type: string - format: uri - description: Optional JSON-LD context URLs indicating item types to search across - GeoJSONGeometry: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/GeoJSONGeometry' - Address: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Address' - Location: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Location' - SpatialConstraint: - type: object - description: > - **Spatial predicate** using **OGC CQL2 (JSON semantics)** applied to one or more geometry targets in an item. This is where clients express spatial intent. - - Key ideas: - `targets`: one or more **JSONPath-like** pointers that locate geometry - - fields within each item document (e.g., `$['beckn:availableAt'][*]['geo']`). - - `op`: spatial operator (CQL2). Common ones: - - • `s_within` (A is completely inside B) - • `s_intersects` (A intersects B) - • `s_contains` (A contains B) - • `s_dwithin` (A within distance of B) - - `geometry`: **GeoJSON** literal used as the predicate reference geometry. - `distanceMeters`: required for `s_dwithin` when using a GeoJSON Point/shape. - `quantifier`: if a target resolves to an array, choose whether **any** (default), - - **all**, or **none** of elements must satisfy the predicate. - - CRS: unless otherwise stated, all coordinates are **EPSG:4326**. - - required: [op, targets] - properties: - op: - type: string - enum: - - s_within - - s_contains - - s_intersects - - s_disjoint - - s_overlaps - - s_crosses - - s_touches - - s_equals - - s_dwithin - description: OGC CQL2 spatial operator. - targets: - description: > - One or more JSONPath-like pointers to geometry fields within the item. Example pointers: - `$['beckn:availableAt'][*]['geo']` (array of site Points) - `$['beckn:itemAttributes']['ride:dropOff']['geo']` (drop zone Polygon) - - oneOf: - - type: string - - type: array - items: {type: string} - geometry: - $ref: '#/components/schemas/GeoJSONGeometry' - distanceMeters: - type: number - minimum: 0 - description: > - For `s_dwithin`: maximum distance in meters from the target geometry to `geometry` (e.g., “within 5000 m of this Point”). Ignored for other ops. - - quantifier: - type: string - enum: [any, all, none] - default: any - description: > - How to evaluate when `targets` resolves to an array: - **any**: at least one element matches (default) - **all**: every element must match - **none**: no element may match - - srid: - type: string - description: > - Coordinate Reference System identifier for `geometry`. Default is `"EPSG:4326"`. If provided, servers MAY reproject to EPSG:4326 internally. - - example: "EPSG:4326" - additionalProperties: false - examples: - within_circle_as_distance: - summary: EV sites within 5 km of a center (via s_dwithin) - value: - op: s_dwithin - targets: "$['beckn:availableAt'][*]['geo']" - geometry: - type: Point - coordinates: [77.5946, 12.9716] - distanceMeters: 5000 - pickup_at_point: - summary: Pickup at a defined point (GeoJSON Point) - description: > - Example of a DiscoverRequest spatial constraint representing a specific pickup location. The requester defines a GeoJSON Point as the pickup location, and the server finds providers whose service area **contains** this point. - - value: - op: s_contains - targets: "$['beckn:itemAttributes']['ride:serviceArea']['geo']" # provider polygon field - geometry: - type: Point - coordinates: [77.5946, 12.9716] # MG Road (Bengaluru) — [lon, lat] - drop_intersects_user_box: - summary: Provider drop zone intersects user’s rectangle - value: - op: s_intersects - targets: "$['beckn:itemAttributes']['ride:dropOff']['geo']" - geometry: - type: Polygon - coordinates: - - [[77.6100, 12.9200], [77.6400, 12.9200], [77.6400, 12.9500], [77.6100, 12.9500], [77.6100, 12.9200]] - pickup_location_example: - summary: A defined pickup location object - value: - geo: - type: Point - coordinates: [77.5946, 12.9716] # [lon, lat] - address: - streetAddress: "MG Road" - addressLocality: "Bengaluru" - addressRegion: "Karnataka" - postalCode: "560001" - addressCountry: "IN" - MediaSearch: - type: object - description: > - Container for multimodal search inputs and configuration. Supports searching through **images, audio notes, and videos** alongside text, filters, and spatial predicates. For GET, this object should be JSON-encoded and URL-escaped. - - properties: - media: - type: array - description: > - One or more references to **images, audio notes, or videos** supplied as part of a multimodal search. Each entry references a media resource accessible via HTTPS or data URI. - - items: - $ref: '#/components/schemas/MediaInput' - example: - - id: "snap-1" - type: image - url: "https://cdn.example.com/user/snaps/ccs2-cable.jpg" - contentType: "image/jpeg" - options: - $ref: '#/components/schemas/MediaSearchOptions' - description: > - Options controlling how the discovery engine interprets the supplied media — e.g., whether to perform OCR/ASR, semantic similarity, or object detection. - - additionalProperties: false - example: - media: - - id: "snap-1" - type: image - url: "https://cdn.example.com/user/snaps/ccs2-cable.jpg" - contentType: "image/jpeg" - options: - goals: ["visual-object-detect", "text-from-image"] - augment_text_search: true - MediaInput: - type: object - description: Reference to an image, audio clip, or video used for multimodal search. - required: [type, url] - properties: - id: - type: string - description: Client-supplied identifier for this media input. - type: - type: string - enum: [image, audio, video] - description: Media category. - url: - type: string - format: uri - description: HTTPS URL or data URI pointing to the media resource. - contentType: - type: string - description: MIME type, e.g., image/jpeg, audio/mpeg, video/mp4. - textHint: - type: string - description: Optional pre-extracted text (OCR/ASR) for search augmentation. - language: - type: string - description: Language code (BCP-47) of `textHint` or spoken audio. - startMs: - type: integer - description: Optional start offset in milliseconds (for audio/video segments). - endMs: - type: integer - description: Optional end offset in milliseconds (for audio/video segments). - additionalProperties: false - MediaSearchOptions: - type: object - description: How the discovery engine should use the provided media inputs. - properties: - goals: - type: array - description: > - Desired processing goals for the media. - - items: - type: string - enum: - - visual-similarity # find visually similar items - - visual-object-detect # detect object classes within image/video - - text-from-image # extract text (OCR) - - text-from-audio # extract text (ASR) - - semantic-audio-match # audio embedding similarity - - semantic-video-match # video scene/keyframe similarity - augment_text_search: - type: boolean - default: true - description: > - Whether to append extracted text from OCR/ASR to `text_search`. - - restrict_results_to_media_proximity: - type: boolean - default: false - description: > - Restrict results to spatial proximity of media-derived coordinates (e.g., EXIF GPS tags). - - additionalProperties: false - AckResponse: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/AckResponse' - Catalog: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Catalog' - Item: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Item' - Offer: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Offer' - Attributes: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Attributes' - Provider: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Provider' - PriceSpecification: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/PriceSpecification' - Eligibility: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Eligibility' - Descriptor: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Descriptor' - CategoryCode: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/CategoryCode' - TimePeriod: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/TimePeriod' - Rating: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Rating' - ErrorResponse: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/ErrorResponse' - Error: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Error' - TransactionContext: - allOf: - - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications/refs/heads/master/api/transaction/build/transaction.yaml#/components/schemas/Context' - - type: object - description: > - Beckn Context extended for Transaction flows. Mirrors DiscoveryContext pattern to enable validation and per-endpoint action constraints. network_id/schema_context are optional for routing and JSON-LD hints. - - properties: - network_id: - type: array - items: {type: string} - description: Optional list of addressed networks (for routing/allowlisting) - schema_context: - type: array - items: - type: string - format: uri - description: Optional JSON-LD context URLs relevant to the items/offers in this transaction - # -------------------------------- - # Core schemas (referenced from attributes.yaml) - # -------------------------------- - Order: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Order' - OrderItem: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/OrderItem' - Invoice: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Invoice' - Fulfillment: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Fulfillment' - TrackAction: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/TrackAction' - Payment: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Payment' - Buyer: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Buyer' - SupportInfo: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/SupportInfo' - Tracking: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Tracking' - RatingInput: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/RatingInput' - # ---------- Envelopes ---------- - CatalogPublishRequest: - type: object - required: [context, message] - properties: - context: - allOf: - - $ref: '#/components/schemas/DiscoveryContext' - - type: object - properties: - action: - type: string - enum: [catalog_publish] - message: - type: object - required: [catalogs] - properties: - catalogs: - type: array - description: Array of catalogs containing items - items: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Catalog' - minItems: 1 - description: | - Catalog Publish request envelope. - *context.version* MUST indicate the supported protocol version (e.g., "2.0.0"). - CatalogPublishResponse: - type: object - required: [context, message] - properties: - context: - allOf: - - $ref: '#/components/schemas/DiscoveryContext' - - type: object - properties: - action: - type: string - enum: [on_catalog_publish] - message: - type: object - properties: - results: - type: array - description: Per-catalog processing results - items: - $ref: '#/components/schemas/CatalogProcessingResult' - # ---------- Result model ---------- - CatalogProcessingResult: - type: object - required: [catalog_id, status] - properties: - catalog_id: - type: string - description: The "beckn:id" of the submitted catalog - status: - type: string - enum: [ACCEPTED, REJECTED, PARTIAL] - description: Final processing outcome for this catalog - item_count: - type: integer - minimum: 0 - description: Number of items indexed (when accepted/partial) - warnings: - type: array - description: Non-fatal issues encountered - items: - $ref: '#/components/schemas/ProcessingNotice' - error: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Error' - ProcessingNotice: - type: object - required: [code, message] - properties: - code: - type: string - message: - type: string - details: - type: object - additionalProperties: true - examples: - # ---------- /discover request examples ---------- - discover_structured_query: - summary: Structured discover (electronics) - value: - context: - version: "2.0.0" - action: "discover" - timestamp: "2024-04-10T16:10:50+05:30" - message_id: "5c8f1a2b-9d3e-4f76-8b21-3a4c5d6e7f80" - transaction_id: "d3b07384-4a1c-4f5e-9c2b-7e6d5c4b3a21" - bap_id: "bap.example.com" - bap_uri: "https://bap.example.com" - ttl: "PT30S" - schema_context: - - "https://example.org/schema/items/v1/ElectronicItem/schema-context.jsonld" - message: - text_search: "gaming laptop premium tech" - filters: - type: "jsonpath" - expression: "$[?(@.rating.value >= 4 && @.electronic.brand.name == 'Premium Tech')]" - discover_natural_language: - summary: Natural-language discover (electronics) - value: - context: - version: "2.0.0" - action: "discover" - timestamp: "2024-04-10T16:10:50+05:30" - message_id: "9a7b6c5d-8e4f-4a3b-9c2d-1e0f2a3b4c5d" - transaction_id: "1f2e3d4c-5b6a-4789-8c0d-1a2b3c4d5e6f" - bap_id: "bap.example.com" - bap_uri: "https://bap.example.com" - ttl: "PT30S" - schema_context: - - "https://example.org/schema/items/v1/ElectronicItem/schema-context.jsonld" - message: - text_search: "Looking for a premium gaming laptop under $2000 near San Francisco" - discover_grocery_search: - summary: Structured discover (grocery) - value: - context: - version: "2.0.0" - action: "discover" - timestamp: "2024-04-10T16:10:50+05:30" - message_id: "2a3b4c5d-6e7f-4890-9a1b-2c3d4e5f6071" - transaction_id: "7e6d5c4b-3a21-4c5d-8f70-9a1b2c3d4e5f" - bap_id: "bap.example.com" - bap_uri: "https://bap.example.com" - ttl: "PT30S" - schema_context: - - "https://example.org/schema/items/v1/GroceryItem/schema-context.jsonld" - message: - text_search: "organic apples fresh" - filters: - type: "jsonpath" - expression: "$[?(@.grocery.organicCertification ~ 'USDA Organic')]" - discover_combined_search: - summary: Combined text + filters - value: - context: - version: "2.0.0" - action: "discover" - timestamp: "2024-04-10T16:10:50+05:30" - message_id: "3b4c5d6e-7f80-41a2-93b4-c5d6e7f8091a" - transaction_id: "8f70e6d5-c4b3-42a1-9c2d-3e4f5a6b7c8d" - bap_id: "bap.example.com" - bap_uri: "https://bap.example.com" - ttl: "PT30S" - schema_context: - - "https://example.org/schema/items/v1/ElectronicItem/schema-context.jsonld" - message: - text_search: "gaming laptop" - filters: - type: "jsonpath" - expression: "$[?(@.electronic.price['schema:price'] <= 2000 && @.electronic.brand.name == 'Premium Tech')]" - discover_multi_schema_search: - summary: Multi-schema discover (electronics + grocery) - value: - context: - version: "2.0.0" - action: "discover" - timestamp: "2024-04-10T16:10:50+05:30" - message_id: "4c5d6e7f-8091-42b3-94c5-d6e7f8091a2b" - transaction_id: "9c2d3e4f-5a6b-47c8-8d90-1a2b3c4d5e6f" - bap_id: "bap.example.com" - bap_uri: "https://bap.example.com" - ttl: "PT30S" - schema_context: - - "https://example.org/schema/items/v1/ElectronicItem/schema-context.jsonld" - - "https://example.org/schema/items/v1/GroceryItem/schema-context.jsonld" - message: - text_search: "premium tech and organic food" - filters: - type: "jsonpath" - expression: "$[?(@.rating.value >= 4 && (@.electronic.brand.name == 'Premium Tech' || @.grocery.organicCertification ~ 'USDA Organic'))]" - # ---------- /on_discover callback (DiscoverResponse) examples ---------- - on_discover_electronics_catalog: - summary: Electronics catalog callback - value: - context: - version: "2.0.0" - action: "on_discover" - timestamp: "2024-04-10T16:10:50+05:30" - message_id: "a1b2c3d4-e5f6-4789-90ab-cdef12345678" - transaction_id: "b2c3d4e5-f6a7-4890-8b9a-cdef23456789" - bpp_id: "bpp.example.com" - bpp_uri: "https://bpp.example.com" - ttl: "PT30S" - message: - catalogs: - - "@context": "https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/context.jsonld" - "@type": "beckn:Catalog" - "beckn:id": "catalog-electronics-001" - "beckn:descriptor": {"@type": "beckn:Descriptor", "schema:name": "Premium Tech Electronics Store"} - "beckn:items": [{"@context": "https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/context.jsonld", "@type": "beckn:Item", "beckn:id": "laptop-item-002", "beckn:descriptor": {"@type": "beckn:Descriptor", "schema:name": "Premium Gaming Laptop Pro 15”", "beckn:shortDesc": "Intel i7, 16GB RAM, 512GB SSD, RTX 4060"}, "beckn:category": {"@type": "schema:CategoryCode", "schema:codeValue": "electronics", "schema:name": "Electronics"}, "beckn:rateable": true, "beckn:rating": {"@type": "beckn:Rating", "beckn:ratingValue": 4.7, "beckn:ratingCount": 932}, "beckn:networkId": ["bap.net/electronics"], "beckn:itemAttributes": {"@context": "https://example.org/schema/items/v1/ElectronicItem/schema-context.jsonld", "@type": "beckn:ElectronicItem", "electronic:brand": "Premium Tech", "electronic:model": "G15-Pro-2025", "electronic:processor": "Intel Core i7-13700H", "electronic:ram": "16GB DDR5", "electronic:storage": "512GB NVMe SSD", "electronic:graphics": "NVIDIA GeForce RTX 4060", "electronic:display": "15.6\" 240Hz QHD", "electronic:warranty": "24 months"}, "beckn:provider": {"beckn:id": "tech-store-001", "beckn:descriptor": {"@type": "beckn:Descriptor", "schema:name": "Premium Tech Electronics Store"}}}, {"@context": "https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/context.jsonld", "@type": "beckn:Item", "beckn:id": "headphones-item-001", "beckn:descriptor": {"@type": "beckn:Descriptor", "schema:name": "Aurora X200 Noise-Cancelling Headphones", "beckn:shortDesc": "Over-ear ANC, 40h battery, BT 5.3, multipoint"}, "beckn:category": {"@type": "schema:CategoryCode", "schema:codeValue": "electronics", "schema:name": "Electronics"}, "beckn:rateable": true, "beckn:rating": {"@type": "beckn:Rating", "beckn:ratingValue": 4.5, "beckn:ratingCount": 1543}, "beckn:networkId": ["bap.net/electronics"], "beckn:itemAttributes": {"@context": "https://example.org/schema/items/v1/ElectronicItem/schema-context.jsonld", "@type": "beckn:ElectronicItem", "electronic:brand": "Aurora", "electronic:model": "X200", "electronic:wirelessTech": "Bluetooth 5.3", "electronic:features": ["ANC", "Transparency Mode", "Multipoint"], "electronic:batteryLifeHours": 40, "electronic:chargingPort": "USB-C", "electronic:warranty": "12 months"}, "beckn:provider": {"beckn:id": "tech-store-001", "beckn:descriptor": {"@type": "beckn:Descriptor", "schema:name": "Premium Tech Electronics Store"}}}] - on_discover_grocery_catalog: - summary: Grocery catalog callback - value: - context: - version: "2.0.0" - action: "on_discover" - timestamp: "2024-04-10T16:10:50+05:30" - message_id: "c3d4e5f6-a7b8-49c0-9dab-ef1234567890" - transaction_id: "d4e5f6a7-b8c9-4ad1-8cab-1234567890ef" - bpp_id: "bpp.example.com" - bpp_uri: "https://bpp.example.com" - ttl: "PT30S" - message: - catalogs: - - "@context": "https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/context.jsonld" - "@type": "beckn:Catalog" - "beckn:id": "catalog-grocery-001" - "beckn:descriptor": {"@type": "beckn:Descriptor", "schema:name": "Fresh Grocery Store"} - "beckn:items": [{"@context": "https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/context.jsonld", "@type": "beckn:Item", "beckn:id": "apples-item-001", "beckn:descriptor": {"@type": "beckn:Descriptor", "schema:name": "Organic Fuji Apples (1 kg)", "beckn:shortDesc": "Crisp, sweet USDA Organic apples — farm fresh"}, "beckn:category": {"@type": "schema:CategoryCode", "schema:codeValue": "grocery", "schema:name": "Grocery"}, "beckn:rateable": true, "beckn:rating": {"@type": "beckn:Rating", "beckn:ratingValue": 4.6, "beckn:ratingCount": 387}, "beckn:networkId": ["bap.net/grocery"], "beckn:itemAttributes": {"@context": "https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/context.jsonld", "@type": "beckn:GroceryItem", "grocery:brand": "Fresh Fields", "grocery:organicCertification": "USDA Organic", "grocery:variety": "Fuji", "grocery:unitSize": "1 kg", "grocery:origin": "Himachal Pradesh, IN", "grocery:shelfLifeDays": 10}, "beckn:provider": {"beckn:id": "grocery-store-001", "beckn:descriptor": {"@type": "beckn:Descriptor", "schema:name": "Fresh Grocery Store"}}}, {"@context": "https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/context.jsonld", "@type": "beckn:Item", "beckn:id": "bread-item-001", "beckn:descriptor": {"@type": "beckn:Descriptor", "schema:name": "Whole Wheat Bread (500 g)", "beckn:shortDesc": "High-fiber artisan loaf, no added sugar"}, "beckn:category": {"@type": "schema:CategoryCode", "schema:codeValue": "grocery", "schema:name": "Grocery"}, "beckn:rateable": true, "beckn:rating": {"@type": "beckn:Rating", "beckn:ratingValue": 4.3, "beckn:ratingCount": 812}, "beckn:networkId": ["bap.net/grocery"], "beckn:itemAttributes": {"@context": "https://example.org/schema/items/v1/GroceryItem/schema-context.jsonld", "@type": "beckn:GroceryItem", "grocery:brand": "BakeHouse", "grocery:unitSize": "500 g", "grocery:ingredients": ["Whole wheat flour", "Yeast", "Salt", "Olive oil"], "grocery:allergens": ["Gluten"], "grocery:shelfLifeDays": 5}, "beckn:provider": {"beckn:id": "grocery-store-001", "beckn:descriptor": {"@type": "beckn:Descriptor", "schema:name": "Fresh Grocery Store"}}}] - # ---------- ACK / NACK examples ---------- - ack_success: - summary: ACK - value: - transaction_id: "e5f6a7b8-c9d0-4e1f-9a2b-3c4d5e6f7081" - timestamp: "2024-04-10T16:10:50+05:30" - ack_status: "ACK" - ack_bad_request: - summary: NACK — bad request - value: - transaction_id: "f6a7b8c9-d0e1-42f3-8a2b-3c4d5e6f7081" - timestamp: "2024-04-10T16:10:50+05:30" - ack_status: "NACK" - error: - code: "INVALID_REQUEST" - paths: "context.schema_context" - message: "Invalid schema context provided" - ack_server_error: - summary: NACK — internal error - value: - transaction_id: "a7b8c9d0-e1f2-43a4-9b2c-3d4e5f607081" - timestamp: "2024-04-10T16:10:50+05:30" - ack_status: "NACK" - error: - code: "INTERNAL_ERROR" - paths: "server" - message: "Internal server error occurred" - # ---------- /discover/browser-search JSON example ---------- - browser_search_electronic_items: - summary: Browser-search JSON response (electronics) - value: - id: "api.beckn.discover.browser-search" - ver: "v2" - ts: "2024-04-10T16:10:50+05:30" - params: - msgid: "0a1b2c3d-4e5f-6789-8a0b-1c2d3e4f5a6b" - traceid: "1b2c3d4e-5f60-4781-92a3-b4c5d6e7f809" - response: - context: - version: "2.0.0" - action: "on_discover" - catalogs: - - "@context": "https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/context.jsonld" - "@type": "beckn:Catalog" - "beckn:id": "catalog-electronics-001" - "beckn:descriptor": - "@type": "beckn:Descriptor" - "schema:name": "Premium Tech Electronics Store" - "beckn:shortDesc": "High-quality electronics and gaming equipment" - "beckn:validity": - "@type": "beckn:TimePeriod" - "schema:startDate": "2025-01-27T09:00:00Z" - "schema:endDate": "2026-12-31T23:59:59Z" - "beckn:items": - - "@context": "https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/context.jsonld" - "@type": "beckn:Item" - "beckn:id": "laptop-item-001" - "beckn:descriptor": - "@type": "beckn:Descriptor" - "schema:name": "Premium Gaming Laptop Pro" - "beckn:shortDesc": "High-performance gaming laptop with RTX graphics" - "beckn:category": - "@type": "schema:CategoryCode" - "schema:codeValue": "electronics" - "schema:name": "Electronics" - "beckn:rating": - "@type": "beckn:Rating" - "beckn:ratingValue": 4.8 - "beckn:ratingCount": 156 - "beckn:rateable": true - "beckn:networkId": ["bap.net/electronics"] - "beckn:itemAttributes": - "@context": "https://example.org/schema/items/v1/ElectronicItem/schema-context.jsonld" - "@type": "beckn:ElectronicItem" - "electronic:brand": "ASUS" - "electronic:model": "ROG Strix G15" - "electronic:processor": "Intel Core i7-12700H" - "electronic:ram": "16GB DDR4" - "electronic:storage": "512GB NVMe SSD" - "electronic:graphics": "NVIDIA RTX 3060" - "beckn:provider": - "beckn:id": "tech-store-001" - "beckn:descriptor": - "@type": "beckn:Descriptor" - "schema:name": "Premium Tech Store" - responses: - Ack200: - description: "ACK — request received (validation passed)" - content: - application/json: - schema: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/AckResponse' - examples: - success_ack: - $ref: '#/components/examples/ack_success' - Ack400: - description: Bad request - content: - application/json: - schema: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/AckResponse' - examples: - bad_request: - $ref: '#/components/examples/ack_bad_request' - Ack500: - description: Internal server error - content: - application/json: - schema: - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/AckResponse' - examples: - server_error: - $ref: '#/components/examples/ack_server_error' \ No newline at end of file diff --git a/api/beckn.yaml b/api/beckn.yaml new file mode 120000 index 0000000..4663a0e --- /dev/null +++ b/api/beckn.yaml @@ -0,0 +1 @@ +v2/beckn.yaml \ No newline at end of file diff --git a/api/v2.1/beckn.yaml b/api/v2.1/beckn.yaml new file mode 100644 index 0000000..ab86f5f --- /dev/null +++ b/api/v2.1/beckn.yaml @@ -0,0 +1,1212 @@ +openapi: 3.1.1 +info: + title: Beckn Protocol V2.0 API Specification + description: | + The API specification of Beckn Protocol covering the four stages of an order lifecycle: + - Discovery: Discovery of catalogs + - Ordering: Price negotiation, terms negotiation, and order confirmation + - Fulfillment: Order tracking, status updates, order updates and cancellation + - Post-fulfillment: Rating, feedback, and customer support + version: 2.1.0 + contact: + name: Beckn Protocol + url: https://beckn.io + license: + name: CC-BY-NC-SA 4.0 International + url: https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en + +paths: +# Discovery APIs + /beckn/discover: + get: + summary: Discover catalogs on a network + description: | + Search and discover catalogs on an open network. This endpoint can be implemented by Catalog Discovery Services, and BPPs. Supports text search, JSONPath-based filtering (RFC 9535), or both together with automatic schema adaptation. This endpoint returns an **ACK/NACK** confirming receipt/validation. Can be implemented by any entity hosting catalogs. + operationId: discoverCatalog + tags: [Catalog Discovery Service, BPP] + requestBody: + required: true + content: + application/json: + schema: + properties: + context: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Context' + - type: object + properties: + action: + const: discover + message: + $ref: '#/components/schemas/DiscoverMessage' + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + + /beckn/on_discover: + post: + summary: Callback response to `discover` request + description: | + Callback endpoint that contains Catalogs hosted by multiple BPPs. This endpoint is called by the BPP to return the search results after processing the discover request. **This endpoint returns only an ACK/NACK** confirming receipt and validation of the catalog payload. + operationId: onDiscoverCatalog + tags: [Catalog Publishing Service, BAP] + requestBody: + required: true + content: + application/json: + schema: + context: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Context' + - type: object + properties: + action: + const: on_discover + message: + $ref: '#/components/schemas/OnDiscoverMessage' + examples: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/examples/v2.1/on_discover.examples.yaml' + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + +# Ordering APIs + /beckn/select: + post: + summary: BAP requests for quote + description: 'The BAP selects the items, item quantities, associated offers, coupon codes, sometimes a proposed bid against a specfic selection, and requests the BPP to provide a quote. This action is performed without sharing any PII of the consumer. This action is particularly useful when the BAP and BPP have an ongoing commercial agreement independent of their users, that allows special rates and entitlements to their respective users. This action is also used for placing anonymous bids on a selection of items, especially during auctions.' + tags: [BPP] + requestBody: + required: true + content: + application/json: + schema: + context: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Context' + - type: object + properties: + action: + const: select + message: + $ref: '#/components/schemas/SelectMessage' + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + + /beckn/on_select: + post: + summary: BPP sends quote with optional additional forms + description: 'The BPP calculates the total cost, evaluates offers, verifies coupon codes, the proposed bid (if allowed) against a specfic selection, and generates a quote. At this stage, it is also recommended for the BPP to check the inventory for the availability of the items, or the serviceability of the order. In the case of auctions, the BPP can return the value of the highest bid to prompt the BAP user to match the bid or outbid the current value. Furthermore, in some cases, the BPP may require additional information to be provided initiate the order, sometimes even on external websites. In those cases, the BPP provides links to external forms that need to be filled and submitted before proceeding with the order.' + tags: [BAP] + requestBody: + required: true + content: + application/json: + schema: + context: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Context' + - type: object + properties: + action: + const: on_select + message: + $ref: '#/components/schemas/OnSelectMessage' + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + + /beckn/init: + post: + summary: BAP requests final draft order with terms + description: BAP initates the final order by providing all billing, fulfillment, and source payment information required for calculating the final terms of the order, and also references to any form data that may have submitted outside the transaction layer in previous interactions. Upon receiving a successful ACK response, the BAP should expect an `on_init` containing the final draft order with payment terms. Sometimes, the BPP may also send a successful `ACK` with a status code indicating that there may be additional forms that may need to be submitted on external URLs. Until the BAP receives an ACK response with a success code, it must continue calling the `init` endpoint of the BPP. Furthermore, the BAP must ensure that the form links are hosted on a trusted domain with a valid SSL certificate. If the form links are untrustworthy, the BAP MUST send a NACK with an appropriate error code. + tags: [BPP] + requestBody: + required: true + content: + application/json: + schema: + context: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Context' + - type: object + properties: + action: + const: init + message: + $ref: '#/components/schemas/InitMessage' + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + + /beckn/on_init: + post: + summary: BPP sends final draft of order with terms of service + description: BPP provides the final draft of the order after processing the billing, fulfillment, and source payment information provided by the buyer. In this state, the BPP can also send a personalized quote, payment terms, and freebies based on the credentials of the buyer. This is especially useful when the BPP user (i.e the Provider) offers loyalty programs. Furthermore, the BPP can also attach additional form links to the `Order` object requesting the BAP for additional information. Typical forms could include KYC forms, T&Cs and disclaimers, declarations, etc. The form links must contain a reference to the ongoing transaction. This reference is by default, a path or query parameter appended to the form link. The BAP MUST NOT delete this parameter as it will dereference the form data from the underlying transaction, thus rendering it invalid. The BPP MUST ensure that the forms links are trustworthy and are hosted on HTTP/S endpoints with a valid SSL certificate. Until the BPP has received all the information needed to proceed to confirmation, it must continue sending an ACK with a status code indicating the further information is needed from the BAP before proceeding to confirmation. The final on_init call with the draft order MUST contain a credentialized receipt of all form data the BAP user has submitted outside the Beckn API layer. Only the final on_init callback SHOULD contain the payment terms of the BPP. The BPP MUST NOT request the BAP for payment at any point before this stage. + tags: [BAP] + requestBody: + required: true + content: + application/json: + schema: + context: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Context' + - type: object + properties: + action: + const: on_init + message: + $ref: '#/components/schemas/OnInitMessage' + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + + /beckn/confirm: + post: + summary: BAP confirms the order + description: BAP accepts and fulfills any terms required before order confirmation, like payment proofs/references, links to attested documents, form data with submission reference, authorization tokens etc; and requests the BPP to confirm the order. + tags: [BPP] + requestBody: + required: true + content: + application/json: + schema: + context: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Context' + - type: object + properties: + action: + const: confirm + message: + $ref: '#/components/schemas/ConfirmMessage' + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + + /beckn/on_confirm: + post: + summary: BPP sends confirmed order + description: BPP evaluates if all the terms and conditions required for the creation of the order have been accepted and fulfilled (including payment), and sends a confirmed order with Order ID with the latest state of fulfillment. + tags: [BAP] + requestBody: + required: true + content: + application/json: + schema: + context: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Context' + - type: object + properties: + action: + const: on_confirm + message: + $ref: '#/components/schemas/OnConfirmMessage' + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + +# Fulfillment APIs + /beckn/status: + post: + summary: BAP requests latest state of the order + tags: [BPP] + requestBody: + required: true + content: + application/json: + schema: + context: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Context' + - type: object + properties: + action: + const: status + message: + $ref: '#/components/schemas/StatusMessage' + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + + /beckn/on_status: + post: + summary: BPP sends the latest state of the order with fulfillment status. + description: BPP sends the latest state of the order with fulfillment status. The BPP can independently call this endpoint any number of times without the BAP explicitly requesting it. However, the BPP must receive at least one `status` request from the BAP to initiate the on_status callback stream. The purpose of this endpoint is to notify the BAP users about any changes in the state of fulfillment. Typical scenarios include - the Order being picked up, the order being on its way, order almost at the door, etc. **Note - This endpoint is _NOT_ for real-time tracking - only status updates worth notifying the user through say, a push notification. So it is strongly recommended for BAPs to NOT long poll the BPP with `status` requests.** + tags: [BAP] + requestBody: + required: true + content: + application/json: + schema: + context: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Context' + - type: object + properties: + action: + const: on_status + message: + $ref: '#/components/schemas/OnStatusMessage' + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + + /beckn/update: + post: + summary: Request to update and active order + description: The BAP requests the BPP to update an active order and recalculate the terms, including payment. The updates may involve change of items, item quantities, billing information, fulfillment information, or payment information.' + tags: [BPP] + requestBody: + required: true + content: + application/json: + schema: + oneOf: + # Branch 1: context.try === true -> OnUpdateInitMessage + - type: object + required: [context, message] + properties: + context: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Context' + - type: object + properties: + action: + const: update + try: + const: true + message: + $ref: '#/components/schemas/UpdateInitMessage' + + # Branch 2: context.try === false -> OnUpdateConfirmMessage + - type: object + required: [context, message] + properties: + context: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Context' + - type: object + properties: + action: + const: update + try: + const: false + message: + $ref: '#/components/schemas/UpdateConfirmMessage' + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + + /beckn/on_update: + post: + summary: BPP sends updated order with updated terms, including payment. + description: 'The BPP sends an updated order with recalculated quote and payment terms. Typical scenarios include a fulfillment agent being allocated or reallocated, items updated or removed from the order, payment information updated, etc. This endpoint can be called any number of times by the BPP without the BAP explicitly requesting for it. Furthermore, the BPP may also use the `on_update` endpoint to request the user for additional information submitted via external form links to the `Order` object requesting the BAP for additional information. Typical forms could include KYC forms, T&Cs and disclaimers, declarations, etc. The form links must contain _two_ references to the ongoing transaction, namely - the `transaction_id` and the `order_id`, appended as a path or query parameter to the form URL. The BAP MUST NOT delete these parameters as it will dereference the form data from the underlying transaction, thus rendering it invalid. The BPP MUST ensure that the forms links are trustworthy and are hosted on HTTP/S endpoints with a valid SSL certificate. Until the BPP has received all the information needed to proceed to confirmation, it MUST continue sending multiple `on_update` calls with a status code indicating the further information is needed from the BAP before proceeding to confirmation. Each `on_update` call with the draft order MUST contain a credentialized receipt of all form data the BAP user has submitted outside the Beckn API layer. As the order is already active, the MAY request the BAP for payment at any point in this state.' + tags: [BAP] + requestBody: + required: true + content: + application/json: + schema: + oneOf: + # Branch 1: context.try === true -> OnUpdateInitMessage + - type: object + required: [context, message] + properties: + context: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Context' + - type: object + properties: + action: + const: on_update + try: + const: true + message: + $ref: '#/components/schemas/OnUpdateInitMessage' + + # Branch 2: context.try === false -> OnUpdateConfirmMessage + - type: object + required: [context, message] + properties: + context: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Context' + - type: object + properties: + action: + const: on_update + try: + const: false + message: + $ref: '#/components/schemas/OnUpdateConfirmMessage' + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + + /beckn/cancel: + post: + summary: Request to cancel an order + description: 'TODO' + tags: [BPP] + requestBody: + required: true + content: + application/json: + schema: + oneOf: + # Branch 1: context.try === true -> CancelInitMessage + - type: object + required: [context, message] + properties: + context: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Context' + - type: object + properties: + action: + const: cancel + try: + const: true + message: + $ref: '#/components/schemas/CancelInitMessage' + + # Branch 2: context.try === false -> CancelConfirmMessage + - type: object + required: [context, message] + properties: + context: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Context' + - type: object + properties: + action: + const: cancel + try: + const: false + message: + $ref: '#/components/schemas/CancelConfirmMessage' + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + + /beckn/on_cancel: + post: + summary: Provider returns cancelled order (may reflect refund/payment update via PaymentRef) + tags: [BAP] + requestBody: + required: true + content: + application/json: + schema: + oneOf: + # Branch 1: context.try === true -> OnCancelInitMessage + - type: object + required: [context, message] + properties: + context: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Context' + - type: object + properties: + action: + const: on_cancel + try: + const: true + message: + $ref: '#/components/schemas/OnCancelInitMessage' + + # Branch 2: context.try === false -> OnCancelConfirmMessage + - type: object + required: [context, message] + properties: + context: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Context' + - type: object + properties: + action: + const: on_cancel + try: + const: false + message: + $ref: '#/components/schemas/OnCancelConfirmMessage' + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + + /beckn/track: + post: + summary: Track order + description: Request to track an active order in real-time + tags: [BPP] + requestBody: + required: true + content: + application/json: + schema: + type: object + required: [context, message] + properties: + context: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Context' + - type: object + properties: + action: + const: track + message: + $ref: '#/components/schemas/TrackMessage' + + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + + /beckn/on_track: + post: + summary: Send real-time tracking handles for an active order + tags: [BAP] + requestBody: + required: true + content: + application/json: + schema: + type: object + required: [context, message] + properties: + context: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Context' + - type: object + properties: + action: + const: on_track + message: + $ref: '#/components/schemas/OnTrackMessage' + + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + +# Post-fulfillment APIs + + /beckn/rate: + post: + summary: Rate any aspect of an order. + tags: [BPP] + requestBody: + required: true + content: + application/json: + schema: + oneOf: + # Branch 1: context.try === true -> OnUpdateInitMessage + - type: object + required: [context, message] + properties: + context: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Context' + - type: object + properties: + try: + const: true + action: + const: rate + message: + $ref: '#/components/schemas/RateInitMessage' + + # Branch 2: context.try === false -> OnUpdateConfirmMessage + - type: object + required: [context, message] + properties: + context: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Context' + - type: object + properties: + try: + const: false + action: + const: rate + message: + $ref: '#/components/schemas/RateConfirmMessage' + + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + + /beckn/on_rate: + post: + summary: Provider acknowledges/returns rating receipt (optional aggregate snapshot) + tags: [BAP] + requestBody: + required: true + content: + application/json: + schema: + oneOf: + # Branch 1: context.try === true -> OnUpdateInitMessage + - type: object + required: [context, message] + properties: + context: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Context' + - type: object + properties: + try: + const: true + action: + const: on_rate + message: + $ref: '#/components/schemas/OnRateInitMessage' + + # Branch 2: context.try === false -> OnUpdateConfirmMessage + - type: object + required: [context, message] + properties: + context: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Context' + - type: object + properties: + try: + const: false + action: + const: on_rate + message: + $ref: '#/components/schemas/OnRateConfirmMessage' + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + + /beckn/support: + post: + summary: Request support details for an entity (order/item/provider/etc.) + tags: [BPP] + requestBody: + required: true + content: + application/json: + schema: + oneOf: + # Branch 1: context.try === true -> OnSupportInitMessage + - type: object + required: [context, message] + properties: + context: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Context' + - type: object + properties: + try: + const: true + action: + const: support + message: + $ref: '#/components/schemas/OnSupportInitMessage' + + # Branch 2: context.try === false -> OnSupportConfirmMessage + - type: object + required: [context, message] + properties: + context: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Context' + - type: object + properties: + try: + const: false + action: + const: support + message: + $ref: '#/components/schemas/OnSupportConfirmMessage' + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + + /beckn/on_support: + post: + summary: Provider returns support details + tags: [BAP] + requestBody: + required: true + content: + application/json: + schema: + type: object + required: [context, message] + properties: + context: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Context' + - type: object + properties: + action: + const: on_support + message: + type: object + required: [support] + properties: + support: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/SupportInfo' + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + +# Catalog Publishing Service APIs + + /beckn/catalog/publish: + post: + summary: Publish one or more catalogs for indexing + description: | + BPP submits catalogs to be indexed. Returns **ACK** immediately if accepted for processing. + The detailed per-catalog processing result arrives later via **/on_publish**. + operationId: publishCatalogs + tags: [Catalog Publishing Service] + requestBody: + required: true + content: + application/json: + schema: + type: object + required: [context, message] + properties: + context: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Context' + - type: object + properties: + action: + const: catalog/publish + message: + $ref: '#/components/schemas/CatalogPublishMessage' + + examples: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/examples/v2.1/on_publish.examples.yaml' + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + + /beckn/catalog/on_publish: + post: + summary: Callback with catalog publish processing results + description: | + Discovery Service calls back with per-catalog processing results (accepted/rejected, errors, derived stats). + The receiver should respond with an **AckResponse**. + operationId: onCatalogPublish + tags: [Provider] + requestBody: + required: true + content: + application/json: + schema: + type: object + required: [context, message] + properties: + context: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Context' + - type: object + properties: + action: + const: catalog/on_publish + message: + $ref: '#/components/schemas/CatalogOnPublishMessage' + examples: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/examples/v2.1/on_publish.examples.yaml' + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + +components: + schemas: + DiscoverMessage: + type: object + required: + - intent + properties: + intent: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Intent' + + OnDiscoverMessage: + type: object + required: + - catalogs + properties: + catalogs: + type: array + items: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Catalog' + + SelectMessage: + type: object + required: + - order + properties: + order: # Add API level constraints here + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Order' + + OnSelectMessage: + type: object + required: + - order + properties: + order: # Add API level constraints here + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Order' + + InitMessage: + type: object + required: + - order + properties: + order: # Add API level constraints here + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Order' + + OnInitMessage: + type: object + required: + - order + properties: + order: # Add API level constraints here + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Order' + + ConfirmMessage: + type: object + required: + - order + properties: + order: # Add API level constraints here + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Order' + + OnConfirmMessage: + type: object + required: + - order + properties: + order: # Add API level constraints here + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Order' + + StatusMessage: + type: object + required: + - order + properties: + order: + type: object + properties: + beckn:id: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Order/properties/beckn:id' + + OnStatusMessage: + type: object + required: + - order + properties: + order: # Add API level constraints here + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Order' + + UpdateInitMessage: + type: object + required: + - order + properties: + order: # Add API level constraints here + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Order' + + UpdateConfirmMessage: + type: object + required: + - order + properties: + order: # Add API level constraints here + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Order' + + OnUpdateInitMessage: + type: object + required: + - order + properties: + order: # Add API level constraints here + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Order' + + OnUpdateConfirmMessage: + type: object + required: + - order + properties: + order: # Add API level constraints here + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Order' + + TrackMessage: + type: object + required: + - tracking + properties: + tracking: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/TrackAction' + - required: [orderId, refId] + + OnTrackMessage: + type: object + required: + - tracking + properties: + tracking: + tracking: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/TrackAction' + - required: [orderId, refId] + + CancelInitMessage: + type: object + required: + - order + properties: + cancelAction: + type: object + properties: + order: + type: object + additionalProperties: false + required: + - beckn:id + properties: + beckn:id: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Order/properties/beckn:id' + reason: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/CancellationDetails' + + OnCancelInitMessage: + type: object + required: + - cancelAction + properties: + cancelAction: + type: object + properties: + order: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Order' + - required: [beckn:id, beckn:cancellationPolicy] + reason: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/CancellationDetails' + + CancelConfirmMessage: + type: object + required: + - cancelAction + properties: + cancelAction: + type: object + required: [order, reason] + properties: + order: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Order' + - required: [id, docs] + reason: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/CancellationReason' + # Cancellation Reasons, are part of metadata of a cancellationAction + + OnCancelConfirmMessage: + type: object + required: + - cancelAction + properties: + cancelAction: + type: object + properties: + order: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Order' + - required: [cancellationPolicy, cancellationOutcome, docs] + reason: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/CancellationReason' + + RateInitMessage: + type: object + required: + - order + properties: + order: + type: object + properties: + beckn:id: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Order/properties/id' + + OnRateInitMessage: + type: object + required: + - order + properties: + order: + type: object + properties: + beckn:id: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Order/properties/id' + ratings: + type: array + items: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Rating' + feedback: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Feedback' + + RateConfirmMessage: + order: + type: object + properties: + beckn:id: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Order/properties/id' + ratings: + type: array + items: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Rating' + feedback: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Feedback' + + OnRateConfirmMessage: + type: object + required: + - rating + properties: + order: + type: object + properties: + beckn:id: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Order/properties/id' + ratings: + type: array + items: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Rating' + feedback: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Feedback' + + SupportInitMessage: + type: object + required: + - support + properties: + support: + type: object + properties: + order: + type: object + properties: + beckn:id: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Order/properties/id' + required: + - beckn:id + + OnSupportInitMessage: + type: object + required: + - support + properties: + support: + type: object + properties: + order: + type: object + properties: + beckn:id: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Order/properties/id' + required: + - beckn:id + methods: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/SupportMethods' + tickets: + type: array + items: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Ticket' + + SupportConfirmMessage: + type: object + required: + - support + properties: + support: + type: object + properties: + order: + type: object + properties: + beckn:id: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Order/properties/id' + required: + - beckn:id + methods: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/SupportMethods' + tickets: + type: array + items: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Ticket' + + OnSupportConfirmMessage: + type: object + required: + - support + properties: + support: + type: object + properties: + order: + type: object + properties: + beckn:id: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Order/properties/id' + required: + - beckn:id + methods: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/SupportMethods' + tickets: + type: array + items: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Ticket' + + CatalogPublishMessage: + type: object + required: + - catalogs + properties: + catalogs: + type: array + description: Array of catalogs containing items + items: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/Catalog' + minItems: 1 + description: | + Catalog Publish request envelope. + *context.version* MUST indicate the supported protocol version (e.g., "2.0.0"). + + OnCatalogPublishMessage: + type: object + required: + - results + properties: + results: + type: array + description: Per-catalog processing results + items: + $ref: '#/components/schemas/CatalogProcessingResult' + + responses: + Ack200: + description: "ACK — request received (validation passed)" + content: + application/json: + schema: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/AckResponse' + examples: + success_ack: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/examples/v2.1/ack.examples.yaml#/ack_success' + Ack400: + description: Bad request + content: + application/json: + schema: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/AckResponse' + examples: + bad_request: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/examples/v2.1/ack.examples.yaml#/ack_bad_request' + Ack500: + description: Internal server error + content: + application/json: + schema: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/attributes.yaml#/components/schemas/AckResponse' + examples: + server_error: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/examples/v2.1/ack.examples.yaml#/ack_server_error' \ No newline at end of file diff --git a/api/v2/beckn.yaml b/api/v2/beckn.yaml new file mode 100644 index 0000000..7b2486c --- /dev/null +++ b/api/v2/beckn.yaml @@ -0,0 +1,1688 @@ +openapi: 3.1.1 +info: + title: Beckn Protocol API + description: | + A unified OpenAPI specification for the Beckn Protocol covering: + - Discovery: Search and discover items across multiple schemas + - Transaction: Order lifecycle (select, init, confirm, update, cancel, status, track, support, rating) + - Catalog Publish: Asynchronous catalog ingestion for Discovery Service + + This specification combines the Discovery API, Transaction API, and Catalog Publish API into a single comprehensive document. + version: 2.0.0 + contact: + name: Beckn Protocol + url: https://becknprotocol.io + license: + name: MIT + url: https://opensource.org/licenses/MIT + +servers: + - url: https://staging-api.becknprotocol.io + description: Staging server + - url: http://localhost:8080 + description: Local development server + +paths: + /beckn/discover: + get: + summary: Discover items across multiple schemas + description: | + Search and discover items across any schemas in Beckn Schema registry. Supports text search, JSONPath-based filtering (RFC 9535), or both together with automatic schema adaptation. This endpoint may return either an **ACK/NACK** confirming receipt/validation or a synchronous **DiscoverResponse** providing discovery results in catalog format. Networks may still choose to deliver results asynchronously via **/beckn/on_discover**. + operationId: discoverItems + tags: [Discovery] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/DiscoverRequest' + examples: + structured_query: + $ref: '#/components/examples/discover_structured_query' + natural_language: + $ref: '#/components/examples/discover_natural_language' + grocery_search: + $ref: '#/components/examples/discover_grocery_search' + combined_search: + $ref: '#/components/examples/discover_combined_search' + multi_schema_search: + $ref: '#/components/examples/discover_multi_schema_search' + responses: + '200': + description: ACK — received the discover request (validation passed) + content: + application/json: + schema: + oneOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/AckResponse' + - $ref: '#/components/schemas/DiscoverResponse' + examples: + discover_electronics_catalog: + $ref: '#/components/examples/on_discover_electronics_catalog' + discover_grocery_catalog: + $ref: '#/components/examples/on_discover_grocery_catalog' + success_ack: + $ref: '#/components/examples/ack_success' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + /beckn/on_discover: + post: + summary: On Discover response with catalog data + description: | + Callback endpoint that provides the actual discovery results in catalog format. This endpoint is called by the BPP to return the search results after processing the discover request. **This endpoint returns only an ACK/NACK** confirming receipt and validation of the catalog payload. + operationId: onDiscoverItems + tags: [Discovery] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/DiscoverResponse' + examples: + electronic_items_catalog: + $ref: '#/components/examples/on_discover_electronics_catalog' + grocery_items_catalog: + $ref: '#/components/examples/on_discover_grocery_catalog' + responses: + '200': + description: ACK — received catalog data for the corresponding discover request + content: + application/json: + schema: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/AckResponse' + examples: + success_ack: + $ref: '#/components/examples/ack_success' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + /beckn/discover/browser-search: + get: + summary: Browser-friendly search API + description: | + URL-based search API for browser navigation and direct links using JSONPath expressions. + Response format is determined by the Accept header: + - Accept: text/html → Returns browser-friendly HTML page (default) + - Accept: application/json → Returns structured JSON data in same format as structured query API + + Supports complex filtering via URL-encoded JSONPath expressions. + Generic search across all entity types (items, providers, catalogs) based on filter criteria. + operationId: browserSearch + tags: [Browser Search] + parameters: + - name: Accept + in: header + required: false + schema: + type: string + enum: ["text/html", "application/json"] + default: "text/html" + description: | + Response format preference. + - Accept: text/html → Returns browser-friendly HTML page (default) + - Accept: application/json → Returns structured JSON data in same format as structured query API + examples: + default: + value: "text/html" + - name: filters + in: query + required: false + schema: + type: string + description: URL-encoded JSONPath expression for complex filtering + examples: + sample: + value: "%24%5B%3F%28%40.price%20%3C%3D%201000%20%26%26%20%40.brand%20%3D%3D%20%27Premium%20Tech%27%29%5D" + responses: + '200': + description: Successful search response + content: + text/html: + schema: + type: string + examples: + html_example: + summary: Browser-friendly HTML page + value: | + Search Results - Premium Tech Electronics | Beckn Catalog + Search + + # Premium Tech Electronics Store + + High-quality electronics and gaming equipment + + Available from Jan 27, 2025 to Dec 31, 2026 + + ## Premium Gaming Laptop Pro + + High-performance gaming laptop with RTX graphics + + ★★★★★ 4.8 (156 reviews) + + $1,499.99 USD + + Brand: Premium Tech + + ID: laptop-item-001 + + © 2024 Beckn Catalog. Powered by Beckn Protocol. + application/json: + schema: + $ref: '#/components/schemas/DiscoverResponse' + examples: + electronic_items: + $ref: '#/components/examples/browser_search_electronic_items' + '400': + description: Bad request - Invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + examples: + invalid_entity_type: + summary: Invalid entity type error + description: Error when entity_type is missing or invalid + value: + error: + code: "INVALID_ENTITY_TYPE" + message: "entity_type is required and must be one of: item, provider, catalog" + '404': + description: No results found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + examples: + no_results: + summary: No results found error + description: Error when no items match the search criteria + value: + error: + code: "NO_RESULTS_FOUND" + message: "No items found matching the specified criteria" + details: + search_criteria: + entity_type: "item" + category: "electric_vehicles" + price_max: 50000 + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + /beckn/select: + post: + summary: "Buyer selects items/offers — returns priced order" + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - context + - message + properties: + context: + allOf: + - $ref: '#/components/schemas/TransactionContext' + - type: object + properties: + action: + const: select + message: + type: object + required: + - order + properties: + order: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Order' + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + /beckn/on_select: + post: + summary: Provider returns priced order (quote) + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - context + - message + properties: + context: + allOf: + - $ref: '#/components/schemas/TransactionContext' + - type: object + properties: + action: + const: on_select + message: + type: object + required: + - order + properties: + order: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Order' + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + /beckn/init: + post: + summary: Initialize order (party details, fulfillment mode, payment intent) + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - context + - message + properties: + context: + allOf: + - $ref: '#/components/schemas/TransactionContext' + - type: object + properties: + action: + const: init + message: + type: object + required: + - order + properties: + order: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Order' + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + /beckn/on_init: + post: + summary: Provider echoes initialized order (with refs populated) + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - context + - message + properties: + context: + allOf: + - $ref: '#/components/schemas/TransactionContext' + - type: object + properties: + action: + const: on_init + message: + type: object + required: + - order + properties: + order: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Order' + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + /beckn/confirm: + post: + summary: Confirm order (final selections; payment/fulfillment committed) + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - context + - message + properties: + context: + allOf: + - $ref: '#/components/schemas/TransactionContext' + - type: object + properties: + action: + const: confirm + message: + type: object + required: + - order + properties: + order: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Order' + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + /beckn/on_confirm: + post: + summary: Provider returns confirmed order + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - context + - message + properties: + context: + allOf: + - $ref: '#/components/schemas/TransactionContext' + - type: object + properties: + action: + const: on_confirm + message: + type: object + required: + - order + properties: + order: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Order' + - type: object + required: + - beckn:id + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + /beckn/status: + post: + summary: Fetch order status by id + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - context + - message + properties: + context: + allOf: + - $ref: '#/components/schemas/TransactionContext' + - type: object + properties: + action: + const: status + message: + type: object + required: + - order + properties: + order: + oneOf: + - type: object + additionalProperties: false + required: + - beckn:id + properties: + beckn:id: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Order/properties/beckn:id' + - allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Order' + - type: object + required: + - beckn:id + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + /beckn/on_status: + post: + summary: Provider returns current order (or tracking via fulfillment packs) + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - context + - message + properties: + context: + allOf: + - $ref: '#/components/schemas/TransactionContext' + - type: object + properties: + action: + const: on_status + message: + type: object + properties: + order: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Order' + - type: object + required: + - beckn:id + anyOf: + - required: + - order + - required: [] + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + /beckn/update: + post: + summary: Request order mutation (replace, cancel line, address change, etc.) + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - context + - message + properties: + context: + allOf: + - $ref: '#/components/schemas/TransactionContext' + - type: object + properties: + action: + const: update + message: + type: object + required: + - order + properties: + order: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Order' + - type: object + required: + - beckn:id + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + /beckn/on_update: + post: + summary: Provider returns mutated order + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - context + - message + properties: + context: + allOf: + - $ref: '#/components/schemas/TransactionContext' + - type: object + properties: + action: + const: on_update + message: + type: object + required: + - order + properties: + order: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Order' + - type: object + required: + - beckn:id + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + /beckn/cancel: + post: + summary: Request to cancel an order + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - context + - message + properties: + context: + allOf: + - $ref: '#/components/schemas/TransactionContext' + - type: object + properties: + action: + const: cancel + message: + type: object + required: + - order + properties: + order: + oneOf: + - type: object + additionalProperties: false + required: + - beckn:id + properties: + beckn:id: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Order/properties/beckn:id' + beckn:orderItems: + type: array + minItems: 1 + items: + oneOf: + - type: object + required: + - beckn:orderedItem + properties: + beckn:orderedItem: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Item/properties/beckn:id' + beckn:lineId: + type: string + description: Unique line id within order + beckn:quantity: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Quantity' + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/OrderItem' + - allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Order' + - type: object + required: + - beckn:id + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + /beckn/on_cancel: + post: + summary: Provider returns cancelled order (may reflect refund/payment update via PaymentRef) + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - context + - message + properties: + context: + allOf: + - $ref: '#/components/schemas/TransactionContext' + - type: object + properties: + action: + const: on_cancel + message: + type: object + required: + - order + properties: + order: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Order' + - type: object + required: + - beckn:id + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + /beckn/support: + post: + summary: Request support details for an entity (order/item/provider/etc.) + requestBody: + required: true + content: + application/json: + schema: + type: object + required: [context, message] + properties: + context: + allOf: + - $ref: '#/components/schemas/TransactionContext' + - type: object + properties: + action: + const: support + message: + type: object + required: [refId, refType] + properties: + refId: + type: string + description: ID of the entity for which support is requested (order/item/fulfillment/provider/agent). # legacy kept minimal + refType: + type: string + description: Entity type for which support is requested. + enum: [ORDER, FULFILLMENT, ITEM, PROVIDER, AGENT, OTHER] + support: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/SupportInfo' + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + /beckn/on_support: + post: + summary: Provider returns support details + requestBody: + required: true + content: + application/json: + schema: + type: object + required: [context, message] + properties: + context: + allOf: + - $ref: '#/components/schemas/TransactionContext' + - type: object + properties: + action: + const: on_support + message: + type: object + required: [support] + properties: + support: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/SupportInfo' + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + /beckn/track: + post: + summary: Request tracking handle/link for an active order/fulfillment + requestBody: + required: true + content: + application/json: + schema: + type: object + required: [context, message] + properties: + context: + allOf: + - $ref: '#/components/schemas/TransactionContext' + - type: object + properties: + action: + const: track + message: + type: object + required: + - tracking + properties: + tracking: + type: object + required: + - id + properties: + id: + type: string + description: Tracking identifier + callbackUrl: + type: string + format: uri + description: Optional callback URL for streaming tracking coordinates/updates + mode_hint: + type: string + description: Optional delivery mode for the tracking handle. + enum: [link_only, deep_link, webhook, ws_handle] + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + /beckn/on_track: + post: + summary: Provider returns tracking handle/link and status + requestBody: + required: true + content: + application/json: + schema: + type: object + required: [context, message] + properties: + context: + allOf: + - $ref: '#/components/schemas/TransactionContext' + - type: object + properties: + action: + const: on_track + message: + type: object + required: + - tracking + properties: + tracking: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/TrackAction' + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + /beckn/rating: + post: + summary: Submit a rating (optionally with feedback) for an entity + requestBody: + required: true + content: + application/json: + schema: + type: object + required: [context, message] + properties: + context: + allOf: + - $ref: '#/components/schemas/TransactionContext' + - type: object + properties: + action: + const: rating + message: + ratings: + type: array + items: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/RatingInput' + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + /beckn/on_rating: + post: + summary: Provider acknowledges/returns rating receipt (optional aggregate snapshot) + requestBody: + required: true + content: + application/json: + schema: + type: object + required: [context, message] + properties: + context: + allOf: + - $ref: '#/components/schemas/TransactionContext' + - type: object + properties: + action: + const: on_rating + message: + type: object + properties: + received: + type: boolean + default: true + aggregate: + type: object + description: Optional current aggregate rating snapshot. + properties: + count: + type: integer + minimum: 0 + value: + type: number + minimum: 0 + best: + type: number + minimum: 0 + worst: + type: number + minimum: 0 + feedbackForm: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Form' + description: Optional feedback form for additional detailed feedback collection + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + /beckn/catalog/publish: + post: + summary: Publish one or more catalogs for indexing + description: | + BPP submits catalogs to be indexed. Returns **ACK** immediately if accepted for processing. + The detailed per-catalog processing result arrives later via **/on_catalog_publish**. + operationId: publishCatalogs + tags: [Catalog Publish] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CatalogPublishRequest' + examples: + publish_basic: + summary: Minimal publish + value: + context: + version: "2.0.0" + action: "catalog_publish" + timestamp: "2025-09-01T10:30:00+05:30" + message_id: "u-req-123" + transaction_id: "u-txn-123" + bap_id: "bpp.example.com" + bap_uri: "https://bpp.example.com/callbacks" # where /on_catalog_publish is exposed + ttl: "PT30S" + catalogs: + - "@context": "https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/EvChargingOffer/v1/context.jsonld" + "@type": "beckn:Catalog" + "beckn:id": "catalog-001" + "beckn:descriptor": {"@type": "beckn:Descriptor", "schema:name": "BPP Test Catalog"} + "beckn:items": [] + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' + /beckn/catalog/on_publish: + post: + summary: Callback with catalog publish processing results + description: | + Discovery Service calls back with per-catalog processing results (accepted/rejected, errors, derived stats). + The receiver should respond with an **AckResponse**. + operationId: onCatalogPublish + tags: [Catalog Publish] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CatalogPublishResponse' + examples: + results_basic: + summary: Example processing results + value: + context: + version: "2.0.0" + action: "on_catalog_publish" + timestamp: "2025-09-01T10:31:05+05:30" + message_id: "u-resp-123" + transaction_id: "u-txn-123" + bpp_id: "discovery-indexer.example.com" + bpp_uri: "https://discovery-indexer.example.com" + ttl: "PT30S" + message: + results: + - catalog_id: "catalog-001" + status: "ACCEPTED" + item_count: 42 + warnings: + - code: "NON_NORMALIZED_BRAND" + message: "Some brand values were normalized" + - catalog_id: "catalog-002" + status: "REJECTED" + error: + code: "INVALID_ITEM" + message: "Invalid item payload at index 3" + paths: "catalogs[1].items[3]" + responses: + '200': + $ref: '#/components/responses/Ack200' + '400': + $ref: '#/components/responses/Ack400' + '500': + $ref: '#/components/responses/Ack500' +components: + schemas: + DiscoverRequest: + type: object + required: [context] + properties: + context: + allOf: + - $ref: '#/components/schemas/DiscoveryContext' + - type: object + properties: + action: + type: string + enum: [discover] + message: + type: object + description: Discover payload containing search criteria + properties: + text_search: + type: string + description: Free text search query for items + example: "gaming laptop premium tech" + filters: + type: object + description: Filter criteria for items + properties: + type: + type: string + enum: [jsonpath] + default: jsonpath + description: Type of filter expression + expression: + type: string + description: Filter expression based on the specified type + example: "$[?(@.rating.value >= 4.0 && @.electronic.brand.name == 'Premium Tech')]" + required: [type, expression] + spatial: + type: array + description: Optional array of spatial constraints (CQL2-JSON semantics). + items: + $ref: '#/components/schemas/SpatialConstraint' + media_search: + $ref: '#/components/schemas/MediaSearch' + anyOf: + - required: [text_search] + - required: [filters] + - required: [spatial] + - required: [filters, spatial] + DiscoverResponse: + type: object + required: [context, message] + properties: + context: + allOf: + - $ref: '#/components/schemas/DiscoveryContext' + - type: object + properties: + action: + type: string + enum: [on_discover] + message: + type: object + properties: + catalogs: + type: array + description: Array of catalogs containing items + items: + $ref: '#/components/schemas/Catalog' + DiscoveryContext: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications/refs/heads/master/api/transaction/build/transaction.yaml#/components/schemas/Context' + - type: object + description: Beckn Context extended for Discovery. + properties: + schema_context: + type: array + items: + type: string + format: uri + description: Optional JSON-LD context URLs indicating item types to search across + GeoJSONGeometry: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/GeoJSONGeometry' + Address: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Address' + Location: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Location' + SpatialConstraint: + type: object + description: > + **Spatial predicate** using **OGC CQL2 (JSON semantics)** applied to one or more geometry targets in an item. This is where clients express spatial intent. + + Key ideas: - `targets`: one or more **JSONPath-like** pointers that locate geometry + + fields within each item document (e.g., `$['beckn:availableAt'][*]['geo']`). + - `op`: spatial operator (CQL2). Common ones: + + • `s_within` (A is completely inside B) + • `s_intersects` (A intersects B) + • `s_contains` (A contains B) + • `s_dwithin` (A within distance of B) + - `geometry`: **GeoJSON** literal used as the predicate reference geometry. - `distanceMeters`: required for `s_dwithin` when using a GeoJSON Point/shape. - `quantifier`: if a target resolves to an array, choose whether **any** (default), + + **all**, or **none** of elements must satisfy the predicate. + + CRS: unless otherwise stated, all coordinates are **EPSG:4326**. + + required: [op, targets] + properties: + op: + type: string + enum: + - s_within + - s_contains + - s_intersects + - s_disjoint + - s_overlaps + - s_crosses + - s_touches + - s_equals + - s_dwithin + description: OGC CQL2 spatial operator. + targets: + description: > + One or more JSONPath-like pointers to geometry fields within the item. Example pointers: - `$['beckn:availableAt'][*]['geo']` (array of site Points) - `$['beckn:itemAttributes']['ride:dropOff']['geo']` (drop zone Polygon) + + oneOf: + - type: string + - type: array + items: {type: string} + geometry: + $ref: '#/components/schemas/GeoJSONGeometry' + distanceMeters: + type: number + minimum: 0 + description: > + For `s_dwithin`: maximum distance in meters from the target geometry to `geometry` (e.g., “within 5000 m of this Point”). Ignored for other ops. + + quantifier: + type: string + enum: [any, all, none] + default: any + description: > + How to evaluate when `targets` resolves to an array: - **any**: at least one element matches (default) - **all**: every element must match - **none**: no element may match + + srid: + type: string + description: > + Coordinate Reference System identifier for `geometry`. Default is `"EPSG:4326"`. If provided, servers MAY reproject to EPSG:4326 internally. + + example: "EPSG:4326" + additionalProperties: false + examples: + within_circle_as_distance: + summary: EV sites within 5 km of a center (via s_dwithin) + value: + op: s_dwithin + targets: "$['beckn:availableAt'][*]['geo']" + geometry: + type: Point + coordinates: [77.5946, 12.9716] + distanceMeters: 5000 + pickup_at_point: + summary: Pickup at a defined point (GeoJSON Point) + description: > + Example of a DiscoverRequest spatial constraint representing a specific pickup location. The requester defines a GeoJSON Point as the pickup location, and the server finds providers whose service area **contains** this point. + + value: + op: s_contains + targets: "$['beckn:itemAttributes']['ride:serviceArea']['geo']" # provider polygon field + geometry: + type: Point + coordinates: [77.5946, 12.9716] # MG Road (Bengaluru) — [lon, lat] + drop_intersects_user_box: + summary: Provider drop zone intersects user’s rectangle + value: + op: s_intersects + targets: "$['beckn:itemAttributes']['ride:dropOff']['geo']" + geometry: + type: Polygon + coordinates: + - [[77.6100, 12.9200], [77.6400, 12.9200], [77.6400, 12.9500], [77.6100, 12.9500], [77.6100, 12.9200]] + pickup_location_example: + summary: A defined pickup location object + value: + geo: + type: Point + coordinates: [77.5946, 12.9716] # [lon, lat] + address: + streetAddress: "MG Road" + addressLocality: "Bengaluru" + addressRegion: "Karnataka" + postalCode: "560001" + addressCountry: "IN" + MediaSearch: + type: object + description: > + Container for multimodal search inputs and configuration. Supports searching through **images, audio notes, and videos** alongside text, filters, and spatial predicates. For GET, this object should be JSON-encoded and URL-escaped. + + properties: + media: + type: array + description: > + One or more references to **images, audio notes, or videos** supplied as part of a multimodal search. Each entry references a media resource accessible via HTTPS or data URI. + + items: + $ref: '#/components/schemas/MediaInput' + example: + - id: "snap-1" + type: image + url: "https://cdn.example.com/user/snaps/ccs2-cable.jpg" + contentType: "image/jpeg" + options: + $ref: '#/components/schemas/MediaSearchOptions' + description: > + Options controlling how the discovery engine interprets the supplied media — e.g., whether to perform OCR/ASR, semantic similarity, or object detection. + + additionalProperties: false + example: + media: + - id: "snap-1" + type: image + url: "https://cdn.example.com/user/snaps/ccs2-cable.jpg" + contentType: "image/jpeg" + options: + goals: ["visual-object-detect", "text-from-image"] + augment_text_search: true + MediaInput: + type: object + description: Reference to an image, audio clip, or video used for multimodal search. + required: [type, url] + properties: + id: + type: string + description: Client-supplied identifier for this media input. + type: + type: string + enum: [image, audio, video] + description: Media category. + url: + type: string + format: uri + description: HTTPS URL or data URI pointing to the media resource. + contentType: + type: string + description: MIME type, e.g., image/jpeg, audio/mpeg, video/mp4. + textHint: + type: string + description: Optional pre-extracted text (OCR/ASR) for search augmentation. + language: + type: string + description: Language code (BCP-47) of `textHint` or spoken audio. + startMs: + type: integer + description: Optional start offset in milliseconds (for audio/video segments). + endMs: + type: integer + description: Optional end offset in milliseconds (for audio/video segments). + additionalProperties: false + MediaSearchOptions: + type: object + description: How the discovery engine should use the provided media inputs. + properties: + goals: + type: array + description: > + Desired processing goals for the media. + + items: + type: string + enum: + - visual-similarity # find visually similar items + - visual-object-detect # detect object classes within image/video + - text-from-image # extract text (OCR) + - text-from-audio # extract text (ASR) + - semantic-audio-match # audio embedding similarity + - semantic-video-match # video scene/keyframe similarity + augment_text_search: + type: boolean + default: true + description: > + Whether to append extracted text from OCR/ASR to `text_search`. + + restrict_results_to_media_proximity: + type: boolean + default: false + description: > + Restrict results to spatial proximity of media-derived coordinates (e.g., EXIF GPS tags). + + additionalProperties: false + AckResponse: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/AckResponse' + Catalog: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Catalog' + Item: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Item' + Offer: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Offer' + Attributes: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Attributes' + Provider: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Provider' + PriceSpecification: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/PriceSpecification' + Eligibility: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Eligibility' + Descriptor: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Descriptor' + CategoryCode: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/CategoryCode' + TimePeriod: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/TimePeriod' + Rating: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Rating' + ErrorResponse: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/ErrorResponse' + Error: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Error' + TransactionContext: + allOf: + - $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications/refs/heads/master/api/transaction/build/transaction.yaml#/components/schemas/Context' + - type: object + description: > + Beckn Context extended for Transaction flows. Mirrors DiscoveryContext pattern to enable validation and per-endpoint action constraints. network_id/schema_context are optional for routing and JSON-LD hints. + + properties: + network_id: + type: array + items: {type: string} + description: Optional list of addressed networks (for routing/allowlisting) + schema_context: + type: array + items: + type: string + format: uri + description: Optional JSON-LD context URLs relevant to the items/offers in this transaction + # -------------------------------- + # Core schemas (referenced from attributes.yaml) + # -------------------------------- + Order: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Order' + OrderItem: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/OrderItem' + Invoice: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Invoice' + Fulfillment: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Fulfillment' + TrackAction: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/TrackAction' + Payment: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Payment' + Buyer: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Buyer' + SupportInfo: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/SupportInfo' + Tracking: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Tracking' + RatingInput: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/RatingInput' + # ---------- Envelopes ---------- + CatalogPublishRequest: + type: object + required: [context, message] + properties: + context: + allOf: + - $ref: '#/components/schemas/DiscoveryContext' + - type: object + properties: + action: + type: string + enum: [catalog_publish] + message: + type: object + required: [catalogs] + properties: + catalogs: + type: array + description: Array of catalogs containing items + items: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Catalog' + minItems: 1 + description: | + Catalog Publish request envelope. + *context.version* MUST indicate the supported protocol version (e.g., "2.0.0"). + CatalogPublishResponse: + type: object + required: [context, message] + properties: + context: + allOf: + - $ref: '#/components/schemas/DiscoveryContext' + - type: object + properties: + action: + type: string + enum: [on_catalog_publish] + message: + type: object + properties: + results: + type: array + description: Per-catalog processing results + items: + $ref: '#/components/schemas/CatalogProcessingResult' + # ---------- Result model ---------- + CatalogProcessingResult: + type: object + required: [catalog_id, status] + properties: + catalog_id: + type: string + description: The "beckn:id" of the submitted catalog + status: + type: string + enum: [ACCEPTED, REJECTED, PARTIAL] + description: Final processing outcome for this catalog + item_count: + type: integer + minimum: 0 + description: Number of items indexed (when accepted/partial) + warnings: + type: array + description: Non-fatal issues encountered + items: + $ref: '#/components/schemas/ProcessingNotice' + error: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/Error' + ProcessingNotice: + type: object + required: [code, message] + properties: + code: + type: string + message: + type: string + details: + type: object + additionalProperties: true + examples: + # ---------- /discover request examples ---------- + discover_structured_query: + summary: Structured discover (electronics) + value: + context: + version: "2.0.0" + action: "discover" + timestamp: "2024-04-10T16:10:50+05:30" + message_id: "5c8f1a2b-9d3e-4f76-8b21-3a4c5d6e7f80" + transaction_id: "d3b07384-4a1c-4f5e-9c2b-7e6d5c4b3a21" + bap_id: "bap.example.com" + bap_uri: "https://bap.example.com" + ttl: "PT30S" + schema_context: + - "https://example.org/schema/items/v1/ElectronicItem/schema-context.jsonld" + message: + text_search: "gaming laptop premium tech" + filters: + type: "jsonpath" + expression: "$[?(@.rating.value >= 4 && @.electronic.brand.name == 'Premium Tech')]" + discover_natural_language: + summary: Natural-language discover (electronics) + value: + context: + version: "2.0.0" + action: "discover" + timestamp: "2024-04-10T16:10:50+05:30" + message_id: "9a7b6c5d-8e4f-4a3b-9c2d-1e0f2a3b4c5d" + transaction_id: "1f2e3d4c-5b6a-4789-8c0d-1a2b3c4d5e6f" + bap_id: "bap.example.com" + bap_uri: "https://bap.example.com" + ttl: "PT30S" + schema_context: + - "https://example.org/schema/items/v1/ElectronicItem/schema-context.jsonld" + message: + text_search: "Looking for a premium gaming laptop under $2000 near San Francisco" + discover_grocery_search: + summary: Structured discover (grocery) + value: + context: + version: "2.0.0" + action: "discover" + timestamp: "2024-04-10T16:10:50+05:30" + message_id: "2a3b4c5d-6e7f-4890-9a1b-2c3d4e5f6071" + transaction_id: "7e6d5c4b-3a21-4c5d-8f70-9a1b2c3d4e5f" + bap_id: "bap.example.com" + bap_uri: "https://bap.example.com" + ttl: "PT30S" + schema_context: + - "https://example.org/schema/items/v1/GroceryItem/schema-context.jsonld" + message: + text_search: "organic apples fresh" + filters: + type: "jsonpath" + expression: "$[?(@.grocery.organicCertification ~ 'USDA Organic')]" + discover_combined_search: + summary: Combined text + filters + value: + context: + version: "2.0.0" + action: "discover" + timestamp: "2024-04-10T16:10:50+05:30" + message_id: "3b4c5d6e-7f80-41a2-93b4-c5d6e7f8091a" + transaction_id: "8f70e6d5-c4b3-42a1-9c2d-3e4f5a6b7c8d" + bap_id: "bap.example.com" + bap_uri: "https://bap.example.com" + ttl: "PT30S" + schema_context: + - "https://example.org/schema/items/v1/ElectronicItem/schema-context.jsonld" + message: + text_search: "gaming laptop" + filters: + type: "jsonpath" + expression: "$[?(@.electronic.price['schema:price'] <= 2000 && @.electronic.brand.name == 'Premium Tech')]" + discover_multi_schema_search: + summary: Multi-schema discover (electronics + grocery) + value: + context: + version: "2.0.0" + action: "discover" + timestamp: "2024-04-10T16:10:50+05:30" + message_id: "4c5d6e7f-8091-42b3-94c5-d6e7f8091a2b" + transaction_id: "9c2d3e4f-5a6b-47c8-8d90-1a2b3c4d5e6f" + bap_id: "bap.example.com" + bap_uri: "https://bap.example.com" + ttl: "PT30S" + schema_context: + - "https://example.org/schema/items/v1/ElectronicItem/schema-context.jsonld" + - "https://example.org/schema/items/v1/GroceryItem/schema-context.jsonld" + message: + text_search: "premium tech and organic food" + filters: + type: "jsonpath" + expression: "$[?(@.rating.value >= 4 && (@.electronic.brand.name == 'Premium Tech' || @.grocery.organicCertification ~ 'USDA Organic'))]" + # ---------- /on_discover callback (DiscoverResponse) examples ---------- + on_discover_electronics_catalog: + summary: Electronics catalog callback + value: + context: + version: "2.0.0" + action: "on_discover" + timestamp: "2024-04-10T16:10:50+05:30" + message_id: "a1b2c3d4-e5f6-4789-90ab-cdef12345678" + transaction_id: "b2c3d4e5-f6a7-4890-8b9a-cdef23456789" + bpp_id: "bpp.example.com" + bpp_uri: "https://bpp.example.com" + ttl: "PT30S" + message: + catalogs: + - "@context": "https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/context.jsonld" + "@type": "beckn:Catalog" + "beckn:id": "catalog-electronics-001" + "beckn:descriptor": {"@type": "beckn:Descriptor", "schema:name": "Premium Tech Electronics Store"} + "beckn:items": [{"@context": "https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/context.jsonld", "@type": "beckn:Item", "beckn:id": "laptop-item-002", "beckn:descriptor": {"@type": "beckn:Descriptor", "schema:name": "Premium Gaming Laptop Pro 15”", "beckn:shortDesc": "Intel i7, 16GB RAM, 512GB SSD, RTX 4060"}, "beckn:category": {"@type": "schema:CategoryCode", "schema:codeValue": "electronics", "schema:name": "Electronics"}, "beckn:rateable": true, "beckn:rating": {"@type": "beckn:Rating", "beckn:ratingValue": 4.7, "beckn:ratingCount": 932}, "beckn:networkId": ["bap.net/electronics"], "beckn:itemAttributes": {"@context": "https://example.org/schema/items/v1/ElectronicItem/schema-context.jsonld", "@type": "beckn:ElectronicItem", "electronic:brand": "Premium Tech", "electronic:model": "G15-Pro-2025", "electronic:processor": "Intel Core i7-13700H", "electronic:ram": "16GB DDR5", "electronic:storage": "512GB NVMe SSD", "electronic:graphics": "NVIDIA GeForce RTX 4060", "electronic:display": "15.6\" 240Hz QHD", "electronic:warranty": "24 months"}, "beckn:provider": {"beckn:id": "tech-store-001", "beckn:descriptor": {"@type": "beckn:Descriptor", "schema:name": "Premium Tech Electronics Store"}}}, {"@context": "https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/context.jsonld", "@type": "beckn:Item", "beckn:id": "headphones-item-001", "beckn:descriptor": {"@type": "beckn:Descriptor", "schema:name": "Aurora X200 Noise-Cancelling Headphones", "beckn:shortDesc": "Over-ear ANC, 40h battery, BT 5.3, multipoint"}, "beckn:category": {"@type": "schema:CategoryCode", "schema:codeValue": "electronics", "schema:name": "Electronics"}, "beckn:rateable": true, "beckn:rating": {"@type": "beckn:Rating", "beckn:ratingValue": 4.5, "beckn:ratingCount": 1543}, "beckn:networkId": ["bap.net/electronics"], "beckn:itemAttributes": {"@context": "https://example.org/schema/items/v1/ElectronicItem/schema-context.jsonld", "@type": "beckn:ElectronicItem", "electronic:brand": "Aurora", "electronic:model": "X200", "electronic:wirelessTech": "Bluetooth 5.3", "electronic:features": ["ANC", "Transparency Mode", "Multipoint"], "electronic:batteryLifeHours": 40, "electronic:chargingPort": "USB-C", "electronic:warranty": "12 months"}, "beckn:provider": {"beckn:id": "tech-store-001", "beckn:descriptor": {"@type": "beckn:Descriptor", "schema:name": "Premium Tech Electronics Store"}}}] + on_discover_grocery_catalog: + summary: Grocery catalog callback + value: + context: + version: "2.0.0" + action: "on_discover" + timestamp: "2024-04-10T16:10:50+05:30" + message_id: "c3d4e5f6-a7b8-49c0-9dab-ef1234567890" + transaction_id: "d4e5f6a7-b8c9-4ad1-8cab-1234567890ef" + bpp_id: "bpp.example.com" + bpp_uri: "https://bpp.example.com" + ttl: "PT30S" + message: + catalogs: + - "@context": "https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/context.jsonld" + "@type": "beckn:Catalog" + "beckn:id": "catalog-grocery-001" + "beckn:descriptor": {"@type": "beckn:Descriptor", "schema:name": "Fresh Grocery Store"} + "beckn:items": [{"@context": "https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/context.jsonld", "@type": "beckn:Item", "beckn:id": "apples-item-001", "beckn:descriptor": {"@type": "beckn:Descriptor", "schema:name": "Organic Fuji Apples (1 kg)", "beckn:shortDesc": "Crisp, sweet USDA Organic apples — farm fresh"}, "beckn:category": {"@type": "schema:CategoryCode", "schema:codeValue": "grocery", "schema:name": "Grocery"}, "beckn:rateable": true, "beckn:rating": {"@type": "beckn:Rating", "beckn:ratingValue": 4.6, "beckn:ratingCount": 387}, "beckn:networkId": ["bap.net/grocery"], "beckn:itemAttributes": {"@context": "https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/context.jsonld", "@type": "beckn:GroceryItem", "grocery:brand": "Fresh Fields", "grocery:organicCertification": "USDA Organic", "grocery:variety": "Fuji", "grocery:unitSize": "1 kg", "grocery:origin": "Himachal Pradesh, IN", "grocery:shelfLifeDays": 10}, "beckn:provider": {"beckn:id": "grocery-store-001", "beckn:descriptor": {"@type": "beckn:Descriptor", "schema:name": "Fresh Grocery Store"}}}, {"@context": "https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/context.jsonld", "@type": "beckn:Item", "beckn:id": "bread-item-001", "beckn:descriptor": {"@type": "beckn:Descriptor", "schema:name": "Whole Wheat Bread (500 g)", "beckn:shortDesc": "High-fiber artisan loaf, no added sugar"}, "beckn:category": {"@type": "schema:CategoryCode", "schema:codeValue": "grocery", "schema:name": "Grocery"}, "beckn:rateable": true, "beckn:rating": {"@type": "beckn:Rating", "beckn:ratingValue": 4.3, "beckn:ratingCount": 812}, "beckn:networkId": ["bap.net/grocery"], "beckn:itemAttributes": {"@context": "https://example.org/schema/items/v1/GroceryItem/schema-context.jsonld", "@type": "beckn:GroceryItem", "grocery:brand": "BakeHouse", "grocery:unitSize": "500 g", "grocery:ingredients": ["Whole wheat flour", "Yeast", "Salt", "Olive oil"], "grocery:allergens": ["Gluten"], "grocery:shelfLifeDays": 5}, "beckn:provider": {"beckn:id": "grocery-store-001", "beckn:descriptor": {"@type": "beckn:Descriptor", "schema:name": "Fresh Grocery Store"}}}] + # ---------- ACK / NACK examples ---------- + ack_success: + summary: ACK + value: + transaction_id: "e5f6a7b8-c9d0-4e1f-9a2b-3c4d5e6f7081" + timestamp: "2024-04-10T16:10:50+05:30" + ack_status: "ACK" + ack_bad_request: + summary: NACK — bad request + value: + transaction_id: "f6a7b8c9-d0e1-42f3-8a2b-3c4d5e6f7081" + timestamp: "2024-04-10T16:10:50+05:30" + ack_status: "NACK" + error: + code: "INVALID_REQUEST" + paths: "context.schema_context" + message: "Invalid schema context provided" + ack_server_error: + summary: NACK — internal error + value: + transaction_id: "a7b8c9d0-e1f2-43a4-9b2c-3d4e5f607081" + timestamp: "2024-04-10T16:10:50+05:30" + ack_status: "NACK" + error: + code: "INTERNAL_ERROR" + paths: "server" + message: "Internal server error occurred" + # ---------- /discover/browser-search JSON example ---------- + browser_search_electronic_items: + summary: Browser-search JSON response (electronics) + value: + id: "api.beckn.discover.browser-search" + ver: "v2" + ts: "2024-04-10T16:10:50+05:30" + params: + msgid: "0a1b2c3d-4e5f-6789-8a0b-1c2d3e4f5a6b" + traceid: "1b2c3d4e-5f60-4781-92a3-b4c5d6e7f809" + response: + context: + version: "2.0.0" + action: "on_discover" + catalogs: + - "@context": "https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/context.jsonld" + "@type": "beckn:Catalog" + "beckn:id": "catalog-electronics-001" + "beckn:descriptor": + "@type": "beckn:Descriptor" + "schema:name": "Premium Tech Electronics Store" + "beckn:shortDesc": "High-quality electronics and gaming equipment" + "beckn:validity": + "@type": "beckn:TimePeriod" + "schema:startDate": "2025-01-27T09:00:00Z" + "schema:endDate": "2026-12-31T23:59:59Z" + "beckn:items": + - "@context": "https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/context.jsonld" + "@type": "beckn:Item" + "beckn:id": "laptop-item-001" + "beckn:descriptor": + "@type": "beckn:Descriptor" + "schema:name": "Premium Gaming Laptop Pro" + "beckn:shortDesc": "High-performance gaming laptop with RTX graphics" + "beckn:category": + "@type": "schema:CategoryCode" + "schema:codeValue": "electronics" + "schema:name": "Electronics" + "beckn:rating": + "@type": "beckn:Rating" + "beckn:ratingValue": 4.8 + "beckn:ratingCount": 156 + "beckn:rateable": true + "beckn:networkId": ["bap.net/electronics"] + "beckn:itemAttributes": + "@context": "https://example.org/schema/items/v1/ElectronicItem/schema-context.jsonld" + "@type": "beckn:ElectronicItem" + "electronic:brand": "ASUS" + "electronic:model": "ROG Strix G15" + "electronic:processor": "Intel Core i7-12700H" + "electronic:ram": "16GB DDR4" + "electronic:storage": "512GB NVMe SSD" + "electronic:graphics": "NVIDIA RTX 3060" + "beckn:provider": + "beckn:id": "tech-store-001" + "beckn:descriptor": + "@type": "beckn:Descriptor" + "schema:name": "Premium Tech Store" + responses: + Ack200: + description: "ACK — request received (validation passed)" + content: + application/json: + schema: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/AckResponse' + examples: + success_ack: + $ref: '#/components/examples/ack_success' + Ack400: + description: Bad request + content: + application/json: + schema: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/AckResponse' + examples: + bad_request: + $ref: '#/components/examples/ack_bad_request' + Ack500: + description: Internal server error + content: + application/json: + schema: + $ref: 'https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/attributes.yaml#/components/schemas/AckResponse' + examples: + server_error: + $ref: '#/components/examples/ack_server_error' \ No newline at end of file diff --git a/docs/api/Beckn-Transaction-APIs-Overview.md b/docs/api/Beckn-Transaction-APIs-Overview.md new file mode 100644 index 0000000..015ece0 --- /dev/null +++ b/docs/api/Beckn-Transaction-APIs-Overview.md @@ -0,0 +1,398 @@ +# Beckn Protocol 2.1 — Core Transaction APIs Overview (Normative RFC Representation) + +## Request for Comments — DRAFT + +### About this Document + +This document is a **normative overview** of the **server-to-server** Beckn Protocol transaction layer between a **BAP** (Beckn Application Platform) and a **BPP** (Beckn Protocol Provider). It describes: + +* The **four lifecycle stages** and the endpoints in each stage: + + * **Discovery**: `discover`, `publish` + * **Ordering**: `select`, `init`, `confirm` + * **Fulfillment**: `status`, `update`, `track`, `cancel` + * **Post-fulfillment**: `rating`, `support` +* The **payload object families** transported by each endpoint (via `message` schemas). +* Typical **BAP/BPP-facing product triggers** (what user-facing actions usually cause the servers to call these endpoints). +* The **ACK/NACK** pattern and the callback (`on_*`) pattern. + +This document intentionally avoids deep schema commentary. Each endpoint and each payload schema is expected to have its own dedicated specification later. + +--- + +# Context + +## Protocol interaction model (normative) + +1. Beckn is a **BAP ↔ BPP** protocol. All transactional interactions described here are between these two parties. +2. Beckn is **server-to-server**. Any “user action” referenced below is merely the frontend trigger that causes the **BAP server** or **BPP server** to initiate a call. +3. The protocol is **asynchronous by default**: + + * A “request” endpoint (e.g., `select`) is sent from one party to the other and returns an **ACK/NACK** immediately. + * The “response” is delivered later via the corresponding **callback** endpoint (e.g., `on_select`), which also returns an **ACK/NACK** immediately. +4. Each request body is structurally: + + * `context`: protocol envelope (including `action`, and sometimes `try`) + * `message`: the stage/action-specific payload object + +## ACK/NACK (normative) + +* All endpoints in this overview return an **ACK/NACK** response indicating **receipt + basic validation**, not business completion. +* Business results (catalog lists, quotes, confirmed orders, updated terms, etc.) arrive in the `message` payload of the callback (`on_*`) endpoints. + +--- + +# Intended Outcome + +Provide a crisp, implementer-oriented reference for the **foundational transactional communication layer** in Beckn Protocol 2.1, suitable as the entry-point RFC before domain bindings and detailed endpoint RFCs. + +--- + +# Protocol Stages and Endpoint Catalogue + +## Stage 1 — Discovery + +Discovery consists of two actions: + +* `discover` / `on_discover`: discover catalogs available across a network +* `catalog/publish` / `catalog/on_publish`: publish catalogs for indexing + +### 1. `GET /beckn/discover` → `POST /beckn/on_discover` + +**Direction** + +* `discover`: **BAP → (Catalog Discovery Service and/or BPP)** +* `on_discover`: **BPP → BAP** + +**Purpose (normative)** + +* `discover` performs catalog discovery using **text search**, **JSONPath-based filtering (RFC 9535)**, or both, with optional schema adaptation by the implementation. +* `on_discover` returns catalog search results (potentially aggregating catalogs from multiple BPPs). + +**Payload objects** + +* `discover.message`: `DiscoverMessage` +* `on_discover.message`: `OnDiscoverMessage` + +**Typical triggers** + +* **BAP UX**: user searches/browses (“search for restaurants”, “find EV chargers near me”, “search jobs”, etc.). +* **BPP/Discovery Service**: processes filters, queries catalogs/indexes, then posts results to `on_discover`. + +--- + +### 2. `POST /beckn/catalog/publish` → `POST /beckn/catalog/on_publish` + +**Direction** + +* `catalog/publish`: **BPP → Catalog Publishing Service** +* `catalog/on_publish`: **Catalog Publishing Service → BPP** + +**Purpose (normative)** + +* `catalog/publish` submits one or more catalogs to be indexed. Returns ACK if accepted for processing. +* `catalog/on_publish` delivers per-catalog processing outcomes asynchronously. + +**Payload objects** + +* `catalog/publish.message`: `CatalogPublishMessage` +* `catalog/on_publish.message`: `CatalogOnPublishMessage` + +**Typical triggers** + +* **BPP ops/system**: catalog updates, scheduled re-publish, inventory/price refresh pipelines. +* **Publishing service**: validates, indexes, reports results back. + +--- + +## Stage 2 — Ordering + +Ordering consists of: + +* `select` (quote), `init` (final draft), `confirm` (order creation) + +### 3. `POST /beckn/select` → `POST /beckn/on_select` + +**Direction** + +* `select`: **BAP → BPP** +* `on_select`: **BPP → BAP** + +**Purpose (normative)** + +* `select` asks for a **quote** based on chosen items/quantities/offers/coupons and optionally **anonymous bidding**, **without sharing consumer PII**. +* `on_select` returns a computed quote, may check inventory/serviceability, may return auction bid context, and may provide links to external forms if required before proceeding. + +**Payload objects** + +* `select.message`: `SelectMessage` +* `on_select.message`: `OnSelectMessage` + +**Typical triggers** + +* **BAP UX**: “view price”, “apply coupon”, “request quote”, “place anonymous bid”. +* **BPP logic**: pricing rules, offer validation, inventory/serviceability checks, auction logic. + +--- + +### 4. `POST /beckn/init` → `POST /beckn/on_init` + +**Direction** + +* `init`: **BAP → BPP** +* `on_init`: **BPP → BAP** + +**Purpose (normative)** + +* `init` starts forming the **final order** by providing billing + fulfillment + source payment info required to compute final terms. (Also references to any required artifacts/inputs, as applicable.) +* `on_init` returns the final order draft including **terms of service** and potentially additional requirements (e.g., payment steps, attestations, forms). + +**Payload objects** + +* `init.message`: `InitMessage` +* `on_init.message`: `OnInitMessage` + +**Typical triggers** + +* **BAP UX**: “Proceed to checkout”, entering address, selecting delivery slot, choosing payment method. +* **BPP logic**: computes final charges/fees/taxes, validates fulfillment feasibility, generates ToS, creates payment intents/links if needed. + +--- + +### 5. `POST /beckn/confirm` → `POST /beckn/on_confirm` + +**Direction** + +* `confirm`: **BAP → BPP** +* `on_confirm`: **BPP → BAP** + +**Purpose (normative)** + +* `confirm` indicates BAP acceptance/fulfillment of preconditions (e.g., payment proof/reference, attestations, submitted form references, authorizations). +* `on_confirm` returns the **confirmed order** with an Order ID after validating that all conditions (including payment, where required) are satisfied. + +**Payload objects** + +* `confirm.message`: `ConfirmMessage` +* `on_confirm.message`: `OnConfirmMessage` + +**Typical triggers** + +* **BAP UX**: “Place order”, “Pay now”, “Accept terms”, upload/submit required docs. +* **BPP logic**: final validation, order creation, payment reconciliation, allocation initialization. + +--- + +## Stage 3 — Fulfillment + +Fulfillment consists of: + +* `status`, `update`, `track`, `cancel` + +### 6. `POST /beckn/status` → `POST /beckn/on_status` + +**Direction** + +* `status`: **BAP → BPP** +* `on_status`: **BPP → BAP** + +**Purpose (normative)** + +* `status` requests the latest state of an order. +* `on_status` returns the latest state, including fulfillment status. The BPP may also call `on_status` proactively (push updates) even without an explicit `status` request. + +**Payload objects** + +* `status.message`: `StatusMessage` +* `on_status.message`: `OnStatusMessage` + +**Typical triggers** + +* **BAP UX**: order details page refresh, “where is my order?”, background polling. +* **BPP logic**: pushes state transitions (packed/shipped/arrived/completed), exception notifications. + +--- + +### 7. `POST /beckn/track` → `POST /beckn/on_track` + +**Direction** + +* `track`: **BAP → BPP** +* `on_track`: **BPP → BAP** + +**Purpose (normative)** + +* `track` requests real-time tracking for an active order. +* `on_track` returns tracking handles (e.g., tracking URLs, tracker IDs, real-time stream endpoints). + +**Payload objects** + +* `track.message`: `TrackMessage` +* `on_track.message`: `OnTrackMessage` + +**Typical triggers** + +* **BAP UX**: user opens “Live tracking”. +* **BPP logic**: issues/refreshes tracking tokens/links, binds to logistics tracker providers. + +--- + +### 8. `POST /beckn/update` → `POST /beckn/on_update` *(two-mode via `context.try`)* + +**Direction** + +* `update`: **BAP → BPP** +* `on_update`: **BPP → BAP** + +**Purpose (normative)** + +* `update` requests modification of an active order and recalculation of terms (including payment). +* `on_update` returns the updated order with recomputed quote/payment terms. + +**Two-mode behavior (`context.try`)** + +* The spec models two branches: `context.try: true` vs `context.try: false`, enabling a **proposal/preview** vs **commit/confirm** style update flow. + +**Payload objects** + +* `update.message`: `UpdateInitMessage` (try=true) or `UpdateConfirmMessage` (try=false) +* `on_update.message`: `OnUpdateInitMessage` (try=true) or `OnUpdateConfirmMessage` (try=false) + +**Typical triggers** + +* **BAP UX**: change quantities, add/remove items, change address, reschedule slot, modify billing details. +* **BPP logic**: reallocation of fulfillment agent, substitution rules, repricing, payment adjustment links, validation against policies. + +--- + +### 9. `POST /beckn/cancel` → `POST /beckn/on_cancel` *(two-mode via `context.try`; request description currently TODO in source)* + +**Direction** + +* `cancel`: **BAP → BPP** +* `on_cancel`: **BPP → BAP** + +**Purpose (normative)** + +* `cancel` requests cancellation of an order. +* `on_cancel` returns the cancelled order state, potentially reflecting refund/payment updates (via payment references). + +**Two-mode behavior (`context.try`)** + +* Two-branch pattern exists (`context.try: true/false`) consistent with a **pre-check** vs **finalize cancellation** approach. + +**Payload objects** + +* `cancel.message`: `CancelInitMessage` (try=true) or `CancelConfirmMessage` (try=false) +* `on_cancel.message`: `OnCancelInitMessage` (try=true) or `OnCancelConfirmMessage` (try=false) + +**Typical triggers** + +* **BAP UX**: “Cancel order” → show penalty/refund preview (try=true) → “Confirm cancellation” (try=false). +* **BPP logic**: cancellation policy evaluation, fee/refund computation, fulfillment reversal, payment adjustments. + +--- + +## Stage 4 — Post-fulfillment + +Post-fulfillment consists of: + +* `rate`, `support` + +### 10. `POST /beckn/rate` → `POST /beckn/on_rate` *(two-mode via `context.try`)* + +**Direction** + +* `rate`: **BAP → BPP** +* `on_rate`: **BPP → BAP** + +**Purpose (normative)** + +* `rate` submits a rating for any aspect of an order. +* `on_rate` acknowledges rating receipt and may optionally return an aggregate snapshot/receipt. + +**Two-mode behavior (`context.try`)** + +* Two-branch pattern exists (`context.try: true/false`) to support “preview/validate rating target” vs “commit rating” style flows where needed. + +**Payload objects** + +* `rate.message`: `RateInitMessage` (try=true) or `RateConfirmMessage` (try=false) +* `on_rate.message`: `OnRateInitMessage` (try=true) or `OnRateConfirmMessage` (try=false) + +**Typical triggers** + +* **BAP UX**: post-completion rating prompt, rate delivery agent/item/provider, submit feedback. +* **BPP logic**: validates rating applicability, stores rating, optionally returns receipt/updated aggregates. + +--- + +### 11. `POST /beckn/support` → `POST /beckn/on_support` *(request is two-mode via `context.try`)* + +**Direction** + +* `support`: **BAP → BPP** +* `on_support`: **BPP → BAP** + +**Purpose (normative)** + +* `support` requests support details for an entity (order/item/provider/etc.). +* `on_support` returns support contact/details (`SupportInfo`). + +**Two-mode behavior (`context.try`)** + +* `support` supports `context.try: true/false` branching, allowing pre-check/validation vs confirmed support request flows where applicable. + +**Payload objects** + +* `support.message`: `OnSupportInitMessage` (try=true) or `OnSupportConfirmMessage` (try=false) +* `on_support.message.support`: `SupportInfo` + +**Typical triggers** + +* **BAP UX**: “Need help?”, “Contact support”, dispute/issue flows. +* **BPP logic**: routes to correct helpdesk channel, returns contact points, ticket URLs, escalation policy pointers. + +--- + +# Cross-cutting Normative Notes + +## Endpoint naming and lifecycle coupling + +* Each primary action has a corresponding callback: + + * `discover ↔ on_discover` + * `select ↔ on_select` + * `init ↔ on_init` + * `confirm ↔ on_confirm` + * `status ↔ on_status` + * `update ↔ on_update` + * `track ↔ on_track` + * `cancel ↔ on_cancel` + * `rate ↔ on_rate` + * `support ↔ on_support` + * `catalog/publish ↔ catalog/on_publish` + +## The `context.action` field + +* Every endpoint constrains `context.action` to a constant matching the endpoint (e.g., `select`, `on_select`, `catalog/publish`, etc.). This is the primary protocol-level discriminator. + +## The `context.try` field (two-mode operations) + +* Some operations are explicitly modeled with a `try` boolean to enable: + + * quote/preview/check feasibility (`try=true`) + * confirm/commit the change (`try=false`) +* In this overview, `update`, `cancel`, `rate`, and `support` are modeled this way. + +--- + +# Conclusion + +This RFC captures the **minimal normative overview** of Beckn Protocol 2.1’s transactional communication layer: four stages, the endpoint pairs per stage, the message object families transported, and typical system triggers. It should be used as the “map of the terrain” before diving into the detailed endpoint RFCs and domain-specific bindings. + +If you want the next step to be equally formal, I suggest we proceed stage-by-stage (Discovery → Ordering → Fulfillment → Post-fulfillment), and for each endpoint produce: + +* a strict normative definition, +* a state machine slice, +* and message-level conformance rules (including `try` semantics where applicable). diff --git a/docs/api/Catalog-discovery.md b/docs/api/Catalog-discovery.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/api/Registry-Lookup.md b/docs/api/Registry-Lookup.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/architecture/Actors.md b/docs/architecture/Actors.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/architecture/Communication-Protocol.md b/docs/architecture/Communication-Protocol.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/architecture/Network-Architecture.md b/docs/architecture/Network-Architecture.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/governance/ATTRIBUTION-DRAFT-01.md b/docs/governance/ATTRIBUTION-DRAFT-01.md new file mode 100644 index 0000000..76f52a3 --- /dev/null +++ b/docs/governance/ATTRIBUTION-DRAFT-01.md @@ -0,0 +1,537 @@ +# **1. Attribution Playbook for NFOs [DRAFT]** + +## *Publishing network architecture, IG overlays, schema extensions, and examples **without** forking/copy-pasting—while giving implementers **a single front door*** + +--- + +## **1.1 About this Document** + +### **1.1.1 Latest published version** + +To be added. + +### **1.1.2 Latest editor’s draft** + +To be added. + +> Note: Contributors are expected to request commenter access prior to proposing changes. Before requesting access, contributors are expected to review the Community Guidelines for Contributing. + +### **1.1.3 Implementation report** + +To be added. + +### **1.1.4 Editors** + +* Ravi Prakash (Beckn Labs) +* Pramod Varma (Networks for Humanity) + +### **1.1.5 Authors** + +* Ravi Prakash (Beckn Labs) + +### **1.1.6 Feedback** + +#### **1.1.6.1 Issues** + +No issues have been raised. + +#### **1.1.6.2 Discussions** + +No discussions are currently open. + +#### **1.1.6.3 Pull Requests** + +No pull requests are currently open on this topic. + +#### **1.1.6.4 GitHub Labels** + +The following labels are expected to be used when raising Issues, initiating Discussions, and submitting Pull Requests regarding this document: + +* `governance` +* `attribution` +* `core-v2` + +### **1.1.7 Errata** + +No errata exist as of this version. + +--- + +## **1.2 Acknowledgements** + +The author acknowledges the following individuals for their valuable contributions: + +1. Pramod Varma +2. Sujith Nair +3. Tanmoy Adhikary + +--- + +## **1.3 Notice** + +This document is **within the scope of the Governance Model of the Beckn Protocol** (“Governance Model”). + +The Governance Model is the **authoritative source** for Beckn’s governing intent—its **philosophies**, **design principles**, and **policies**. Documents such as this one are **derived instruments** that translate that intent into operational recommendations (analogous to how *regulations* are derived from *policies*). + +Accordingly: + +* This document **does not redefine** Beckn’s core philosophies, design principles, or policies. +* Where interpretation is required, the **Governance Model prevails**. +* Conflicts, ambiguity, or gaps are to be treated as **input for improving the Governance Model**, rather than as justification for divergence from governing intent. + +**1.3.1 Lineage (recommended):** + +* **Governing Source:** Governance Model of the Beckn Protocol +* **Derived From:** Applicable policies / principles defined therein +* **This Document:** Attribution Playbook for NFOs — operational recommendations and processes derived from the above + +--- + +# **2. Status and Applicability** + +This playbook constitutes a **strong recommendation** for Network Facilitator Organizations (NFOs) publishing network-specific repositories for Beckn-based open networks. While not framed as a strictly mandatory requirement, it is intended to be treated as the **default expected approach** for responsible publication, attribution, and long-term maintainability. + +Deviation from the guidance in this playbook is expected to be **exceptional**, **justified**, and **explicitly documented**, including the rationale and the compensating measures used to mitigate drift, attribution risk, and implementer confusion. + +--- + +# **3. Context** + +Beckn Protocol v2 is designed as a **three-layer ecosystem** intended to scale across domains, regions, and networks without repeated reinvention: + +1. **Core layer (Beckn Protocol v2):** Domain-agnostic actions (“verbs”) and a standard vocabulary for the order lifecycle (Discovery → Ordering → Fulfillment → Post-fulfillment), accompanied by broadly semantically aligned schemas (e.g., via JSON-LD). +2. **Domain layer (Layer-2 specifications):** Domain communities—often in collaboration with Networks for Humanity Foundation (NFH) and contributors—publish **domain-specific bindings**, including schemas, vocabulary, and Implementation Guides (IGs), to adapt the core specification to specific industries (e.g., energy, mobility). +3. **Network layer (Layer-3 specifications):** Individual networks (led by NFOs) introduce **region- and network-specific requirements**, including policy constraints, regulatory identifiers, payment mechanisms, operational rules, and network governance, while aiming to remain compatible with core and domain foundations. + +This layering is intentional: the **core** is expected to remain stable, **domains** are expected to evolve as practice matures, and **networks** frequently move the fastest due to launch timelines and compliance imperatives. + +In practice, network-level requirements often emerge **before** they can be normalized into the domain layer (and certainly before they can be incorporated into the core). At the same time, implementers building for a specific network generally require **a single authoritative entry point**—a coherent “home” where the network’s rules and examples can be found without repeated navigation across repositories and versions. + +Under these conditions, it is a predictable operational outcome that some networks **republish** domain IG material (and sometimes example payloads) inside network repositories and then extend it with network-specific details. This pattern is commonly driven by: + +* **Asynchronous evolution** across core, domain, and network layers +* **Go-to-market pressures** (launch commitments, regulatory timelines, ecosystem deadlines) +* **Developer experience (DX) pragmatism** (reducing “repo-hopping” for implementers) +* **Lack of a default pattern** for overlaying network rules on top of pinned upstream specifications + +Over time, however, republishing increases ecosystem friction by introducing **drift** between upstream and network material, blurring boundaries between core/domain/network responsibilities, and increasing maintenance burden—especially when upstream continues to evolve. + +This playbook provides a structured approach for NFOs to publish **network-specific architecture documentation, IG overlays, schema extensions, and examples** while treating **Core + Domain** as pinned upstream dependencies and providing implementers a single coherent entry point. + +--- + +# **4. The North Star: One Front Door, Many Rooms** + +The implementer experience is strongly recommended to follow these expectations: + +1. Implementers should be directed to **one URL** (a documentation portal) presenting a clear navigation structure, typically including: + + * Architecture + * Implementation Guides + * Schemas & Contexts + * Examples + * Conformance & Policies + * Release notes / compatibility matrix + +2. The documentation portal should be composed from: + + * **Pinned upstream sources** (Core + Domain) + * **Network-authored overlays** (addenda describing deltas) + * **Machine-readable extensions** (JSON Schemas, JSON-LD contexts) + * **Generated examples** (reproducible from patches) + +The central principle is that **a single “home” does not require a single repository**. + +--- + +# **5. Organization-Level Principles** + +## **5.1 Core and Domain Specifications as Dependencies** + +**Strong recommendation (expected practice):** + +* Upstream references (tags/commits) should be pinned per network release. +* Upstream IG markdown should not be copied and rebranded within network repositories. + +**Rationale:** +Copying upstream content creates drift; drift accumulates into long-term maintenance costs and attribution risk. + +## **5.2 Network IGs as Overlays (Not Duplicates)** + +**Strong recommendation (expected practice):** +Network-authored IG content should primarily articulate: + +* What differs within the network context +* What is stricter +* What is added (extensions, regulatory fields) +* What is forbidden or optional within the network + +## **5.3 Extensions as Machine-Readable and Semantically Bindable** + +**Strong recommendation (expected practice):** + +* Network attribute packs should be published as JSON Schema **and** JSON-LD contexts (`@context`, `@type`). +* These packs should be versioned, and their URLs should remain stable. + +## **5.4 Examples as Patches and Generated Outputs** + +**Strong recommendation (expected practice):** + +* Network repositories should store deltas (e.g., JSON Patch / overlays) and generate full payloads via CI. +* Rebranded upstream examples should not be distributed as hand-edited copies. + +--- + +# **6. Recommended GitHub Organization Blueprint** + +## **6.1 Repository Taxonomy** + +A well-structured GitHub Organization is expected to use approximately **7–10 repositories**, each with a specific responsibility. + +### **6.1.1 Front Door and Navigation** + +1. **`-docs`** + **Purpose:** Documentation portal source (e.g., mkdocs/docusaurus), published via GitHub Pages or equivalent. + **Contains:** Network-authored docs and integration hooks to render pinned upstream content. + +2. **`.github`** (org-wide) + **Purpose:** Community and governance scaffolding (issue templates, PR templates, CODEOWNERS defaults, security policy, contributing). + **Contains:** Organization-level norms and guardrails. + +### **6.1.2 Network Specification Layer** + +3. **`-profile`** + **Purpose:** Network manifest for compatibility and conformance. + **Contains:** pinned dependencies, conformance rules, supported use cases, release metadata. + +4. **`-schemas`** + **Purpose:** Source of truth for network attribute packs. + **Contains:** schemas, JSON-LD contexts, mapping tables (network → beckn → schema.org). + +5. **`-examples`** + **Purpose:** Patch-first examples with generated outputs. + **Contains:** patches, generated outputs, pinned upstream anchors. + +### **6.1.3 Tooling and Automation** + +6. **`-tooling`** + **Purpose:** Tooling required to implement the no-copy pattern (patch applicator, validators, doc composition tools). + +7. **`-ci`** (optional) + **Purpose:** Centralized reusable workflows. + +### **6.1.4 Policies, Legal, Operations** + +8. **`-policy`** (recommended in regulated networks) + **Purpose:** Network policy, security posture, onboarding rules, and associated artifacts. + +9. **`-registry`** (optional) + **Purpose:** Registry data models and fixtures (not the live registry). + +The guiding principle is to avoid consolidating unrelated responsibilities into a single repository that becomes difficult to maintain. + +--- + +# **7. Naming Conventions** + +Predictable naming is strongly recommended so implementers can quickly locate information: + +* Portal: `-docs` +* Compatibility/conformance manifest: `-profile` +* Extensions: `-schemas` +* Examples: `-examples` +* Automation: `-tooling` +* Policies: `-policy` +* Org defaults: `.github` + +Repository descriptions are recommended to begin with a verb (e.g., “Builds…”, “Defines…”, “Publishes…”). + +--- + +# **8. Repository-Level Information Architecture** + +## **8.1 `-profile` (Contract Repository)** + +This repository is expected to serve as the canonical answer to: **what the network supports**. + +### **8.1.1 Recommended structure** + +```text +-profile/ + README.md + LICENSE + NOTICE.md + CHANGELOG.md + + profile/ + DEPENDENCIES.yaml + SUPPORT_MATRIX.md + CONFORMANCE/ + discovery.md + ordering.md + fulfillment.md + post_fulfillment.md + POLICY_REFERENCES.md + + releases/ + v1.4.0.md +``` + +### **8.1.2 Strong recommendation (expected practice)** + +Each release should tag the repository and update `DEPENDENCIES.yaml`, `CHANGELOG.md`, and the compatibility matrix. + +## **8.2 `-schemas` (Attribute Packs and Contexts)** + +### **8.2.1 Recommended structure** + +```text +-schemas/ + README.md + LICENSE + NOTICE.md + CHANGELOG.md + + context/ + network/ + payment.upi.v1.context.jsonld + provider.regulatory.v1.context.jsonld + + jsonschema/ + network/ + payment.upi.v1.schema.json + provider.regulatory.v1.schema.json + + mapping/ + mapping-matrix.csv + notes.md +``` + +### **8.2.2 Strong recommendation (expected practice)** + +Contexts should be stable and resolvable; every pack should include `@type` version semantics, JSON Schema, and mapping notes. + +## **8.3 `-examples` (Patch-First Examples)** + +### **8.3.1 Recommended structure** + +```text +-examples/ + README.md + LICENSE + NOTICE.md + CHANGELOG.md + + upstream-refs/ + ev-charging.yaml + + patches/ + ev-charging/ + on_search.patch.json + on_confirm.patch.json + + generated/ + ev-charging/ + on_search.json + on_confirm.json + + reports/ + latest-validation.json +``` + +### **8.3.2 Strong recommendation (expected practice)** + +Generated outputs should be reproducible from upstream references, patches, and tooling versions. + +## **8.4 `-docs` (Portal Repository)** + +### **8.4.1 Recommended structure** + +```text +-docs/ + README.md + LICENSE + NOTICE.md + + docs/ + index.md + architecture/ + overview.md + participants.md + trust-registry.md + security.md + ig/ + ev-charging/ + overlay.md + conformance.md + workflows/ + faq.md + schemas/ + packs.md + examples/ + ev-charging.md + releases/ + index.md + + mkdocs.yml + tools/ + fetch-upstreams/ +``` + +### **8.4.2 Strong recommendation (expected practice)** + +Upstream content should be rendered without copying it into network-authored documentation. Two accepted patterns are: + +* build-time fetch with pinned refs, or +* submodules/subtrees pinned to commits/tags. + +## **8.5 `.github` (Organization Guardrails)** + +### **8.5.1 Recommended contents** + +```text +.github/ + CONTRIBUTING.md + SECURITY.md + CODE_OF_CONDUCT.md + PULL_REQUEST_TEMPLATE.md + ISSUE_TEMPLATE/ + workflows/ + reusable-validate.yml + reusable-release.yml +``` + +### **8.5.2 Strong recommendation (expected practice)** + +PR checklists should explicitly evaluate: absence of copied upstream content, pinned dependency updates, patch-based example generation, and NOTICE/attribution compliance. + +--- + +# **9. Single Home Without Copying** + +## **9.1 Option A (Preferred)** + +The documentation portal composes upstream content and network overlays. Every upstream-derived page is expected to display the upstream source, pinned reference, and license/notice pointer. + +## **9.2 Option B** + +The portal provides curated indexes and deep-links to upstream content at pinned references. This approach is lower-effort but less cohesive. + +--- + +# **10. Release Mechanics Across Multiple Repositories** + +## **10.1 Profile as Release Coordinator** + +`-profile` is strongly recommended to serve as the canonical release coordinator. + +A network release (e.g., `v1.4.0`) is expected to align with corresponding tags for: + +* `-profile` +* `-schemas` (or a compatible `v1.4.x`) +* `-examples` +* `-docs` (optional but recommended) + +## **10.2 Single Source of Compatibility** + +`DEPENDENCIES.yaml` in `-profile` is expected to serve as the canonical compatibility declaration. + +--- + +# **11. Attribution Controls** + +## **11.1 Repository-Level NOTICE** + +Each repository is expected to include a `NOTICE.md` listing: + +* upstream repositories used +* exact references +* relevant licenses and notice requirements +* a statement that upstream specifications remain authoritative + +## **11.2 File-Level Attribution for Overlays** + +Each overlay IG page is expected to declare: + +* pinned base reference +* what is authored within the overlay +* copyright attribution boundaries + +--- + +# **12. CI Controls (Recommended Enforcement)** + +Minimum CI expectations include: + +* **Schemas repository:** JSON Schema validation and JSON-LD context sanity checks +* **Examples repository:** patch application checks and validation against core/domain/network schemas +* **Docs repository:** build integrity against pinned upstream refs and optional link checking + +--- + +# **13. Anti-Patterns** + +The following patterns are strongly discouraged: + +* A repository that is effectively a fork of an upstream domain repository with only branding changes +* Multiple repositories carrying duplicated copies of IG content +* Hand-edited “generated” examples without a reproducible build pipeline +* Compatibility claims such as “compatible with main” without pinned references + +--- + +# **14. Minimal Starter Kit for Rapid Launch** + +For networks under urgent timelines, the minimum recommended set of repositories is: + +1. `.github` +2. `-profile` +3. `-schemas` +4. `-examples` +5. `-docs` + +This set is typically sufficient to support rapid launch while avoiding the long-term costs of copy-paste drift. + +--- + +# **16. Scaffolding Script Reference** + +To promote consistent repository structure and reduce inadvertent divergence across network repositories, NFOs are **strongly recommended** to use the official scaffolding scripts referenced below to generate the GitHub Organization layout locally. + +These scripts generate only the **folder structure and placeholder file names**, initialize each folder as an independent Git repository, and (where applicable) add **upstream repositories as submodule references** in the documentation portal repository. + +## **16.1 Full-Fledged Organization Scaffold** + +[Click here to view the script](../scripts/network-scaffold/forge-the-network.sh) + +## **16.2 Minimal Starter Organization Scaffold** + +[Click here to view the script](../scripts/network-scaffold/spark-the-network.sh) + +## **16.3 Expected Capabilities** + +The referenced scripts are expected to support, at minimum: + +* creation of the recommended repository folders for the selected scaffold profile (full or minimal), +* `git init` for each repository folder, +* insertion of upstream dependencies as submodules under `-docs/upstream/` (e.g., `core`, `domain`), +* generation of only file/folder names (no authored content). + +## **16.4 Org Folder Structure Description** +The recommended GitHub organization structure for an NFO and its details can be found [here](./NFO_ORG_STRUCTURE.md) + +--- + +# **17. Conclusion** + +This playbook establishes a strongly recommended operating model for NFOs to publish network-specific documentation, overlays, extensions, and examples **without** forking or duplicating upstream content, while still delivering a coherent “single front door” experience for implementers. + +By treating **Core** and **Domain** specifications as pinned upstream dependencies, expressing network requirements through a **profile**, **overlays**, and **machine-readable extension packs**, and generating examples through reproducible pipelines rather than manual copying, networks can: + +* reduce long-term drift and maintenance burden, +* preserve clear responsibility boundaries across Core → Domain → Network layers, +* strengthen attribution fidelity and ecosystem trust, and +* accelerate iteration without sacrificing interoperability. + +The recommended organization-level structure is intended to remain lightweight in day-to-day use while being robust enough to withstand fast network evolution, regulatory change, and multi-stakeholder implementation realities. + diff --git a/docs/governance/Beckn-JSONLD-Governance.md b/docs/governance/Beckn-JSONLD-Governance.md new file mode 100644 index 0000000..961b988 --- /dev/null +++ b/docs/governance/Beckn-JSONLD-Governance.md @@ -0,0 +1,557 @@ +# Beckn JSON-LD Governance Rules + +**Request for Comments – DRAFT** + +--- + +## About this Document + +### Status of this Memo + +This document defines **normative governance rules** for the use of JSON-LD within Beckn Protocol V2.x. +Distribution of this memo is unlimited. + +--- + +### Latest Published Version + +Not yet published. This document is under active review and iteration. + +--- + +### Latest Editor’s Draft + +The editorial source of truth for this document resides in the Beckn Protocol V2 repository. + +--- + +### Editors + +* Beckn Protocol Core Maintainers + +--- + +### Feedback + +Feedback should be provided via GitHub issues or pull requests against the protocol-specifications-v2 repository. + +--- + +## 1. Background and Motivation + +Beckn Protocol V2 adopts JSON-LD to enable **global semantic interoperability** while preserving strict, machine-verifiable contracts. +This requires a disciplined separation between **runtime JSON processing** and **design-time semantic modeling**. + +Historically, ecosystems that blur this boundary suffer from semantic drift, breaking changes hidden as “minor edits,” and brittle AI or agent behavior—risks that are unacceptable in federated, auditable networks like Beckn. + +--- + +## 2. Scope of This Document + +This RFC governs **only two JSON-LD artifacts** used in Beckn: + +* `context.jsonld` +* `vocab.jsonld` + +It explicitly does **not** define: + +* API schemas +* JSON Schema validation rules +* Domain-specific extension vocabularies (except where governance applies) + +--- + +## 3. Terminology + +This section establishes precise meanings for commonly used terms to avoid ambiguity. + +* **Runtime**: JSON-LD expansion/compaction during message exchange +* **Design-time**: Semantic modeling, ontology alignment, and review +* **Canonical**: The authoritative Beckn-defined semantic identity + +--- + +## 4. Prime Directive (Non-Negotiable) + +Every JSON-LD file in Beckn has **exactly one responsibility**. + +| File | Single Responsibility | +| ---------------- | ----------------------------------------------- | +| `context.jsonld` | Runtime term resolution and value normalization | +| `vocab.jsonld` | Semantic truth: concepts, relations, alignment | + +**Any change that violates this separation is invalid, regardless of intent or correctness.** + +--- + +## 5. Artifact-Specific Governance Rules + +### 5.1 `context.jsonld` + +This file exists solely to answer: +**“At runtime, what IRI does this JSON key or value resolve to?”** + +It must remain deterministic, minimal, and completely free of semantic or ontological claims. + +--- + +#### ✅ Allowed Content + +The following examples are correct because they **only perform term mapping and value typing**, which are required for deterministic JSON-LD expansion. + +```json +{ + "@context": { + "@protected": true, + "beckn": "https://becknprotocol.io/schema/", + "isActive": { + "@id": "beckn:isActive", + "@type": "xsd:boolean" + } + } +} +``` + +**Why this is correct** + +* Maps JSON keys to stable IRIs +* Explicitly types values to avoid ambiguity +* Introduces no semantic meaning or constraints + +--- + +#### ❌ Forbidden Content + +The following examples are invalid because they **introduce semantic or ontological constructs into a runtime artifact**. + +```json +{ + "@graph": [ + { + "@id": "beckn:Order", + "owl:equivalentClass": "schema:Order" + } + ] +} +``` + +```json +{ + "orderStatus": { + "schema:hasEnumerationMember": [] + } +} +``` + +**What is wrong** + +* Declares semantic identity (`owl:equivalentClass`) +* Embeds ontology (`@graph`, enumerations) in a runtime context +* Collapses runtime resolution with semantic truth + +**Potential consequences in applications** + +* Silent semantic changes across network participants +* Context edits become breaking changes without versioning +* LLMs and agents infer incorrect equivalence +* Auditing and dispute resolution become unreliable + +--- + +### 5.2 `vocab.jsonld` + +This file defines **what concepts exist**, how they relate, and how they align with global vocabularies. +It is the **only authoritative source of semantic truth** in Beckn. + +--- + +#### ✅ Allowed Content + +The following examples are valid because they **declare meaning without enforcing structure or validation**. + +```json +{ + "@id": "beckn:Order", + "@type": "rdfs:Class", + "rdfs:subClassOf": "schema:Order" +} +``` + +```json +{ + "@id": "beckn:isActive", + "@type": "rdf:Property", + "schema:domainIncludes": "beckn:Item", + "schema:rangeIncludes": "schema:Boolean" +} +``` + +**Why this is correct** + +* Declares classes and properties explicitly +* Uses schema.org for alignment, not enforcement +* Leaves validation to protocol schemas + +--- + +#### ❌ Forbidden Content + +The following examples are invalid because they **mix validation or runtime concerns into a semantic vocabulary**. + +```json +{ + "@id": "beckn:Order", + "type": "object", + "required": ["id"] +} +``` + +```json +{ + "@id": "beckn:orderStatus", + "@context": {} +} +``` + +**What is wrong** + +* Introduces JSON Schema concepts into vocab +* Embeds runtime context logic in semantic definitions +* Confuses meaning with structure + +**Potential consequences in applications** + +* Tooling misinterprets vocab as a validation schema +* Conflicting enforcement across implementations +* Domain extensions become brittle and unsafe +* False assumptions about protocol guarantees + +--- + +## 6. Prefix and Namespace Governance + +Namespaces establish **global semantic identity** and must never be redefined or hijacked. + +--- + +### ✅ Allowed + +These examples are correct because they reference **globally authoritative namespaces**. + +```json +{ + "schema": "https://schema.org/", + "beckn": "https://becknprotocol.io/schema/" +} +``` + +**Why this is correct** + +* Preserves global dereferenceability +* Ensures all participants resolve identical IRIs + +--- + +### ❌ Forbidden + +These examples are invalid because they **fork or override global namespaces**. + +```json +{ + "schema": "https://example.com/schema/" +} +``` + +```json +{ + "beckn": "https://my-network.example/beckn/" +} +``` + +**What is wrong** + +* Breaks global meaning of well-known prefixes +* Introduces private semantics under public names + +**Potential consequences in applications** + +* Cross-network interoperability collapses +* Semantic mappings become non-portable +* Agents hallucinate equivalence +* Federation-level reasoning fails + +--- + +## 7. Mapping to schema.org (Global-first) + +Beckn is **schema.org–aligned**, but never schema.org–dependent. + +This section governs how alignment is declared without collapsing identities. + +--- + +### Canonical Mapping Rules + +| Concept Type | Preferred Strategy | +| ------------ | ------------------------------------------ | +| Class | `rdfs:subClassOf schema:*` | +| Property | Reuse schema.org if exact | +| Enum value | Beckn canonical + optional `schema:sameAs` | + +--- + +### ❌ Forbidden + +```json +{ + "@id": "beckn:Order", + "owl:equivalentClass": "schema:Order" +} +``` + +```json +{ + "@id": "beckn:priceCurrency" +} +``` + +**What is wrong** + +* Asserts semantic identity instead of alignment +* Duplicates existing global concepts + +**Potential consequences in applications** + +* Beckn semantics become externally mutable +* Versioning guarantees are violated +* Agents cannot distinguish protocol vs global meaning + +--- + +## 8. Typing Discipline + +Typing rules differ sharply between runtime and design-time artifacts. + +--- + +### 8.1 Typing in `context.jsonld` + +Typing here exists **only to disambiguate runtime values**. + +#### ✅ Allowed + +```json +{ + "provider": { + "@id": "beckn:provider", + "@type": "@id" + } +} +``` + +**Why this is correct** + +* Makes IRI intent explicit +* Avoids literal vs reference ambiguity + +--- + +#### ❌ Forbidden + +```json +{ + "provider": { + "@id": "beckn:provider" + } +} +``` + +**What is wrong** + +* Leaves value interpretation ambiguous + +**Potential consequences** + +* Inconsistent expansion across processors +* Agents mis-handle references vs literals + +--- + +### 8.2 Typing in `vocab.jsonld` + +Typing here is **descriptive, not enforceable**. + +* Prefer `schema:rangeIncludes` +* Use `rdfs:range` only when unavoidable + +--- + +## 9. Enumeration Governance (Critical Section) + +Enumerations are one of the highest-risk areas for semantic drift. + +--- + +### Canonical Pattern + +```json +{ + "@id": "beckn:OrderStatus", + "@type": "schema:Enumeration", + "schema:hasEnumerationMember": [ + { "@id": "beckn:OrderCancelled" } + ] +} +``` + +--- + +### ❌ Forbidden + +```json +{ + "schema:hasEnumerationMember": [ + { "@id": "schema:OrderCancelled" } + ] +} +``` + +**What is wrong** + +* Makes schema.org values canonical +* Transfers semantic authority outside Beckn + +**Potential consequences in applications** + +* Enum meaning changes without Beckn versioning +* Domain extensions break unexpectedly +* Post-facto audits become unreliable + +--- + +## 10. Domain and Range Discipline + +Over-constraining domain or range harms extensibility. + +--- + +### ✅ Preferred + +```json +{ + "schema:domainIncludes": ["beckn:Order", "beckn:Item"], + "schema:rangeIncludes": "schema:Boolean" +} +``` + +--- + +### ❌ Forbidden + +```json +{ + "rdfs:domain": "beckn:Order" +} +``` + +**What is wrong** + +* Imposes closed-world assumptions + +**Potential consequences** + +* Extensions become invalid by default +* Cross-domain reuse is blocked + +--- + +## 11. Identity and Equivalence Rules + +Identity claims have **irreversible consequences** in federated systems. + +--- + +### Allowed + +* `rdfs:subClassOf` +* `rdfs:seeAlso` +* `schema:sameAs` (only when exact) + +--- + +### ❌ Forbidden + +```json +"owl:equivalentClass" +"owl:equivalentProperty" +``` + +**Potential consequences** + +* Semantic lock-in +* Network-wide breaking changes +* Impossible rollback + +--- + +## 12. Extension and Federation Rules + +Extensions may **add meaning**, never rewrite it. + +--- + +### ❌ Forbidden + +```json +{ + "orderStatus": { + "@id": "mobility:tripStatus" + } +} +``` + +```json +{ + "CANCELLED": "mobility:TripCancelled" +} +``` + +**Potential consequences** + +* Canonical meaning is lost +* Cross-network reasoning fails + +--- + +## 13. Backward Compatibility + +Semantic contracts are long-lived and auditable. + +--- + +### ❌ Forbidden + +```json +"beckn:OrderCancelled" → "beckn:OrderCanceled" +``` + +**Potential consequences** + +* Historical payloads become ambiguous +* Legal and audit trails break + +--- + +## 14. Guidance for LLMs and Tooling + +This section defines **expected refusal behavior** for automated systems. + +LLMs and tools **must refuse** to: + +* Add OWL axioms to `context.jsonld` +* Replace Beckn IRIs with schema.org IRIs +* Treat contexts as ontologies + +**Syntactic validity does not imply semantic correctness.** + +--- \ No newline at end of file diff --git a/docs/governance/CONTRIBUTING_SCHEMAS.md b/docs/governance/CONTRIBUTING_SCHEMAS.md new file mode 100644 index 0000000..6ba0465 --- /dev/null +++ b/docs/governance/CONTRIBUTING_SCHEMAS.md @@ -0,0 +1,132 @@ +# 📚 Contributing Domain-specific Schemas + +> This document has been copied from `schemas/README.md` folder. All content below this is to be reviewed and updated. + +--- + +## 🚀 Adding a New Schema Bundle + +### 📁 Folder Structure + +```bash +schema/ +└── YourUseCase/ + └── v1/ + ├── 📄 attributes.yaml # OpenAPI attribute schemas + ├── 🗺️ context.jsonld # JSON-LD context mapping + ├── 📋 profile.json # Schema profile & operational hints + ├── 🎨 renderer.json # UI rendering templates + ├── 📚 vocab.jsonld # Use-case vocabulary + ├── 📖 README.md # Documentation + ├── 📁 examples/ + │ └── 📁 schema/ + │ ├── 📄 item-example.json + │ ├── 📄 offer-example.json + │ └── 📄 provider-attributes-example.json + ├── 📁 migrations/ # Scripts to migrate from existing schema to new schema + ├── 📁 validations/ # Scripts to validate the schema with actual data + └── 📁 tests/ # Scripts to test the schema changes +``` + +### 📋 File Descriptions + +| 📄 **File / Folder** | 🎯 **Purpose** | +| --- | --- | +| 🗺️ **context.jsonld** | Maps all properties to schema.org and local beckn: IRIs. Defines semantic equivalences (e.g., serviceLocation ≡ beckn:availableAt). | +| | | +| 🔧 **attributes.yaml** | OpenAPI 3.1.1 attribute schemas for use-case specific entities, each annotated with x-jsonld. Reuses schema.org entities where possible. | +| | | +| 📋 **profile.json** | Lists included schemas, operational/index hints, minimal attributes for discovery, and privacy guidance for implementers. | +| | | +| 🎨 **renderer.json** | Defines rendering templates (HTML + JSON data paths) for discovery cards, offer chips, and status views used in UI implementations. | +| | | +| 📚 **vocab.jsonld** | Local vocabulary for use-case specific terms in JSON-LD format with RDFS definitions and semantic relationships. | +| | | +| 📁 **examples/** | Contains working examples showing each attribute type in the context of Beckn discover and transaction flows. | +| | | +| 📁 **migrations/** | Scripts to migrate from existing schema to new schema versions, including data transformation utilities. | +| | | +| 📁 **validations/** | Scripts to validate the schema with actual data, including compliance checks and data integrity tests. | +| | | +| 📁 **tests/** | Scripts to test schema changes, including unit tests, integration tests, and regression tests. | + +### 🗺️ Local Namespace Mapping + +The beckn namespace is mapped **locally**: + +```json +{ "beckn": "./vocab.jsonld#" } +``` + +> 💡 **Vocabulary files** live in `v1/vocab.jsonld` and use this same local mapping. + +When publishing, replace `./vocab.jsonld#` with an absolute URL, e.g.: + +``` +https://schemas.example.org/your-use-case/v1/vocab.jsonld# +``` + +> ✅ **This supports both local development and public hosting.** + +### 📝 Conventions + +| Convention | Description | +| --- | --- | +| **Naming** | Use `YourUseCase` format for bundle names | +| **Versioning** | Version folders use semantic versioning (v1, v2, etc.) | +| **Schema Reuse** | Reuse or repurpose schema.org entities and definitions where possible | +| **Custom Properties** | Define individual properties only when not available in schema.org | +| **Namespace** | Use `beckn:` namespace for use-case specific terms | +| **Examples** | Include working examples for all attribute types | + +--- + +## ❓ When to Add a New Schema Bundle + +Create a new schema bundle when: + +| # | Criteria | Description | +|---|----------|-------------| +| 1️⃣ | **New Use Case** | Introducing a completely new business use case (e.g., healthcare, education, logistics) | +| 2️⃣ | **Independent Attributes** | Use case has unique attributes that don't overlap with existing bundles | +| 3️⃣ | **Different Business Processes** | Serving distinct user scenarios or workflows | +| 4️⃣ | **Regulatory Separation** | Different compliance or regulatory requirements | +| 5️⃣ | **Technology Stack** | Different underlying technologies or standards | + +--- + +## 🔗 Schema Extension Guidelines + +### 🎯 When to Extend + +Extend an existing schema bundle when: + +| # | Scenario | Description | +|---|----------|-------------| +| 1️⃣ | **Regional Variations** | Same use case but different regional requirements (e.g., `EvChargingService_EU`) | +| 2️⃣ | **Regulatory Compliance** | Additional fields for specific jurisdictions | +| 3️⃣ | **Feature Additions** | Adding optional features to existing use case | +| 4️⃣ | **Backward Compatibility** | Maintaining existing implementations while adding new capabilities | + +### 🏗️ Extension Pattern + +```bash +schema/ +├── EvChargingService/ +│ └── v1/ # 📦 Base schema +└── EvChargingService_EU/ # 🔗 Extension + └── v1/ + ├── 📄 attributes.yaml # Extends base attributes + ├── 🗺️ context.jsonld # Additional mappings + └── 📖 README.md # Extension documentation +``` + +### ✅ Extension Requirements + +| Requirement | Description | +|-------------|-------------| +| **Inheritance** | Inherit from base schema via `allOf` or `$ref` | +| **Additive Only** | Add only new fields, don't modify existing ones | +| **Compatibility** | Maintain backward compatibility | +| **Documentation** | Document differences clearly | +| **Examples** | Include examples showing extended functionality | diff --git a/docs/governance/NFO_ORG_STRUCTURE-DRAFT01.md b/docs/governance/NFO_ORG_STRUCTURE-DRAFT01.md new file mode 100644 index 0000000..82e1d20 --- /dev/null +++ b/docs/governance/NFO_ORG_STRUCTURE-DRAFT01.md @@ -0,0 +1,615 @@ +# Org-level folder structure (detailed) generated by `forge-the-network.sh` + +`forge-the-network.sh` forges a **local “org workspace” directory** that contains multiple **sibling git repositories**, each with a sharply defined purpose. This implements the Attribution Playbook’s core pattern: **“One Front Door, Many Rooms”**—a single docs portal, but not a monorepo. (See *ATTRIBUTION.md*, sections “One Front Door, Many Rooms” + “Repository Taxonomy”.) + +Default parameters: + +* `NETWORK_SLUG="${1:-acmenet}"` +* `WORKDIR="${2:-$PWD/${NETWORK_SLUG}-org}"` + +So by default the workspace root becomes: + +```text +acmenet-org/ + .github/ + acmenet-profile/ + acmenet-schemas/ + acmenet-examples/ + acmenet-tooling/ + acmenet-policy/ + acmenet-docs/ + acmenet-workspace/ (optional; created when CREATE_WORKSPACE_REPO=true) +``` + +Each folder above is initialized as its **own git repo** (`git init`). + +--- + +## 0) Workspace root: `acmenet-org/` + +This is **not** a git repo by default; it’s just a **container directory** holding the org’s repos side-by-side. + +Why this matters: + +* You can clone/push each repo independently to GitHub later. +* You avoid “monorepo gravity” while still giving implementers one coherent entrypoint via `-docs`. + +--- + +## 1) Org guardrails repo: `.github/` + +Created by the script: + +```text +.github/ + CONTRIBUTING.md + SECURITY.md + CODE_OF_CONDUCT.md + PULL_REQUEST_TEMPLATE.md + ISSUE_TEMPLATE/ + bug_report.md + feature_request.md + workflows/ + reusable-validate.yml + reusable-release.yml + .gitkeep +``` + +### Folder / file explanations + +* **`.github/` (repo)** + + * The GitHub convention repo for **org-wide defaults** and “how we collaborate”. + * The idea is: every repo inherits a consistent social/engineering contract. + +* **`CONTRIBUTING.md`** + + * Contribution rules: branching, PR expectations, review etiquette, how to propose changes. + * Keeps the org from turning into a “choose-your-own-adventure” of process. + +* **`SECURITY.md`** + + * Security reporting and disclosure process. + * This is both a trust signal and a practical routing mechanism for vulnerabilities. + +* **`CODE_OF_CONDUCT.md`** + + * Expected community behavior and escalation process. + * Prevents governance-by-surprise and sets a baseline. + +* **`PULL_REQUEST_TEMPLATE.md`** + + * Forces consistent PR metadata: what changed, why, how tested, any backwards-compat impact. + +* **`ISSUE_TEMPLATE/bug_report.md`** + + * Prompts for reproducible bugs: environment, steps, expected/actual. + +* **`ISSUE_TEMPLATE/feature_request.md`** + + * Prompts for problem framing + rationale so the org doesn’t accumulate random “wishlist gravel”. + +* **`workflows/`** + + * **Reusable GitHub Actions** (intended to be called from other repos). + * Centralizes the “house rules” for validation and releases. + +* **`workflows/reusable-validate.yml`** + + * Placeholder for validation jobs (schema checks, linting, example generation verification, etc.). + +* **`workflows/reusable-release.yml`** + + * Placeholder for release automation (tagging, changelog checks, packaging artifacts). + +* **`.gitkeep`** + + * A “keep directory tracked” sentinel created by `init_repo()` in case the repo has only empty folders. + +--- + +## 2) Network contract repo: `-profile/` (e.g., `acmenet-profile/`) + +Created structure: + +```text +acmenet-profile/ + README.md + LICENSE + NOTICE.md + CHANGELOG.md + profile/ + DEPENDENCIES.yaml + SUPPORT_MATRIX.md + POLICY_REFERENCES.md + CONFORMANCE/ + discovery.md + ordering.md + fulfillment.md + post_fulfillment.md + releases/ + v0.1.0.md + .gitkeep +``` + +### Folder / file explanations + +* **`README.md`** + + * Human entrypoint for the repo: what the network profile is and how to interpret it. + +* **`LICENSE`** + + * Repo licensing. (Important because the playbook is about attribution hygiene—licensing clarity is part of that.) + +* **`NOTICE.md`** + + * Attribution + notices required by upstream dependencies or org policy. + * In practice: this is where you record “derived from” and other legal/credit obligations. + +* **`CHANGELOG.md`** + + * Chronological summary of profile changes (especially useful as network rules evolve fast). + +* **`profile/`** + + * The **machine- and human-readable “network manifest”** directory. + +* **`profile/DEPENDENCIES.yaml`** + + * The pinned upstream dependency intent for the network (core + domain versions/tags/commits). + * This implements the playbook recommendation: treat core/domain as **dependencies**, not copy-pasted content. + +* **`profile/SUPPORT_MATRIX.md`** + + * A compatibility table: supported domains, flows, versions, optional features, etc. + +* **`profile/POLICY_REFERENCES.md`** + + * Pointers to policies (often in `-policy`) that constrain implementations. + +* **`profile/CONFORMANCE/`** + + * Conformance rules organized by lifecycle stage. + +* **`profile/CONFORMANCE/discovery.md`** + + * Network-specific conformance overlays for discovery (e.g., constraints on `search`, required tags, stricter validations). + +* **`profile/CONFORMANCE/ordering.md`** + + * Conformance overlays for ordering stage. + +* **`profile/CONFORMANCE/fulfillment.md`** + + * Conformance overlays for fulfillment stage. + +* **`profile/CONFORMANCE/post_fulfillment.md`** + + * Conformance overlays for post-fulfillment stage (returns, disputes, settlement, etc.). + +* **`releases/`** + + * Release notes for each network release. + +* **`releases/v0.1.0.md`** + + * First release note template. Typically includes pinned upstream refs + change summary + migration notes. + +--- + +## 3) Extensions repo: `-schemas/` (e.g., `acmenet-schemas/`) + +Created structure: + +```text +acmenet-schemas/ + README.md + LICENSE + NOTICE.md + CHANGELOG.md + context/ + network/ + .gitkeep + jsonschema/ + network/ + .gitkeep + mapping/ + mapping-matrix.csv + notes.md + .gitkeep +``` + +### Folder / file explanations + +* **`README.md`** + + * Explains how to use schema packs, versioning conventions, and integration steps. + +* **`LICENSE` / `NOTICE.md` / `CHANGELOG.md`** + + * Standard repo hygiene: legal clarity + change tracking. + +* **`context/`** + + * JSON-LD contexts live here. + * Supports the playbook’s recommendation: extensions should be **semantically bindable** (not just structural JSON schema). + +* **`context/network/`** + + * Network-specific contexts (Layer-3). + * `.gitkeep` exists so the folder is committed even before you add contexts. + +* **`jsonschema/`** + + * JSON Schema definitions live here. + +* **`jsonschema/network/`** + + * Network-specific schema pack folder. + * `.gitkeep` keeps it tracked until real schemas arrive. + +* **`mapping/`** + + * This repo anticipates real-world messiness: networks often need mapping tables. + +* **`mapping/mapping-matrix.csv`** + + * A mapping matrix (commonly: network field → beckn field → schema.org/other vocab). + * Helps implementers and auditors understand semantics, not just shape. + +* **`mapping/notes.md`** + + * Human explanation and caveats for the mapping matrix (why certain fields map imperfectly, exceptions, etc.). + +--- + +## 4) Examples repo: `-examples/` (e.g., `acmenet-examples/`) + +Created structure: + +```text +acmenet-examples/ + README.md + LICENSE + NOTICE.md + CHANGELOG.md + upstream-refs/ + ev-charging.yaml + patches/ + ev-charging/ + on_search.patch.json + on_confirm.patch.json + generated/ + ev-charging/ + on_search.json + on_confirm.json + reports/ + latest-validation.json + .gitkeep +``` + +### Folder / file explanations + +This repo embodies the playbook’s strongest anti-drift tactic: **store deltas, generate outputs**. + +* **`README.md`** + + * Explains the patch workflow: what is upstream, what is network overlay, how to regenerate. + +* **`upstream-refs/`** + + * “Anchors” copied as references (often pointers, minimal upstream snapshots, or structured notes). + * The goal is to avoid republishing full upstream IG content, while still making provenance explicit. + +* **`upstream-refs/ev-charging.yaml`** + + * Placeholder upstream reference for an EV-charging domain example set. + * In a mature setup, this might include upstream file path refs + pinned commits. + +* **`patches/`** + + * Stores the **network-specific deltas** (often JSON Patch, merge patch, or overlay format). + +* **`patches/ev-charging/on_search.patch.json`** + + * Patch describing how the network modifies the upstream `on_search` example (adds required tags, IDs, policy fields, etc.). + +* **`patches/ev-charging/on_confirm.patch.json`** + + * Patch describing how the network modifies the upstream `on_confirm` example. + +* **`generated/`** + + * Deterministic outputs produced by applying patches to upstream anchors. + +* **`generated/ev-charging/on_search.json`** + + * Fully generated “final” example payload implementers can copy/test against. + +* **`generated/ev-charging/on_confirm.json`** + + * Same for `on_confirm`. + +* **`reports/`** + + * Validation outputs that prove the generated artifacts pass schema/conformance checks. + +* **`reports/latest-validation.json`** + + * A latest-run report artifact (CI would typically update this or publish it in release assets). + +--- + +## 5) Tooling repo: `-tooling/` (e.g., `acmenet-tooling/`) + +Created structure: + +```text +acmenet-tooling/ + README.md + LICENSE + NOTICE.md + CHANGELOG.md + scripts/ + .gitkeep + bin/ + .gitkeep + .gitkeep +``` + +### Folder / file explanations + +This repo exists because the “no-copy overlay” approach needs real machinery. + +* **`README.md`** + + * Describes tools provided, usage patterns, and how other repos consume them. + +* **`scripts/`** + + * High-level scripts (bash/python/node) that orchestrate tasks: + + * apply patches + * fetch upstream refs + * run validators + * generate docs artifacts + +* **`scripts/.gitkeep`** + + * Placeholder to keep the folder tracked. + +* **`bin/`** + + * Executable utilities (packaged CLI, small binaries, wrappers). + +* **`bin/.gitkeep`** + + * Placeholder. + +--- + +## 6) Policy repo: `-policy/` (e.g., `acmenet-policy/`) + +Created structure: + +```text +acmenet-policy/ + README.md + LICENSE + NOTICE.md + CHANGELOG.md + policies/ + network-policy.md + security-policy.md + onboarding.md + .gitkeep +``` + +### Folder / file explanations + +This repo isolates the “rules of the network” from the technical artifacts. + +* **`README.md`** + + * Explains policy scope: who it applies to (BAPs/BPPs), enforcement, change process. + +* **`policies/network-policy.md`** + + * The core network policy: eligibility, participation rules, compliance requirements. + +* **`policies/security-policy.md`** + + * Security posture, minimum requirements, incident reporting, key management expectations, etc. + +* **`policies/onboarding.md`** + + * Step-by-step onboarding: registration steps, conformance process, certification or sandbox details. + +--- + +## 7) Docs “front door” repo: `-docs/` (e.g., `acmenet-docs/`) + +Created structure: + +```text +acmenet-docs/ + README.md + LICENSE + NOTICE.md + mkdocs.yml + docs/ + index.md + architecture/ + overview.md + participants.md + trust-registry.md + security.md + ig/ + ev-charging/ + overlay.md + conformance.md + workflows/ + .gitkeep + faq.md + schemas/ + packs.md + examples/ + ev-charging.md + releases/ + index.md + tools/ + fetch-upstreams/ + .gitkeep + upstream/ + core/ (git submodule) + domain/ (git submodule) + PINNED_REFS.txt + .gitkeep +``` + +### Folder / file explanations + +This is the **single implementer entrypoint** (“one front door”). + +* **`mkdocs.yml`** + + * MkDocs site configuration (nav, theme, plugins). + * Makes the docs buildable/publishable (GitHub Pages or similar). + +* **`docs/index.md`** + + * Landing page: what the network is, where to start, “read this first”. + +* **`docs/architecture/overview.md`** + + * High-level architecture narrative for the network. + +* **`docs/architecture/participants.md`** + + * Roles/actors: NFO, participants, registry/trust components, etc. + +* **`docs/architecture/trust-registry.md`** + + * Explains trust machinery: registries, keys, verification methods, onboarding validations. + +* **`docs/architecture/security.md`** + + * Security model summary and links to the authoritative policy repo. + +* **`docs/ig/`** + + * Network-authored Implementation Guide overlays. + * Key idea from the playbook: **overlays, not duplicated upstream IGs**. + +* **`docs/ig/ev-charging/overlay.md`** + + * The delta narrative: what’s stricter/added/forbidden compared to upstream EV-charging IG. + +* **`docs/ig/ev-charging/conformance.md`** + + * Concrete conformance requirements for EV-charging in this network. + +* **`docs/ig/ev-charging/workflows/.gitkeep`** + + * Placeholder for workflow diagrams/step docs. + +* **`docs/ig/ev-charging/faq.md`** + + * FAQ for implementers to avoid “same question, 400 times” syndrome. + +* **`docs/schemas/packs.md`** + + * Explains schema packs: versions, URLs, how to import contexts, how to validate. + +* **`docs/examples/ev-charging.md`** + + * Documentation view of example flows; typically points to generated JSON in `-examples`. + +* **`docs/releases/index.md`** + + * Release page for the portal: compatibility matrix + links to profile releases. + +* **`tools/fetch-upstreams/`** + + * Placeholder for scripts that pull or index upstream docs for rendering/composition. + +* **`upstream/`** + + * Where the upstream dependencies are mounted via git submodules. + +* **`upstream/core/` (submodule)** + + * Points to `UPSTREAM_CORE_URL` (default: `beckn/protocol-specifications`). + * This is the “core layer” dependency. + +* **`upstream/domain/` (submodule)** + + * Points to `UPSTREAM_DOMAIN_URL` (default: `beckn/DEG`). + * This is the “domain layer” dependency. + +* **`upstream/PINNED_REFS.txt`** + + * Generated by the script to record intent: + + * `core_url`, `core_ref` + * `domain_url`, `domain_ref` + * Important nuance (explicitly written in the file): **the script does not auto-checkout** those refs; it records them for humans/CI to enforce. + +--- + +## 8) Optional “meta” repo: `-workspace/` (e.g., `acmenet-workspace/`) + +Created only when: + +* `CREATE_WORKSPACE_REPO=true` (default in the script) + +Structure: + +```text +acmenet-workspace/ + README.md + NOTICE.md + repos/ + .github/ (submodule) + acmenet-profile/ (submodule) + acmenet-schemas/ (submodule) + acmenet-examples/ (submodule) + acmenet-tooling/ (submodule) + acmenet-policy/ (submodule) + acmenet-docs/ (submodule) + .gitkeep +``` + +### Folder / file explanations + +* **`acmenet-workspace/`** + + * A coordinating repo that can **track all sibling repos** as submodules. + * This is for maintainers (not implementers). + +* **`repos/`** + + * Submodule mount point containing every repo forged above. + +* **`repos/.github` etc.** + + * Added as **relative-path submodules** (e.g., `../acmenet-docs`), making this workspace portable inside the forged directory. + +* **`README.md`** + + * Intended to describe how to clone the org as a coordinated set and how to update submodules. + +* **`NOTICE.md`** + + * Workspace-level notices/attribution. + +--- + +## Cross-cutting note: why so many `LICENSE`, `NOTICE.md`, `CHANGELOG.md`? + +This is deliberate “boring excellence”: + +* **`NOTICE.md`** is the concrete place to satisfy attribution and derived-work obligations (the entire purpose of the Attribution Playbook). +* **`CHANGELOG.md`** enables auditability when network rules move faster than upstream layers. +* **`LICENSE`** prevents downstream reuse from becoming legally ambiguous. \ No newline at end of file diff --git a/docs/governance/STYLE_GUIDE-DRAFT-01.md b/docs/governance/STYLE_GUIDE-DRAFT-01.md new file mode 100644 index 0000000..ba62c27 --- /dev/null +++ b/docs/governance/STYLE_GUIDE-DRAFT-01.md @@ -0,0 +1,600 @@ +# Beckn Protocol V2.0 Spec Authoring Style Guide \[DRAFT\] + +## For core protocol authors & maintainers, and for anyone publishing domain / network schema packs & API profiles + +This style guide exists because small “paper-cut” inconsistencies (casing drift, ambiguous names like `type`, enum mismatches, endpoint tokenization oddities, docs referring to non-existent schemas, etc.) compound into big interoperability debt across Beckn’s **API**, **schemas**, **JSON-LD vocab/context**, **profiles**, and **documentation**. + +It takes inspiration from Schema.org’s approach to naming and clarity—TitleCase types, lowerCamelCase properties, singular terms, avoid “type” unless you mean “class/type”—but adds the protocol-specific rigor Beckn needs: multi-artifact consistency, JSON-LD binding rules, extension pack discipline, and a practical “don’t break the world” evolution policy. ([Schema.org](https://schema.org/docs/styleguide.html)) + +--- + +# 1\. Scope and audiences + +## 1.1 Who this is for + +* **Core protocol maintainers**: editing `api/beckn.yaml` and `schema/core/v2/**`. +* **Domain spec authors (Layer 2\)**: publishing sector-specific schema packs and optional profiles / IGs (Implementation Guides). +* **Network spec authors (Layer 3\)**: extending domain packs with regional/network policy fields and network IGs. + +## 1.2 What this covers + +* API endpoint naming & action/callback pairing. +* Schema naming (types/classes), property naming, enum conventions. +* JSON-LD conventions (contexts, vocabularies, compact IRIs, bindings to schema.org). +* Cross-artifact consistency rules (OpenAPI ↔ JSON-LD ↔ profiles ↔ README ↔ examples). +* Editorial quality and documentation norms. +* A practical change-management policy (how to evolve without turning everyone’s parsers into confetti). +* Attribution & reuse expectations for domain/network layers. + +--- + +# 2\. Beckn V2.0 modeling philosophy (the “why” behind the rules) + +## 2.1 “Core \+ schema packs” is the design + +Beckn v2 models core entities as **JSON-LD graphs** (`@context`, `@type`) and relies on a modular **core \+ pluggable schema packs** approach for domain and network needs. ([GitHub](https://github.com/beckn/protocol-specifications-new/tree/draft)) + +## 2.2 Extension happens via “Attributes” containers, not core bloat + +Core entities expose explicit extension points (e.g., `...Attributes`) typed as an **Attributes** “JSON-LD aware bag” that requires `@context` and `@type`, and permits additional properties. + +This gives forward compatibility: unknown schema can be passed through or ignored if a participant doesn’t understand it, without breaking base parsing. ([GitHub](https://github.com/beckn/protocol-specifications-new/tree/draft)) + +## 2.3 Three-layer ecosystem reality + +In practice: + +* **Layer 1 (Core)** changes slowest. +* **Layer 2 (Domain)** changes faster and includes semantic bindings \+ IGs. +* **Layer 3 (Network)** changes fastest due to go-to-market and policy pressure. + +This guide is designed to keep those layers composable *without* incentivizing permanent forks and attribution loss. + +--- + +# 3\. Normative keywords (kept minimal, but precise) + +* **MUST** / **MUST NOT**: hard requirements for spec compatibility and tooling stability. +* **SHOULD** / **SHOULD NOT**: strong defaults; deviating needs a documented reason. +* **MAY**: optional patterns. + +--- + +# 4\. Repository artifacts and “source of truth” + +Beckn V2 specs typically ship as **bundles**. A “bundle” is only healthy if it stays internally consistent. + +## 4.1 Core bundle + +* `api/beckn.yaml` — normative API definition. +* `schema/core/v2/attributes.yaml` — normative schemas. +* `schema/core/v2/context.jsonld` — normative JSON-LD context. +* `schema/core/v2/vocab.jsonld` — normative vocabulary (human+machine meaning). + +## 4.2 Domain / Network schema pack bundle (expected structure) + +A schema pack is expected to include, at minimum: + +* `attributes.yaml` +* `context.jsonld` +* `vocab.jsonld` +* `README.md` (human guidance) +* `examples/**` (payloads that validate) +* Optional: `profile.json` (capabilities/config for services like discovery profiles) + +PRs \#67 and \#68 explicitly call out that name changes must be applied across **attributes.yaml, vocab.jsonld, context.jsonld, README.md, profile.json** to prevent drift. ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/67)) + +## 4.3 Canonical naming authority (when conflicts exist) + +When artifacts disagree, the priority order is: + +1. **`attributes.yaml`** schema names and property names (machine contracts). +2. **`context.jsonld`** bindings (semantic meaning / interoperability). +3. **`vocab.jsonld`** labels/definitions (human meaning). +4. **Examples** (must validate against \#1). +5. **README / docs** (must match everything else). + +If \#4 or \#5 disagree with \#1: examples/docs are wrong until fixed. + +--- + +# 5\. Naming conventions + +Beckn naming rules deliberately align with Schema.org where possible: + +* **Types/classes**: TitleCase (PascalCase) ([Schema.org](https://schema.org/docs/styleguide.html)) +* **Properties**: lowerCamelCase ([Schema.org](https://schema.org/docs/styleguide.html)) +* **Singular terms** even if the value is an array ([Schema.org](https://schema.org/docs/styleguide.html)) +* Avoid naming a **type** and a **property** the same thing ([Schema.org](https://schema.org/docs/styleguide.html)) + +Then Beckn adds protocol-specific rules for endpoints, JSON-LD compact IRIs, enums, and extension packs. + +--- + +# 6\. API endpoint and action naming + +## 6.1 Base endpoint shape + +* All protocol endpoints MUST be rooted under: `//beckn/...` (exact server root varies by deployment; path after it is normative). +* Endpoint path segments MUST be **lowercase**. +* Multi-word tokens MUST use **snake\_case** (`browser_search`), not hyphenation (`browser-search`). + +**Example (fixed):** `browser-search` → `browser_search` ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/67)) + +## 6.2 Action vs callback pairing + +* For every action endpoint `/<...>/`, the callback endpoint MUST be `/<...>/on_`. +* If an action name is compound (multi-segment), the *canonical action identifier* MUST be the segments joined with `_` for use in `context.action`. + +This explicitly resolves the drift described in the context doc (path tokenization vs `context.action`). + +**Rule: canonical action name** + +* Strip the leading `/beckn/` +* Join remaining path segments with `_` + +Examples: + +* `/beckn/select` → `select` +* `/beckn/on_select` → `on_select` +* `/beckn/discover/offer` → `discover_offer` +* `/beckn/on_discover/offer` → `on_discover_offer` + +## 6.3 Versioning MUST NOT live in endpoint path + +Protocol versioning belongs in the message metadata (`context.version`, etc.), not in the URL path. The context file flags `/beckn/v2/...` as an inconsistency that creates taxonomy drift. + +If you need a non-backward-compatible API surface, that is a **new protocol major version**, not a path fork. + +## 6.4 Endpoint namespaces (allowed, but disciplined) + +Namespaces like `/discover/...` are allowed when: + +* They represent a durable conceptual grouping (e.g., discovery vs transaction). +* They follow the same action/callback pairing rules. +* They do not create ambiguous “is the action `publish` or `catalog_publish`?” situations. + +## 6.5 Legacy exceptions + +Some legacy shapes exist (e.g., noun-form `rating`), and MUST be explicitly documented as exceptions so they don’t become precedents. + +--- + +# 7\. Schema pack names, folder names, and type names + +## 7.1 Folder name ↔ root class name alignment + +**Rule:** A schema pack folder name and its “primary” schema class name MUST match 1:1 for domain/network packs. + +PR \#68 made this explicit by renaming EV Charging classes to match folders: + +* `EvChargingService`: `ChargingService` → `EvChargingService` +* `EvChargingOffer`: `ChargingOffer` → `EvChargingOffer` +* `EvChargingSession`: `ChargingSession` → `EvChargingSession` +* `EvChargingPointOperator`: `ChargingPointOperator` → `EvChargingPointOperator` ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/68)) + +**Rationale:** Domain objects are domain-specific and not meant to be reused across domains; alignment prevents collisions and confusion. ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/68)) + +## 7.2 Core types vs domain types + +* **Core types MUST be domain-agnostic** (e.g., `Order`, `Item`, `Fulfillment`, `Invoice`, `Payment`). +* **Domain types MUST be explicitly domain-scoped** (prefix, namespace, or pack naming) to avoid collisions over time. + +## 7.3 When to use `*Action` types + +If you model a concept as an **action/event** (often aligned with schema.org `Action`), use `*Action`: + +* Use `TrackAction` when representing “the act of tracking” (event semantics). +* Use `Tracking` (noun) when representing a persistent “tracking object/state”. + +The context doc highlights confusion when both exist without clear rules. + +**Decision test:** + +* If it has an **agent**, **object/target**, and **time-bounded execution** → `*Action`. +* If it’s a **thing with state** over time → noun. + +--- + +# 8\. Property naming + +## 8.1 Universal casing rule + +* New properties MUST be **lowerCamelCase**. ([Schema.org](https://schema.org/docs/styleguide.html)) +* snake\_case is legacy and MUST NOT be introduced in new work. + +PR \#67 and \#68 standardized many fields accordingly: + +* `transaction_id` → `transactionId` +* `ack_status` → `ackStatus` +* `tl_method` → `tlMethod` +* `expires_at` → `expiresAt` +* `mime_type` → `mimeType` +* `submission_id` → `submissionId` ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/67)) + +And in profile/API configs: + +* `schema_context` → `schemaContext` +* `network_id` → `networkId` +* `catalog_id` → `catalogId` +* `item_count` → `itemCount` ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/68)) + +## 8.2 Reserved/ambiguous names are forbidden + +Avoid property names that are overloaded by JSON Schema/OpenAPI or unclear to humans. + +**Forbidden unless explicitly required by an external standard:** + +* `type` (except JSON-LD’s `@type`) + +PR \#67 renamed a real example: + +* `filters.type` → `filters.expressionType` (avoids JSON Schema reserved keyword) ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/67)) + +## 8.3 Singular property names (even for arrays) + +Property names MUST be singular. The array-ness is expressed by the schema type, not by pluralization. ([Schema.org](https://schema.org/docs/styleguide.html)) + +✅ `item`, `fulfillment`, `location` ✅ `item` can be `type: array` ❌ `itemsList`, `locationsArray`, `parents` + +## 8.4 Prepositions go last + +Use Schema.org’s guidance: prepositions come after the noun/verb concept. ([Schema.org](https://schema.org/docs/styleguide.html)) + +✅ `reservationFor` ❌ `forReservation` + +## 8.5 Abbreviations and acronyms + +**Default rule:** spell out abbreviations unless it becomes painfully verbose. ([Schema.org](https://schema.org/docs/styleguide.html)) + +**Beckn-specific additions:** + +* Use consistent casing for repeated acronyms across the spec. +* If an acronym is an industry-standard identifier, preserve it. + +PR \#67 standardized a unit-casing example: + +* `meteredEnergyKWh` → `meteredEnergyKWH` (to match `maxPowerKW`) ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/67)) + +PR \#68 lists explicit “industry standard identifier” exceptions (kept as-is): + +* `connectorType` enum values like `CCS2`, `Type2`, `CHAdeMO`, `GB_T` ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/68)) + +## 8.6 Dates and times + +Use: + +* `...At` for instants (`expiresAt`, `createdAt`) +* `...On` for date-only semantics (`issueDate` / `issueOn` depending on type clarity) + +Be consistent across packs. + +## 8.7 Legacy exceptions (document; don’t copy) + +PR \#68 explicitly kept certain **context object** fields in snake\_case as legacy from v1.x: + +* `message_id`, `bap_id`, `bap_uri`, `bpp_id`, `bpp_uri` ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/68)) + +**Rule:** These are exceptions; new fields MUST NOT follow that pattern. + +--- + +# 9\. Enum value conventions + +## 9.1 Canonical enum style + +Enum values MUST be **SCREAMING\_SNAKE\_CASE**: + +* Uppercase ASCII letters, digits, and `_` +* No hyphens, spaces, or mixed casing + +PR \#67 and \#68 standardized many enums: + +* `parkingType`: `OnStreet` → `ON_STREET` +* `amenityFeature`: `WI-FI` → `WI_FI` +* `vehicleType`: `2-WHEELER` → `2_WHEELER` ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/67)) + +API enums: + +* `mode_hint`: `link_only` → `LINK_ONLY`, etc. +* `quantifier`: `any` → `ANY` +* `goals`: `visual-similarity` → `VISUAL_SIMILARITY` ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/68)) + +Core enum: + +* `tlMethod`: `http/get` → `HTTP_GET`, etc. ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/68)) + +## 9.2 Grammar rules for enums + +Enum members MUST be grammatically consistent within an enum: + +* **Statuses** should be adjectives or past participles (`PENDING`, `ACTIVE`, `COMPLETED`, `STOPPED`), not raw verbs. + +PR \#67 example: + +* `sessionStatus`: `STOP` → `STOPPED` ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/67)) + +## 9.3 Stability and evolution + +* Enum values are part of the public contract. +* Adding values is usually backward compatible. +* Renaming/removing values is breaking and requires a migration strategy (see §13). + +--- + +# 10\. JSON-LD conventions (contexts, vocab, and compact IRIs) + +## 10.1 Every serializable entity MUST be JSON-LD self-describing + +Core and extension objects MUST include: + +* `@context` (URI) +* `@type` (compact or full IRI) + +This is a core design principle used by the Attributes container. + +## 10.2 Namespacing strategy + +* Use `schema:` (schema.org) when semantics match schema.org. +* Use `beckn:` when semantics are protocol-specific. + +When mapping a field to schema.org, provide an explicit binding (e.g., using an extension such as `x-jsonld` in schema definitions). The core schema uses this pattern for mappings like `schema:priceSpecification`. + +## 10.3 Context and vocab must not drift from schemas + +For every term/type defined in `attributes.yaml`, ensure: + +* `context.jsonld` defines how it maps to IRIs +* `vocab.jsonld` contains human-readable labels/definitions aligned to that meaning +* README references the correct canonical names + +PR \#67 explicitly fixed a README mismatch: + +* `ChargingProvider` → `ChargingPointOperator` ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/67)) + +## 10.4 Backward-compatibility mappings + +When renaming a property or enum value: + +* Provide a migration path in the JSON-LD context layer when feasible (e.g., aliasing old terms/values), and document it clearly. PR \#67 notes backward-compatibility mappings were added for enum value changes. ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/67)) + +--- + +# 11\. Schema authoring rules (OpenAPI/JSON Schema) + +## 11.1 Structural correctness is non-negotiable + +Broken indentation can accidentally introduce nonsense fields (e.g., an unintended property literally named `items`). The context doc calls out a real case where `items` was mis-indented. PR \#67 fixed that `amenityFeature` array structure. ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/67)) + +**Rule:** All schema bundles MUST pass: + +* YAML syntax validation +* OpenAPI validation +* JSON Schema validation (at least for examples) + +## 11.2 Closed core, open extensions + +* Core entity schemas SHOULD default to `additionalProperties: false`. +* Extension containers (`Attributes`) MUST allow `additionalProperties: true` and require `@context` and `@type`. + +## 11.3 Required fields: be conservative + +Adding a required field is a breaking change for producers. + +**Rule:** Make fields required only when: + +* The object is invalid/meaningless without it, AND +* A safe default cannot exist, AND +* You are willing to treat this as a compatibility commitment. + +## 11.4 Prefer reuse over duplication + +If semantics already exist in core or schema.org, reuse rather than inventing near-duplicates. Schema.org explicitly encourages reuse and warns that terms have specific semantic meaning beyond the name. ([Schema.org](https://schema.org/docs/styleguide.html)) + +--- + +# 12\. Examples and documentation quality gates + +## 12.1 Examples MUST validate + +Every example payload MUST match: + +* property names (case-sensitive) +* enum casing and values +* schema structure + +PR \#67 fixed real example mismatches: + +* `Tracking.trackingStatus`: `"active"` → `"ACTIVE"` +* `SupportInfo.channels`: `["web","phone","email"]` → `["WEB","PHONE","EMAIL"]` +* `AcceptedPaymentMethod`: `["UPI","Card","Wallet"]` → `["UPI","CREDIT_CARD","WALLET"]` ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/67)) + +## 12.2 Documentation must name real things + +README tables MUST reference canonical schema names, not “what we meant”. + +PR \#67 fixed a mismatch (`ChargingProvider` → `ChargingPointOperator`). ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/67)) + +## 12.3 Editorial tone and consistency + +* Use US English spelling. ([Schema.org](https://schema.org/docs/styleguide.html)) +* Expand acronyms on first use in READMEs/docs (unless globally obvious in the Beckn ecosystem). +* Avoid internal jargon unless defined in a glossary. + +--- + +# 13\. Change management and backward compatibility + +## 13.1 What counts as breaking + +Breaking changes include: + +* Renaming a property (`transaction_id` → `transactionId`) +* Renaming a type (`ChargingService` → `EvChargingService`) +* Renaming enum values (`http/get` → `HTTP_GET`) +* Changing required fields +* Changing the meaning of an existing field + +PR \#68 explicitly lists these as breaking categories. ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/68)) + +## 13.2 Preferred evolution path (practical and safe) + +When you need change: + +1. **Add new field / new enum value** (keep old). +2. Mark old as **deprecated** in description/docs. +3. Provide a **migration note** and (when feasible) a JSON-LD alias mapping. +4. Remove only in a planned major release. + +## 13.3 Don’t silently “semantic shift” + +Never reuse an existing name with a new meaning. If meaning changes, create a new term and deprecate the old. + +--- + +# 14\. Domain-specific schema & API spec rules (Layer 2\) + +Domain packs exist because “core can’t model all nouns” and need sector vocabularies bound back to Beckn for validation/interoperability. + +## 14.1 Domain packs MUST be additive to core + +* Do NOT fork core semantics into new names when an extension pack suffices. +* Use core’s `...Attributes` extension points to attach domain objects at runtime. + +## 14.2 Semantic binding is mandatory (eventually) + +A domain pack SHOULD provide JSON-LD mappings to: + +* `beckn:` terms when it is protocol-specific +* `schema:` terms when schema.org already captures the semantics + +This is key for validators like Beckn ONIX to validate extended schema “comfortably” without breaking interoperability. + +## 14.3 Domain pack naming + +* Pack folder: TitleCase (e.g., `EvChargingService`) +* Primary types: match folder name and be domain-scoped (see §7.1) ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/68)) +* Properties: lowerCamelCase; enums SCREAMING\_SNAKE\_CASE (see §8–§9) + +## 14.4 Domain profiles and IGs + +Implementation Guides are **recommendations**, not protocol law, but they must still: + +* Use canonical schema names +* Provide validating examples +* Declare deviations/policies explicitly + +--- + +# 15\. Network-specific schema & API spec rules (Layer 3\) + +Networks often need regional identifiers (e.g., UPI IDs, FSSAI license numbers) and policy constraints. + +## 15.1 Extension strategy + +Network specs SHOULD extend **domain packs**, not core, unless: + +* The field is universally applicable across domains, and +* It is proven stable enough for core. + +## 15.2 Network namespacing + +Network-specific attributes MUST be namespaced to avoid collisions: + +* Prefer network context URIs and network-specific `@type` values. +* Avoid “generic” names like `licenseNumber` without context; be specific (`fssaiLicenseNumber`, etc.). + +## 15.3 Fast-moving does not mean sloppy-moving + +Even if go-to-market forces a network to ship quickly: + +* Keep a clear mapping to domain/core semantics. +* File upstream PRs/issues when possible. +* Don’t create permanent forks without attribution and traceability. + +--- + +# 16\. Attribution and reuse guidelines (Core → Domain → Network) + +Because specs are reused, copied, and sometimes forked, governance must ensure attribution is preserved—especially when networks publish their own IGs and schema extensions. + +## 16.1 Minimum attribution requirements (practical, not ceremonial) + +Anyone publishing a domain or network spec derived from Beckn MUST: + +* Preserve upstream license notices and copyright headers. +* Include a visible “Based on Beckn Protocol v2.x” attribution in README. +* Link to the upstream repository and the specific release/commit/tag used as the base. +* Maintain a `CHANGES.md` (or equivalent section) listing what was modified from upstream. + +## 16.2 Forking is allowed; silent copying is not + +If you must fork to meet timelines: + +* Make the fork explicit. +* Keep attribution intact. +* Track upstream merges so the fork doesn’t become a permanent parallel universe. + +--- + +# 17\. Cross-artifact consistency checklist (for every PR) + +Use this as a PR review gate: + +## Naming & casing + +- [ ] Types are TitleCase; properties lowerCamelCase; enums SCREAMING\_SNAKE\_CASE. ([Schema.org](https://schema.org/docs/styleguide.html)) +- [ ] No new snake\_case except documented legacy exceptions. ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/68)) +- [ ] No ambiguous reserved names like `type` (unless JSON-LD `@type`). ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/67)) + +## API + +- [ ] Endpoint tokens use lowercase \+ snake\_case; no hyphens. ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/67)) +- [ ] Action/callback pairing is consistent (`on_` prefix). + +## Schemas + +- [ ] YAML structure validated (arrays have correctly nested `items`, etc.). ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/67)) +- [ ] Domain pack folder ↔ class name alignment holds. ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/68)) + +## JSON-LD and docs + +- [ ] `attributes.yaml` changes mirrored in `context.jsonld`, `vocab.jsonld`, README, profile.json. ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/67)) +- [ ] Examples validate against schemas; enum casing matches. ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/67)) + +## Compatibility and governance + +- [ ] Breaking changes are clearly labeled and include migration guidance. ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/68)) +- [ ] Domain/network extensions include attribution and traceability to upstream. + +--- + +# 18\. Quick reference tables + +## 18.1 Casing summary + +| Thing | Format | Example | +| :---- | :---- | :---- | +| Schema type/class | TitleCase | `EvChargingService` ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/68)) | +| Property (general) | lowerCamelCase | `transactionId` ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/67)) | +| Enum values | SCREAMING\_SNAKE\_CASE | `HTTP_GET`, `LINK_ONLY` ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/68)) | +| JSON-LD keywords | JSON-LD standard | `@context`, `@type` | +| Endpoint tokens | lowercase \+ snake\_case | `browser_search` ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/67)) | + +## 18.2 “Before → After” examples pulled from real cleanups + +* Reserved ambiguity: `filters.type` → `filters.expressionType` ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/67)) +* snake\_case → camelCase: `expires_at` → `expiresAt` ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/67)) +* Enum normalization: `http/get` → `HTTP_GET` ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/68)) +* Domain scoping: `ChargingSession` → `EvChargingSession` ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/68)) + +--- + +# 19\. Source materials used for this guide + +* Beckn style-guide context (problem statements, inconsistency classes). +* Attribution & layering context (core→domain→network, IG realities, attribution problem). +* Beckn core schema reference (Attributes container pattern, JSON-LD requirements). +* Schema.org naming guidance baseline (TitleCase / lowerCamelCase / singular / avoid “type”). ([Schema.org](https://schema.org/docs/styleguide.html)) +* Beckn PR \#67 (naming, enum, example fixes). ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/67)) +* Beckn PR \#68 (domain class alignment, remaining casing/enum standardization, legacy exceptions). ([GitHub](https://github.com/beckn/protocol-specifications-v2/pull/68)) diff --git a/docs/implementation/Discovering-catalogs-on-Beckn.md b/docs/implementation/Discovering-catalogs-on-Beckn.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/implementation/Fulfillment-on-Beckn.md b/docs/implementation/Fulfillment-on-Beckn.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/BECKN-010-QR-Codes.md b/docs/implementation/Implementing-Beckn-Aware-QR-Codes.md similarity index 99% rename from docs/BECKN-010-QR-Codes.md rename to docs/implementation/Implementing-Beckn-Aware-QR-Codes.md index ccef3e6..a7bbc8c 100644 --- a/docs/BECKN-010-QR-Codes.md +++ b/docs/implementation/Implementing-Beckn-Aware-QR-Codes.md @@ -88,6 +88,6 @@ The merchant generated QR code will have specific bpp id and provider id in the - Show the catalog from cache or - Send a live search to all BPPs and then show specific merchant’s catalog - Send live search for specific bpp id in context, however in that case the BAP would need the bpp url (from local lookup). -- All BAPs would need to support beckn anchor tags across different platforms i.e. web, android and iOS. +- All BAPs would need to support beckn anchor tags across different platforms, i.e., web, Android, and iOS. The BAPs would need to maintain a local lookup for registry endpoints based on the network, in case the BAP is complying to multiple networks within beckn. diff --git a/docs/implementation/Ordering-on-Beckn.md b/docs/implementation/Ordering-on-Beckn.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/implementation/Payments-on-Beckn.md b/docs/implementation/Payments-on-Beckn.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/implementation/Publishing-your-catalog-on-Beckn.md b/docs/implementation/Publishing-your-catalog-on-Beckn.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/implementation/Rating-on-Beckn.md b/docs/implementation/Rating-on-Beckn.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/implementation/Registering-on-Beckn.md b/docs/implementation/Registering-on-Beckn.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/implementation/Support-on-Beckn.md b/docs/implementation/Support-on-Beckn.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/overview/How-to-navigate.md b/docs/overview/How-to-navigate.md new file mode 100644 index 0000000..98e34fa --- /dev/null +++ b/docs/overview/How-to-navigate.md @@ -0,0 +1,3 @@ +# How to navigate this repository + +TODO \ No newline at end of file diff --git a/docs/schema/Schema-Design-Guide.md b/docs/schema/Schema-Design-Guide.md new file mode 100644 index 0000000..1011f1e --- /dev/null +++ b/docs/schema/Schema-Design-Guide.md @@ -0,0 +1,156 @@ +# A Robust, Forward-looking Schema Design Framework to Create Domain-specific Bindings for Beckn Protocol 2.0 + +## Request for Comments – Jan 19, 2026 - DRAFT + +# About this Document + +### Latest published version + +To be published. This RFC is currently under community review and iteration. + +### Latest editor's draft + +* Google Docs (comment access required): [https://docs.google.com/document/d/17JJMherJ68ILYRqMqpnNdto1eENs24_d5ylin8uNkQ0/edit?usp=sharing](https://docs.google.com/document/d/17JJMherJ68ILYRqMqpnNdto1eENs24_d5ylin8uNkQ0/edit?usp=sharing) +* GitHub (editorial source of truth): To be added + +Contributors are requested to review the Community Guidelines for Contributing before requesting access. + +### Implementation report + +Not available at the time of publishing this draft. + +### Editors + +* Ravi Prakash (Beckn Labs) +* Pramod Varma (Networks for Humanity) + +### Authors + +* Ravi Prakash (Beckn Labs) + +### Feedback + +#### Issues + +To view open issues on this topic, [click here](https://github.com/beckn/protocol-specifications-v2/issues?q=is%3Aissue%20state%3Aopen%20label%3Aschema-design) + +#### Discussions + +To view discussions on this topic [click here](https://github.com/beckn/protocol-specifications-v2/discussions?discussions_q=is:open%20label:schema-design) + +#### Pull Requests + +To be tracked via GitHub Pull Requests. + +### Errata + +No errata recorded as of this draft. + +# Acknowledgements + +The author would like to thank the following contributors for their insights and reviews: + +1. Abhishek Jain + +# Context + +## Beckn Protocol 2.0 + +Beckn Protocol 2.0 represents a structural evolution of the Beckn ecosystem, shifting from loosely coupled, interpretation-heavy payloads to a rigorously defined, schema-first transactional protocol. The core objective of Beckn v2.0 is to enable interoperable, verifiable, and automatable commerce across heterogeneous networks, platforms, and AI agents. + +A central pillar of this evolution is the introduction of strict core schemas, explicit domain extensions, and a clear separation between protocol-level guarantees and domain-specific semantics. This allows Beckn to scale horizontally across industries such as mobility, commerce, energy, logistics, and finance without fragmenting the protocol itself. + +## Adoption Landscape + +As Beckn adoption increases across sectors, domain implementers bring with them pre-existing data standards, ontologies, and operational schemas (for example, GTFS in mobility or industry-specific catalog formats in commerce). Without a consistent methodology to bind these domain standards to Beckn, implementations risk semantic drift, incompatible payloads, and brittle integrations. + +This RFC addresses that gap. + +# Intended Outcome + +A developer building a Beckn Protocol 2.0 endpoint for a domain-specific application (BAP or BPP) should be able to: + +1. Install Beckn ONIX. +2. Install a domain binding plugin (for example, mobility-beckn or gtfs-beckn) on the ONIX adapter. +3. Map an existing domain schema to Beckn core and extension schemas using a predictable, repeatable process. +4. Validate payloads deterministically at runtime. +5. Achieve semantic interoperability with other Beckn participants without bespoke bilateral agreements. + +# Problem + +## Current State + +Today, domain-specific Beckn implementations often rely on ad-hoc schema extensions, implicit assumptions, or undocumented field mappings. Different teams may model the same real-world concept in incompatible ways, even within the same domain. + +Common symptoms include: + +* Reuse of Beckn fields with domain-specific overloading. +* Proliferation of custom attributes without shared semantics. +* Ambiguous precedence between schema.org, Beckn core schemas, and domain vocabularies. +* Difficulty validating payload correctness beyond basic structural checks. + +## Consequences + +This approach leads to: + +* Reduced interoperability across networks. +* Increased integration costs for new participants. +* Fragile agent behavior due to semantic ambiguity. +* Inability to reason over transactions programmatically at scale. + +## Problem Statement + +How do we enable domain experts and implementers to reuse existing domain standards while producing Beckn-compliant schemas that are unambiguous, verifiable, and interoperable across networks? + +# Solution + +## Design Principles + +1. Human intent precedes machine enforcement. +2. Closed schemas are required for validation and contract enforcement. +3. Openness is achieved through semantic equivalence, not schema inheritance. +4. Beckn core schemas remain minimal and domain-agnostic. +5. Domain-specific semantics are isolated, versioned, and explicitly bound. + +## Proposed Framework + +The framework defines a staged schema derivation pipeline: + +1. **Domain Standard**: Human-readable specifications such as PDFs, HTML documents, or markdown files that describe domain concepts and rules. +2. **Closed Domain Vocabulary**: A machine-readable but closed representation of domain terms, independent of JSON-LD or web semantics. +3. **Closed JSON-LD Schema**: A strict JSON-LD schema with a self-contained vocabulary, suitable for validation and runtime enforcement. +4. **Open Semantic Mapping Layer**: A derived schema that declares semantic equivalence to schema.org and/or Beckn schemas without relaxing validation rules. + +This staged approach ensures clarity at each level while preventing premature coupling to external ontologies. + +## Schema Precedence Rules + +1. Beckn core schemas take precedence for protocol-level constructs. +2. Domain schemas define semantics within their declared scope. +3. schema.org is used as a semantic reference, not as a validation authority. +4. In the absence of a suitable mapping, new domain vocabulary entries must be explicitly defined and versioned. + +## Concrete Example (Mobility / GTFS) + +* Existing GTFS fields are first mapped to Beckn core entities where semantic equivalence exists. +* Fields without Beckn counterparts are mapped to schema.org terms if appropriate. +* Remaining unmapped fields are defined in a domain vocabulary file (for example, mobility/gtfs/vocab.json). +* Validation rules for these fields are enforced via the closed JSON-LD schema. + +## Tooling Requirements + +To operationalize this framework at scale, the following tooling is required: + +* Schema binding repositories with clear versioning. +* Automated validators for closed JSON-LD schemas. +* Linting tools to detect ambiguous or conflicting mappings. +* Plugin-based adapters (for example, Beckn ONIX plugins) that load domain bindings dynamically. +* CI pipelines to enforce schema governance rules. + +## Flow Diagram + +Refer to the accompanying schema design methodology diagram that illustrates the staged derivation and semantic binding process. + +# Conclusion + +This RFC proposes a disciplined, forward-looking schema design framework that balances strict validation with semantic openness. By separating concerns across layers and enforcing clear precedence rules, Beckn Protocol 2.0 can support deep domain specialization without sacrificing interoperability or long-term evolvability. diff --git a/examples/v2.1/AcceptedPaymentMethod.examples.yaml b/examples/v2.1/AcceptedPaymentMethod.examples.yaml new file mode 100644 index 0000000..64f688d --- /dev/null +++ b/examples/v2.1/AcceptedPaymentMethod.examples.yaml @@ -0,0 +1,8 @@ +# Examples for AcceptedPaymentMethod schema + +basic: + summary: Basic payment methods + value: + - UPI + - Card + - Wallet diff --git a/examples/v2.1/GeoJSONGeometry.examples.yaml b/examples/v2.1/GeoJSONGeometry.examples.yaml new file mode 100644 index 0000000..47b6274 --- /dev/null +++ b/examples/v2.1/GeoJSONGeometry.examples.yaml @@ -0,0 +1,41 @@ +# Examples for GeoJSONGeometry schema + +point: + summary: Point geometry + value: + coordinates: + - 77.5946 + - 12.9716 + type: Point + +polygon_rectangle: + summary: Polygon rectangle geometry + value: + coordinates: + - - - 77.61 + - 12.92 + - - 77.64 + - 12.92 + - - 77.64 + - 12.95 + - - 77.61 + - 12.95 + - - 77.61 + - 12.92 + type: Polygon + +geometry_collection: + summary: Geometry collection + value: + geometries: + - coordinates: + - 77.6 + - 12.95 + type: Point + - coordinates: + - - 77.6 + - 12.95 + - - 77.62 + - 12.97 + type: LineString + type: GeometryCollection diff --git a/examples/v2.1/Location.examples.yaml b/examples/v2.1/Location.examples.yaml new file mode 100644 index 0000000..2e0815a --- /dev/null +++ b/examples/v2.1/Location.examples.yaml @@ -0,0 +1,28 @@ +# Examples for Location schema + +site_point: + summary: Location with address and point + value: + address: MG Road, Bengaluru + geo: + coordinates: + - 77.5946 + - 12.9716 + type: Point + +service_area: + summary: Location with polygon service area + value: + geo: + coordinates: + - - - 77.61 + - 12.92 + - - 77.64 + - 12.92 + - - 77.64 + - 12.95 + - - 77.61 + - 12.95 + - - 77.61 + - 12.92 + type: Polygon diff --git a/examples/v2.1/MediaSearch.examples.yaml b/examples/v2.1/MediaSearch.examples.yaml new file mode 100644 index 0000000..9ceda9f --- /dev/null +++ b/examples/v2.1/MediaSearch.examples.yaml @@ -0,0 +1,15 @@ +# Examples for MediaSearch schema + +basic: + summary: Media search with image + value: + media: + - id: snap-1 + type: image + url: https://cdn.example.com/user/snaps/ccs2-cable.jpg + contentType: image/jpeg + options: + goals: + - VISUAL_OBJECT_DETECT + - TEXT_FROM_IMAGE + augmentTextSearch: true diff --git a/examples/v2.1/SpatialConstraint.examples.yaml b/examples/v2.1/SpatialConstraint.examples.yaml new file mode 100644 index 0000000..085dbcc --- /dev/null +++ b/examples/v2.1/SpatialConstraint.examples.yaml @@ -0,0 +1,59 @@ +# Examples for SpatialConstraint schema + +within_circle: + summary: EV sites within 5 km of a center (via S_DWITHIN) + value: + op: S_DWITHIN + targets: $['beckn:availableAt'][*]['geo'] + geometry: + type: Point + coordinates: + - 77.5946 + - 12.9716 + distanceMeters: 5000 + +pickup_at_point: + summary: Pickup at a defined point (GeoJSON Point) + description: 'Example of a DiscoverRequest spatial constraint representing a specific pickup location. The requester defines a GeoJSON Point as the pickup location, and the server finds providers whose service area **contains** this point.' + value: + op: S_CONTAINS + targets: $['beckn:itemAttributes']['ride:serviceArea']['geo'] + geometry: + type: Point + coordinates: + - 77.5946 + - 12.9716 + +drop_intersects: + summary: Provider drop zone intersects user's rectangle + value: + op: S_INTERSECTS + targets: $['beckn:itemAttributes']['ride:dropOff']['geo'] + geometry: + type: Polygon + coordinates: + - - - 77.61 + - 12.92 + - - 77.64 + - 12.92 + - - 77.64 + - 12.95 + - - 77.61 + - 12.95 + - - 77.61 + - 12.92 + +pickup_location: + summary: A defined pickup location object + value: + geo: + type: Point + coordinates: + - 77.5946 + - 12.9716 + address: + streetAddress: MG Road + addressLocality: Bengaluru + addressRegion: Karnataka + postalCode: '560001' + addressCountry: IN diff --git a/examples/v2.1/SupportInfo.examples.yaml b/examples/v2.1/SupportInfo.examples.yaml new file mode 100644 index 0000000..352d77d --- /dev/null +++ b/examples/v2.1/SupportInfo.examples.yaml @@ -0,0 +1,14 @@ +# Examples for SupportInfo schema + +basic: + summary: Basic support information + value: + channels: + - web + - phone + - email + email: support@acme.example + hours: Mon–Sat 09:00–20:00 IST + name: Acme Support + phone: +91-80-1234-5678 + url: https://acme.example/support diff --git a/examples/v2.1/Tracking.examples.yaml b/examples/v2.1/Tracking.examples.yaml new file mode 100644 index 0000000..99939f6 --- /dev/null +++ b/examples/v2.1/Tracking.examples.yaml @@ -0,0 +1,9 @@ +# Examples for Tracking schema + +basic: + summary: Basic tracking information + value: + expires_at: '2025-10-16T18:30:00Z' + tl_method: http/get + trackingStatus: active + url: https://track.bpp.example?order_id=ORD-123 diff --git a/examples/v2.1/ack.examples.yaml b/examples/v2.1/ack.examples.yaml new file mode 100644 index 0000000..e0dedc5 --- /dev/null +++ b/examples/v2.1/ack.examples.yaml @@ -0,0 +1,26 @@ +ack_success: + summary: ACK + value: + transactionId: "e5f6a7b8-c9d0-4e1f-9a2b-3c4d5e6f7081" + timestamp: "2024-04-10T16:10:50+05:30" + ackStatus: "ACK" +ack_bad_request: + summary: NACK — bad request + value: + transactionId: "f6a7b8c9-d0e1-42f3-8a2b-3c4d5e6f7081" + timestamp: "2024-04-10T16:10:50+05:30" + ackStatus: "NACK" + error: + code: "INVALID_REQUEST" + paths: "context.schemaContext" + message: "Invalid schema context provided" +ack_server_error: + summary: NACK — internal error + value: + transactionId: "a7b8c9d0-e1f2-43a4-9b2c-3d4e5f607081" + timestamp: "2024-04-10T16:10:50+05:30" + ackStatus: "NACK" + error: + code: "INTERNAL_ERROR" + paths: "server" + message: "Internal server error occurred" \ No newline at end of file diff --git a/examples/v2.1/catalog_on_publish.examples.yaml b/examples/v2.1/catalog_on_publish.examples.yaml new file mode 100644 index 0000000..55fc8e4 --- /dev/null +++ b/examples/v2.1/catalog_on_publish.examples.yaml @@ -0,0 +1,26 @@ +results_basic: + summary: Example processing results + value: + context: + version: "2.0.0" + action: "on_catalog_publish" + timestamp: "2025-09-01T10:31:05+05:30" + message_id: "u-resp-123" + transaction_id: "u-txn-123" + bpp_id: "discovery-indexer.example.com" + bpp_uri: "https://discovery-indexer.example.com" + ttl: "PT30S" + message: + results: + - catalog_id: "catalog-001" + status: "ACCEPTED" + item_count: 42 + warnings: + - code: "NON_NORMALIZED_BRAND" + message: "Some brand values were normalized" + - catalog_id: "catalog-002" + status: "REJECTED" + error: + code: "INVALID_ITEM" + message: "Invalid item payload at index 3" + paths: "catalogs[1].items[3]" diff --git a/examples/v2.1/catalog_publish.examples.yaml b/examples/v2.1/catalog_publish.examples.yaml new file mode 100644 index 0000000..628dcd9 --- /dev/null +++ b/examples/v2.1/catalog_publish.examples.yaml @@ -0,0 +1,19 @@ +publish_basic: + summary: Minimal publish + value: + context: + version: "2.0.0" + action: "catalog_publish" + timestamp: "2025-09-01T10:30:00+05:30" + message_id: "u-req-123" + transaction_id: "u-txn-123" + bap_id: "bpp.example.com" + bap_uri: "https://bpp.example.com/callbacks" # where /on_catalog_publish is exposed + ttl: "PT30S" + catalogs: + - "@context": "https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/EvChargingOffer/v1/context.jsonld" + "@type": "beckn:Catalog" + "beckn:id": "catalog-001" + "beckn:descriptor": + { "@type": "beckn:Descriptor", "schema:name": "BPP Test Catalog" } + "beckn:items": [] diff --git a/examples/v2.1/discover.examples.yaml b/examples/v2.1/discover.examples.yaml new file mode 100644 index 0000000..0b747c4 --- /dev/null +++ b/examples/v2.1/discover.examples.yaml @@ -0,0 +1,93 @@ +discover_structured_query: + summary: Structured discover (electronics) + value: + context: + version: "2.0.0" + action: "discover" + timestamp: "2024-04-10T16:10:50+05:30" + message_id: "5c8f1a2b-9d3e-4f76-8b21-3a4c5d6e7f80" + transactionId: "d3b07384-4a1c-4f5e-9c2b-7e6d5c4b3a21" + bap_id: "bap.example.com" + bap_uri: "https://bap.example.com" + ttl: "PT30S" + schemaContext: + - "https://example.org/schema/items/v1/ElectronicItem/schema-context.jsonld" + message: + textSearch: "gaming laptop premium tech" + filters: + expressionType: "jsonpath" + expression: "$[?(@.rating.value >= 4 && @.electronic.brand.name == 'Premium Tech')]" +discover_natural_language: + summary: Natural-language discover (electronics) + value: + context: + version: "2.0.0" + action: "discover" + timestamp: "2024-04-10T16:10:50+05:30" + message_id: "9a7b6c5d-8e4f-4a3b-9c2d-1e0f2a3b4c5d" + transactionId: "1f2e3d4c-5b6a-4789-8c0d-1a2b3c4d5e6f" + bap_id: "bap.example.com" + bap_uri: "https://bap.example.com" + ttl: "PT30S" + schemaContext: + - "https://example.org/schema/items/v1/ElectronicItem/schema-context.jsonld" + message: + textSearch: "Looking for a premium gaming laptop under $2000 near San Francisco" +discover_grocery_search: + summary: Structured discover (grocery) + value: + context: + version: "2.0.0" + action: "discover" + timestamp: "2024-04-10T16:10:50+05:30" + message_id: "2a3b4c5d-6e7f-4890-9a1b-2c3d4e5f6071" + transactionId: "7e6d5c4b-3a21-4c5d-8f70-9a1b2c3d4e5f" + bap_id: "bap.example.com" + bap_uri: "https://bap.example.com" + ttl: "PT30S" + schemaContext: + - "https://example.org/schema/items/v1/GroceryItem/schema-context.jsonld" + message: + textSearch: "organic apples fresh" + filters: + expressionType: "jsonpath" + expression: "$[?(@.grocery.organicCertification ~ 'USDA Organic')]" +discover_combined_search: + summary: Combined text + filters + value: + context: + version: "2.0.0" + action: "discover" + timestamp: "2024-04-10T16:10:50+05:30" + message_id: "3b4c5d6e-7f80-41a2-93b4-c5d6e7f8091a" + transactionId: "8f70e6d5-c4b3-42a1-9c2d-3e4f5a6b7c8d" + bap_id: "bap.example.com" + bap_uri: "https://bap.example.com" + ttl: "PT30S" + schemaContext: + - "https://example.org/schema/items/v1/ElectronicItem/schema-context.jsonld" + message: + textSearch: "gaming laptop" + filters: + expressionType: "jsonpath" + expression: "$[?(@.electronic.price['schema:price'] <= 2000 && @.electronic.brand.name == 'Premium Tech')]" +discover_multi_schema_search: + summary: Multi-schema discover (electronics + grocery) + value: + context: + version: "2.0.0" + action: "discover" + timestamp: "2024-04-10T16:10:50+05:30" + message_id: "4c5d6e7f-8091-42b3-94c5-d6e7f8091a2b" + transactionId: "9c2d3e4f-5a6b-47c8-8d90-1a2b3c4d5e6f" + bap_id: "bap.example.com" + bap_uri: "https://bap.example.com" + ttl: "PT30S" + schemaContext: + - "https://example.org/schema/items/v1/ElectronicItem/schema-context.jsonld" + - "https://example.org/schema/items/v1/GroceryItem/schema-context.jsonld" + message: + textSearch: "premium tech and organic food" + filters: + expressionType: "jsonpath" + expression: "$[?(@.rating.value >= 4 && (@.electronic.brand.name == 'Premium Tech' || @.grocery.organicCertification ~ 'USDA Organic'))]" diff --git a/examples/v2.1/on_discover.examples.yaml b/examples/v2.1/on_discover.examples.yaml new file mode 100644 index 0000000..c4686ac --- /dev/null +++ b/examples/v2.1/on_discover.examples.yaml @@ -0,0 +1,38 @@ +on_discover_electronics_catalog: + summary: Electronics catalog callback + value: + context: + version: "2.0.0" + action: "on_discover" + timestamp: "2024-04-10T16:10:50+05:30" + message_id: "a1b2c3d4-e5f6-4789-90ab-cdef12345678" + transactionId: "b2c3d4e5-f6a7-4890-8b9a-cdef23456789" + bpp_id: "bpp.example.com" + bpp_uri: "https://bpp.example.com" + ttl: "PT30S" + message: + catalogs: + - "@context": "https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/tags/core-v2.0.0-rc2/schema/core/v2/context.jsonld" + "@type": "beckn:Catalog" + "beckn:id": "catalog-electronics-001" + "beckn:descriptor": {"@type": "beckn:Descriptor", "schema:name": "Premium Tech Electronics Store"} + "beckn:items": [{"@context": "https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/tags/core-v2.0.0-rc2/schema/core/v2/context.jsonld", "@type": "beckn:Item", "beckn:id": "laptop-item-002", "beckn:descriptor": {"@type": "beckn:Descriptor", "schema:name": "Premium Gaming Laptop Pro 15”", "beckn:shortDesc": "Intel i7, 16GB RAM, 512GB SSD, RTX 4060"}, "beckn:category": {"@type": "schema:CategoryCode", "schema:codeValue": "electronics", "schema:name": "Electronics"}, "beckn:rateable": true, "beckn:rating": {"@type": "beckn:Rating", "beckn:ratingValue": 4.7, "beckn:ratingCount": 932}, "beckn:networkId": ["bap.net/electronics"], "beckn:itemAttributes": {"@context": "https://example.org/schema/items/v1/ElectronicItem/schema-context.jsonld", "@type": "beckn:ElectronicItem", "electronic:brand": "Premium Tech", "electronic:model": "G15-Pro-2025", "electronic:processor": "Intel Core i7-13700H", "electronic:ram": "16GB DDR5", "electronic:storage": "512GB NVMe SSD", "electronic:graphics": "NVIDIA GeForce RTX 4060", "electronic:display": "15.6\" 240Hz QHD", "electronic:warranty": "24 months"}, "beckn:provider": {"beckn:id": "tech-store-001", "beckn:descriptor": {"@type": "beckn:Descriptor", "schema:name": "Premium Tech Electronics Store"}}}, {"@context": "https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/tags/core-v2.0.0-rc2/schema/core/v2/context.jsonld", "@type": "beckn:Item", "beckn:id": "headphones-item-001", "beckn:descriptor": {"@type": "beckn:Descriptor", "schema:name": "Aurora X200 Noise-Cancelling Headphones", "beckn:shortDesc": "Over-ear ANC, 40h battery, BT 5.3, multipoint"}, "beckn:category": {"@type": "schema:CategoryCode", "schema:codeValue": "electronics", "schema:name": "Electronics"}, "beckn:rateable": true, "beckn:rating": {"@type": "beckn:Rating", "beckn:ratingValue": 4.5, "beckn:ratingCount": 1543}, "beckn:networkId": ["bap.net/electronics"], "beckn:itemAttributes": {"@context": "https://example.org/schema/items/v1/ElectronicItem/schema-context.jsonld", "@type": "beckn:ElectronicItem", "electronic:brand": "Aurora", "electronic:model": "X200", "electronic:wirelessTech": "Bluetooth 5.3", "electronic:features": ["ANC", "Transparency Mode", "Multipoint"], "electronic:batteryLifeHours": 40, "electronic:chargingPort": "USB-C", "electronic:warranty": "12 months"}, "beckn:provider": {"beckn:id": "tech-store-001", "beckn:descriptor": {"@type": "beckn:Descriptor", "schema:name": "Premium Tech Electronics Store"}}}] +on_discover_grocery_catalog: + summary: Grocery catalog callback + value: + context: + version: "2.0.0" + action: "on_discover" + timestamp: "2024-04-10T16:10:50+05:30" + message_id: "c3d4e5f6-a7b8-49c0-9dab-ef1234567890" + transactionId: "d4e5f6a7-b8c9-4ad1-8cab-1234567890ef" + bpp_id: "bpp.example.com" + bpp_uri: "https://bpp.example.com" + ttl: "PT30S" + message: + catalogs: + - "@context": "https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/tags/core-v2.0.0-rc2/schema/core/v2/context.jsonld" + "@type": "beckn:Catalog" + "beckn:id": "catalog-grocery-001" + "beckn:descriptor": {"@type": "beckn:Descriptor", "schema:name": "Fresh Grocery Store"} + "beckn:items": [{"@context": "https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/tags/core-v2.0.0-rc2/schema/core/v2/context.jsonld", "@type": "beckn:Item", "beckn:id": "apples-item-001", "beckn:descriptor": {"@type": "beckn:Descriptor", "schema:name": "Organic Fuji Apples (1 kg)", "beckn:shortDesc": "Crisp, sweet USDA Organic apples — farm fresh"}, "beckn:category": {"@type": "schema:CategoryCode", "schema:codeValue": "grocery", "schema:name": "Grocery"}, "beckn:rateable": true, "beckn:rating": {"@type": "beckn:Rating", "beckn:ratingValue": 4.6, "beckn:ratingCount": 387}, "beckn:networkId": ["bap.net/grocery"], "beckn:itemAttributes": {"@context": "https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/tags/core-v2.0.0-rc2/schema/core/v2/context.jsonld", "@type": "beckn:GroceryItem", "grocery:brand": "Fresh Fields", "grocery:organicCertification": "USDA Organic", "grocery:variety": "Fuji", "grocery:unitSize": "1 kg", "grocery:origin": "Himachal Pradesh, IN", "grocery:shelfLifeDays": 10}, "beckn:provider": {"beckn:id": "grocery-store-001", "beckn:descriptor": {"@type": "beckn:Descriptor", "schema:name": "Fresh Grocery Store"}}}, {"@context": "https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/tags/core-v2.0.0-rc2/schema/core/v2/context.jsonld", "@type": "beckn:Item", "beckn:id": "bread-item-001", "beckn:descriptor": {"@type": "beckn:Descriptor", "schema:name": "Whole Wheat Bread (500 g)", "beckn:shortDesc": "High-fiber artisan loaf, no added sugar"}, "beckn:category": {"@type": "schema:CategoryCode", "schema:codeValue": "grocery", "schema:name": "Grocery"}, "beckn:rateable": true, "beckn:rating": {"@type": "beckn:Rating", "beckn:ratingValue": 4.3, "beckn:ratingCount": 812}, "beckn:networkId": ["bap.net/grocery"], "beckn:itemAttributes": {"@context": "https://example.org/schema/items/v1/GroceryItem/schema-context.jsonld", "@type": "beckn:GroceryItem", "grocery:brand": "BakeHouse", "grocery:unitSize": "500 g", "grocery:ingredients": ["Whole wheat flour", "Yeast", "Salt", "Olive oil"], "grocery:allergens": ["Gluten"], "grocery:shelfLifeDays": 5}, "beckn:provider": {"beckn:id": "grocery-store-001", "beckn:descriptor": {"@type": "beckn:Descriptor", "schema:name": "Fresh Grocery Store"}}}] \ No newline at end of file diff --git a/governance/README.md b/governance/README.md deleted file mode 100644 index 8fce1b7..0000000 --- a/governance/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Governance - -TBD diff --git a/schema/EvChargingOffer/v1/README.md b/schema/EvChargingOffer/v1/README.md index 7f24da4..3bf8351 100644 --- a/schema/EvChargingOffer/v1/README.md +++ b/schema/EvChargingOffer/v1/README.md @@ -1,5 +1,55 @@ # EV Charging — Charging Offer Definition Bundle (v1) +--- +

+ Migration Notice +

+ +

+ Effective: 2026-02-06 + Removal: 2026-02-20 +

+ +## This schema is being moved. **Migrate now.** + +**What’s changing:** This schema is being migrated to **[DEG Specification](https://github.com/beckn/DEG)**. +**Impact:** Run-time references to files in this folder may continue to work until the removal date, after which they will fail. + +### Recommended action +1. Switch to **DEG Specification Repository** (see **[Announcements](https://github.com/beckn/DEG/discussions/categories/announcements)** for migration guide). +2. Update your integrations before **2026-02-20**. +3. If blocked, open an issue with logs and request context. + +

+ + + Report an issue + + + Announcements + + + DEG Specification + +

+ +> [!CAUTION] +> #### Heads-up:If you maintain downstream specs or SDKs, pin versions and communicate timelines clearly. + +

+ Migration Notice End +

+ +--- + +# Overview + This bundle defines **EV-specific attribute extensions for Offer** (commercial terms). It reuses Beckn core objects and adds only domain-specific attributes relevant to charging tariffs and policies. Attach these schemas as follows: diff --git a/schema/EvChargingPointOperator/v1/README.md b/schema/EvChargingPointOperator/v1/README.md index cd13326..b749ead 100644 --- a/schema/EvChargingPointOperator/v1/README.md +++ b/schema/EvChargingPointOperator/v1/README.md @@ -1,5 +1,55 @@ # EV Charging — Charging Point Operator Definition Bundle (v1) +--- +

+ Migration Notice +

+ +

+ Effective: 2026-02-06 + Removal: 2026-02-20 +

+ +## This schema is being moved. **Migrate now.** + +**What’s changing:** This schema is being migrated to **[DEG Specification](https://github.com/beckn/DEG)**. +**Impact:** Run-time references to files in this folder may continue to work until the removal date, after which they will fail. + +### Recommended action +1. Switch to **DEG Specification Repository** (see **[Announcements](https://github.com/beckn/DEG/discussions/categories/announcements)** for migration guide). +2. Update your integrations before **2026-02-20**. +3. If blocked, open an issue with logs and request context. + +

+ + + Report an issue + + + Announcements + + + DEG Specification + +

+ +> [!CAUTION] +> #### Heads-up:If you maintain downstream specs or SDKs, pin versions and communicate timelines clearly. + +

+ Migration Notice End +

+ +--- + +# Overview + This bundle defines **EV-specific attribute extensions for Provider** (operator profile). It reuses Beckn core objects and adds only domain-specific attributes relevant to charging operators. Attach these schemas as follows: diff --git a/schema/EvChargingService/v1/README.md b/schema/EvChargingService/v1/README.md index dfc3619..2f7de4c 100644 --- a/schema/EvChargingService/v1/README.md +++ b/schema/EvChargingService/v1/README.md @@ -1,4 +1,53 @@ # EV Charging — Charging Service Definition Bundle (v1) +--- +

+ Migration Notice +

+ +

+ Effective: 2026-02-06 + Removal: 2026-02-20 +

+ +## This schema is being moved. **Migrate now.** + +**What’s changing:** This schema is being migrated to **[DEG Specification](https://github.com/beckn/DEG)**. +**Impact:** Run-time references to files in this folder may continue to work until the removal date, after which they will fail. + +### Recommended action +1. Switch to **DEG Specification Repository** (see **[Announcements](https://github.com/beckn/DEG/discussions/categories/announcements)** for migration guide). +2. Update your integrations before **2026-02-20**. +3. If blocked, open an issue with logs and request context. + +

+ + + Report an issue + + + Announcements + + + DEG Specification + +

+ +> [!CAUTION] +> #### Heads-up:If you maintain downstream specs or SDKs, pin versions and communicate timelines clearly. + +

+ Migration Notice End +

+ +--- + +# Overview This bundle defines **EV-specific attribute extensions only** (no Beckn core objects). diff --git a/schema/EvChargingSession/v1/README.md b/schema/EvChargingSession/v1/README.md index e6ef0c2..f163a66 100644 --- a/schema/EvChargingSession/v1/README.md +++ b/schema/EvChargingSession/v1/README.md @@ -1,5 +1,53 @@ # EV Charging — Charging Session Definition Bundle (v1) +--- +

+ Migration Notice +

+ +

+ Effective: 2026-02-06 + Removal: 2026-02-20 +

+ +## This schema is being moved. **Migrate now.** + +**What’s changing:** This schema is being migrated to **[DEG Specification](https://github.com/beckn/DEG)**. +**Impact:** Run-time references to files in this folder may continue to work until the removal date, after which they will fail. + +### Recommended action +1. Switch to **DEG Specification Repository** (see **[Announcements](https://github.com/beckn/DEG/discussions/categories/announcements)** for migration guide). +2. Update your integrations before **2026-02-20**. +3. If blocked, open an issue with logs and request context. + +

+ + + Report an issue + + + Announcements + + + DEG Specification + +

+ +> [!CAUTION] +> #### Heads-up:If you maintain downstream specs or SDKs, pin versions and communicate timelines clearly. + +

+ Migration Notice End +

+ +--- + This bundle defines **EV-specific attribute extensions for Order/Fulfillment** (ChargingSession). It reuses Beckn core objects and adds domain-specific attributes for session state, telemetry, and billing snapshots. Attach these schemas as follows: diff --git a/schema/PaymentSettlement/v1/README.md b/schema/PaymentSettlement/v1/README.md index ebff4ad..b35aa59 100644 --- a/schema/PaymentSettlement/v1/README.md +++ b/schema/PaymentSettlement/v1/README.md @@ -1,4 +1,56 @@ # Payment Settlement Definition Bundle (v1) +--- +

+ Migration Notice +

+ +

+ Effective: 2026-02-06 + Removal: 2026-02-20 +

+ +## This schema is being moved. **Migrate now.** + + +**What’s changing:** This schema is being merged with the **Core Schema**. +**Impact:** Run-time references to files in this folder may continue to work until the removal date, after which they will fail. + +### Recommended action +1. Change your schema context to **[Core](../../core/v2.1/)**. +2. Update your integrations before **2026-02-20**. +3. If blocked, open an issue with logs and request context. + +

+ + + Report an issue + + + Announcements + +

+ + + + + +
+ Heads-up: If you maintain downstream specs or SDKs, pin versions and communicate timelines clearly. +
+ +

+ Migration Notice End +

+ +--- + +# Overview This bundle defines **payment settlement attribute extensions** for Provider and Payment objects. It provides settlement account details required for inter-party fund transfers in Beckn payment transactions. diff --git a/schema/PaymentSettlement/v1/vocab.jsonld b/schema/PaymentSettlement/v1/vocab.jsonld index 6397356..2c28a5b 100644 --- a/schema/PaymentSettlement/v1/vocab.jsonld +++ b/schema/PaymentSettlement/v1/vocab.jsonld @@ -69,7 +69,7 @@ "rdfs:comment": "Virtual Payment Address (UPI ID).", "rdfs:domain": "beckn:PaymentSettlement", "schema:rangeIncludes": "schema:Text" - }, + } ] } diff --git a/schema/README.md b/schema/README.md index 210e932..18bd6a6 100644 --- a/schema/README.md +++ b/schema/README.md @@ -1,4 +1,4 @@ -# 📚 Beckn Schema Registry +# 📚 The Beckn Schema Registry > **A centralized repository for Beckn Protocol schemas with core schemas and use-case specific attribute packs.** diff --git a/schema/core/v2.1/README.md b/schema/core/v2.1/README.md new file mode 100644 index 0000000..eee9669 --- /dev/null +++ b/schema/core/v2.1/README.md @@ -0,0 +1,140 @@ +# How to navigate this folder + +You’re looking at a **three-file schema package** where each file plays a distinct role in the data contract. Read them in this order and with a clear objective per file. + + +## What each file is for + +### 1) `attributes.yaml` — **structural contract + validation surface** + +This file defines the **JSON shape**: + +* which object types exist (e.g., `Order`, `Item`, `Payment`) +* required fields +* field types (`string`, `array`, `object`) +* constraints (`enum`, formats, min/max, etc.) + +In most setups like this, the actionable content is under: + +* `components.schemas..required` +* `components.schemas..properties` + +You also typically see an extension like `x-jsonld` on fields. Treat that as a **semantic pointer** that ties a JSON field to a JSON-LD term IRI. + +**Primary question this file answers:** + +> “What fields are allowed and what constitutes a valid instance?” + + +### 2) `context.jsonld` — **term mapping and compaction/expansion rules** + +This file defines how JSON keys map to **IRIs** and how values should be interpreted during JSON-LD expansion. + +Typical contents: + +* prefix definitions (e.g., `schema`, `rdf`, `xsd`, plus your domain prefix like `beckn`) +* term definitions (mapping `"name"` → `schema:name`, `"orderStatus"` → `beckn:orderStatus`, etc.) +* value mappings for enums (mapping `"CANCELLED"` → `beckn:OrderCancelled`, etc.) +* `@type` coercion rules (e.g., treat a field as an `@id`) + +**Primary question this file answers:** + +> “When a payload contains key `X` and value `Y`, what exact IRIs do they correspond to?” + + +### 3) `vocab.jsonld` — **vocabulary/ontology definitions** + +This is the **domain vocabulary**: the canonical definitions for classes, properties, and enumerations. + +Typical contents (usually in `@graph`): + +* classes (`rdfs:Class`) +* properties (domain/range, labels, comments) +* enumerations and their members + +**Primary question this file answers:** + +> “What does this term represent in the domain model?” + +## How to read them effectively: trace one field end-to-end + +Pick a single property and resolve it across all three layers. This prevents you from reading the files as three disconnected artifacts. + +### Example: `Order.orderStatus` + +#### Step A — Start in `attributes.yaml` (constraints) + +Locate: + +* `components.schemas.Order.properties["beckn:orderStatus"]` + +Extract: + +* the JSON type (e.g., `string`) +* allowed values (`enum`: `CREATED`, `PENDING`, `CONFIRMED`, …) +* the semantic binding if present: + + * `x-jsonld: { "@id": "beckn:orderStatus" }` + +Outcome: + +* You know the **validation rule set** for the field. +* You know which **semantic property** it is intended to represent. + +#### Step B — Go to `context.jsonld` (mapping behavior) + +Find the context entry for `orderStatus` (or the equivalent compact term). + +You should see: + +* the property mapping to `beckn:orderStatus` +* a rule such as `@type: "@id"` if the value is intended to expand into an IRI +* a nested mapping for enum tokens: + + * `"CREATED"` → `beckn:OrderCreated` + * `"CANCELLED"` → `beckn:OrderCancelled` + * etc. + +Outcome: + +* You know **exactly how** the string enum token is transformed into an identifier in the expanded JSON-LD/RDF representation. + +#### Step C — Validate meaning in `vocab.jsonld` (domain definition) + +In `vocab.jsonld`, locate: + +* the definition of `beckn:OrderStatus` (likely an enumeration) +* the member terms such as `beckn:OrderCancelled`, `beckn:OrderCreated`, etc. + +Outcome: + +* You know how the term is defined conceptually (labels/comments), and you can verify the enum member inventory is consistent with the YAML/context. + + +## Recommended reading order and workflow + +1. **Inventory object types and required fields** from `attributes.yaml`. + This gives you the “API surface area” quickly. + +2. For any field you care about, use `x-jsonld.@id` (if present) to jump to the corresponding term in `context.jsonld` / `vocab.jsonld`. + +3. Use `context.jsonld` to determine: + + * the **exact IRI** for each field + * whether values are interpreted as strings vs identifiers (`@type: "@id"`) + * how enums map from tokens to term IRIs + +4. Use `vocab.jsonld` as the authoritative **domain glossary** for: + + * term definitions + * class/property relationships + * enumeration membership + + +## Important boundary: mapping vs validation + +* `context.jsonld` + `vocab.jsonld` establish **semantics** (meaning and identifiers). +* `attributes.yaml` establishes **syntactic validity** (shape/type/enums/required). + +JSON-LD by itself does **not** enforce constraints like “required field” or “enum membership.” If you need **semantic validation** on the expanded graph (e.g., constraints based on RDF types and relationships), that is typically done with **SHACL** or **ShEx** after expansion. + diff --git a/schema/core/v2.1/attributes.yaml b/schema/core/v2.1/attributes.yaml new file mode 100644 index 0000000..dd2a96a --- /dev/null +++ b/schema/core/v2.1/attributes.yaml @@ -0,0 +1,2126 @@ +openapi: 3.1.1 +info: + title: Beckn Core Schemas v2 + description: Core schemas for the Beckn Protocol v2. This file contains the fundamental object structures and payload shapes used when executing discovery, ordering, fulfillment, post-fulfillment and other workflows on Beckn + version: 2.1.0 + contact: + name: Beckn Labs + url: https://beckn.io + license: + name: CC-BY-NC-SA 4.0 International + url: https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en +components: + schemas: + AcceptedPaymentMethod: + description: Payment methods accepted for this offer + type: array + items: + type: string + enum: + - UPI + - CREDIT_CARD + - DEBIT_CARD + - WALLET + - BANK_TRANSFER + - CASH + - APPLE_PAY + x-jsonld: + '@id': beckn:acceptedPaymentMethod + examples: + - $ref: '../../examples/v2.1/AcceptedPaymentMethod.examples.yaml#/basic' + AckResponse: + type: object + properties: + ack_status: + type: string + enum: + - ACK + - NACK + error: + $ref: '#/components/schemas/Error' + timestamp: + type: string + format: date-time + transaction_id: + type: string + required: + - transaction_id + - timestamp + - ack_status + additionalProperties: false + allOf: + - if: + properties: + ack_status: + const: NACK + required: + - ack_status + then: + required: + - error + - if: + properties: + ack_status: + const: ACK + required: + - ack_status + then: + not: + required: + - error + Address: + description: '**Postal address** aligned with schema.org `PostalAddress`. Use for human-readable addresses. Geometry + lives in `Location.geo` as GeoJSON.' + type: object + properties: + addressCountry: + description: Country name or ISO-3166-1 alpha-2 code. + type: string + example: IN + addressLocality: + description: City/locality. + type: string + example: Bengaluru + addressRegion: + description: State/region/province. + type: string + example: Karnataka + extendedAddress: + description: Address extension (apt/suite/floor, C/O). + type: string + example: Apt 4B + postalCode: + description: Postal/ZIP code. + type: string + example: '560001' + streetAddress: + description: Street address (building name/number and street). + type: string + example: 123 Tech Street + additionalProperties: false + Alert: + type: object + properties: + '@context': + type: string + format: uri + const: https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/context.jsonld + '@type': + type: string + enum: + - beckn:Alert + beckn:affectedEntities: + description: IDs of entities affected (route/order/fulfillment/etc.) + type: array + items: + type: string + beckn:descriptor: + $ref: '#/components/schemas/Descriptor' + beckn:id: + type: string + beckn:severity: + type: string + beckn:validity: + $ref: '#/components/schemas/TimePeriod' + required: + - '@context' + - '@type' + - beckn:id + - beckn:descriptor + additionalProperties: false + Attributes: + description: JSON-LD aware container for domain-specific attributes of an Item. MUST include @context (URI) and @type + (compact or full IRI). Any additional properties are allowed and interpreted per the provided JSON-LD context. + type: object + properties: + '@context': + description: JSON-LD context URI for the specific domain schema (e.g., ElectronicItem) + type: string + format: uri + example: https://example.org/schema/items/v1/ElectronicItem/schema-context.jsonld + '@type': + description: JSON-LD type within the domain schema + type: string + example: beckn:ElectronicItem + required: + - '@context' + - '@type' + additionalProperties: true + minProperties: 2 + Consumer: + type: object + properties: + '@context': + type: string + format: uri + const: https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/context.jsonld + '@type': + type: string + enum: + - beckn:Consumer + x-jsonld: + '@id': schema:Thing + beckn:buyerAttributes: + description: 'Attribute Pack reference for richer identity: # buyer/identity.v1 (contact details: email, phone, + address) # buyer/org-ids.v1 (LEI, GSTIN, ISIN, CUSIP…) # buyer/kyc.v1 (jurisdictional compliance fields) # buyer/preferences.v1 + (delivery preferences, accessibility needs, etc.)' + allOf: + - $ref: '#/components/schemas/Attributes' + beckn:displayName: + description: Human-readable display name + type: string + x-jsonld: + '@id': schema:name + beckn:email: + description: Email Address + type: string + x-jsonld: + '@id': schema:email + format: email + beckn:id: + description: Unique identifier for the buyer (personId or orgId in legacy schema) + type: string + x-jsonld: + '@id': schema:identifier + beckn:role: + description: The functional role of the buyer in the transaction. + type: string + x-jsonld: + '@id': schema:roleName + beckn:taxID: + description: Tax identifier for the buyer. + type: string + x-jsonld: + '@id': schema:taxID + beckn:telephone: + description: Telephone number + type: string + x-jsonld: + '@id': schema:telephone + required: + - '@context' + - '@type' + - beckn:id + additionalProperties: false + CancellationOutcome: + type: object + properties: + descriptor: + $ref: '#/components/schemas/Descriptor' + CancellationPolicy: + type: object + properties: + descriptor: + $ref: '#/components/schemas/Descriptor' + CancellationReason: + type: object + properties: + descriptor: + $ref: '#/components/schemas/Descriptor' + Catalog: + type: object + properties: + '@context': + description: JSON-LD context URI for the core Catalog schema + type: string + format: uri + const: https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/context.jsonld + '@type': + description: Type of the catalog + type: string + example: beckn:Catalog + beckn:bppId: + description: BPP (Beckn Protocol Provider) identifier that publishes this catalog + type: string + example: bpp.example.com + beckn:bppUri: + description: BPP (Beckn Protocol Provider) URI endpoint + type: string + format: uri + example: https://bpp.example.com + beckn:descriptor: + $ref: '#/components/schemas/Descriptor' + beckn:id: + description: Unique identifier for the catalog + type: string + example: catalog-electronics-001 + beckn:isActive: + description: Whether the catalog is active + type: boolean + default: true + beckn:items: + description: Array of beckn core Item entities in this catalog, returned directly without ItemResult wrapper for + improved performance and simplified response structure + type: array + items: + $ref: '#/components/schemas/Item' + beckn:offers: + type: array + items: + $ref: '#/components/schemas/Offer' + beckn:providerId: + description: Reference to the provider that owns this catalog + type: string + example: tech-store-001 + beckn:validity: + $ref: '#/components/schemas/TimePeriod' + required: + - '@context' + - '@type' + - beckn:id + - beckn:descriptor + - beckn:bppId + - beckn:bppUri + - beckn:items + additionalProperties: false + CategoryCode: + type: object + properties: + '@type': + description: Type of the category code + type: string + enum: + - schema:CategoryCode + example: schema:CategoryCode + schema:codeValue: + description: Category code value + type: string + example: electronics + schema:description: + description: Category description + type: string + example: Electronic devices and equipment + schema:name: + description: Category name + type: string + example: Electronics + required: + - '@type' + - schema:codeValue + Constraint: + type: object + properties: + '@context': + type: string + format: uri + const: https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/context.jsonld + '@type': + type: string + enum: + - beckn:Constraint + beckn:constraintType: + description: Type of constraint (extensible term) + type: string + beckn:id: + description: Identifier for the constraint + type: string + beckn:operator: + description: Comparator/operator (<=, >=, =, etc.) + type: string + beckn:unitCode: + description: Unit code (e.g., km, min) + type: string + beckn:validity: + $ref: '#/components/schemas/TimePeriod' + beckn:value: + description: Constraint value + type: number + required: + - '@context' + - '@type' + - beckn:id + additionalProperties: false + Context: + description: Every API call in beckn protocol has a context. It provides a high-level overview to the receiver about + the nature of the intended transaction. Typically, it is the BAP that sets the transaction context based on the consumer's + location and action on their UI. But sometimes, during unsolicited callbacks, the BPP also sets the transaction context + but it is usually the same as the context of a previous full-cycle, request-callback interaction between the BAP and + the BPP. The context object contains four types of fields.
  1. Demographic information about the transaction using + fields like `domain`, `country`, and `region`.
  2. Addressing details like the sending and receiving platform's + ID and API URL.
  3. Interoperability information like the protocol version that implemented by the sender and,
  4. Transaction + details like the method being called at the receiver's endpoint, the transaction_id that represents an end-to-end + user session at the BAP, a message ID to pair requests with callbacks, a timestamp to capture sending times, a ttl + to specifiy the validity of the request, and a key to encrypt information if necessary.
This object must + be passed in every interaction between a BAP and a BPP. In HTTP/S implementations, it is not necessary to send the + context during the synchronous response. However, in asynchronous protocols, the context must be sent during all interactions, + type: object + properties: + action: + description: The Beckn protocol method being called by the sender and executed at the receiver. + type: string + bapId: + description: A globally unique identifier of the BAP, Typically it is the fully qualified domain name (FQDN) of + the BAP + type: string + bapUri: + description: API URL of the BAP for accepting callbacks from BPPs. + type: string + format: uri + bppId: + description: A globally unique identifier of the BAP, Typically it is the fully qualified domain name (FQDN) of + the BAP + type: string + bppUri: + description: API URL of the BPP for accepting calls from BAPs. + type: string + format: uri + messageId: + description: This is a unique value which persists during a request / callback cycle. Since beckn protocol APIs + are asynchronous, BAPs need a common value to match an incoming callback from a BPP to an earlier call. This value + can also be used to ignore duplicate messages coming from the BPP. It is recommended to generate a fresh message_id + for every new interaction. When sending unsolicited callbacks, BPPs must generate a new message_id. + type: string + format: uuid + networkId: + description: A unique identifier representing a group of platforms. By default, it is the url of the network registry + on the Beckn network + type: string + schemas: + description: Optional JSON-LD context URLs relevant to the items/offers in this transaction + type: array + items: + type: string + format: uri + timestamp: + description: Time of request generation in RFC3339 format + type: string + format: date-time + transactionId: + description: This is a unique value which persists across all API calls from `search` through `confirm`. This is + done to indicate an active user session across multiple requests. The BPPs can use this value to push personalized + recommendations, and dynamic offerings related to an ongoing transaction despite being unaware of the user active + on the BAP. + type: string + format: uuid + try: + description: A flag to indicate that this request is intended to 'try' an operation. Typically set to `false` by + default, but set to `true` when negotiating terms, updating or cancelling an active order. When set to `true`, + the receiver must respond with the expected consequences as per the terms of service initially agreed between + the BAP and the BPP during the `init/on_init` cycle. For example, A BAP will set this flag to `true` when requesting + the BPP to cancel the order. Upon receiving this the BPP could respond with updated cost, cancellation fees, reasons + for cancellation, a cancellation form, payment links, and any additional notifications or prompts informing the + BAP about future consequences if continued (like an account ban, or reduced rating). When both participants are + ready to continue the transaction, this flag MUST be set back to `false`. + type: boolean + default: false + ttl: + description: The duration in ISO8601 format after timestamp for which this message holds valid + type: string + version: + description: Version of beckn protocol being used by the sender + type: string + const: 2.1.0 + Credential: + type: object + properties: + '@context': + type: string + format: uri + const: https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/context.jsonld + '@type': + type: string + enum: + - beckn:Credential + beckn:descriptor: + $ref: '#/components/schemas/Descriptor' + beckn:expiresAt: + type: string + format: date-time + beckn:id: + type: string + beckn:issueDate: + type: string + format: date-time + beckn:issuer: + description: Issuing authority/entity + type: string + beckn:number: + description: Credential/license number + type: string + required: + - '@context' + - '@type' + - beckn:id + - beckn:descriptor + additionalProperties: false + Descriptor: + type: object + properties: + '@type': + description: Type of the descriptor + type: string + enum: + - beckn:Descriptor + example: beckn:Descriptor + beckn:longDesc: + description: Detailed description of the item + type: string + example: Powerful gaming laptop with NVIDIA RTX graphics, fast SSD storage, and high-refresh display + beckn:shortDesc: + description: Short description of the item + type: string + example: High-performance gaming laptop with RTX graphics + beckn:images: + type: array + items: + type: string + format: uri + beckn:name: + description: Name of the entity being described + type: string + example: Premium Gaming Laptop Pro + beckn:mediaFile: + description: Links to docs + type: array + items: + $ref: '#/components/schemas/Document' + required: + - '@type' + Eligibility: + type: object + properties: + eligibleQuantity: + type: object + properties: + max: + type: number + min: + type: number + eligibleRegion: + type: string + x-jsonld: + '@id': schema:DefinedRegion|schema:QuantitativeValue + Entitlement: + type: object + properties: + '@context': + type: string + format: uri + const: https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/context.jsonld + '@type': + type: string + enum: + - beckn:Entitlement + beckn:descriptor: + $ref: '#/components/schemas/Descriptor' + beckn:entitlementType: + description: Type of entitlement (ticket, voucher, pass, token, etc.) + type: string + beckn:id: + type: string + beckn:number: + description: Human-readable entitlement number + type: string + beckn:validity: + $ref: '#/components/schemas/TimePeriod' + required: + - '@context' + - '@type' + - beckn:id + - beckn:descriptor + additionalProperties: false + Error: + type: object + properties: + code: + description: Error code + type: string + example: INVALID_SCHEMA_FIELD + details: + description: Additional error details + type: object + message: + description: Human-readable error message + type: string + example: Field 'electronic:invalidField' not found in ElectronicItem schema + required: + - code + - message + ErrorResponse: + type: object + properties: + error: + $ref: '#/components/schemas/Error' + required: + - error + Feature: + type: object + properties: + '@context': + type: string + format: uri + const: https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/context.jsonld + '@type': + type: string + enum: + - beckn:Feature + beckn:category: + $ref: '#/components/schemas/CategoryCode' + beckn:descriptor: + $ref: '#/components/schemas/Descriptor' + beckn:id: + description: Identifier for the feature term + type: string + required: + - '@context' + - '@type' + - beckn:id + - beckn:descriptor + additionalProperties: false + Feedback: + description: Feedback + type: object + Form: + description: Describes a form + type: object + properties: + '@context': + type: string + format: uri + const: https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/context.jsonld + '@type': + type: string + enum: + - beckn:Form + x-jsonld: + '@id': beckn:Form + data: + description: The form submission data + type: object + additionalProperties: + type: string + mime_type: + description: This field indicates the nature and format of the form received by querying the url. MIME types are + defined and standardized in IETF's RFC 6838. + type: string + enum: + - text/html + - application/xml + submission_id: + type: string + format: uuid + url: + description: The URL from where the form can be fetched. The content fetched from the url must be processed as per + the mime_type specified in this object. Once fetched, the rendering platform can choosed to render the form as-is + as an embeddable element; or process it further to blend with the theme of the application. In case the interface + is non-visual, the the render can process the form data and reproduce it as per the standard specified in the + form. + type: string + format: uri + required: + - '@context' + - '@type' + Fulfillment: + type: object + properties: + '@context': + type: string + format: uri + const: https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/context.jsonld + '@type': + type: string + enum: + - beckn:Fulfillment + x-jsonld: + '@id': schema:Thing + beckn:agent: + description: 'The entity that directly performs the fulfillment' + allOf: + - $ref: '#/components/schemas/FulfillmentAgent' + beckn:provider: + description: 'The agency or organization that performs the fulfillment service' + allOf: + - $ref: '#/components/schemas/Provider' + beckn:fulfillmentAttributes: + description: 'Extensible set of domain-specific attributes describing the fulfillment' + allOf: + - $ref: '#/components/schemas/Attributes' + beckn:docs: + description: 'An attached set of docs related to the fulfillment of the order. It could be tickets, passes, shipment manifests, etc' + type: array + items: + $ref: '#/components/schemas/Document' + beckn:currentState: + allOf: + - $ref: '#/components/schemas/Descriptor' + x-jsonld: + '@id': 'beckn:fulfillmentState' + beckn:id: + description: Fulfillment identifier + type: string + x-jsonld: + '@id': schema:identifier + beckn:instructions: + type: array + items: + $ref: '#/components/schemas/Descriptor' + beckn:mode: + description: 'Extensible set of attributes describing the mode of fulfillment. Varies with Industry Use Case' + allOf: + - $ref: '#/components/schemas/FulfillmentMode' + x-jsonld: + '@id': beckn:FulfillmentMode + beckn:participants: + description: A list of participants who are entitled to receive the fulfillment of the order. By default, it is the consumer who placed the order + type: array + items: + $ref: '#/components/schemas/Participant' + minItems: 1 + beckn:state: + description: 'The current state of fulfillment' + allOf: + $ref: '#/components/schemas/State' + beckn:stages: + description: 'The various stages of the fulfillment' + type: array + items: + $ref: '#/components/schemas/FulfillmentStage' + minItems: 1 + beckn:trackingEnabled: + description: Whether tracking is enabled / possible for this fulfillment + type: boolean + required: + - '@context' + - '@type' + - beckn:mode + additionalProperties: false + FulfillmentAgent: + description: The entity directly involved in fulfilling the order. It could be a person, a machine, a software application, or an AI Agent + type: object + properties: + beckn:id: + type: string + x-jsonld: + '@id': 'schema:identifier' + beckn:name: + type: string + x-jsonld: + '@id': 'schema:name' + beckn:AgentAttributes: + description: An extensible set of attributes that describe the agent of fulfillment + allOf: + $ref: '#/components/schemas/Attributes' + + FulfillmentStage: + type: object + properties: + '@context': + type: string + format: uri + const: https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/context.jsonld + '@type': + type: string + enum: + - beckn:FulfillmentStage + beckn:id: + description: A unique identifier for this stage of fulfillment + type: string + beckn:instructions: + description: A set of instructions to follow during this stage of fulfillment + type: array + items: + $ref: '#/components/schemas/Instruction' + beckn:start: + description: An extensible set of attributes that describe the criteria required to start this stage of fulfillment + allOf: + $ref: '#/components/schemas/Attributes' + beckn:end: + description: An extensible set of attributes that describe the criteria required to end this stage of fulfillment + allOf: + $ref: '#/components/schemas/Attributes' + beckn:FulfillmentStageAttributes: + description: An extensible set of attributes that describe this stage of fulfillment + allOf: + $ref: '#/components/schemas/Attributes' + x-jsonld: + '@id': beckn:fulfillmentStage + required: + - '@context' + - '@type' + - beckn:id + - beckn:location + additionalProperties: false + + GeoJSONGeometry: + description: "**GeoJSON geometry** per RFC 7946. Coordinates are in **EPSG:4326 (WGS-84)** and MUST follow **[longitude,\ + \ latitude, (altitude?)]** order.\nSupported types: - Point, LineString, Polygon - MultiPoint, MultiLineString, MultiPolygon\ + \ - GeometryCollection (uses `geometries` instead of `coordinates`)\nNotes: - For rectangles, use a Polygon with a\ + \ single linear ring where the first\n and last positions are identical.\n- Circles are **not native** to GeoJSON.\ + \ For circular searches, use\n `SpatialConstraint` with `op: s_dwithin` and a Point + `distanceMeters`,\n or approximate\ + \ the circle as a Polygon.\n- Optional `bbox` is `[west, south, east, north]` in degrees.\n" + type: object + properties: + bbox: + description: Optional bounding box `[west, south, east, north]` in degrees. + type: array + minItems: 4 + maxItems: 4 + coordinates: + description: 'Coordinates per RFC 7946 for all types **except** GeometryCollection. Order is **[lon, lat, (alt)]**. + For Polygons, this is an array of linear rings; each ring is an array of positions. + + ' + type: array + geometries: + description: 'Member geometries when `type` is **GeometryCollection**. + + ' + type: array + items: + $ref: '#/components/schemas/GeoJSONGeometry' + type: + type: string + enum: + - Point + - LineString + - Polygon + - MultiPoint + - MultiLineString + - MultiPolygon + - GeometryCollection + required: + - type + additionalProperties: true + examples: + - $ref: '../../examples/v2.1/GeoJSONGeometry.examples.yaml#/point' + - $ref: '../../examples/v2.1/GeoJSONGeometry.examples.yaml#/polygon_rectangle' + - $ref: '../../examples/v2.1/GeoJSONGeometry.examples.yaml#/geometry_collection' + Instruction: + type: object + properties: + '@context': + type: string + format: uri + const: https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/context.jsonld + '@type': + type: string + enum: + - beckn:Instruction + beckn:descriptor: + $ref: '#/components/schemas/Descriptor' + beckn:id: + type: string + beckn:validity: + $ref: '#/components/schemas/TimePeriod' + required: + - '@context' + - '@type' + - beckn:id + - beckn:descriptor + additionalProperties: false + Invoice: + type: object + properties: + '@context': + type: string + format: uri + const: https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/context.jsonld + '@type': + type: string + enum: + - beckn:Invoice + x-jsonld: + '@id': schema:Invoice + beckn:dueDate: + type: string + x-jsonld: + '@id': schema:paymentDueDate + format: date + nullable: true + beckn:id: + description: Stable invoice identifier (system id) + type: string + x-jsonld: + '@id': schema:identifier + beckn:invoiceAttributes: + description: Attribute Pack for tax regime (e.g., GST/VAT), e-invoice refs, legal boilerplate, etc. + allOf: + - $ref: '#/components/schemas/Attributes' + beckn:issueDate: + type: string + x-jsonld: + '@id': schema:dateIssued + format: date + beckn:number: + description: Human-visible invoice number + type: string + x-jsonld: + '@id': schema:confirmationNumber + beckn:payee: + description: Seller / issuer of the invoice + x-jsonld: + '@id': schema:provider + allOf: + - $ref: '#/components/schemas/Provider/properties/beckn:id' + beckn:payer: + description: Buyer being invoiced + x-jsonld: + '@id': schema:customer + allOf: + - $ref: '#/components/schemas/Buyer/properties/beckn:id' + beckn:priceComponents: + type: array + items: + $ref: '#/components/schemas/PriceComponent' + beckn:totals: + description: Invoice grand totals (tax/shipping/discount components inside) + x-jsonld: + '@id': schema:priceSpecification + allOf: + - $ref: '#/components/schemas/PriceSpecification' + required: + - '@context' + - '@type' + - beckn:id + - beckn:number + - beckn:issueDate + - beckn:totals + - beckn:payee + - beckn:payer + additionalProperties: false + Item: + type: object + properties: + '@context': + description: JSON-LD context URI for the core Item schema + type: string + format: uri + const: https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/context.jsonld + '@type': + description: Type of the core item + type: string + enum: + - beckn:Item + beckn:availabilityWindow: + description: Time periods when the item is available + type: array + items: + $ref: '#/components/schemas/TimePeriod' + beckn:availableAt: + description: Physical locations where the item is available + type: array + items: + $ref: '#/components/schemas/Location' + beckn:category: + $ref: '#/components/schemas/CategoryCode' + beckn:constraints: + type: array + items: + $ref: '#/components/schemas/Constraint' + beckn:descriptor: + $ref: '#/components/schemas/Descriptor' + beckn:features: + type: array + items: + $ref: '#/components/schemas/Feature' + beckn:id: + description: Unique identifier for the item + type: string + example: gaming-laptop-001 + beckn:isActive: + description: Whether the item is active + type: boolean + default: true + beckn:itemAttributes: + $ref: '#/components/schemas/Attributes' + beckn:networkId: + description: Array of network identifiers for the BAP (Beckn App Provider) that offers this item + type: array + items: + type: string + example: + - bap.net/electronics + - bap.net/tech + beckn:policies: + type: array + items: + $ref: '#/components/schemas/Policy' + beckn:provider: + $ref: '#/components/schemas/Provider' + beckn:rateable: + description: Whether the item can be rated by customers + type: boolean + example: true + beckn:rating: + $ref: '#/components/schemas/Rating' + required: + - '@context' + - '@type' + - beckn:id + - beckn:descriptor + - beckn:provider + - beckn:itemAttributes + additionalProperties: false + Intent: + description: A declaration of an intent to discover catalogs. + type: object + properties: + text_search: + description: Free text search query for items + type: string + example: gaming laptop premium tech + filters: + description: Filter criteria for items + type: object + properties: + type: + description: Type of filter expression + type: string + enum: + - jsonpath + default: jsonpath + expression: + description: Filter expression based on the specified type + type: string + example: $[?(@.rating.value >= 4.0 && @.electronic.brand.name == 'Premium Tech')] + required: + - type + - expression + spatial: + description: Optional array of spatial constraints (CQL2-JSON semantics). + type: array + items: + $ref: '#/components/schemas/SpatialConstraint' + media_search: + $ref: '#/components/schemas/MediaSearch' + anyOf: + - required: + - text_search + - required: + - filters + - required: + - spatial + - required: + - filters + - spatial + MediaInput: + description: Reference to an image, audio clip, or video used for multimodal search. + type: object + properties: + id: + description: Client-supplied identifier for this media input. + type: string + type: + description: Media category. + type: string + enum: + - image + - audio + - video + url: + description: HTTPS URL or data URI pointing to the media resource. + type: string + format: uri + contentType: + description: MIME type, e.g., image/jpeg, audio/mpeg, video/mp4. + type: string + textHint: + description: Optional pre-extracted text (OCR/ASR) for search augmentation. + type: string + language: + description: Language code (BCP-47) of `textHint` or spoken audio. + type: string + startMs: + description: Optional start offset in milliseconds (for audio/video segments). + type: integer + endMs: + description: Optional end offset in milliseconds (for audio/video segments). + type: integer + required: + - type + - url + additionalProperties: false + MediaSearchOptions: + description: How the discovery engine should use the provided media inputs. + type: object + properties: + goals: + description: 'Desired processing goals for the media. + + ' + type: array + items: + type: string + enum: + - VISUAL_SIMILARITY + - VISUAL_OBJECT_DETECT + - TEXT_FROM_IMAGE + - TEXT_FROM_AUDIO + - SEMANTIC_AUDIO_MATCH + - SEMANTIC_VIDEO_MATCH + augmentTextSearch: + description: 'Whether to append extracted text from OCR/ASR to `textSearch`. + + ' + type: boolean + default: true + restrictResultsToMediaProximity: + description: 'Restrict results to spatial proximity of media-derived coordinates (e.g., EXIF GPS tags). + + ' + type: boolean + default: false + additionalProperties: false + Location: + description: 'A **place** represented by **GeoJSON geometry** (Point/Polygon/Multi*) and optional human-readable `address`. + This unifies all Beckn location fields into a single, widely-adopted representation (GeoJSON). + + ' + type: object + properties: + '@type': + type: string + enum: + - beckn:Location + address: + description: Optional human-readable address for the same place/area. + oneOf: + - type: string + - $ref: '#/components/schemas/Address' + geo: + $ref: '#/components/schemas/GeoJSONGeometry' + required: + - geo + additionalProperties: false + examples: + - $ref: '../../examples/v2.1/Location.examples.yaml#/site_point' + - $ref: '../../examples/v2.1/Location.examples.yaml#/service_area' + Offer: + type: object + properties: + '@context': + type: string + format: uri + const: https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/context.jsonld + '@type': + type: string + enum: + - beckn:Offer + x-jsonld: + '@id': schema:Offer + beckn:acceptedPaymentMethod: + $ref: '#/components/schemas/AcceptedPaymentMethod' + beckn:addOnItems: + description: Optional extras modeled as items (e.g., toppings, accessories) + type: array + items: + $ref: '#/components/schemas/Item/properties/beckn:id' + x-jsonld: + '@id': schema:addOn + beckn:addOns: + description: Optional extra Offers that can be attached (e.g., warranty, gift wrap) + type: array + items: + $ref: '#/components/schemas/Offer/properties/beckn:id' + x-jsonld: + '@id': schema:addOn + beckn:constraints: + type: array + items: + $ref: '#/components/schemas/Constraint' + beckn:descriptor: + $ref: '#/components/schemas/Descriptor' + beckn:eligibleRegion: + description: Regions where the offer is eligible + type: array + items: + $ref: '#/components/schemas/Location' + beckn:features: + type: array + items: + $ref: '#/components/schemas/Feature' + beckn:id: + description: Unique id for this offer + type: string + x-jsonld: + '@id': schema:identifier + beckn:isActive: + description: Whether the offer is active + type: boolean + default: true + beckn:items: + description: Base item(s) the offer applies to (single or bundle) + type: array + items: + $ref: '#/components/schemas/Item/properties/beckn:id' + x-jsonld: + '@id': schema:itemOffered + minItems: 1 + beckn:offerAttributes: + description: Attribute Pack attachment (pricing models, discounts, rail terms, etc.) + allOf: + - $ref: '#/components/schemas/Attributes' + beckn:policies: + type: array + items: + $ref: '#/components/schemas/Policy' + beckn:price: + description: Price snapshot; detailed models can live in offerAttributes + x-jsonld: + '@id': schema:priceSpecification + allOf: + - $ref: '#/components/schemas/PriceSpecification' + beckn:provider: + description: Seller / provider of this offer + x-jsonld: + '@id': schema:seller + allOf: + - $ref: '#/components/schemas/Provider/properties/beckn:id' + beckn:validity: + description: Offer validity window + x-jsonld: + '@id': schema:availabilityStarts|schema:availabilityEnds + allOf: + - $ref: '#/components/schemas/TimePeriod' + required: + - '@context' + - '@type' + - beckn:id + - beckn:descriptor + - beckn:provider + - beckn:items + additionalProperties: false + Order: + type: object + properties: + '@context': + type: string + format: uri + const: https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/context.jsonld + '@type': + type: string + enum: + - beckn:Order + x-jsonld: + '@id': schema:Order + beckn:acceptedOffers: + description: Offers accepted at order-level (optional if captured per line) + type: array + items: + $ref: '#/components/schemas/Offer' + x-jsonld: + '@id': schema:acceptedOffer + beckn:consumer: + x-jsonld: + '@id': schema:customer + allOf: + - $ref: '#/components/schemas/Consumer' + beckn:entitlements: + type: array + items: + $ref: '#/components/schemas/Entitlement' + beckn:fulfillment: + description: Parcel delivery or reservation summary + x-jsonld: + '@id': schema:ParcelDelivery|schema:Reservation + allOf: + - $ref: '#/components/schemas/Fulfillment' + beckn:id: + type: string + x-jsonld: + '@id': schema:identifier + beckn:invoice: + description: Invoice reference/summary + x-jsonld: + '@id': schema:Invoice + allOf: + - $ref: '#/components/schemas/Invoice/properties/beckn:id' + beckn:orderAttributes: + description: Order-level Attribute Pack (vertical/regulatory specifics) + allOf: + - $ref: '#/components/schemas/Attributes' + beckn:orderItems: + type: array + items: + $ref: '#/components/schemas/OrderItem' + x-jsonld: + '@id': schema:orderItem + minItems: 1 + beckn:orderNumber: + description: Human-visible order number + type: string + x-jsonld: + '@id': schema:orderNumber + beckn:orderStatus: + description: Order status/state + type: string + enum: + - CREATED + - PENDING + - CONFIRMED + - INPROGRESS + - PARTIALLYFULFILLED + - COMPLETED + - CANCELLED + - REJECTED + - FAILED + - RETURNED + - REFUNDED + - ONHOLD + x-jsonld: + '@id': beckn:orderStatus + beckn:orderValue: + description: Order totals snapshot (derivable from lines; optional) + x-jsonld: + '@id': schema:priceSpecification + allOf: + - $ref: '#/components/schemas/PriceSpecification' + beckn:participants: + type: array + items: + $ref: '#/components/schemas/Participant' + beckn:paymentTerms: + description: Method/status; rail-specific payloads go to packs + x-jsonld: + '@id': schema:PaymentMethod|schema:PaymentStatusType + allOf: + - $ref: '#/components/schemas/PaymentTerms' + beckn:policies: + type: array + items: + $ref: '#/components/schemas/Policy' + beckn:provider: + x-jsonld: + '@id': schema:seller + allOf: + - $ref: '#/components/schemas/Provider' + beckn:state: + $ref: '#/components/schemas/State' + required: + - '@context' + - '@type' + - beckn:orderStatus + - beckn:provider + - beckn:consumer + - beckn:orderItems + additionalProperties: false + OrderItem: + type: object + properties: + beckn:acceptedOffer: + description: Offer applied to this line (if different from order-level) + x-jsonld: + '@id': schema:acceptedOffer + allOf: + - $ref: '#/components/schemas/Offer' + beckn:lineId: + description: Unique line id within order + type: string + beckn:orderItemAttributes: + description: Line-level Attribute Pack (options, substitutions, ESG, etc.) + allOf: + - $ref: '#/components/schemas/Attributes' + beckn:orderedItem: + x-jsonld: + '@id': schema:orderedItem + allOf: + - $ref: '#/components/schemas/Item/properties/beckn:id' + beckn:price: + description: Line price composition (unit/tax/delivery/discount) + x-jsonld: + '@id': schema:priceSpecification + allOf: + - $ref: '#/components/schemas/PriceSpecification' + beckn:quantity: + x-jsonld: + '@id': beckn:quantity + allOf: + - $ref: '#/components/schemas/Quantity' + required: + - beckn:orderedItem + Participant: + type: object + properties: + '@context': + type: string + format: uri + const: https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/context.jsonld + '@type': + type: string + enum: + - beckn:Participant + beckn:credentials: + type: array + items: + $ref: '#/components/schemas/Credential' + beckn:displayName: + type: string + beckn:email: + type: string + format: email + beckn:id: + type: string + beckn:rating: + $ref: '#/components/schemas/Rating' + beckn:role: + description: Role of participant (buyer, recipient, rider, patient, operator, etc.) + type: string + beckn:skills: + type: array + items: + $ref: '#/components/schemas/Skill' + beckn:telephone: + type: string + required: + - '@context' + - '@type' + - beckn:id + - beckn:role + additionalProperties: false + PaymentAction: + type: object + properties: + '@context': + type: string + format: uri + const: https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/context.jsonld + '@type': + type: string + enum: + - beckn:Payment + x-jsonld: + '@id': schema:Thing + beckn:payer: + type: object + beckn:payee: + type: object + beckn:amount: + description: Amount associated with this payment action + type: object + properties: + currency: + type: string + x-jsonld: + '@id': schema:priceCurrency + value: + type: number + x-jsonld: + '@id': schema:price + beckn:beneficiary: + description: Who will be the beneficiary or recipient of the payment + type: string + enum: + - BPP + - BAP + - BUYER + x-jsonld: + '@id': schema:beneficiary + example: BPP + beckn:id: + description: Payment record identifier + type: string + x-jsonld: + '@id': schema:identifier + beckn:paidAt: + description: When the last terminal event (capture/refund) happened + type: string + x-jsonld: + '@id': schema:paymentDueDate + format: date-time + nullable: true + beckn:paymentStatus: + description: Payment lifecycle status (Pending | Authorized | Captured | Failed | Refunded | PartialRefund …) + type: string + enum: + - INITIATED + - PENDING + - AUTHORIZED + - CAPTURED + - COMPLETED + - FAILED + - CANCELLED + - REFUNDED + - PARTIALLY_REFUNDED + - CHARGEBACK + - DISPUTED + - EXPIRED + - REVERSED + - VOIDED + - SETTLED + - ON_HOLD + - ADJUSTED + x-jsonld: + '@id': beckn:paymentStatus + beckn:paymentURL: + description: URL for payment processing/redirection + type: string + x-jsonld: + '@id': schema:url + format: uri + example: https://payments.example.com/pay?transaction_id=123&amount=100 + beckn:state: + $ref: '#/components/schemas/State' + beckn:txnRef: + description: PSP/gateway/bank transaction reference + type: string + x-jsonld: + '@id': schema:transactionNumber + required: + - '@context' + - '@type' + - beckn:paymentStatus + additionalProperties: false + + PaymentTerms: + type: object + properties: + beckn:collectedBy: + $ref: '#/components/schemas/PaymentCollector' + beckn:paymentSchedule: + $ref: '#/components/schemas/PaymentSchedule' + beckn:payTo: + $ref: '#/components/schemas/SettlementAccount' + beckn:refundTo: + $ref: '#/components/schemas/SettlementAccount' + beckn:paymentAttributes: + description: 'Rail-specific attribute pack (e.g., UPI: VPA/UTR; CARD: token/3DS; BNPL: plan/schedule)' + $ref: '#/components/schemas/Attributes' + + PaymentCollector: + description: The entity that is liable to collect the payment from the consumer + type: string + enum: + - BAP + - BPP + - PROVIDER + - FULFILLMENT_AGENT + - THIRD_PARTY_AGENT + + Policy: + type: object + properties: + '@context': + type: string + format: uri + const: https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/context.jsonld + '@type': + type: string + enum: + - beckn:Policy + beckn:descriptor: + $ref: '#/components/schemas/Descriptor' + beckn:documents: + description: Optional supporting documents/forms + type: array + items: + $ref: '#/components/schemas/Form' + beckn:id: + description: Identifier for the policy + type: string + beckn:policyType: + description: Type/kind of policy (extensible term) + type: string + beckn:validity: + description: Validity window for this policy version + allOf: + - $ref: '#/components/schemas/TimePeriod' + required: + - '@context' + - '@type' + - beckn:id + - beckn:descriptor + additionalProperties: false + PriceComponent: + type: object + properties: + '@context': + type: string + format: uri + const: https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/context.jsonld + '@type': + type: string + enum: + - beckn:PriceComponent + beckn:amount: + type: number + beckn:category: + description: Component category (tax, fee, discount, etc.) + allOf: + - $ref: '#/components/schemas/CategoryCode' + beckn:currency: + type: string + beckn:descriptor: + $ref: '#/components/schemas/Descriptor' + beckn:id: + type: string + required: + - '@context' + - '@type' + - beckn:id + - beckn:descriptor + - beckn:amount + - beckn:currency + additionalProperties: false + PriceSpecification: + type: object + properties: + applicableQuantity: + x-jsonld: + '@id': schema:eligibleQuantity + allOf: + - $ref: '#/components/schemas/Quantity' + beckn:priceComponents: + type: array + items: + $ref: '#/components/schemas/PriceComponent' + components: + description: Optional components (tax, shipping, discount, fee, surcharge) + type: array + items: + type: object + properties: + currency: + type: string + description: + type: string + type: + type: string + enum: + - UNIT + - TAX + - DELIVERY + - DISCOUNT + - FEE + - SURCHARGE + value: + type: number + currency: + description: ISO 4217 code + type: string + value: + description: Total value for this price specification + type: number + x-jsonld: + '@id': schema:PriceSpecification + additionalProperties: true + Provider: + type: object + properties: + beckn:alerts: + type: array + items: + $ref: '#/components/schemas/Alert' + beckn:descriptor: + $ref: '#/components/schemas/Descriptor' + beckn:features: + type: array + items: + $ref: '#/components/schemas/Feature' + beckn:id: + description: Unique identifier for the provider + type: string + example: tech-store-001 + beckn:locations: + description: Physical locations where the provider operates + type: array + items: + $ref: '#/components/schemas/Location' + beckn:policies: + type: array + items: + $ref: '#/components/schemas/Policy' + beckn:providerAttributes: + $ref: '#/components/schemas/Attributes' + beckn:rateable: + description: Whether the provider can be rated by customers + type: boolean + example: true + beckn:rating: + $ref: '#/components/schemas/Rating' + beckn:validity: + $ref: '#/components/schemas/TimePeriod' + required: + - beckn:id + - beckn:descriptor + additionalProperties: false + Quantity: + type: object + properties: + maxQuantity: + description: Maximum quantity for this price + type: number + x-jsonld: + '@id': schema:Number + example: 100 + minQuantity: + description: Minimum quantity for this price + type: number + x-jsonld: + '@id': schema:Number + example: 1 + unitCode: + description: Unit code for the quoted price (e.g., KWH, MIN, H, MON) + type: string + x-jsonld: + '@id': schema:unitCode + example: KWH + unitQuantity: + description: Quantity of the unit + type: number + x-jsonld: + '@id': schema:Number + example: 1 + unitText: + description: Unit for the quoted price (e.g., kWh, minute, hour, month) + type: string + x-jsonld: + '@id': schema:unitText + example: kWh + x-jsonld: + '@id': schema:QuantitativeValue + additionalProperties: false + Rating: + type: object + properties: + '@type': + description: Type of the rating + type: string + enum: + - beckn:Rating + example: beckn:Rating + beckn:ratingCount: + description: Number of ratings + type: integer + minimum: 0 + example: 1250 + beckn:ratingValue: + description: Rating value (0-5) + type: number + minimum: 0 + maximum: 5 + example: 4.8 + required: + - '@type' + RatingInput: + type: object + properties: + '@context': + type: string + format: uri + const: https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/context.jsonld + '@type': + type: string + enum: + - beckn:RatingInput + x-jsonld: + '@id': beckn:RatingInput + bestRating: + description: Maximum of the rating scale (default 5 if omitted). + type: number + category: + description: What is being rated. + type: string + enum: + - ORDER + - FULFILLMENT + - ITEM + - PROVIDER + - AGENT + - OTHER + feedback: + type: object + properties: + comments: + type: string + tags: + type: array + items: + type: string + additionalProperties: false + id: + description: Target entity ID being rated (order/item/fulfillment/provider/agent). + type: string + ratingValue: + description: Numeric rating value (legacy usually 1–5). + type: number + minimum: 0 + worstRating: + description: Minimum of the rating scale (default 1 or 0 if omitted). + type: number + required: + - '@context' + - '@type' + - id + - ratingValue + x-jsonld: + '@type': schema:Rating + schema:bestRating: $.best + schema:itemReviewed: $.id + schema:ratingValue: $.value + schema:worstRating: $.worst + additionalProperties: false + Skill: + type: object + properties: + '@context': + type: string + format: uri + const: https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/context.jsonld + '@type': + type: string + enum: + - beckn:Skill + beckn:category: + $ref: '#/components/schemas/CategoryCode' + beckn:descriptor: + $ref: '#/components/schemas/Descriptor' + beckn:id: + type: string + required: + - '@context' + - '@type' + - beckn:id + - beckn:descriptor + additionalProperties: false + SpatialConstraint: + description: "**Spatial predicate** using **OGC CQL2 (JSON semantics)** applied to one or more geometry targets in an\ + \ item. This is where clients express spatial intent.\nKey ideas: - `targets`: one or more **JSONPath-like** pointers\ + \ that locate geometry\n\n fields within each item document (e.g., `$['beckn:availableAt'][*]['geo']`).\n- `op`:\ + \ spatial operator (CQL2). Common ones:\n\n • `S_WITHIN` (A is completely inside B)\n • `S_INTERSECTS` (A\ + \ intersects B)\n • `S_CONTAINS` (A contains B)\n • `S_DWITHIN` (A within distance of B)\n- `geometry`:\ + \ **GeoJSON** literal used as the predicate reference geometry. - `distanceMeters`: required for `S_DWITHIN` when\ + \ using a GeoJSON Point/shape. - `quantifier`: if a target resolves to an array, choose whether **ANY** (default),\n\ + \n **ALL**, or **NONE** of elements must satisfy the predicate.\n\nCRS: unless otherwise stated, all coordinates\ + \ are **EPSG:4326**.\n" + type: object + properties: + op: + description: OGC CQL2 spatial operator. + type: string + enum: + - S_WITHIN + - S_CONTAINS + - S_INTERSECTS + - S_DISJOINT + - S_OVERLAPS + - S_CROSSES + - S_TOUCHES + - S_EQUALS + - S_DWITHIN + targets: + description: 'One or more JSONPath-like pointers to geometry fields within the item. Example pointers: - `$[''beckn:availableAt''][*][''geo'']` + (array of site Points) - `$[''beckn:itemAttributes''][''ride:dropOff''][''geo'']` (drop zone Polygon) + + ' + oneOf: + - type: string + - type: array + items: + type: string + geometry: + $ref: '#/components/schemas/GeoJSONGeometry' + distanceMeters: + description: 'For `S_DWITHIN`: maximum distance in meters from the target geometry to `geometry` (e.g., "within + 5000 m of this Point"). Ignored for other ops. + + ' + type: number + minimum: 0 + quantifier: + description: 'How to evaluate when `targets` resolves to an array: - **any**: at least one element matches (default) + - **all**: every element must match - **none**: no element may match + + ' + type: string + enum: + - ANY + - ALL + - NONE + default: any + srid: + description: 'Coordinate Reference System identifier for `geometry`. Default is `"EPSG:4326"`. If provided, servers + MAY reproject to EPSG:4326 internally. + + ' + type: string + example: EPSG:4326 + required: + - op + - targets + additionalProperties: false + examples: + - $ref: '../../examples/v2.1/SpatialConstraint.examples.yaml#/within_circle' + - $ref: '../../examples/v2.1/SpatialConstraint.examples.yaml#/pickup_at_point' + - $ref: '../../examples/v2.1/SpatialConstraint.examples.yaml#/drop_intersects' + - $ref: '../../examples/v2.1/SpatialConstraint.examples.yaml#/pickup_location' + State: + type: object + properties: + '@context': + type: string + format: uri + const: https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/context.jsonld + '@type': + type: string + enum: + - beckn:State + beckn:descriptor: + $ref: '#/components/schemas/Descriptor' + beckn:id: + description: State code/identifier + type: string + required: + - '@context' + - '@type' + - beckn:id + additionalProperties: false + SupportInfo: + description: Canonical support contact for an entity, mapped to schema.org ContactPoint. + type: object + properties: + '@context': + type: string + format: uri + const: https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/context.jsonld + '@type': + type: string + enum: + - beckn:SupportInfo + x-jsonld: + '@id': beckn:SupportInfo + channels: + description: Available support channels. + type: array + items: + type: string + enum: + - PHONE + - EMAIL + - WEB + - CHAT + - WHATSAPP + - IN_APP + - OTHER + email: + description: Support email address. + type: string + format: email + hours: + description: Human-readable support hours (local time). + type: string + name: + description: Name of the support organization or contact. + type: string + phone: + description: Telephone number. + type: string + url: + description: Webpage or chat endpoint for support. + type: string + format: uri + required: + - '@context' + - '@type' + x-jsonld: + '@type': schema:ContactPoint + schema:contactType: '"Customer Support"' + schema:email: $.email + schema:hoursAvailable: $.hours + schema:name: $.name + schema:telephone: $.phone + schema:url: $.url + additionalProperties: false + examples: + - $ref: '../../examples/v2.1/SupportInfo.examples.yaml#/basic' + SupportMethod: + type: string + SupportTicket: + type: object + TimePeriod: + description: Time window with date-time precision for availability/validity + type: object + properties: + '@type': + description: JSON-LD type for a date-time period + type: string + example: beckn:TimePeriod + schema:endDate: + description: End instant (exclusive or inclusive per domain semantics) + type: string + format: date-time + example: '2025-12-31T23:59:59Z' + schema:endTime: + description: End time of the time period + type: string + format: time + example: '22:00:00' + schema:startDate: + description: Start instant (inclusive) + type: string + format: date-time + example: '2025-01-27T09:00:00Z' + schema:startTime: + description: Start time of the time period + type: string + format: time + example: 09:00:00 + required: + - '@type' + anyOf: + - required: + - schema:startDate + - required: + - schema:endDate + - required: + - schema:startTime + - schema:endTime + TrackAction: + description: Minimal schema.org TrackAction for clickable tracking. + type: object + properties: + id: + description: Tracking action identifier + type: string + x-jsonld: + '@id': schema:identifier + url: + description: Tracking page URL + type: string + x-jsonld: + '@id': schema:url + format: uri + x-jsonld: + '@type': schema:TrackAction + additionalProperties: true + TrackingRequest: + type: object + properties: + id: + description: Tracking reference identifier + type: string + callbackUrl: + description: Optional callback URL for streaming tracking coordinates/updates + type: string + format: uri + mode_hint: + description: Optional delivery mode for the tracking handle. + type: string + enum: + - link_only + - deep_link + - webhook + - ws_handle + required: + - id + Tracking: + description: Non-streaming tracking handle per legacy semantics (url/transport/status). + type: object + properties: + '@context': + type: string + format: uri + const: https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/context.jsonld + '@type': + type: string + enum: + - beckn:Tracking + x-jsonld: + '@id': beckn:Tracking + beckn:state: + $ref: '#/components/schemas/State' + expires_at: + description: ISO 8601 expiry timestamp for the tracking handle. + type: string + format: date-time + tl_method: + description: Transport/method used to access the tracking handle. + type: string + enum: + - http/get + - http/post + - http/redirect + - ws/handle + - custom + trackingStatus: + type: string + enum: + - ACTIVE + - DISABLED + - COMPLETED + url: + description: Link/handle to off-network tracking UI or endpoint. + type: string + format: uri + required: + - '@context' + - '@type' + - tl_method + - url + - trackingStatus + x-jsonld: + '@type': schema:TrackAction + beckn:trackingStatus: $.trackingStatus + schema:deliveryMethod: $.tl_method + schema:target: $.url + additionalProperties: false + examples: + - $ref: '../../examples/v2.1/Tracking.examples.yaml#/basic' + CatalogProcessingResult: + type: object + properties: + catalogId: + description: The "beckn:id" of the submitted catalog + type: string + status: + description: Final processing outcome for this catalog + type: string + enum: + - ACCEPTED + - REJECTED + - PARTIAL + itemCount: + description: Number of items indexed (when accepted/partial) + type: integer + minimum: 0 + warnings: + description: Non-fatal issues encountered + type: array + items: + $ref: '#/components/schemas/ProcessingNotice' + error: + $ref: https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2/attributes.yaml#/components/schemas/Error + required: + - catalogId + - status + ProcessingNotice: + type: object + properties: + code: + type: string + message: + type: string + details: + type: object + additionalProperties: true + required: + - code + - message + MediaSearch: + description: 'Container for multimodal search inputs and configuration. Supports searching through **images, audio notes, + and videos** alongside text, filters, and spatial predicates. For GET, this object should be JSON-encoded and URL-escaped. + + ' + type: object + properties: + media: + description: 'One or more references to **images, audio notes, or videos** supplied as part of a multimodal search. + Each entry references a media resource accessible via HTTPS or data URI. + + ' + type: array + items: + $ref: '#/components/schemas/MediaInput' + example: + - id: snap-1 + type: image + url: https://cdn.example.com/user/snaps/ccs2-cable.jpg + contentType: image/jpeg + options: + description: 'Options controlling how the discovery engine interprets the supplied media — e.g., whether to perform + OCR/ASR, semantic similarity, or object detection. + + ' + $ref: '#/components/schemas/MediaSearchOptions' + additionalProperties: false + examples: + - $ref: '../../examples/v2.1/MediaSearch.examples.yaml#/basic' diff --git a/schema/core/v2.1/context.jsonld b/schema/core/v2.1/context.jsonld new file mode 100644 index 0000000..c37a029 --- /dev/null +++ b/schema/core/v2.1/context.jsonld @@ -0,0 +1,331 @@ +{ + "@context": { + "@version": 1.1, + "@protected": true, + "schema": "https://schema.org/", + "xsd": "http://www.w3.org/2001/XMLSchema#", + "beckn": "https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/schema/core/v2.1/", + "AcceptedPaymentMethod": "beckn:AcceptedPaymentMethod", + "AckResponse": "beckn:AckResponse", + "Address": "beckn:Address", + "Alert": "beckn:Alert", + "Attributes": "beckn:Attributes", + "Buyer": "beckn:Buyer", + "CancellationOutcome": "beckn:CancellationOutcome", + "CancellationPolicy": "beckn:CancellationPolicy", + "CancellationReason": "beckn:CancellationReason", + "Catalog": "beckn:Catalog", + "CatalogProcessingResult": "beckn:CatalogProcessingResult", + "CategoryCode": "beckn:CategoryCode", + "Constraint": "beckn:Constraint", + "Context": "beckn:Context", + "Credential": "beckn:Credential", + "Descriptor": "beckn:Descriptor", + "Document": "beckn:Document", + "Eligibility": "beckn:Eligibility", + "Entitlement": "beckn:Entitlement", + "Error": "beckn:Error", + "ErrorResponse": "beckn:ErrorResponse", + "Feature": "beckn:Feature", + "Feedback": "beckn:Feedback", + "Form": "beckn:Form", + "Fulfillment": "beckn:Fulfillment", + "FulfillmentStop": "beckn:FulfillmentStop", + "GeoJSONGeometry": "beckn:GeoJSONGeometry", + "Instruction": "beckn:Instruction", + "Intent": "beckn:Intent", + "Invoice": "beckn:Invoice", + "Item": "beckn:Item", + "Location": "beckn:Location", + "MediaInput": "beckn:MediaInput", + "MediaSearch": "beckn:MediaSearch", + "MediaSearchOptions": "beckn:MediaSearchOptions", + "Offer": "beckn:Offer", + "Order": "beckn:Order", + "OrderItem": "beckn:OrderItem", + "Participant": "beckn:Participant", + "Payment": "beckn:Payment", + "Policy": "beckn:Policy", + "PriceComponent": "beckn:PriceComponent", + "PriceSpecification": "beckn:PriceSpecification", + "ProcessingNotice": "beckn:ProcessingNotice", + "Provider": "beckn:Provider", + "Quantity": "beckn:Quantity", + "Rating": "beckn:Rating", + "RatingInput": "beckn:RatingInput", + "Skill": "beckn:Skill", + "SpatialConstraint": "beckn:SpatialConstraint", + "State": "beckn:State", + "SupportInfo": "beckn:SupportInfo", + "SupportMethod": "beckn:SupportMethod", + "SupportTicket": "beckn:SupportTicket", + "TimePeriod": "beckn:TimePeriod", + "TrackAction": "beckn:TrackAction", + "Tracking": "beckn:Tracking", + "TrackingRequest": "beckn:TrackingRequest", + "acceptedOffer": "beckn:acceptedOffer", + "acceptedOffers": "beckn:acceptedOffers", + "acceptedPaymentMethod": { + "@id": "beckn:acceptedPaymentMethod", + "@type": "@id", + "@context": { + "UPI": "beckn:UPI", + "CREDIT_CARD": "beckn:CREDIT_CARD", + "DEBIT_CARD": "beckn:DEBIT_CARD", + "WALLET": "beckn:WALLET", + "BANK_TRANSFER": "beckn:BANK_TRANSFER", + "CASH": "beckn:CASH", + "APPLE_PAY": "beckn:APPLE_PAY" + } + }, + "addOnItems": "beckn:addOnItems", + "addOns": "beckn:addOns", + "address": "beckn:address", + "amount": "beckn:amount", + "applicableQuantity": "beckn:applicableQuantity", + "availabilityWindow": "beckn:availabilityWindow", + "availableAt": "beckn:availableAt", + "beneficiary": { + "@id": "beckn:beneficiary", + "@type": "@id", + "@context": { + "BPP": "beckn:BPP", + "BAP": "beckn:BAP" + } + }, + "bestRating": "beckn:bestRating", + "buyer": "beckn:buyer", + "buyerAttributes": "beckn:buyerAttributes", + "category": "beckn:category", + "channels": { + "@id": "beckn:channels", + "@type": "@id", + "@context": { + "PHONE": "beckn:SupportChannelPhone", + "EMAIL": "beckn:SupportChannelEmail", + "WEB": "beckn:SupportChannelWeb", + "CHAT": "beckn:SupportChannelChat", + "WHATSAPP": "beckn:SupportChannelWhatsApp", + "WHATS_APP": "beckn:SupportChannelWhatsApp", + "IN_APP": "beckn:SupportChannelInApp", + "IN-APP": "beckn:SupportChannelInApp", + "OTHER": "beckn:SupportChannelOther" + } + }, + "components": "beckn:components", + "createdAt": "beckn:createdAt", + "currency": "beckn:currency", + "deliveryAttributes": "beckn:deliveryAttributes", + "fulfillmentStatus": "beckn:fulfillmentStatus", + "descriptor": "beckn:descriptor", + "displayName": "beckn:displayName", + "dueDate": "beckn:dueDate", + "eligibleQuantity": "beckn:eligibleQuantity", + "eligibleRegion": "beckn:eligibleRegion", + "email": "schema:email", + "endDate": "beckn:endDate", + "endTime": "beckn:endTime", + "errorCode": "beckn:errorCode", + "errorDetails": "beckn:errorDetails", + "errorMessage": "beckn:errorMessage", + "expiresAt": "beckn:expiresAt", + "feedback": "beckn:feedback", + "form": "beckn:form", + "fulfillment": "beckn:fulfillment", + "geo": "beckn:geo", + "hours": "beckn:hours", + "id": "beckn:id", + "invoice": "beckn:invoice", + "invoiceAttributes": "beckn:invoiceAttributes", + "isActive": "beckn:isActive", + "issueDate": "beckn:issueDate", + "itemAttributes": "beckn:itemAttributes", + "itemCondition": "beckn:itemCondition", + "items": "beckn:items", + "lineId": "beckn:lineId", + "location": "beckn:location", + "locations": "beckn:locations", + "longDesc": "beckn:longDesc", + "maxQuantity": "beckn:maxQuantity", + "method": "beckn:method", + "minQuantity": "beckn:minQuantity", + "networkId": "beckn:networkId", + "number": "beckn:number", + "offerAttributes": "beckn:offerAttributes", + "offers": "beckn:offers", + "orderAttributes": "beckn:orderAttributes", + "orderItemAttributes": "beckn:orderItemAttributes", + "orderItems": "beckn:orderItems", + "orderNumber": "beckn:orderNumber", + "orderStatus": { + "@id": "beckn:orderStatus", + "@type": "@id", + "@context": { + "CREATED": "beckn:OrderCreated", + "PENDING": "beckn:OrderPending", + "CONFIRMED": "beckn:OrderConfirmed", + "INPROGRESS": "beckn:OrderInProgress", + "PARTIALLYFULFILLED": "beckn:OrderPartiallyFulfilled", + "COMPLETED": "beckn:OrderCompleted", + "CANCELLED": "beckn:OrderCancelled", + "REJECTED": "beckn:OrderRejected", + "FAILED": "beckn:OrderFailed", + "RETURNED": "beckn:OrderReturned", + "REFUNDED": "beckn:OrderRefunded", + "ONHOLD": "beckn:OrderOnHold", + "ON-HOLD": "beckn:OrderOnHold" + } + }, + "orderValue": "beckn:orderValue", + "orderedItem": "beckn:orderedItem", + "paidAt": "beckn:paidAt", + "payee": "beckn:payee", + "payer": "beckn:payer", + "payment": "beckn:payment", + "paymentAttributes": "beckn:paymentAttributes", + "paymentURL": "beckn:paymentURL", + "paymentStatus": { + "@id": "beckn:paymentStatus", + "@type": "@id", + "@context": { + "INITIATED": "beckn:PaymentInitiated", + "PENDING": "beckn:PaymentPending", + "AUTHORIZED": "beckn:PaymentAuthorized", + "CAPTURED": "beckn:PaymentCaptured", + "COMPLETED": "beckn:PaymentCompleted", + "FAILED": "beckn:PaymentFailed", + "CANCELLED": "beckn:PaymentCancelled", + "CANCELED": "beckn:PaymentCancelled", + "REFUNDED": "beckn:PaymentRefunded", + "PARTIALLY_REFUNDED": "beckn:PaymentPartiallyRefunded", + "PARTIALLY-REFUNDED": "beckn:PaymentPartiallyRefunded", + "CHARGEBACK": "beckn:PaymentChargeback", + "DISPUTED": "beckn:PaymentDisputed", + "EXPIRED": "beckn:PaymentExpired", + "REVERSED": "beckn:PaymentReversed", + "VOIDED": "beckn:PaymentVoided", + "SETTLED": "beckn:PaymentSettled", + "ON_HOLD": "beckn:PaymentOnHold", + "ON-HOLD": "beckn:PaymentOnHold", + "ADJUSTED": "beckn:PaymentAdjusted" + } + }, + "phone": "beckn:phone", + "price": "beckn:price", + "provider": "beckn:provider", + "providerAttributes": "beckn:providerAttributes", + "providerId": "beckn:providerId", + "bppId": "beckn:bppId", + "bppUri": "beckn:bppUri", + "quantity": "beckn:quantity", + "rateable": "beckn:rateable", + "rating": "beckn:rating", + "ratingCount": "beckn:ratingCount", + "ratingValue": "beckn:ratingValue", + "reviewText": "beckn:reviewText", + "role": "beckn:role", + "worstRating": "beckn:worstRating", + "seller": "beckn:seller", + "shortDesc": "beckn:shortDesc", + "startDate": "beckn:startDate", + "startTime": "beckn:startTime", + "supportInfo": "beckn:supportInfo", + "taxID": "beckn:taxID", + "telephone": "schema:telephone", + "tlMethod": "beckn:tlMethod", + "trackingStatus": { + "@id": "beckn:trackingStatus", + "@type": "@id", + "@context": { + "ACTIVE": "beckn:TrackingActive", + "DISABLED": "beckn:TrackingDisabled", + "COMPLETED": "beckn:TrackingCompleted" + } + }, + "totals": "beckn:totals", + "trackAction": "beckn:trackAction", + "tracking": "beckn:tracking", + "trackingAction": "beckn:trackingAction", + "txnRef": "beckn:txnRef", + "unitCode": "beckn:unitCode", + "unitQuantity": "beckn:unitQuantity", + "unitText": "beckn:unitText", + "updatedAt": "beckn:updatedAt", + "validity": "beckn:validity", + "value": "beckn:value", + "features": "beckn:features", + "policies": "beckn:policies", + "constraints": "beckn:constraints", + "participants": "beckn:participants", + "skills": "beckn:skills", + "credentials": "beckn:credentials", + "instructions": "beckn:instructions", + "entitlements": "beckn:entitlements", + "alerts": "beckn:alerts", + "priceComponents": "beckn:priceComponents", + "state": "beckn:state", + "stops": "beckn:stops", + "stopType": "beckn:stopType", + "severity": "beckn:severity", + "affectedEntities": "beckn:affectedEntities", + "augmentTextSearch": "beckn:augmentTextSearch", + "cancellationOutcome": "beckn:cancellationOutcome", + "cancellationPolicy": "beckn:cancellationPolicy", + "cancellationReason": "beckn:cancellationReason", + "catalogId": "beckn:catalogId", + "code": "beckn:code", + "codeValue": "beckn:codeValue", + "comments": "beckn:comments", + "constraintType": "beckn:constraintType", + "contentType": "beckn:contentType", + "data": "beckn:data", + "deliveryMethod": "beckn:deliveryMethod", + "description": "beckn:description", + "details": "beckn:details", + "distanceMeters": "beckn:distanceMeters", + "documents": "beckn:documents", + "endMs": "beckn:endMs", + "entitlementType": "beckn:entitlementType", + "error": "beckn:error", + "expression": "beckn:expression", + "filters": "beckn:filters", + "geometry": "beckn:geometry", + "goals": "beckn:goals", + "images": "beckn:images", + "issuer": "beckn:issuer", + "itemCount": "beckn:itemCount", + "language": "beckn:language", + "media": "beckn:media", + "mediaFile": "beckn:mediaFile", + "media_search": "beckn:media_search", + "message": "beckn:message", + "methods": "beckn:methods", + "mimeType": "beckn:mimeType", + "mime_type": "beckn:mime_type", + "mode": "beckn:mode", + "name": "beckn:name", + "op": "beckn:op", + "operator": "beckn:operator", + "options": "beckn:options", + "policyType": "beckn:policyType", + "quantifier": "beckn:quantifier", + "restrictResultsToMediaProximity": "beckn:restrictResultsToMediaProximity", + "results": "beckn:results", + "schemas": "beckn:schemas", + "spatial": "beckn:spatial", + "srid": "beckn:srid", + "startMs": "beckn:startMs", + "status": "beckn:status", + "submissionId": "beckn:submissionId", + "submission_id": "beckn:submission_id", + "tags": "beckn:tags", + "targets": "beckn:targets", + "textHint": "beckn:textHint", + "text_search": "beckn:text_search", + "tickets": "beckn:tickets", + "time": "beckn:time", + "type": "beckn:type", + "url": "beckn:url", + "warnings": "beckn:warnings" + } +} diff --git a/schema/core/v2.1/vocab.jsonld b/schema/core/v2.1/vocab.jsonld new file mode 100644 index 0000000..26cd150 --- /dev/null +++ b/schema/core/v2.1/vocab.jsonld @@ -0,0 +1,1991 @@ +{ + "@context": { + "@version": 1.1, + "beckn": "https://raw.githubusercontent.com/beckn/protocol-specifications-v2/refs/heads/draft/main/schema/core/v2/#", + "schema": "https://schema.org/", + "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", + "rdfs": "http://www.w3.org/2000/01/rdf-schema#", + "xsd": "http://www.w3.org/2001/XMLSchema#" + }, + "@graph": [ + { + "@id": "beckn:Catalog", + "@type": "rdfs:Class", + "rdfs:label": "Catalog", + "rdfs:comment": "A collection of items and offers made available by a provider." + }, + { + "@id": "beckn:Item", + "@type": "rdfs:Class", + "rdfs:label": "Item", + "rdfs:comment": "A sellable item or service entry in a catalog." + }, + { + "@id": "beckn:Offer", + "@type": "rdfs:Class", + "rdfs:label": "Offer", + "rdfs:comment": "A commercial offer describing pricing/terms for one or more items." + }, + { + "@id": "beckn:Provider", + "@type": "rdfs:Class", + "rdfs:label": "Provider", + "rdfs:comment": "An entity that provides items and offers in a catalog." + }, + { + "@id": "beckn:Order", + "@type": "rdfs:Class", + "rdfs:label": "Order", + "rdfs:comment": "A purchase order containing items, pricing and fulfillment details." + }, + { + "@id": "beckn:OrderItem", + "@type": "rdfs:Class", + "rdfs:label": "Order Item", + "rdfs:comment": "An item entry within an order, referencing a catalog item and offer." + }, + { + "@id": "beckn:Fulfillment", + "@type": "rdfs:Class", + "rdfs:label": "Fulfillment", + "rdfs:comment": "Information about delivery, reservation or service execution." + }, + { + "@id": "beckn:Payment", + "@type": "rdfs:Class", + "rdfs:label": "Payment", + "rdfs:comment": "Payment instrument, status and settlement information for an order." + }, + { + "@id": "beckn:PriceSpecification", + "@type": "rdfs:Class", + "rdfs:label": "Price Specification", + "rdfs:comment": "Structured price snapshot including currency, value and optional components." + }, + { + "@id": "beckn:Quantity", + "@type": "rdfs:Class", + "rdfs:label": "Quantity", + "rdfs:comment": "A quantitative value specifying units, codes, and quantity constraints", + "schema:rangeIncludes": "schema:QuantitativeValue" + }, + { + "@id": "beckn:Buyer", + "@type": "rdfs:Class", + "rdfs:label": "Buyer", + "rdfs:comment": "A person or organization purchasing items; identity via attribute packs" + }, + { + "@id": "beckn:Descriptor", + "@type": "rdfs:Class", + "rdfs:label": "Descriptor", + "rdfs:comment": "Human-readable metadata such as names, images and short descriptions." + }, + { + "@id": "beckn:CategoryCode", + "@type": "rdfs:Class", + "rdfs:label": "Category Code", + "rdfs:comment": "Categorization or taxonomy code for items or services." + }, + { + "@id": "beckn:TimePeriod", + "@type": "rdfs:Class", + "rdfs:label": "Time Period", + "rdfs:comment": "A period defined by start and end date-times." + }, + { + "@id": "beckn:Rating", + "@type": "rdfs:Class", + "rdfs:label": "Rating", + "rdfs:comment": "A rating or review for an item, order or fulfillment." + }, + { + "@id": "beckn:Error", + "@type": "rdfs:Class", + "rdfs:label": "Error", + "rdfs:comment": "Standard error object for reporting failures in API flows." + }, + { + "@id": "beckn:Location", + "@type": "rdfs:Class", + "rdfs:label": "Location", + "rdfs:comment": "A physical location including geo and postal address." + }, + { + "@id": "beckn:Address", + "@type": "rdfs:Class", + "rdfs:label": "Address", + "rdfs:comment": "A structured postal address for a location." + }, + { + "@id": "beckn:GeoJSONGeometry", + "@type": "rdfs:Class", + "rdfs:label": "GeoJSON Geometry", + "rdfs:comment": "A GeoJSON geometry object (Point, LineString, Polygon, etc.)." + }, + { + "@id": "beckn:Invoice", + "@type": "rdfs:Class", + "rdfs:label": "Invoice", + "rdfs:comment": "Billing document issued for an order." + }, + { + "@id": "beckn:TrackAction", + "@type": "rdfs:Class", + "rdfs:label": "Track Action", + "rdfs:comment": "An action that enables tracking a fulfillment or session." + }, + { + "@id": "beckn:SupportInfo", + "@type": "rdfs:Class", + "rdfs:label": "Support Info", + "rdfs:comment": "Support contact details and guidance for buyers." + }, + { + "@id": "beckn:Tracking", + "@type": "rdfs:Class", + "rdfs:label": "Tracking", + "rdfs:comment": "Tracking metadata for a fulfillment including URLs and status." + }, + { + "@id": "beckn:RatingInput", + "@type": "rdfs:Class", + "rdfs:label": "Rating Input", + "rdfs:comment": "Buyer-provided rating input payload." + }, + { + "@id": "beckn:Form", + "@type": "rdfs:Class", + "rdfs:label": "Form", + "rdfs:comment": "A structured form for input capture in flows (e.g., init, support)." + }, + { + "@id": "beckn:Eligibility", + "@type": "rdfs:Class", + "rdfs:label": "Eligibility", + "rdfs:comment": "Eligibility constraints for an offer such as region or quantity." + }, + { + "@id": "beckn:Attributes", + "@type": "rdfs:Class", + "rdfs:label": "Attributes", + "rdfs:comment": "JSON-LD aware attribute pack container used across entities." + }, + { + "@id": "beckn:id", + "@type": "rdf:Property", + "rdfs:label": "Identifier", + "rdfs:comment": "Primary identifier (string/URN) for an entity.", + "rdfs:domain": [ + "beckn:Catalog", + "beckn:Item", + "beckn:Offer", + "beckn:Provider", + "beckn:Order", + "beckn:Fulfillment", + "beckn:Payment", + "beckn:Buyer", + "beckn:Descriptor", + "beckn:Location", + "beckn:Invoice", + "beckn:Rating", + "beckn:SupportInfo", + "beckn:Tracking" + ], + "schema:rangeIncludes": "schema:Text" + }, + { + "@id": "beckn:descriptor", + "@type": "rdf:Property", + "rdfs:label": "Descriptor", + "rdfs:comment": "Human-readable descriptor for display.", + "rdfs:domain": [ + "beckn:Catalog", + "beckn:Item", + "beckn:Offer", + "beckn:Provider" + ], + "schema:rangeIncludes": "beckn:Descriptor" + }, + { + "@id": "beckn:isActive", + "@type": "rdf:Property", + "rdfs:label": "Is Active", + "rdfs:comment": "Whether the entity is currently active or listed.", + "rdfs:domain": [ + "beckn:Item", + "beckn:Offer" + ], + "schema:rangeIncludes": "schema:Boolean" + }, + { + "@id": "beckn:provider", + "@type": "rdf:Property", + "rdfs:label": "Provider", + "rdfs:comment": "Provider associated with a catalog, item or order.", + "rdfs:domain": [ + "beckn:Catalog", + "beckn:Item", + "beckn:Order" + ], + "schema:rangeIncludes": "beckn:Provider" + }, + { + "@id": "beckn:category", + "@type": "rdf:Property", + "rdfs:label": "Category", + "rdfs:comment": "Category or taxonomy classification.", + "rdfs:domain": [ + "beckn:Item", + "beckn:Offer" + ], + "schema:rangeIncludes": [ + "beckn:CategoryCode", + "schema:Text" + ] + }, + { + "@id": "beckn:items", + "@type": "rdf:Property", + "rdfs:label": "Items", + "rdfs:comment": "List of item identifiers or references.", + "rdfs:domain": [ + "beckn:Catalog", + "beckn:Offer", + "beckn:Order" + ], + "schema:rangeIncludes": [ + "schema:ItemList", + "schema:Text" + ] + }, + { + "@id": "beckn:price", + "@type": "rdf:Property", + "rdfs:label": "Price", + "rdfs:comment": "Price specification including components.", + "rdfs:domain": [ + "beckn:Offer", + "beckn:Order", + "beckn:OrderItem", + "beckn:Invoice" + ], + "schema:rangeIncludes": "schema:PriceSpecification" + }, + { + "@id": "beckn:value", + "@type": "rdf:Property", + "rdfs:label": "Price value", + "rdfs:comment": "Numeric value captured in the price specification.", + "rdfs:domain": [ + "beckn:PriceSpecification", + "beckn:Quantity" + ], + "schema:rangeIncludes": "schema:Number", + "owl:equivalentProperty": "schema:price" + }, + { + "@id": "beckn:minQuantity", + "@type": "rdf:Property", + "rdfs:label": "Minimum quantity", + "rdfs:comment": "Minimum quantity threshold for which the price applies.", + "rdfs:domain": [ + "beckn:Quantity", + "beckn:PriceSpecification" + ], + "schema:rangeIncludes": "schema:Number", + "owl:equivalentProperty": "schema:minValue" + }, + { + "@id": "beckn:maxQuantity", + "@type": "rdf:Property", + "rdfs:label": "Maximum quantity", + "rdfs:comment": "Maximum quantity threshold for which the price applies.", + "rdfs:domain": [ + "beckn:Quantity", + "beckn:PriceSpecification" + ], + "schema:rangeIncludes": "schema:Number", + "owl:equivalentProperty": "schema:maxValue" + }, + { + "@id": "beckn:acceptedPaymentMethod", + "@type": "rdf:Property", + "rdfs:label": "Accepted payment method", + "rdfs:comment": "Payment methods accepted for this entity.", + "rdfs:domain": [ + "beckn:Offer", + "beckn:Item", + "beckn:Payment" + ], + "schema:rangeIncludes": "beckn:AcceptedPaymentMethod" + }, + { + "@id": "beckn:AcceptedPaymentMethod", + "@type": "schema:Enumeration", + "schema:name": "Accepted Payment Method", + "rdfs:comment": "Enumeration of payment methods supported across core entities.", + "schema:hasEnumerationMember": [ + { "@id": "beckn:UPI" }, + { "@id": "beckn:CREDIT_CARD" }, + { "@id": "beckn:DEBIT_CARD" }, + { "@id": "beckn:WALLET" }, + { "@id": "beckn:BANK_TRANSFER" }, + { "@id": "beckn:CASH" }, + { "@id": "beckn:APPLE_PAY" } + ] + }, + { + "@id": "beckn:UPI", + "@type": [ + "beckn:AcceptedPaymentMethod", + "schema:Enumeration" + ], + "schema:name": "UPI", + "schema:identifier": "UPI" + }, + { + "@id": "beckn:CREDIT_CARD", + "@type": [ + "beckn:AcceptedPaymentMethod", + "schema:Enumeration" + ], + "schema:name": "CREDIT_CARD", + "schema:identifier": "CREDIT_CARD", + "schema:alternateName": "CREDIT-CARD" + }, + { + "@id": "beckn:DEBIT_CARD", + "@type": [ + "beckn:AcceptedPaymentMethod", + "schema:Enumeration" + ], + "schema:name": "DEBIT_CARD", + "schema:identifier": "DEBIT_CARD", + "schema:alternateName": "DEBIT-CARD" + }, + { + "@id": "beckn:WALLET", + "@type": [ + "beckn:AcceptedPaymentMethod", + "schema:Enumeration" + ], + "schema:name": "WALLET", + "schema:identifier": "WALLET" + }, + { + "@id": "beckn:BANK_TRANSFER", + "@type": [ + "beckn:AcceptedPaymentMethod", + "schema:Enumeration" + ], + "schema:name": "BANK_TRANSFER", + "schema:identifier": "BANK_TRANSFER", + "schema:alternateName": "BANK-TRANSFER" + }, + { + "@id": "beckn:CASH", + "@type": [ + "beckn:AcceptedPaymentMethod", + "schema:Enumeration" + ], + "schema:name": "CASH", + "schema:identifier": "CASH" + }, + { + "@id": "beckn:APPLE_PAY", + "@type": [ + "beckn:AcceptedPaymentMethod", + "schema:Enumeration" + ], + "schema:name": "APPLE_PAY", + "schema:identifier": "APPLE_PAY", + "schema:alternateName": "APPLE-PAY" + }, + { + "@id": "beckn:fulfillment", + "@type": "rdf:Property", + "rdfs:label": "Fulfillment", + "rdfs:comment": "Fulfillment details for the order.", + "rdfs:domain": [ + "beckn:Order", + "beckn:OrderItem" + ], + "schema:rangeIncludes": [ + "schema:ItemList", + "beckn:Fulfillment" + ] + }, + { + "@id": "beckn:payment", + "@type": "rdf:Property", + "rdfs:label": "Payment", + "rdfs:comment": "Payment instrument or status for the order.", + "rdfs:domain": [ + "beckn:Order", + "beckn:Invoice" + ], + "schema:rangeIncludes": [ + "schema:ItemList", + "beckn:Payment" + ] + }, + { + "@id": "beckn:location", + "@type": "rdf:Property", + "rdfs:label": "Location", + "rdfs:comment": "Physical location or place.", + "rdfs:domain": [ + "beckn:Provider", + "beckn:Fulfillment", + "beckn:Order" + ], + "schema:rangeIncludes": "beckn:Location" + }, + { + "@id": "beckn:supportInfo", + "@type": "rdf:Property", + "rdfs:label": "Support info", + "rdfs:comment": "Support information for the order or provider.", + "rdfs:domain": [ + "beckn:Order", + "beckn:Provider" + ], + "schema:rangeIncludes": "beckn:SupportInfo" + }, + { + "@id": "beckn:form", + "@type": "rdf:Property", + "rdfs:label": "Form", + "rdfs:comment": "Form to capture input during a flow.", + "rdfs:domain": [ + "beckn:Order", + "beckn:Fulfillment", + "beckn:SupportInfo" + ], + "schema:rangeIncludes": "beckn:Form" + }, + { + "@id": "beckn:createdAt", + "@type": "rdf:Property", + "rdfs:label": "Created at", + "rdfs:comment": "Creation timestamp (UTC).", + "rdfs:domain": [ + "beckn:Order", + "beckn:Invoice", + "beckn:Offer" + ], + "schema:rangeIncludes": "schema:DateTime" + }, + { + "@id": "beckn:updatedAt", + "@type": "rdf:Property", + "rdfs:label": "Updated at", + "rdfs:comment": "Last update timestamp (UTC).", + "rdfs:domain": [ + "beckn:Order", + "beckn:Invoice", + "beckn:Offer" + ], + "schema:rangeIncludes": "schema:DateTime" + }, + { + "@id": "beckn:rateable", + "@type": "rdf:Property", + "rdfs:label": "Rateable", + "rdfs:comment": "Whether the entity can be rated by customers.", + "rdfs:domain": [ + "beckn:Item", + "beckn:Provider" + ], + "schema:rangeIncludes": "schema:Boolean" + }, + { + "@id": "beckn:rating", + "@type": "rdf:Property", + "rdfs:label": "Rating", + "rdfs:comment": "Rating summary for the entity.", + "rdfs:domain": [ + "beckn:Item", + "beckn:Provider" + ], + "schema:rangeIncludes": "beckn:Rating" + }, + { + "@id": "beckn:validity", + "@type": "rdf:Property", + "rdfs:label": "Validity", + "rdfs:comment": "Validity window for the entity.", + "rdfs:domain": [ + "beckn:Offer", + "beckn:Catalog", + "beckn:Provider" + ], + "schema:rangeIncludes": "beckn:TimePeriod" + }, + { + "@id": "beckn:fulfillmentStatus", + "@type": "rdf:Property", + "rdfs:label": "Fulfillment status", + "rdfs:comment": "Lifecycle status for a fulfillment (e.g., PENDING, CONFIRMED, COMPLETED).", + "rdfs:domain": "beckn:Fulfillment", + "schema:rangeIncludes": "schema:Text", + "owl:equivalentProperty": "schema:orderStatus" + }, + { + "@id": "beckn:paymentStatus", + "@type": "rdf:Property", + "rdfs:label": "Payment status", + "rdfs:comment": "Lifecycle status for a payment (Pending, Authorized, Captured, Failed, Refunded, etc.).", + "rdfs:domain": "beckn:Payment", + "schema:rangeIncludes": "beckn:PaymentStatus", + "owl:equivalentProperty": "schema:paymentStatus" + }, + { + "@id": "beckn:trackingStatus", + "@type": "rdf:Property", + "rdfs:label": "Tracking status", + "rdfs:comment": "Status value for a tracking handle (active, disabled, completed).", + "rdfs:domain": "beckn:Tracking", + "schema:rangeIncludes": "beckn:TrackingStatus", + "owl:equivalentProperty": "schema:actionStatus" + }, + { + "@id": "beckn:TrackingStatus", + "@type": "schema:Enumeration", + "schema:name": "Tracking Status", + "rdfs:comment": "Enumeration of tracking lifecycle statuses for fulfillment handles.", + "schema:hasEnumerationMember": [ + { "@id": "beckn:TrackingActive" }, + { "@id": "beckn:TrackingDisabled" }, + { "@id": "beckn:TrackingCompleted" } + ] + }, + { + "@id": "beckn:TrackingActive", + "@type": [ + "beckn:TrackingStatus", + "schema:Enumeration" + ], + "schema:name": "ACTIVE", + "schema:identifier": "ACTIVE" + }, + { + "@id": "beckn:TrackingDisabled", + "@type": [ + "beckn:TrackingStatus", + "schema:Enumeration" + ], + "schema:name": "DISABLED", + "schema:identifier": "DISABLED" + }, + { + "@id": "beckn:TrackingCompleted", + "@type": [ + "beckn:TrackingStatus", + "schema:Enumeration" + ], + "schema:name": "COMPLETED", + "schema:identifier": "COMPLETED" + }, + { + "@id": "beckn:PaymentStatus", + "@type": "schema:Enumeration", + "schema:name": "Payment Status", + "rdfs:comment": "Enumeration of payment processing statuses used across the network.", + "schema:hasEnumerationMember": [ + { "@id": "beckn:PaymentInitiated" }, + { "@id": "beckn:PaymentPending" }, + { "@id": "beckn:PaymentAuthorized" }, + { "@id": "beckn:PaymentCaptured" }, + { "@id": "beckn:PaymentCompleted" }, + { "@id": "beckn:PaymentFailed" }, + { "@id": "beckn:PaymentCancelled" }, + { "@id": "beckn:PaymentRefunded" }, + { "@id": "beckn:PaymentPartiallyRefunded" }, + { "@id": "beckn:PaymentChargeback" }, + { "@id": "beckn:PaymentDisputed" }, + { "@id": "beckn:PaymentExpired" }, + { "@id": "beckn:PaymentReversed" }, + { "@id": "beckn:PaymentVoided" }, + { "@id": "beckn:PaymentSettled" }, + { "@id": "beckn:PaymentOnHold" }, + { "@id": "beckn:PaymentAdjusted" } + ] + }, + { + "@id": "beckn:PaymentInitiated", + "@type": [ + "beckn:PaymentStatus", + "schema:Enumeration" + ], + "schema:name": "INITIATED", + "schema:identifier": "INITIATED" + }, + { + "@id": "beckn:PaymentPending", + "@type": [ + "beckn:PaymentStatus", + "schema:Enumeration" + ], + "schema:name": "PENDING", + "schema:identifier": "PENDING" + }, + { + "@id": "beckn:PaymentAuthorized", + "@type": [ + "beckn:PaymentStatus", + "schema:Enumeration" + ], + "schema:name": "AUTHORIZED", + "schema:identifier": "AUTHORIZED" + }, + { + "@id": "beckn:PaymentCaptured", + "@type": [ + "beckn:PaymentStatus", + "schema:Enumeration" + ], + "schema:name": "CAPTURED", + "schema:identifier": "CAPTURED" + }, + { + "@id": "beckn:PaymentCompleted", + "@type": [ + "beckn:PaymentStatus", + "schema:Enumeration" + ], + "schema:name": "COMPLETED", + "schema:identifier": "COMPLETED" + }, + { + "@id": "beckn:PaymentFailed", + "@type": [ + "beckn:PaymentStatus", + "schema:Enumeration" + ], + "schema:name": "FAILED", + "schema:identifier": "FAILED" + }, + { + "@id": "beckn:PaymentCancelled", + "@type": [ + "beckn:PaymentStatus", + "schema:Enumeration" + ], + "schema:name": "CANCELLED", + "schema:identifier": "CANCELLED", + "schema:alternateName": "CANCELED" + }, + { + "@id": "beckn:PaymentRefunded", + "@type": [ + "beckn:PaymentStatus", + "schema:Enumeration" + ], + "schema:name": "REFUNDED", + "schema:identifier": "REFUNDED" + }, + { + "@id": "beckn:PaymentPartiallyRefunded", + "@type": [ + "beckn:PaymentStatus", + "schema:Enumeration" + ], + "schema:name": "PARTIALLY_REFUNDED", + "schema:identifier": "PARTIALLY_REFUNDED", + "schema:alternateName": "PARTIALLY-REFUNDED" + }, + { + "@id": "beckn:PaymentChargeback", + "@type": [ + "beckn:PaymentStatus", + "schema:Enumeration" + ], + "schema:name": "CHARGEBACK", + "schema:identifier": "CHARGEBACK" + }, + { + "@id": "beckn:PaymentDisputed", + "@type": [ + "beckn:PaymentStatus", + "schema:Enumeration" + ], + "schema:name": "DISPUTED", + "schema:identifier": "DISPUTED" + }, + { + "@id": "beckn:PaymentExpired", + "@type": [ + "beckn:PaymentStatus", + "schema:Enumeration" + ], + "schema:name": "EXPIRED", + "schema:identifier": "EXPIRED" + }, + { + "@id": "beckn:PaymentReversed", + "@type": [ + "beckn:PaymentStatus", + "schema:Enumeration" + ], + "schema:name": "REVERSED", + "schema:identifier": "REVERSED" + }, + { + "@id": "beckn:PaymentVoided", + "@type": [ + "beckn:PaymentStatus", + "schema:Enumeration" + ], + "schema:name": "VOIDED", + "schema:identifier": "VOIDED" + }, + { + "@id": "beckn:PaymentSettled", + "@type": [ + "beckn:PaymentStatus", + "schema:Enumeration" + ], + "schema:name": "SETTLED", + "schema:identifier": "SETTLED" + }, + { + "@id": "beckn:PaymentOnHold", + "@type": [ + "beckn:PaymentStatus", + "schema:Enumeration" + ], + "schema:name": "ON_HOLD", + "schema:identifier": "ON_HOLD", + "schema:alternateName": "ON-HOLD" + }, + { + "@id": "beckn:PaymentAdjusted", + "@type": [ + "beckn:PaymentStatus", + "schema:Enumeration" + ], + "schema:name": "ADJUSTED", + "schema:identifier": "ADJUSTED" + }, + { + "@id": "beckn:currency", + "@type": "rdf:Property", + "rdfs:label": "Currency", + "rdfs:comment": "ISO 4217 currency code associated with a price amount.", + "rdfs:domain": "beckn:PriceSpecification", + "schema:rangeIncludes": "schema:Text", + "owl:equivalentProperty": "schema:priceCurrency" + }, + { + "@id": "beckn:applicableQuantity", + "@type": "rdf:Property", + "rdfs:label": "Applicable quantity", + "rdfs:comment": "Quantity context for which the quoted price applies.", + "rdfs:domain": "beckn:PriceSpecification", + "schema:rangeIncludes": "beckn:Quantity", + "owl:equivalentProperty": "schema:eligibleQuantity" + }, + { + "@id": "beckn:components", + "@type": "rdf:Property", + "rdfs:label": "Price components", + "rdfs:comment": "Optional component breakdowns such as unit, tax, delivery, discount or surcharge.", + "rdfs:domain": "beckn:PriceSpecification", + "schema:rangeIncludes": [ + "schema:ItemList", + "schema:StructuredValue" + ] + }, + { + "@id": "beckn:unitText", + "@type": "rdf:Property", + "rdfs:label": "Unit text", + "rdfs:comment": "Human-readable unit for a quantitative value.", + "rdfs:domain": "beckn:Quantity", + "schema:rangeIncludes": "schema:Text", + "owl:equivalentProperty": "schema:unitText" + }, + { + "@id": "beckn:unitCode", + "@type": "rdf:Property", + "rdfs:label": "Unit code", + "rdfs:comment": "Code (UN/CEFACT, ISO) representing the measurement unit.", + "rdfs:domain": "beckn:Quantity", + "schema:rangeIncludes": "schema:Text", + "owl:equivalentProperty": "schema:unitCode" + }, + { + "@id": "beckn:unitQuantity", + "@type": "rdf:Property", + "rdfs:label": "Unit quantity", + "rdfs:comment": "Quantity of the referenced measurement unit.", + "rdfs:domain": "beckn:Quantity", + "schema:rangeIncludes": "schema:Number", + "owl:equivalentProperty": "schema:value" + }, + { + "@id": "beckn:validity", + "@type": "rdf:Property", + "rdfs:label": "Validity", + "rdfs:comment": "Validity window for the offer.", + "rdfs:domain": "beckn:Offer", + "schema:rangeIncludes": "beckn:TimePeriod" + }, + { + "@id": "beckn:itemCondition", + "@type": "rdf:Property", + "rdfs:label": "Item condition", + "rdfs:comment": "Condition of the item being offered.", + "rdfs:domain": "beckn:Offer", + "schema:rangeIncludes": "schema:Text" + }, + { + "@id": "beckn:eligibleRegion", + "@type": "rdf:Property", + "rdfs:label": "Eligible region", + "rdfs:comment": "The region(s) for which the offer is eligible.", + "rdfs:domain": "beckn:Offer", + "schema:rangeIncludes": "schema:DefinedRegion" + }, + { + "@id": "beckn:eligibleQuantity", + "@type": "rdf:Property", + "rdfs:label": "Eligible quantity", + "rdfs:comment": "Quantity constraints (min/max) for which the offer is eligible.", + "rdfs:domain": "beckn:Offer", + "schema:rangeIncludes": "beckn:Quantity" + }, + { + "@id": "beckn:addOns", + "@type": "rdf:Property", + "rdfs:label": "Add-on offers", + "rdfs:comment": "Optional extra offers that can be attached.", + "rdfs:domain": "beckn:Offer", + "schema:rangeIncludes": [ + "schema:ItemList", + "beckn:Offer" + ] + }, + { + "@id": "beckn:addOnItems", + "@type": "rdf:Property", + "rdfs:label": "Add-on items", + "rdfs:comment": "Optional extras modeled as items.", + "rdfs:domain": "beckn:Offer", + "schema:rangeIncludes": [ + "schema:ItemList", + "beckn:Item", + "schema:Text" + ] + }, + { + "@id": "beckn:offerAttributes", + "@type": "rdf:Property", + "rdfs:label": "Offer attributes", + "rdfs:comment": "Attribute pack for offer terms and pricing models.", + "rdfs:domain": "beckn:Offer", + "schema:rangeIncludes": "beckn:Attributes" + }, + { + "@id": "beckn:orderItems", + "@type": "rdf:Property", + "rdfs:label": "Order items", + "rdfs:comment": "Items included in the order.", + "rdfs:domain": "beckn:Order", + "schema:rangeIncludes": [ + "schema:ItemList", + "beckn:OrderItem" + ] + }, + { + "@id": "beckn:acceptedOffers", + "@type": "rdf:Property", + "rdfs:label": "Accepted offers", + "rdfs:comment": "Offers accepted as part of an order.", + "rdfs:domain": "beckn:Order", + "schema:rangeIncludes": [ + "schema:ItemList", + "beckn:Offer" + ] + }, + { + "@id": "beckn:orderValue", + "@type": "rdf:Property", + "rdfs:label": "Order value", + "rdfs:comment": "Total order value as a price specification.", + "rdfs:domain": "beckn:Order", + "schema:rangeIncludes": "schema:PriceSpecification" + }, + { + "@id": "beckn:OrderStatus", + "@type": "schema:Enumeration", + "schema:name": "Order Status", + "rdfs:comment": "Enumeration of order lifecycle statuses.", + "schema:hasEnumerationMember": [ + { "@id": "beckn:OrderCreated" }, + { "@id": "beckn:OrderPending" }, + { "@id": "beckn:OrderConfirmed" }, + { "@id": "beckn:OrderInProgress" }, + { "@id": "beckn:OrderPartiallyFulfilled" }, + { "@id": "beckn:OrderCompleted" }, + { "@id": "beckn:OrderCancelled" }, + { "@id": "beckn:OrderRejected" }, + { "@id": "beckn:OrderFailed" }, + { "@id": "beckn:OrderReturned" }, + { "@id": "beckn:OrderRefunded" }, + { "@id": "beckn:OrderOnHold" } + ] + }, + { + "@id": "beckn:OrderCreated", + "@type": [ + "beckn:OrderStatus", + "schema:Enumeration" + ], + "schema:name": "CREATED", + "schema:identifier": "CREATED" + }, + { + "@id": "beckn:OrderPending", + "@type": [ + "beckn:OrderStatus", + "schema:Enumeration" + ], + "schema:name": "PENDING", + "schema:identifier": "PENDING" + }, + { + "@id": "beckn:OrderConfirmed", + "@type": [ + "beckn:OrderStatus", + "schema:Enumeration" + ], + "schema:name": "CONFIRMED", + "schema:identifier": "CONFIRMED" + }, + { + "@id": "beckn:OrderInProgress", + "@type": [ + "beckn:OrderStatus", + "schema:Enumeration" + ], + "schema:name": "INPROGRESS", + "schema:identifier": "INPROGRESS" + }, + { + "@id": "beckn:OrderPartiallyFulfilled", + "@type": [ + "beckn:OrderStatus", + "schema:Enumeration" + ], + "schema:name": "PARTIALLYFULFILLED", + "schema:identifier": "PARTIALLYFULFILLED" + }, + { + "@id": "beckn:OrderCompleted", + "@type": [ + "beckn:OrderStatus", + "schema:Enumeration" + ], + "schema:name": "COMPLETED", + "schema:identifier": "COMPLETED" + }, + { + "@id": "beckn:OrderCancelled", + "@type": [ + "beckn:OrderStatus", + "schema:Enumeration" + ], + "schema:name": "CANCELLED", + "schema:identifier": "CANCELLED" + }, + { + "@id": "beckn:OrderRejected", + "@type": [ + "beckn:OrderStatus", + "schema:Enumeration" + ], + "schema:name": "REJECTED", + "schema:identifier": "REJECTED" + }, + { + "@id": "beckn:OrderFailed", + "@type": [ + "beckn:OrderStatus", + "schema:Enumeration" + ], + "schema:name": "FAILED", + "schema:identifier": "FAILED" + }, + { + "@id": "beckn:OrderReturned", + "@type": [ + "beckn:OrderStatus", + "schema:Enumeration" + ], + "schema:name": "RETURNED", + "schema:identifier": "RETURNED" + }, + { + "@id": "beckn:OrderRefunded", + "@type": [ + "beckn:OrderStatus", + "schema:Enumeration" + ], + "schema:name": "REFUNDED", + "schema:identifier": "REFUNDED" + }, + { + "@id": "beckn:OrderOnHold", + "@type": [ + "beckn:OrderStatus", + "schema:Enumeration" + ], + "schema:name": "ONHOLD", + "schema:identifier": "ONHOLD", + "schema:alternateName": "ON-HOLD" + }, + { + "@id": "beckn:buyer", + "@type": "rdf:Property", + "rdfs:label": "Buyer", + "rdfs:comment": "Buyer associated with an order.", + "rdfs:domain": "beckn:Order", + "schema:rangeIncludes": "beckn:Buyer" + }, + { + "@id": "beckn:orderStatus", + "@type": "rdf:Property", + "rdfs:label": "Order status", + "rdfs:comment": "Order status/state.", + "rdfs:domain": "beckn:Order", + "schema:rangeIncludes": "beckn:OrderStatus" + }, + { + "@id": "beckn:orderNumber", + "@type": "rdf:Property", + "rdfs:label": "Order number", + "rdfs:comment": "Human-visible order number.", + "rdfs:domain": "beckn:Order", + "schema:rangeIncludes": "schema:Text" + }, + { + "@id": "beckn:seller", + "@type": "rdf:Property", + "rdfs:label": "Seller", + "rdfs:comment": "Seller or provider associated with an order.", + "rdfs:domain": "beckn:Order", + "schema:rangeIncludes": "beckn:Provider" + }, + { + "@id": "beckn:invoice", + "@type": "rdf:Property", + "rdfs:label": "Invoice", + "rdfs:comment": "Invoice reference/summary for the order.", + "rdfs:domain": "beckn:Order", + "schema:rangeIncludes": "beckn:Invoice" + }, + { + "@id": "beckn:orderAttributes", + "@type": "rdf:Property", + "rdfs:label": "Order attributes", + "rdfs:comment": "Order-level attribute pack.", + "rdfs:domain": "beckn:Order", + "schema:rangeIncludes": "beckn:Attributes" + }, + { + "@id": "beckn:address", + "@type": "rdf:Property", + "rdfs:label": "Address", + "rdfs:comment": "Postal address for a location.", + "rdfs:domain": "beckn:Location", + "schema:rangeIncludes": "beckn:Address" + }, + { + "@id": "beckn:geo", + "@type": "rdf:Property", + "rdfs:label": "Geo", + "rdfs:comment": "GeoJSON geometry for the location.", + "rdfs:domain": "beckn:Location", + "schema:rangeIncludes": "beckn:GeoJSONGeometry" + }, + { + "@id": "beckn:startDate", + "@type": "rdf:Property", + "rdfs:label": "Start date", + "rdfs:comment": "Start date-time of a period (UTC).", + "rdfs:domain": "beckn:TimePeriod", + "schema:rangeIncludes": "schema:DateTime" + }, + { + "@id": "beckn:endDate", + "@type": "rdf:Property", + "rdfs:label": "End date", + "rdfs:comment": "End date-time of a period (UTC).", + "rdfs:domain": "beckn:TimePeriod", + "schema:rangeIncludes": "schema:DateTime" + }, + { + "@id": "beckn:startTime", + "@type": "rdf:Property", + "rdfs:label": "Start time", + "rdfs:comment": "Start time of a period.", + "rdfs:domain": "beckn:TimePeriod", + "schema:rangeIncludes": "schema:Time" + }, + { + "@id": "beckn:endTime", + "@type": "rdf:Property", + "rdfs:label": "End time", + "rdfs:comment": "End time of a period.", + "rdfs:domain": "beckn:TimePeriod", + "schema:rangeIncludes": "schema:Time" + }, + { + "@id": "beckn:ratingValue", + "@type": "rdf:Property", + "rdfs:label": "Rating value", + "rdfs:comment": "Numeric rating score.", + "rdfs:domain": "beckn:Rating", + "schema:rangeIncludes": "schema:Number" + }, + { + "@id": "beckn:ratingCount", + "@type": "rdf:Property", + "rdfs:label": "Rating count", + "rdfs:comment": "Number of individual ratings aggregated for this entity.", + "rdfs:domain": "beckn:Rating", + "schema:rangeIncludes": "schema:Integer" + }, + { + "@id": "beckn:reviewText", + "@type": "rdf:Property", + "rdfs:label": "Review text", + "rdfs:comment": "Free-form review text.", + "rdfs:domain": "beckn:Rating", + "schema:rangeIncludes": "schema:Text" + }, + { + "@id": "beckn:errorCode", + "@type": "rdf:Property", + "rdfs:label": "Error code", + "rdfs:comment": "Machine-readable error code.", + "rdfs:domain": "beckn:Error", + "schema:rangeIncludes": "schema:Text" + }, + { + "@id": "beckn:errorMessage", + "@type": "rdf:Property", + "rdfs:label": "Error message", + "rdfs:comment": "Human-readable error message.", + "rdfs:domain": "beckn:Error", + "schema:rangeIncludes": "schema:Text" + }, + { + "@id": "beckn:errorDetails", + "@type": "rdf:Property", + "rdfs:label": "Error details", + "rdfs:comment": "Additional error details.", + "rdfs:domain": "beckn:Error", + "schema:rangeIncludes": "schema:Text" + }, + { + "@id": "beckn:trackAction", + "@type": "rdf:Property", + "rdfs:label": "Track action", + "rdfs:comment": "Tracking entry point for a fulfillment.", + "rdfs:domain": "beckn:Fulfillment", + "schema:rangeIncludes": "beckn:TrackAction" + }, + { + "@id": "beckn:tracking", + "@type": "rdf:Property", + "rdfs:label": "Tracking", + "rdfs:comment": "Tracking metadata including URLs and status.", + "rdfs:domain": "beckn:Fulfillment", + "schema:rangeIncludes": "beckn:Tracking" + }, + { + "@id": "beckn:mode", + "@type": "rdf:Property", + "rdfs:label": "Fulfillment mode", + "rdfs:comment": "Mode for fulfilling an order (e.g., DELIVERY, PICKUP, RESERVATION, DIGITAL).", + "rdfs:domain": "beckn:Fulfillment", + "schema:rangeIncludes": "schema:Text" + }, + { + "@id": "beckn:trackingAction", + "@type": "rdf:Property", + "rdfs:label": "Tracking action", + "rdfs:comment": "Entry point for tracking this fulfillment.", + "rdfs:domain": "beckn:Fulfillment", + "schema:rangeIncludes": "beckn:TrackAction" + }, + { + "@id": "beckn:deliveryAttributes", + "@type": "rdf:Property", + "rdfs:label": "Delivery attributes", + "rdfs:comment": "Attribute pack for fulfillment mode details.", + "rdfs:domain": "beckn:Fulfillment", + "schema:rangeIncludes": "beckn:Attributes" + }, + { + "@id": "beckn:availableAt", + "@type": "rdf:Property", + "rdfs:label": "Available at", + "rdfs:comment": "Physical locations where the item is available.", + "rdfs:domain": "beckn:Item", + "schema:rangeIncludes": [ + "schema:ItemList", + "beckn:Location" + ] + }, + { + "@id": "beckn:availabilityWindow", + "@type": "rdf:Property", + "rdfs:label": "Availability window", + "rdfs:comment": "Time periods when the item is available.", + "rdfs:domain": "beckn:Item", + "schema:rangeIncludes": [ + "schema:ItemList", + "beckn:TimePeriod" + ] + }, + { + "@id": "beckn:networkId", + "@type": "rdf:Property", + "rdfs:label": "Network ID", + "rdfs:comment": "A unique identifier representing a group of platforms. By default, it is the url of the network registry on the Beckn network", + "rdfs:domain": [ + "beckn:Context", + "beckn:Item" + ], + "schema:rangeIncludes": "schema:Text" + }, + { + "@id": "beckn:itemAttributes", + "@type": "rdf:Property", + "rdfs:label": "Item attributes", + "rdfs:comment": "Domain-specific attribute pack for the item.", + "rdfs:domain": "beckn:Item", + "schema:rangeIncludes": "beckn:Attributes" + }, + { + "@id": "beckn:providerId", + "@type": "rdf:Property", + "rdfs:label": "Provider identifier", + "rdfs:comment": "Identifier of the provider who owns this catalog.", + "rdfs:domain": "beckn:Catalog", + "schema:rangeIncludes": "schema:Text" + }, + { + "@id": "beckn:bppId", + "@type": "rdf:Property", + "rdfs:label": "BPP identifier", + "rdfs:comment": "BPP (Beckn Protocol Provider) identifier that publishes this catalog.", + "rdfs:domain": "beckn:Catalog", + "schema:rangeIncludes": "schema:Text" + }, + { + "@id": "beckn:bppUri", + "@type": "rdf:Property", + "rdfs:label": "BPP URI", + "rdfs:comment": "BPP (Beckn Protocol Provider) URI endpoint.", + "rdfs:domain": "beckn:Catalog", + "schema:rangeIncludes": "schema:URL" + }, + { + "@id": "beckn:offers", + "@type": "rdf:Property", + "rdfs:label": "Offers", + "rdfs:comment": "Commercial offers in this catalog.", + "rdfs:domain": "beckn:Catalog", + "schema:rangeIncludes": [ + "schema:ItemList", + "beckn:Offer" + ] + }, + { + "@id": "beckn:locations", + "@type": "rdf:Property", + "rdfs:label": "Locations", + "rdfs:comment": "Physical locations where the provider operates.", + "rdfs:domain": "beckn:Provider", + "schema:rangeIncludes": [ + "schema:ItemList", + "beckn:Location" + ] + }, + { + "@id": "beckn:providerAttributes", + "@type": "rdf:Property", + "rdfs:label": "Provider attributes", + "rdfs:comment": "Attribute pack for provider-level metadata.", + "rdfs:domain": "beckn:Provider", + "schema:rangeIncludes": "beckn:Attributes" + }, + { + "@id": "beckn:lineId", + "@type": "rdf:Property", + "rdfs:label": "Line identifier", + "rdfs:comment": "Unique line id within order.", + "rdfs:domain": "beckn:OrderItem", + "schema:rangeIncludes": "schema:Text" + }, + { + "@id": "beckn:orderedItem", + "@type": "rdf:Property", + "rdfs:label": "Ordered item", + "rdfs:comment": "Catalog item referenced in the order line.", + "rdfs:domain": "beckn:OrderItem", + "schema:rangeIncludes": [ + "beckn:Item", + "schema:Text" + ] + }, + { + "@id": "beckn:acceptedOffer", + "@type": "rdf:Property", + "rdfs:label": "Accepted offer (line)", + "rdfs:comment": "Offer applied to this line.", + "rdfs:domain": "beckn:OrderItem", + "schema:rangeIncludes": "beckn:Offer" + }, + { + "@id": "beckn:quantity", + "@type": "rdf:Property", + "rdfs:label": "Quantity", + "rdfs:comment": "Ordered quantity for this line.", + "rdfs:domain": "beckn:OrderItem", + "schema:rangeIncludes": "beckn:Quantity" + }, + { + "@id": "beckn:orderItemAttributes", + "@type": "rdf:Property", + "rdfs:label": "Order item attributes", + "rdfs:comment": "Line-level attribute pack.", + "rdfs:domain": "beckn:OrderItem", + "schema:rangeIncludes": "beckn:Attributes" + }, + { + "@id": "beckn:number", + "@type": "rdf:Property", + "rdfs:label": "Document number", + "rdfs:comment": "Human-visible invoice number.", + "rdfs:domain": "beckn:Invoice", + "schema:rangeIncludes": "schema:Text" + }, + { + "@id": "beckn:issueDate", + "@type": "rdf:Property", + "rdfs:label": "Issue date", + "rdfs:comment": "Invoice issue date.", + "rdfs:domain": "beckn:Invoice", + "schema:rangeIncludes": "schema:Date" + }, + { + "@id": "beckn:dueDate", + "@type": "rdf:Property", + "rdfs:label": "Due date", + "rdfs:comment": "Payment due date for the invoice.", + "rdfs:domain": "beckn:Invoice", + "schema:rangeIncludes": "schema:Date" + }, + { + "@id": "beckn:payee", + "@type": "rdf:Property", + "rdfs:label": "Payee", + "rdfs:comment": "Seller / issuer of the invoice.", + "rdfs:domain": "beckn:Invoice", + "schema:rangeIncludes": "beckn:Provider" + }, + { + "@id": "beckn:payer", + "@type": "rdf:Property", + "rdfs:label": "Payer", + "rdfs:comment": "Buyer being invoiced.", + "rdfs:domain": "beckn:Invoice", + "schema:rangeIncludes": "beckn:Buyer" + }, + { + "@id": "beckn:totals", + "@type": "rdf:Property", + "rdfs:label": "Totals", + "rdfs:comment": "Invoice totals as a price specification.", + "rdfs:domain": "beckn:Invoice", + "schema:rangeIncludes": "schema:PriceSpecification" + }, + { + "@id": "beckn:invoiceAttributes", + "@type": "rdf:Property", + "rdfs:label": "Invoice attributes", + "rdfs:comment": "Invoice-level attribute pack.", + "rdfs:domain": "beckn:Invoice", + "schema:rangeIncludes": "beckn:Attributes" + }, + { + "@id": "beckn:method", + "@type": "rdf:Property", + "rdfs:label": "Payment method", + "rdfs:comment": "The payment rail/method used (e.g., UPI, Card, BNPL).", + "rdfs:domain": "beckn:Payment", + "schema:rangeIncludes": "schema:Text" + }, + { + "@id": "beckn:amount", + "@type": "rdf:Property", + "rdfs:label": "Amount", + "rdfs:comment": "Amount associated with this payment action.", + "rdfs:domain": "beckn:Payment", + "schema:rangeIncludes": "schema:MonetaryAmount" + }, + { + "@id": "beckn:paymentURL", + "@type": "rdf:Property", + "rdfs:label": "Payment URL", + "rdfs:comment": "URL for payment processing/redirection.", + "rdfs:domain": "beckn:Payment", + "schema:rangeIncludes": "schema:URL" + }, + { + "@id": "beckn:txnRef", + "@type": "rdf:Property", + "rdfs:label": "Transaction reference", + "rdfs:comment": "PSP/gateway/bank transaction reference.", + "rdfs:domain": "beckn:Payment", + "schema:rangeIncludes": "schema:Text" + }, + { + "@id": "beckn:paidAt", + "@type": "rdf:Property", + "rdfs:label": "Paid at", + "rdfs:comment": "Timestamp of last terminal payment event.", + "rdfs:domain": "beckn:Payment", + "schema:rangeIncludes": "schema:DateTime" + }, + { + "@id": "beckn:beneficiary", + "@type": "rdf:Property", + "rdfs:label": "Beneficiary", + "rdfs:comment": "Beneficiary/recipient of the payment.", + "rdfs:domain": "beckn:Payment", + "schema:rangeIncludes": "beckn:Beneficiary" + }, + { + "@id": "beckn:paymentAttributes", + "@type": "rdf:Property", + "rdfs:label": "Payment attributes", + "rdfs:comment": "Rail-specific payment attribute pack.", + "rdfs:domain": "beckn:Payment", + "schema:rangeIncludes": "beckn:Attributes" + }, + { + "@id": "beckn:Beneficiary", + "@type": "schema:Enumeration", + "schema:name": "Beneficiary", + "rdfs:comment": "Enumeration of parties who can receive a payment in the Beckn network.", + "schema:hasEnumerationMember": [ + { "@id": "beckn:BPP" }, + { "@id": "beckn:BAP" } + ] + }, + { + "@id": "beckn:BPP", + "@type": [ + "beckn:Beneficiary", + "schema:Enumeration" + ], + "schema:name": "BPP", + "schema:identifier": "BPP" + }, + { + "@id": "beckn:BAP", + "@type": [ + "beckn:Beneficiary", + "schema:Enumeration" + ], + "schema:name": "BAP", + "schema:identifier": "BAP" + }, + { + "@id": "beckn:role", + "@type": "rdf:Property", + "rdfs:label": "Role", + "rdfs:comment": "Functional role of the buyer in the transaction.", + "rdfs:domain": "beckn:Buyer", + "schema:rangeIncludes": "schema:Text" + }, + { + "@id": "beckn:displayName", + "@type": "rdf:Property", + "rdfs:label": "Display name", + "rdfs:comment": "Human-readable display name for the buyer.", + "rdfs:domain": "beckn:Buyer", + "schema:rangeIncludes": "schema:Text" + }, + { + "@id": "schema:telephone", + "@type": "rdf:Property", + "rdfs:label": "Telephone number", + "rdfs:comment": "Telephone number", + "rdfs:domain": "beckn:Buyer", + "schema:rangeIncludes": "schema:Text" + }, + { + "@id": "schema:email", + "@type": "rdf:Property", + "rdfs:label": "Email Address", + "rdfs:comment": "Email Address", + "rdfs:domain": "beckn:Buyer", + "schema:rangeIncludes": "schema:Text" + }, + { + "@id": "beckn:taxID", + "@type": "rdf:Property", + "rdfs:label": "Tax ID", + "rdfs:comment": "Tax identifier for the buyer.", + "rdfs:domain": "beckn:Buyer", + "schema:rangeIncludes": "schema:Text" + }, + { + "@id": "beckn:buyerAttributes", + "@type": "rdf:Property", + "rdfs:label": "Buyer attributes", + "rdfs:comment": "Attribute pack for buyer identity and preferences.", + "rdfs:domain": "beckn:Buyer", + "schema:rangeIncludes": "beckn:Attributes" + }, + { + "@id": "beckn:phone", + "@type": "rdf:Property", + "rdfs:label": "Phone", + "rdfs:comment": "Telephone number for support.", + "rdfs:domain": "beckn:SupportInfo", + "schema:rangeIncludes": "schema:Text" + }, + { + "@id": "beckn:email", + "@type": "rdf:Property", + "rdfs:label": "Email", + "rdfs:comment": "Support email address.", + "rdfs:domain": "beckn:SupportInfo", + "schema:rangeIncludes": "schema:Text" + }, + { + "@id": "beckn:hours", + "@type": "rdf:Property", + "rdfs:label": "Support hours", + "rdfs:comment": "Human-readable support hours.", + "rdfs:domain": "beckn:SupportInfo", + "schema:rangeIncludes": "schema:Text" + }, + { + "@id": "beckn:channels", + "@type": "rdf:Property", + "rdfs:label": "Channels", + "rdfs:comment": "Available support channels.", + "rdfs:domain": "beckn:SupportInfo", + "schema:rangeIncludes": [ + "schema:ItemList", + "beckn:SupportChannel" + ] + }, + { + "@id": "beckn:tlMethod", + "@type": "rdf:Property", + "rdfs:label": "Transport layer method", + "rdfs:comment": "Transport layer method used to access the tracking handle.", + "rdfs:domain": "beckn:Tracking", + "schema:rangeIncludes": "schema:Text" + }, + { + "@id": "beckn:expiresAt", + "@type": "rdf:Property", + "rdfs:label": "Expires at", + "rdfs:comment": "Expiry timestamp for the tracking handle.", + "rdfs:domain": "beckn:Tracking", + "schema:rangeIncludes": "schema:DateTime" + }, + { + "@id": "beckn:SupportChannel", + "@type": "schema:Enumeration", + "schema:name": "Support Channel", + "rdfs:comment": "Enumeration of supported customer service channels.", + "schema:hasEnumerationMember": [ + { "@id": "beckn:SupportChannelPhone" }, + { "@id": "beckn:SupportChannelEmail" }, + { "@id": "beckn:SupportChannelWeb" }, + { "@id": "beckn:SupportChannelChat" }, + { "@id": "beckn:SupportChannelWhatsApp" }, + { "@id": "beckn:SupportChannelInApp" }, + { "@id": "beckn:SupportChannelOther" } + ] + }, + { + "@id": "beckn:SupportChannelPhone", + "@type": [ + "beckn:SupportChannel", + "schema:Enumeration" + ], + "schema:name": "PHONE", + "schema:identifier": "PHONE" + }, + { + "@id": "beckn:SupportChannelEmail", + "@type": [ + "beckn:SupportChannel", + "schema:Enumeration" + ], + "schema:name": "EMAIL", + "schema:identifier": "EMAIL" + }, + { + "@id": "beckn:SupportChannelWeb", + "@type": [ + "beckn:SupportChannel", + "schema:Enumeration" + ], + "schema:name": "WEB", + "schema:identifier": "WEB" + }, + { + "@id": "beckn:SupportChannelChat", + "@type": [ + "beckn:SupportChannel", + "schema:Enumeration" + ], + "schema:name": "CHAT", + "schema:identifier": "CHAT" + }, + { + "@id": "beckn:SupportChannelWhatsApp", + "@type": [ + "beckn:SupportChannel", + "schema:Enumeration" + ], + "schema:name": "WHATSAPP", + "schema:identifier": "WHATSAPP", + "schema:alternateName": "WHATS_APP" + }, + { + "@id": "beckn:SupportChannelInApp", + "@type": [ + "beckn:SupportChannel", + "schema:Enumeration" + ], + "schema:name": "IN_APP", + "schema:identifier": "IN_APP", + "schema:alternateName": "IN-APP" + }, + { + "@id": "beckn:SupportChannelOther", + "@type": [ + "beckn:SupportChannel", + "schema:Enumeration" + ], + "schema:name": "OTHER", + "schema:identifier": "OTHER" + }, + { + "@id": "beckn:ratingValue", + "@type": "rdf:Property", + "rdfs:label": "Rating value", + "rdfs:comment": "Numeric rating value (legacy usually 1–5).", + "rdfs:domain": "beckn:RatingInput", + "schema:rangeIncludes": "schema:Number" + }, + { + "@id": "beckn:bestRating", + "@type": "rdf:Property", + "rdfs:label": "Best rating", + "rdfs:comment": "Maximum of the rating scale (default 5 if omitted).", + "rdfs:domain": "beckn:RatingInput", + "schema:rangeIncludes": "schema:Number" + }, + { + "@id": "beckn:worstRating", + "@type": "rdf:Property", + "rdfs:label": "Worst rating", + "rdfs:comment": "Minimum of the rating scale (default 1 or 0 if omitted).", + "rdfs:domain": "beckn:RatingInput", + "schema:rangeIncludes": "schema:Number" + }, + { + "@id": "beckn:category", + "@type": "rdf:Property", + "rdfs:label": "Category", + "rdfs:comment": "What is being rated.", + "rdfs:domain": "beckn:RatingInput", + "schema:rangeIncludes": "schema:Text" + }, + { + "@id": "beckn:feedback", + "@type": "rdf:Property", + "rdfs:label": "Feedback", + "rdfs:comment": "Feedback object containing comments and tags.", + "rdfs:domain": "beckn:RatingInput", + "schema:rangeIncludes": "schema:Thing" + }, + { + "@id": "beckn:shortDesc", + "@type": "rdf:Property", + "rdfs:label": "Short description", + "rdfs:comment": "Short description for display.", + "rdfs:domain": "beckn:Descriptor", + "schema:rangeIncludes": "schema:Text" + }, + { + "@id": "beckn:longDesc", + "@type": "rdf:Property", + "rdfs:label": "Long description", + "rdfs:comment": "Detailed description text.", + "rdfs:domain": "beckn:Descriptor", + "schema:rangeIncludes": "schema:Text" + }, + { + "@id": "beckn:Feature", + "@type": "rdfs:Class", + "rdfs:label": "Feature", + "rdfs:comment": "A generic capability/amenity/attribute of an offering or provider (e.g., accessibility, connectivity, inclusions).", + "rdfs:subClassOf": "schema:DefinedTerm" + }, + { + "@id": "beckn:Policy", + "@type": "rdfs:Class", + "rdfs:label": "Policy", + "rdfs:comment": "A generic policy artifact describing rules/terms applicable to providers, offerings, orders, or fulfillments.", + "rdfs:subClassOf": "schema:CreativeWork" + }, + { + "@id": "beckn:Constraint", + "@type": "rdfs:Class", + "rdfs:label": "Constraint", + "rdfs:comment": "A generic quantitative or logical constraint applicable to an item or offer (e.g., max duration, max distance, limits).", + "rdfs:subClassOf": "schema:Intangible" + }, + { + "@id": "beckn:Participant", + "@type": "rdfs:Class", + "rdfs:label": "Participant", + "rdfs:comment": "A participant in a transaction with a role (buyer, recipient, rider, patient, operator, etc.).", + "rdfs:subClassOf": "schema:Person" + }, + { + "@id": "beckn:Skill", + "@type": "rdfs:Class", + "rdfs:label": "Skill", + "rdfs:comment": "A skill/competency term applicable to a participant or provider agent.", + "rdfs:subClassOf": "schema:DefinedTerm" + }, + { + "@id": "beckn:Credential", + "@type": "rdfs:Class", + "rdfs:label": "Credential", + "rdfs:comment": "A credential or qualification held by a participant (license, certification, permit, badge, etc.).", + "rdfs:subClassOf": "schema:EducationalOccupationalCredential" + }, + { + "@id": "beckn:Instruction", + "@type": "rdfs:Class", + "rdfs:label": "Instruction", + "rdfs:comment": "Contextual instructions associated with a fulfillment stop, order, or location (e.g., access, pickup, handover).", + "rdfs:subClassOf": "schema:CreativeWork" + }, + { + "@id": "beckn:Entitlement", + "@type": "rdfs:Class", + "rdfs:label": "Entitlement", + "rdfs:comment": "An entitlement/access artifact issued as part of an order (ticket, boarding pass, voucher, permit, token).", + "rdfs:subClassOf": "schema:Ticket" + }, + { + "@id": "beckn:Alert", + "@type": "rdfs:Class", + "rdfs:label": "Alert", + "rdfs:comment": "An alert/notice affecting services, orders, or fulfillments (delay, cancellation, recall, advisory).", + "rdfs:subClassOf": "schema:Event" + }, + { + "@id": "beckn:PriceComponent", + "@type": "rdfs:Class", + "rdfs:label": "Price component", + "rdfs:comment": "A component/line item contributing to a total price (tax, fee, surcharge, discount).", + "rdfs:subClassOf": "schema:PriceSpecification" + }, + { + "@id": "beckn:State", + "@type": "rdfs:Class", + "rdfs:label": "State", + "rdfs:comment": "A generic state label for an entity (order state, fulfillment state, payment state) with extensible vocabularies.", + "rdfs:subClassOf": "schema:DefinedTerm" + }, + { + "@id": "beckn:FulfillmentStop", + "@type": "rdfs:Class", + "rdfs:label": "Fulfillment stop", + "rdfs:comment": "A typed stop/milestone within a fulfillment plan, with location/time/instructions.", + "rdfs:subClassOf": "schema:Intangible" + }, + { + "@id": "beckn:features", + "@type": "rdf:Property", + "rdfs:label": "Features", + "rdfs:comment": "Features/capabilities applicable to an entity.", + "rdfs:domain": [ + "beckn:Item", + "beckn:Offer", + "beckn:Provider", + "beckn:Fulfillment" + ], + "schema:rangeIncludes": "beckn:Feature" + }, + { + "@id": "beckn:policies", + "@type": "rdf:Property", + "rdfs:label": "Policies", + "rdfs:comment": "Policies applicable to an entity.", + "rdfs:domain": [ + "beckn:Provider", + "beckn:Item", + "beckn:Offer", + "beckn:Order", + "beckn:Fulfillment" + ], + "schema:rangeIncludes": "beckn:Policy" + }, + { + "@id": "beckn:constraints", + "@type": "rdf:Property", + "rdfs:label": "Constraints", + "rdfs:comment": "Constraints/limits applicable to an item or offer.", + "rdfs:domain": [ + "beckn:Item", + "beckn:Offer" + ], + "schema:rangeIncludes": "beckn:Constraint" + }, + { + "@id": "beckn:participants", + "@type": "rdf:Property", + "rdfs:label": "Participants", + "rdfs:comment": "Participants associated with an order or fulfillment.", + "rdfs:domain": [ + "beckn:Order", + "beckn:Fulfillment" + ], + "schema:rangeIncludes": "beckn:Participant" + }, + { + "@id": "beckn:skills", + "@type": "rdf:Property", + "rdfs:label": "Skills", + "rdfs:comment": "Skills associated with a participant.", + "rdfs:domain": [ + "beckn:Participant" + ], + "schema:rangeIncludes": "beckn:Skill" + }, + { + "@id": "beckn:credentials", + "@type": "rdf:Property", + "rdfs:label": "Credentials", + "rdfs:comment": "Credentials associated with a participant.", + "rdfs:domain": [ + "beckn:Participant" + ], + "schema:rangeIncludes": "beckn:Credential" + }, + { + "@id": "beckn:instructions", + "@type": "rdf:Property", + "rdfs:label": "Instructions", + "rdfs:comment": "Instructions applicable to an entity (e.g., stop-level access/pickup/handover instructions).", + "rdfs:domain": [ + "beckn:Order", + "beckn:Fulfillment", + "beckn:FulfillmentStop", + "beckn:Location" + ], + "schema:rangeIncludes": "beckn:Instruction" + }, + { + "@id": "beckn:entitlements", + "@type": "rdf:Property", + "rdfs:label": "Entitlements", + "rdfs:comment": "Entitlements issued under an order or fulfillment.", + "rdfs:domain": [ + "beckn:Order", + "beckn:Fulfillment" + ], + "schema:rangeIncludes": "beckn:Entitlement" + }, + { + "@id": "beckn:alerts", + "@type": "rdf:Property", + "rdfs:label": "Alerts", + "rdfs:comment": "Alerts applicable to a provider, order, or fulfillment.", + "rdfs:domain": [ + "beckn:Provider", + "beckn:Order", + "beckn:Fulfillment" + ], + "schema:rangeIncludes": "beckn:Alert" + }, + { + "@id": "beckn:priceComponents", + "@type": "rdf:Property", + "rdfs:label": "Price components", + "rdfs:comment": "Breakdown line items that compose a total price.", + "rdfs:domain": [ + "beckn:PriceSpecification", + "beckn:Invoice" + ], + "schema:rangeIncludes": "beckn:PriceComponent" + }, + { + "@id": "beckn:state", + "@type": "rdf:Property", + "rdfs:label": "State", + "rdfs:comment": "The current state of an entity.", + "rdfs:domain": [ + "beckn:Order", + "beckn:Fulfillment", + "beckn:Payment", + "beckn:Tracking" + ], + "schema:rangeIncludes": "beckn:State" + }, + { + "@id": "beckn:stops", + "@type": "rdf:Property", + "rdfs:label": "Stops", + "rdfs:comment": "Stops/milestones within a fulfillment plan.", + "rdfs:domain": [ + "beckn:Fulfillment" + ], + "schema:rangeIncludes": "beckn:FulfillmentStop" + }, + { + "@id": "beckn:stopType", + "@type": "rdf:Property", + "rdfs:label": "Stop type", + "rdfs:comment": "A typed role/kind of fulfillment stop (pickup, dropoff, hub, checkpoint, etc.).", + "rdfs:domain": [ + "beckn:FulfillmentStop" + ], + "schema:rangeIncludes": "schema:Text" + }, + { + "@id": "beckn:severity", + "@type": "rdf:Property", + "rdfs:label": "Severity", + "rdfs:comment": "Severity level for an alert.", + "rdfs:domain": [ + "beckn:Alert" + ], + "schema:rangeIncludes": "schema:Text" + } + ] +} \ No newline at end of file diff --git a/schema/core/v2/attributes.yaml b/schema/core/v2/attributes.yaml index dafa695..dd0e36e 100644 --- a/schema/core/v2/attributes.yaml +++ b/schema/core/v2/attributes.yaml @@ -16,14 +16,26 @@ components: schemas: Catalog: type: object - required: ["@context", "@type", "beckn:id", "beckn:descriptor", "beckn:bppId", "beckn:bppUri", "beckn:items"] + required: + [ + "@context", + "@type", + "beckn:id", + "beckn:descriptor", + "beckn:bppId", + "beckn:bppUri", + "beckn:items", + ] additionalProperties: false properties: "@context": type: string format: uri description: JSON-LD context URI for the core Catalog schema - enum: ["https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/context.jsonld"] + enum: + [ + "https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/context.jsonld", + ] "@type": type: string description: Type of the catalog @@ -33,7 +45,7 @@ components: description: Unique identifier for the catalog example: "catalog-electronics-001" "beckn:descriptor": - $ref: '#/components/schemas/Descriptor' + $ref: "#/components/schemas/Descriptor" "beckn:providerId": type: string description: Reference to the provider that owns this catalog @@ -48,12 +60,12 @@ components: description: BPP (Beckn Protocol Provider) URI endpoint example: "https://bpp.example.com" "beckn:validity": - $ref: '#/components/schemas/TimePeriod' + $ref: "#/components/schemas/TimePeriod" "beckn:isActive": type: boolean description: Whether the catalog is active default: true - beckn:items: # semantic entities + beckn:items: # semantic entities type: array description: > Array of beckn core Item entities in this catalog, returned directly without @@ -65,14 +77,25 @@ components: Item: type: object - required: ["@context", "@type", "beckn:id", "beckn:descriptor", "beckn:provider", "beckn:itemAttributes"] + required: + [ + "@context", + "@type", + "beckn:id", + "beckn:descriptor", + "beckn:provider", + "beckn:itemAttributes", + ] additionalProperties: false properties: "@context": type: string format: uri description: JSON-LD context URI for the core Item schema - enum: ["https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/context.jsonld"] + enum: + [ + "https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/main/schema/core/v2/context.jsonld", + ] "@type": type: string description: Type of the core item @@ -82,25 +105,25 @@ components: description: Unique identifier for the item example: "gaming-laptop-001" "beckn:descriptor": - $ref: '#/components/schemas/Descriptor' + $ref: "#/components/schemas/Descriptor" "beckn:category": - $ref: '#/components/schemas/CategoryCode' + $ref: "#/components/schemas/CategoryCode" "beckn:availableAt": type: array items: - $ref: '#/components/schemas/Location' + $ref: "#/components/schemas/Location" description: Physical locations where the item is available "beckn:availabilityWindow": type: array items: - $ref: '#/components/schemas/TimePeriod' + $ref: "#/components/schemas/TimePeriod" description: Time periods when the item is available "beckn:rateable": type: boolean description: Whether the item can be rated by customers example: true "beckn:rating": - $ref: '#/components/schemas/Rating' + $ref: "#/components/schemas/Rating" "beckn:isActive": type: boolean description: Whether the item is active @@ -112,9 +135,9 @@ components: description: Array of network identifiers for the BAP (Beckn App Provider) that offers this item example: ["bap.net/electronics", "bap.net/tech"] "beckn:provider": - $ref: '#/components/schemas/Provider' + $ref: "#/components/schemas/Provider" "beckn:itemAttributes": - $ref: '#/components/schemas/Attributes' + $ref: "#/components/schemas/Attributes" Offer: type: object @@ -170,22 +193,23 @@ components: beckn:validity: $ref: "#/components/schemas/TimePeriod" description: Offer validity window - x-jsonld: { "@id": "schema:availabilityStarts|schema:availabilityEnds" } + x-jsonld: + { "@id": "schema:availabilityStarts|schema:availabilityEnds" } beckn:price: $ref: "#/components/schemas/PriceSpecification" description: Price snapshot; detailed models can live in offerAttributes x-jsonld: { "@id": "schema:priceSpecification" } - beckn:eligibleRegion: + beckn:eligibleRegion: type: array items: - $ref: '#/components/schemas/Location' + $ref: "#/components/schemas/Location" description: Regions where the offer is eligible beckn:acceptedPaymentMethod: - $ref: '#/components/schemas/AcceptedPaymentMethod' + $ref: "#/components/schemas/AcceptedPaymentMethod" beckn:offerAttributes: $ref: "#/components/schemas/Attributes" - description: Attribute Pack attachment (pricing models, discounts, rail terms, etc.) - + description: Attribute Pack attachment (pricing models, discounts, rail terms, etc.) + Attributes: type: object description: > @@ -204,14 +228,23 @@ components: "@type": type: string description: JSON-LD type within the domain schema - example: "beckn:ElectronicItem" + example: "beckn:ElectronicItem" AcceptedPaymentMethod: type: array description: Payment methods accepted for this offer items: type: string - enum: ["UPI", "CREDIT_CARD", "DEBIT_CARD", "WALLET", "BANK_TRANSFER", "CASH", "APPLE_PAY"] + enum: + [ + "UPI", + "CREDIT_CARD", + "DEBIT_CARD", + "WALLET", + "BANK_TRANSFER", + "CASH", + "APPLE_PAY", + ] example: ["UPI", "Card", "Wallet"] x-jsonld: { "@id": "beckn:acceptedPaymentMethod" } @@ -225,22 +258,22 @@ components: description: Unique identifier for the provider example: "tech-store-001" "beckn:descriptor": - $ref: '#/components/schemas/Descriptor' + $ref: "#/components/schemas/Descriptor" "beckn:validity": - $ref: '#/components/schemas/TimePeriod' + $ref: "#/components/schemas/TimePeriod" "beckn:locations": type: array items: - $ref: '#/components/schemas/Location' + $ref: "#/components/schemas/Location" description: Physical locations where the provider operates "beckn:rateable": type: boolean description: Whether the provider can be rated by customers example: true "beckn:rating": - $ref: '#/components/schemas/Rating' + $ref: "#/components/schemas/Rating" "beckn:providerAttributes": - $ref: '#/components/schemas/Attributes' + $ref: "#/components/schemas/Attributes" Quantity: type: object @@ -278,9 +311,13 @@ components: additionalProperties: true properties: currency: { type: string, description: ISO 4217 code } - value: { type: number, description: Total value for this price specification } + value: + { + type: number, + description: Total value for this price specification, + } applicableQuantity: - $ref: '#/components/schemas/Quantity' + $ref: "#/components/schemas/Quantity" x-jsonld: { "@id": "schema:eligibleQuantity" } components: type: array @@ -288,12 +325,17 @@ components: items: type: object properties: - type: { type: string, enum: ["UNIT","TAX","DELIVERY","DISCOUNT","FEE","SURCHARGE"] } + type: + { + type: string, + enum: + ["UNIT", "TAX", "DELIVERY", "DISCOUNT", "FEE", "SURCHARGE"], + } value: { type: number } currency: { type: string } description: { type: string } x-jsonld: { "@id": "schema:PriceSpecification" } - + Eligibility: type: object properties: @@ -412,7 +454,7 @@ components: required: [error] properties: error: - $ref: '#/components/schemas/Error' + $ref: "#/components/schemas/Error" Error: type: object @@ -443,7 +485,7 @@ components: type: string enum: [ACK, NACK] error: - $ref: '#/components/schemas/Error' + $ref: "#/components/schemas/Error" required: [transaction_id, timestamp, ack_status] allOf: - if: @@ -474,11 +516,11 @@ components: type: string enum: ["beckn:Location"] geo: - $ref: '#/components/schemas/GeoJSONGeometry' + $ref: "#/components/schemas/GeoJSONGeometry" address: oneOf: - type: string - - $ref: '#/components/schemas/Address' + - $ref: "#/components/schemas/Address" description: Optional human-readable address for the same place/area. required: [geo] additionalProperties: false @@ -492,7 +534,13 @@ components: geo: type: Polygon coordinates: - - [[77.6100, 12.9200], [77.6400, 12.9200], [77.6400, 12.9500], [77.6100, 12.9500], [77.6100, 12.9200]] + - [ + [77.6100, 12.9200], + [77.6400, 12.9200], + [77.6400, 12.9500], + [77.6100, 12.9500], + [77.6100, 12.9200], + ] # Address schema from discover.yaml Address: @@ -570,7 +618,7 @@ components: description: > Member geometries when `type` is **GeometryCollection**. items: - $ref: '#/components/schemas/GeoJSONGeometry' + $ref: "#/components/schemas/GeoJSONGeometry" bbox: type: array description: Optional bounding box `[west, south, east, north]` in degrees. @@ -586,13 +634,22 @@ components: value: type: Polygon coordinates: - - [[77.6100, 12.9200], [77.6400, 12.9200], [77.6400, 12.9500], [77.6100, 12.9500], [77.6100, 12.9200]] + - [ + [77.6100, 12.9200], + [77.6400, 12.9200], + [77.6400, 12.9500], + [77.6100, 12.9500], + [77.6100, 12.9200], + ] geometry_collection: value: type: GeometryCollection geometries: - { type: Point, coordinates: [77.60, 12.95] } - - { type: LineString, coordinates: [[77.60, 12.95], [77.62, 12.97]] } + - { + type: LineString, + coordinates: [[77.60, 12.95], [77.62, 12.97]], + } # -------------------------------- # ORDER (core) @@ -624,7 +681,21 @@ components: beckn:orderStatus: type: string description: Order status/state - enum: ["CREATED","PENDING","CONFIRMED","INPROGRESS","PARTIALLYFULFILLED","COMPLETED","CANCELLED","REJECTED","FAILED","RETURNED","REFUNDED","ONHOLD"] + enum: + [ + "CREATED", + "PENDING", + "CONFIRMED", + "INPROGRESS", + "PARTIALLYFULFILLED", + "COMPLETED", + "CANCELLED", + "REJECTED", + "FAILED", + "RETURNED", + "REFUNDED", + "ONHOLD", + ] x-jsonld: { "@id": "beckn:orderStatus" } beckn:orderNumber: @@ -658,7 +729,7 @@ components: x-jsonld: { "@id": "schema:priceSpecification" } beckn:invoice: - $ref: '#/components/schemas/Invoice/properties/beckn:id' + $ref: "#/components/schemas/Invoice/properties/beckn:id" description: Invoice reference/summary x-jsonld: { "@id": "schema:Invoice" } @@ -708,7 +779,17 @@ components: Invoice: type: object additionalProperties: false - required: ["@context","@type","beckn:id","beckn:number","beckn:issueDate","beckn:totals","beckn:payee","beckn:payer"] + required: + [ + "@context", + "@type", + "beckn:id", + "beckn:number", + "beckn:issueDate", + "beckn:totals", + "beckn:payee", + "beckn:payer", + ] # A commercial document snapshot for billing/tax. Rich tax regimes go in attribute packs. properties: "@context": @@ -750,7 +831,7 @@ components: x-jsonld: { "@id": "schema:priceSpecification" } beckn:invoiceAttributes: $ref: "#/components/schemas/Attributes" - description: Attribute Pack for tax regime (e.g., GST/VAT), e-invoice refs, legal boilerplate, etc. + description: Attribute Pack for tax regime (e.g., GST/VAT), e-invoice refs, legal boilerplate, etc. # --------------------------------- # FULFILLMENT (core) @@ -760,7 +841,7 @@ components: Fulfillment: type: object additionalProperties: false - required: ["@context","@type","beckn:mode"] + required: ["@context", "@type", "beckn:mode"] properties: "@context": type: string @@ -781,7 +862,7 @@ components: x-jsonld: { "@id": "beckn:fulfillmentStatus" } beckn:mode: type: string - enum: ["DELIVERY","PICKUP","RESERVATION","DIGITAL"] + enum: ["DELIVERY", "PICKUP", "RESERVATION", "DIGITAL"] description: | DELIVERY → last-mile / parcel logistics PICKUP → customer collects from a place @@ -789,15 +870,15 @@ components: DIGITAL → digital good / license access x-jsonld: { "@id": "beckn:mode" } trackingAction: - $ref: '#/components/schemas/TrackAction' + $ref: "#/components/schemas/TrackAction" description: > Tracking entrypoint for this fulfillment, modeled as schema.org TrackAction. Use target.url for a clickable tracking URL; may also include deliveryMethod. x-jsonld: - '@type': 'schema:TrackAction' + "@type": "schema:TrackAction" beckn:deliveryAttributes: $ref: "#/components/schemas/Attributes" - description: > + description: > Bundle of attributes for the chosen mode: # DELIVERY: endpoints, slot windows, route & events → map to schema:ParcelDelivery / schema:DeliveryEvent # PICKUP: pickupPlace, counter codes, time windows → map to schema:Place + schema:openingHoursSpecification @@ -808,7 +889,7 @@ components: type: object description: Minimal schema.org TrackAction for clickable tracking. x-jsonld: - '@type': 'schema:TrackAction' + "@type": "schema:TrackAction" properties: id: type: string @@ -819,8 +900,8 @@ components: format: uri description: Tracking page URL x-jsonld: - '@id': 'schema:url' - additionalProperties: true + "@id": "schema:url" + additionalProperties: true # ----------------------------- # PAYMENT (core) @@ -828,7 +909,7 @@ components: Payment: type: object additionalProperties: false - required: ["@context","@type","beckn:paymentStatus"] + required: ["@context", "@type", "beckn:paymentStatus"] # Core payment semantics: rail + status + references. Rail payloads live in payment packs (UPI/Card/BNPL/Wallet). properties: "@context": @@ -846,14 +927,34 @@ components: beckn:paymentStatus: type: string description: Payment lifecycle status (Pending | Authorized | Captured | Failed | Refunded | PartialRefund …) - enum: ["INITIATED","PENDING","AUTHORIZED","CAPTURED","COMPLETED","FAILED","CANCELLED","REFUNDED","PARTIALLY_REFUNDED","CHARGEBACK","DISPUTED","EXPIRED","REVERSED","VOIDED","SETTLED","ON_HOLD","ADJUSTED"] + enum: + [ + "INITIATED", + "PENDING", + "AUTHORIZED", + "CAPTURED", + "COMPLETED", + "FAILED", + "CANCELLED", + "REFUNDED", + "PARTIALLY_REFUNDED", + "CHARGEBACK", + "DISPUTED", + "EXPIRED", + "REVERSED", + "VOIDED", + "SETTLED", + "ON_HOLD", + "ADJUSTED", + ] x-jsonld: { "@id": "beckn:paymentStatus" } beckn:amount: type: object description: Amount associated with this payment action properties: - currency: { type: string, x-jsonld: { "@id": "schema:priceCurrency" } } - value: { type: number, x-jsonld: { "@id": "schema:price" } } + currency: + { type: string, x-jsonld: { "@id": "schema:priceCurrency" } } + value: { type: number, x-jsonld: { "@id": "schema:price" } } beckn:paymentURL: type: string format: uri @@ -871,16 +972,16 @@ components: description: When the last terminal event (capture/refund) happened x-jsonld: { "@id": "schema:paymentDueDate" } # closest temporal anchor for payment events beckn:acceptedPaymentMethod: - $ref: '#/components/schemas/AcceptedPaymentMethod' + $ref: "#/components/schemas/AcceptedPaymentMethod" beckn:beneficiary: type: string description: Who will be the beneficiary or recipient of the payment - enum: ["BPP","BAP","BUYER"] + enum: ["BPP", "BAP", "BUYER"] example: "BPP" x-jsonld: { "@id": "schema:beneficiary" } beckn:paymentAttributes: $ref: "#/components/schemas/Attributes" - description: > + description: > Rail-specific attribute pack (e.g., UPI: VPA/UTR; CARD: token/3DS; BNPL: plan/schedule) # ----------------------------- @@ -889,7 +990,7 @@ components: Buyer: type: object additionalProperties: false - required: ["@context","@type","beckn:id"] + required: ["@context", "@type", "beckn:id"] # A minimal entity that can represent either a Person or an Organization. # Full identity, contact, or KYC details are supplied via buyer attribute packs. properties: @@ -907,7 +1008,8 @@ components: x-jsonld: { "@id": "schema:identifier" } beckn:role: type: string - enum: ["BUYER","SELLER","INTERMEDIARY","PAYER","PAYEE","FULFILLER"] + enum: + ["BUYER", "SELLER", "INTERMEDIARY", "PAYER", "PAYEE", "FULFILLER"] description: The functional role of the buyer in the transaction. x-jsonld: { "@id": "schema:roleName" } beckn:displayName: @@ -929,7 +1031,7 @@ components: x-jsonld: { "@id": "schema:taxID" } beckn:buyerAttributes: $ref: "#/components/schemas/Attributes" - description: > + description: > Attribute Pack reference for richer identity: # buyer/identity.v1 (contact details: email, phone, address) # buyer/org-ids.v1 (LEI, GSTIN, ISIN, CUSIP…) @@ -973,7 +1075,8 @@ components: description: Available support channels. items: type: string - enum: ["PHONE","EMAIL","WEB","CHAT","WHATSAPP","IN_APP","OTHER"] + enum: + ["PHONE", "EMAIL", "WEB", "CHAT", "WHATSAPP", "IN_APP", "OTHER"] example: name: "Acme Support" phone: "+91-80-1234-5678" @@ -982,13 +1085,13 @@ components: hours: "Mon–Sat 09:00–20:00 IST" channels: ["web", "phone", "email"] x-jsonld: - '@type': 'schema:ContactPoint' - 'schema:contactType': '"Customer Support"' - 'schema:telephone': '$.phone' - 'schema:email': '$.email' - 'schema:url': '$.url' - 'schema:name': '$.name' - 'schema:hoursAvailable': '$.hours' + "@type": "schema:ContactPoint" + "schema:contactType": '"Customer Support"' + "schema:telephone": "$.phone" + "schema:email": "$.email" + "schema:url": "$.url" + "schema:name": "$.name" + "schema:hoursAvailable": "$.hours" Tracking: type: object @@ -1008,7 +1111,7 @@ components: tl_method: type: string enum: [http/get, http/post, http/redirect, ws/handle, custom] - description: Transport/method used to access the tracking handle. # mirrors legacy tl_method concept + description: Transport/method used to access the tracking handle. # mirrors legacy tl_method concept url: type: string format: uri @@ -1026,15 +1129,15 @@ components: trackingStatus: "active" expires_at: "2025-10-16T18:30:00Z" x-jsonld: - '@type': 'schema:TrackAction' - 'schema:target': '$.url' # URL to track → EntryPoint(target) - 'schema:deliveryMethod': '$.tl_method' - 'beckn:trackingStatus': '$.trackingStatus' + "@type": "schema:TrackAction" + "schema:target": "$.url" # URL to track → EntryPoint(target) + "schema:deliveryMethod": "$.tl_method" + "beckn:trackingStatus": "$.trackingStatus" RatingInput: type: object additionalProperties: false - required: ["@context","@type","id","ratingValue"] + required: ["@context", "@type", "id", "ratingValue"] properties: "@context": type: string @@ -1049,7 +1152,7 @@ components: description: Target entity ID being rated (order/item/fulfillment/provider/agent). ratingValue: type: number - description: Numeric rating value (legacy usually 1–5). # remains permissive + description: Numeric rating value (legacy usually 1–5). # remains permissive minimum: 0 bestRating: type: number @@ -1070,12 +1173,12 @@ components: type: array items: { type: string } x-jsonld: - '@type': 'schema:Rating' - 'schema:itemReviewed': '$.id' - 'schema:ratingValue': '$.value' - 'schema:bestRating': '$.best' - 'schema:worstRating': '$.worst' - + "@type": "schema:Rating" + "schema:itemReviewed": "$.id" + "schema:ratingValue": "$.value" + "schema:bestRating": "$.best" + "schema:worstRating": "$.worst" + Form: description: Describes a form type: object @@ -1106,4 +1209,4 @@ components: - application/xml submission_id: type: string - format: uuid \ No newline at end of file + format: uuid diff --git a/scripts/v2.1/README.md b/scripts/v2.1/README.md new file mode 100644 index 0000000..b92abc7 --- /dev/null +++ b/scripts/v2.1/README.md @@ -0,0 +1,142 @@ +# Scripts for v2-rc2 + +This directory contains utility scripts for managing the Beckn Protocol v2-rc2 specifications. + +## sort-schemas.py + +A Python script to reorganize schemas in `attributes.yaml` files in alphabetical order, including all properties within each schema. + +### Features + +- **Alphabetically sorts schemas**: All schemas in the `components/schemas` section are sorted alphabetically by name +- **Sorts properties within schemas**: All properties within each schema definition are also sorted alphabetically +- **Preserves structure**: Maintains the OpenAPI 3.1.1 structure and metadata +- **Recursive sorting**: Sorts nested objects throughout the entire schema structure +- **Configurable input/output**: Supports custom input and output file paths + +### Prerequisites + +- Python 3.6 or higher +- PyYAML library + +Install PyYAML if not already installed: +```bash +pip install pyyaml +``` + +### Usage + +#### Default usage (processes schema/core/v2-rc2/attributes.yaml) + +```bash +python3 scripts/v2-rc2/sort-schemas.py +``` + +This will: +- Read from: `schema/core/v2-rc2/attributes.yaml` +- Write to: `schema/core/v2-rc2/attributes.sorted.yaml` + +#### Custom input file + +```bash +python3 scripts/v2-rc2/sort-schemas.py path/to/input.yaml +``` + +Outputs to: `schema/core/v2-rc2/attributes.sorted.yaml` (default) + +#### Custom input and output files + +```bash +python3 scripts/v2-rc2/sort-schemas.py path/to/input.yaml path/to/output.yaml +``` + +### Example + +```bash +# Sort the default attributes.yaml file +cd /home/ravi/www/protocol-specifications-v2 +python3 scripts/v2-rc2/sort-schemas.py + +# Sort a specific file with custom output +python3 scripts/v2-rc2/sort-schemas.py \ + schema/PaymentSettlement/v2-rc2/attributes.yaml \ + schema/PaymentSettlement/v2-rc2/attributes.sorted.yaml +``` + +### Output + +The script will display progress information: + +``` +Reading from: /home/ravi/www/protocol-specifications-v2/schema/core/v2-rc2/attributes.yaml +Found 31 schemas to sort +Writing sorted schemas to: /home/ravi/www/protocol-specifications-v2/schema/core/v2-rc2/attributes.sorted.yaml +✓ Schemas sorted successfully! + - Input: /home/ravi/www/protocol-specifications-v2/schema/core/v2-rc2/attributes.yaml + - Output: /home/ravi/www/protocol-specifications-v2/schema/core/v2-rc2/attributes.sorted.yaml +``` + +### What Gets Sorted + +1. **Schema names**: All schemas under `components/schemas` are sorted alphabetically +2. **Schema properties**: All keys within each schema definition (type, required, properties, etc.) +3. **Nested objects**: All nested objects are recursively sorted +4. **Property keys**: All property keys within the `properties` section of each schema + +### What Is Preserved + +- OpenAPI metadata (openapi, info, etc.) +- Required fields and validation rules +- JSON-LD context and type information +- Examples and descriptions +- All schema relationships and $ref references + +### Example Before and After + +**Before** (schemas in declaration order): +```yaml +components: + schemas: + Catalog: + # ... + Item: + # ... + Offer: + # ... + Attributes: + # ... +``` + +**After** (schemas in alphabetical order): +```yaml +components: + schemas: + AcceptedPaymentMethod: + # ... + AckResponse: + # ... + Address: + # ... + Attributes: + # ... + Buyer: + # ... + Catalog: + # ... +``` + +## network-scaffold/ + +Contains scripts for network provisioning and scaffolding. See [network-scaffold/README.md](network-scaffold/README.md) for details. + +--- + +## Contributing + +When adding new scripts to this directory: + +1. Add appropriate documentation in this README +2. Include usage examples +3. Add error handling and validation +4. Make scripts executable: `chmod +x script-name.sh` or `chmod +x script-name.py` +5. Include a shebang line at the top of the file diff --git a/scripts/v2.1/network-scaffold/README.md b/scripts/v2.1/network-scaffold/README.md new file mode 100644 index 0000000..0d88271 --- /dev/null +++ b/scripts/v2.1/network-scaffold/README.md @@ -0,0 +1,14 @@ +How to run it +``` +chmod +x forge-the-network.sh +./forge-the-network.sh acmenet /path/to/workspace +``` + +Or with environment overrides for upstream URLs: +``` +UPSTREAM_CORE_URL="https://github.com/beckn/protocol-specifications.git" \ +UPSTREAM_DOMAIN_URL="https://github.com/beckn/DEG.git" \ +UPSTREAM_CORE_REF="v2.0.0" \ +UPSTREAM_DOMAIN_REF="main" \ +./forge-the-network.sh acmenet +``` diff --git a/scripts/v2.1/network-scaffold/forge-the-network.sh b/scripts/v2.1/network-scaffold/forge-the-network.sh new file mode 100644 index 0000000..b9d0cea --- /dev/null +++ b/scripts/v2.1/network-scaffold/forge-the-network.sh @@ -0,0 +1,218 @@ +#!/usr/bin/env bash +set -euo pipefail + +# ============================================================ +# forge-the-network.sh +# A repo-forging script for an Open Network GitHub Org layout +# ============================================================ + +# ----------------------------- +# Config (edit these as needed) +# ----------------------------- +NETWORK_SLUG="${1:-acmenet}" # e.g., acmenet, uei, ondc +WORKDIR="${2:-$PWD/${NETWORK_SLUG}-org}" # local workspace root + +# Upstream repos (replace with real URLs as needed) +UPSTREAM_CORE_URL="${UPSTREAM_CORE_URL:-https://github.com/beckn/protocol-specifications.git}" +UPSTREAM_DOMAIN_URL="${UPSTREAM_DOMAIN_URL:-https://github.com/beckn/DEG.git}" + +# Pinned refs (tags/commits/branches). Script does not checkout; it records intent only. +UPSTREAM_CORE_REF="${UPSTREAM_CORE_REF:-v2.0.0}" +UPSTREAM_DOMAIN_REF="${UPSTREAM_DOMAIN_REF:-main}" + +# Toggle: create a top-level "workspace" repo to track everything together +CREATE_WORKSPACE_REPO="${CREATE_WORKSPACE_REPO:-true}" + +# ----------------------------- +# Derived repo names +# ----------------------------- +REPO_DOCS="${NETWORK_SLUG}-docs" +REPO_PROFILE="${NETWORK_SLUG}-profile" +REPO_SCHEMAS="${NETWORK_SLUG}-schemas" +REPO_EXAMPLES="${NETWORK_SLUG}-examples" +REPO_TOOLING="${NETWORK_SLUG}-tooling" +REPO_POLICY="${NETWORK_SLUG}-policy" +REPO_DOTGITHUB=".github" + +# Local paths +P_DOCS="${WORKDIR}/${REPO_DOCS}" +P_PROFILE="${WORKDIR}/${REPO_PROFILE}" +P_SCHEMAS="${WORKDIR}/${REPO_SCHEMAS}" +P_EXAMPLES="${WORKDIR}/${REPO_EXAMPLES}" +P_TOOLING="${WORKDIR}/${REPO_TOOLING}" +P_POLICY="${WORKDIR}/${REPO_POLICY}" +P_DOTGITHUB="${WORKDIR}/${REPO_DOTGITHUB}" +P_WORKSPACE="${WORKDIR}/${NETWORK_SLUG}-workspace" + +# ----------------------------- +# Helpers +# ----------------------------- +say() { printf "\n\033[1m%s\033[0m\n" "$*"; } + +ensure_git() { + if ! command -v git >/dev/null 2>&1; then + echo "ERROR: git is not installed or not on PATH." + exit 1 + fi +} + +init_repo() { + local path="$1" + local name="$2" + mkdir -p "$path" + if [ ! -d "${path}/.git" ]; then + git -C "$path" init >/dev/null + touch "${path}/.gitkeep" 2>/dev/null || true + say "Initialized git repo: ${name} -> ${path}" + else + say "Repo already initialized: ${name} -> ${path}" + fi +} + +touch_files() { + local base="$1" + shift + for f in "$@"; do + mkdir -p "$(dirname "${base}/${f}")" + touch "${base}/${f}" + done +} + +add_submodule() { + local repo_path="$1" + local sub_url="$2" + local sub_path="$3" + + if [ -d "${repo_path}/${sub_path}/.git" ] || git -C "$repo_path" config -f .gitmodules --get "submodule.${sub_path}.url" >/dev/null 2>&1; then + say "Submodule already exists: ${sub_path} in ${repo_path}" + return + fi + + git -C "$repo_path" submodule add "$sub_url" "$sub_path" >/dev/null + say "Added submodule: ${sub_url} -> ${repo_path}/${sub_path}" +} + +# ----------------------------- +# Main +# ----------------------------- +ensure_git + +say "Forging org workspace at: ${WORKDIR}" +mkdir -p "$WORKDIR" + +say "Creating repos (folders) + initializing git repos..." +init_repo "$P_DOTGITHUB" "$REPO_DOTGITHUB" +init_repo "$P_PROFILE" "$REPO_PROFILE" +init_repo "$P_SCHEMAS" "$REPO_SCHEMAS" +init_repo "$P_EXAMPLES" "$REPO_EXAMPLES" +init_repo "$P_TOOLING" "$REPO_TOOLING" +init_repo "$P_POLICY" "$REPO_POLICY" +init_repo "$P_DOCS" "$REPO_DOCS" + +say "Scaffolding file/folder structures..." + +# .github +touch_files "$P_DOTGITHUB" \ + "CONTRIBUTING.md" \ + "SECURITY.md" \ + "CODE_OF_CONDUCT.md" \ + "PULL_REQUEST_TEMPLATE.md" \ + "ISSUE_TEMPLATE/bug_report.md" \ + "ISSUE_TEMPLATE/feature_request.md" \ + "workflows/reusable-validate.yml" \ + "workflows/reusable-release.yml" + +# profile +touch_files "$P_PROFILE" \ + "README.md" "LICENSE" "NOTICE.md" "CHANGELOG.md" \ + "profile/DEPENDENCIES.yaml" \ + "profile/SUPPORT_MATRIX.md" \ + "profile/POLICY_REFERENCES.md" \ + "profile/CONFORMANCE/discovery.md" \ + "profile/CONFORMANCE/ordering.md" \ + "profile/CONFORMANCE/fulfillment.md" \ + "profile/CONFORMANCE/post_fulfillment.md" \ + "releases/v0.1.0.md" + +# schemas +touch_files "$P_SCHEMAS" \ + "README.md" "LICENSE" "NOTICE.md" "CHANGELOG.md" \ + "context/network/.gitkeep" \ + "jsonschema/network/.gitkeep" \ + "mapping/mapping-matrix.csv" \ + "mapping/notes.md" + +# examples +touch_files "$P_EXAMPLES" \ + "README.md" "LICENSE" "NOTICE.md" "CHANGELOG.md" \ + "upstream-refs/ev-charging.yaml" \ + "patches/ev-charging/on_search.patch.json" \ + "patches/ev-charging/on_confirm.patch.json" \ + "generated/ev-charging/on_search.json" \ + "generated/ev-charging/on_confirm.json" \ + "reports/latest-validation.json" + +# tooling +touch_files "$P_TOOLING" \ + "README.md" "LICENSE" "NOTICE.md" "CHANGELOG.md" \ + "scripts/.gitkeep" \ + "bin/.gitkeep" + +# policy +touch_files "$P_POLICY" \ + "README.md" "LICENSE" "NOTICE.md" "CHANGELOG.md" \ + "policies/network-policy.md" \ + "policies/security-policy.md" \ + "policies/onboarding.md" + +# docs portal +touch_files "$P_DOCS" \ + "README.md" "LICENSE" "NOTICE.md" \ + "mkdocs.yml" \ + "docs/index.md" \ + "docs/architecture/overview.md" \ + "docs/architecture/participants.md" \ + "docs/architecture/trust-registry.md" \ + "docs/architecture/security.md" \ + "docs/ig/ev-charging/overlay.md" \ + "docs/ig/ev-charging/conformance.md" \ + "docs/ig/ev-charging/workflows/.gitkeep" \ + "docs/ig/ev-charging/faq.md" \ + "docs/schemas/packs.md" \ + "docs/examples/ev-charging.md" \ + "docs/releases/index.md" \ + "tools/fetch-upstreams/.gitkeep" + +say "Adding upstream submodules to ${REPO_DOCS}..." +mkdir -p "${P_DOCS}/upstream" +add_submodule "$P_DOCS" "$UPSTREAM_CORE_URL" "upstream/core" +add_submodule "$P_DOCS" "$UPSTREAM_DOMAIN_URL" "upstream/domain" + +touch_files "$P_DOCS" "upstream/PINNED_REFS.txt" +cat > "${P_DOCS}/upstream/PINNED_REFS.txt" </dev/null +} + +touch_files() { + local base="$1"; shift + for f in "$@"; do + mkdir -p "$(dirname "${base}/${f}")" + touch "${base}/${f}" + done +} + +add_submodule() { + local repo_path="$1" sub_url="$2" sub_path="$3" + if [ -d "${repo_path}/${sub_path}/.git" ] || git -C "$repo_path" config -f .gitmodules --get "submodule.${sub_path}.url" >/dev/null 2>&1; then + return + fi + git -C "$repo_path" submodule add "$sub_url" "$sub_path" >/dev/null +} + +REPO_DOTGITHUB=".github" +REPO_PROFILE="${NETWORK_SLUG}-profile" +REPO_SCHEMAS="${NETWORK_SLUG}-schemas" +REPO_EXAMPLES="${NETWORK_SLUG}-examples" +REPO_DOCS="${NETWORK_SLUG}-docs" + +P_DOTGITHUB="${WORKDIR}/${REPO_DOTGITHUB}" +P_PROFILE="${WORKDIR}/${REPO_PROFILE}" +P_SCHEMAS="${WORKDIR}/${REPO_SCHEMAS}" +P_EXAMPLES="${WORKDIR}/${REPO_EXAMPLES}" +P_DOCS="${WORKDIR}/${REPO_DOCS}" + +say "Creating minimal workspace at: ${WORKDIR}" +mkdir -p "$WORKDIR" + +say "Initializing repositories..." +init_repo "$P_DOTGITHUB" +init_repo "$P_PROFILE" +init_repo "$P_SCHEMAS" +init_repo "$P_EXAMPLES" +init_repo "$P_DOCS" + +say "Creating placeholder files..." + +touch_files "$P_DOTGITHUB" \ + "CONTRIBUTING.md" \ + "SECURITY.md" \ + "PULL_REQUEST_TEMPLATE.md" \ + "workflows/reusable-validate.yml" + +touch_files "$P_PROFILE" \ + "README.md" "LICENSE" "NOTICE.md" "CHANGELOG.md" \ + "profile/DEPENDENCIES.yaml" \ + "profile/SUPPORT_MATRIX.md" \ + "profile/CONFORMANCE/discovery.md" \ + "releases/v0.1.0.md" + +touch_files "$P_SCHEMAS" \ + "README.md" "LICENSE" "NOTICE.md" "CHANGELOG.md" \ + "context/network/.gitkeep" \ + "jsonschema/network/.gitkeep" + +touch_files "$P_EXAMPLES" \ + "README.md" "LICENSE" "NOTICE.md" "CHANGELOG.md" \ + "upstream-refs/ev-charging.yaml" \ + "patches/ev-charging/on_search.patch.json" \ + "generated/ev-charging/on_search.json" + +touch_files "$P_DOCS" \ + "README.md" "LICENSE" "NOTICE.md" \ + "mkdocs.yml" \ + "docs/index.md" \ + "docs/ig/ev-charging/overlay.md" \ + "tools/fetch-upstreams/.gitkeep" + +say "Adding upstream submodules to docs repo..." +mkdir -p "${P_DOCS}/upstream" +add_submodule "$P_DOCS" "$UPSTREAM_CORE_URL" "upstream/core" +add_submodule "$P_DOCS" "$UPSTREAM_DOMAIN_URL" "upstream/domain" + +say "Minimal scaffold complete." diff --git a/scripts/v2.1/reorder-schema-keys.py b/scripts/v2.1/reorder-schema-keys.py new file mode 100644 index 0000000..39a8851 --- /dev/null +++ b/scripts/v2.1/reorder-schema-keys.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python3 +""" +Reorder OpenAPI schema keys according to Beckn specification standard order: +1. description +2. type +3. properties (if type = object) +4. items (if type = array) +5. enum (if any) +6. required +7. x-jsonld +""" + +import yaml +import sys + +# Custom representer to handle dict ordering without OrderedDict +def represent_dict_order(dumper, data): + return dumper.represent_mapping('tag:yaml.org,2002:map', data.items()) + +yaml.add_representer(dict, represent_dict_order) + +# Define the standard order for schema keys +KEY_ORDER = [ + 'description', + 'type', + 'properties', + 'items', + 'enum', + 'required', + 'x-jsonld' +] + +# Other keys that should come after the standard ones +SECONDARY_KEYS = [ + 'additionalProperties', + 'allOf', + 'anyOf', + 'oneOf', + 'if', + 'then', + 'not', + 'minProperties', + 'maxProperties', + 'minItems', + 'maxItems', + 'minimum', + 'maximum', + 'format', + 'pattern', + 'default', + 'example', + 'examples', + 'const', + 'nullable' +] + +def reorder_schema_keys(schema): + """Reorder keys in a schema object according to the standard order.""" + if not isinstance(schema, dict): + return schema + + ordered = {} + + # First, add keys in the standard order + for key in KEY_ORDER: + if key in schema: + ordered[key] = schema[key] + + # Then add secondary standard keys + for key in SECONDARY_KEYS: + if key in schema: + ordered[key] = schema[key] + + # Finally, add any remaining keys + for key in schema: + if key not in ordered: + ordered[key] = schema[key] + + # Recursively process nested schemas + if 'properties' in ordered and isinstance(ordered['properties'], dict): + for prop_key, prop_value in ordered['properties'].items(): + ordered['properties'][prop_key] = reorder_schema_keys(prop_value) + + if 'items' in ordered: + if isinstance(ordered['items'], dict): + ordered['items'] = reorder_schema_keys(ordered['items']) + elif isinstance(ordered['items'], list): + ordered['items'] = [reorder_schema_keys(item) if isinstance(item, dict) else item for item in ordered['items']] + + if 'allOf' in ordered and isinstance(ordered['allOf'], list): + ordered['allOf'] = [reorder_schema_keys(item) if isinstance(item, dict) else item for item in ordered['allOf']] + + if 'anyOf' in ordered and isinstance(ordered['anyOf'], list): + ordered['anyOf'] = [reorder_schema_keys(item) if isinstance(item, dict) else item for item in ordered['anyOf']] + + if 'oneOf' in ordered and isinstance(ordered['oneOf'], list): + ordered['oneOf'] = [reorder_schema_keys(item) if isinstance(item, dict) else item for item in ordered['oneOf']] + + return ordered + +def process_yaml_file(input_file, output_file): + """Process the YAML file and reorder schema keys.""" + + # Load YAML + with open(input_file, 'r', encoding='utf-8') as f: + data = yaml.safe_load(f) + + # Process all schemas + if 'components' in data and 'schemas' in data['components']: + for schema_name, schema_def in data['components']['schemas'].items(): + data['components']['schemas'][schema_name] = reorder_schema_keys(schema_def) + + # Write back to file with proper formatting + with open(output_file, 'w', encoding='utf-8') as f: + yaml.dump(data, f, + default_flow_style=False, + allow_unicode=True, + sort_keys=False, + width=120, + indent=2) + + print(f"Successfully reordered schema keys in {output_file}") + +if __name__ == '__main__': + input_file = 'schema/core/v2.1/attributes.yaml' + output_file = 'schema/core/v2.1/attributes.yaml' + + if len(sys.argv) > 1: + input_file = sys.argv[1] + if len(sys.argv) > 2: + output_file = sys.argv[2] + + process_yaml_file(input_file, output_file) diff --git a/scripts/v2.1/sort-schemas.py b/scripts/v2.1/sort-schemas.py new file mode 100755 index 0000000..568c2d8 --- /dev/null +++ b/scripts/v2.1/sort-schemas.py @@ -0,0 +1,180 @@ +#!/usr/bin/env python3 +""" +Script to reorganize schemas in attributes.yaml in alphabetical order. +This script sorts both the schemas and their properties alphabetically. + +Usage: + python3 sort-schemas.py [input_file] [output_file] + + If no arguments provided, defaults to: + - input: schema/core/v2-rc2/attributes.yaml + - output: schema/core/v2-rc2/attributes.sorted.yaml +""" + +import sys +import yaml +from pathlib import Path +from collections import OrderedDict + + +def represent_ordereddict(dumper, data): + """Custom representer for OrderedDict to maintain order in YAML output.""" + return dumper.represent_dict(data.items()) + + +def represent_none(dumper, data): + """Represent None as null in YAML.""" + return dumper.represent_scalar('tag:yaml.org,2002:null', 'null') + + +def setup_yaml(): + """Configure YAML to preserve formatting and use OrderedDict.""" + yaml.add_representer(OrderedDict, represent_ordereddict) + yaml.add_representer(type(None), represent_none) + + +def sort_dict_keys(obj, exclude_keys=None): + """ + Recursively sort dictionary keys alphabetically. + + Args: + obj: The object to sort (dict, list, or other) + exclude_keys: List of keys to exclude from sorting (keep their original order) + + Returns: + Sorted object + """ + if exclude_keys is None: + exclude_keys = [] + + if isinstance(obj, dict): + sorted_dict = OrderedDict() + + # Separate keys to exclude from sorting + excluded = OrderedDict() + to_sort = {} + + for key, value in obj.items(): + if key in exclude_keys: + excluded[key] = value + else: + to_sort[key] = value + + # Add excluded keys first (in original order) + for key, value in excluded.items(): + sorted_dict[key] = sort_dict_keys(value, exclude_keys) + + # Add sorted keys + for key in sorted(to_sort.keys()): + sorted_dict[key] = sort_dict_keys(to_sort[key], exclude_keys) + + return sorted_dict + + elif isinstance(obj, list): + return [sort_dict_keys(item, exclude_keys) for item in obj] + + else: + return obj + + +def sort_schemas_in_yaml(input_file, output_file): + """ + Read a YAML file, sort schemas and their properties alphabetically, and write to output. + + Args: + input_file: Path to input YAML file + output_file: Path to output YAML file + """ + print(f"Reading from: {input_file}") + + # Read the YAML file + with open(input_file, 'r', encoding='utf-8') as f: + data = yaml.safe_load(f) + + # Keys that should maintain their original order at the top level + top_level_order = ['openapi', 'info', 'components'] + + # Sort the entire structure, but preserve some top-level ordering + if 'components' in data and 'schemas' in data['components']: + print(f"Found {len(data['components']['schemas'])} schemas to sort") + + # Sort schemas alphabetically + sorted_schemas = OrderedDict(sorted(data['components']['schemas'].items())) + + # Sort properties within each schema + for schema_name, schema_def in sorted_schemas.items(): + if isinstance(schema_def, dict): + # Sort the schema definition keys + sorted_schema = sort_dict_keys(schema_def) + sorted_schemas[schema_name] = sorted_schema + + data['components']['schemas'] = sorted_schemas + + # Reorganize top-level keys + sorted_data = OrderedDict() + + # First add keys in preferred order + for key in top_level_order: + if key in data: + sorted_data[key] = data[key] + + # Then add any remaining keys alphabetically + remaining_keys = sorted([k for k in data.keys() if k not in top_level_order]) + for key in remaining_keys: + sorted_data[key] = data[key] + + print(f"Writing sorted schemas to: {output_file}") + + # Write the sorted YAML to output file + with open(output_file, 'w', encoding='utf-8') as f: + yaml.dump(sorted_data, f, + default_flow_style=False, + sort_keys=False, # We've already sorted manually + allow_unicode=True, + width=120, + indent=2) + + print("✓ Schemas sorted successfully!") + print(f" - Input: {input_file}") + print(f" - Output: {output_file}") + + +def main(): + """Main function to handle command-line arguments and execute sorting.""" + setup_yaml() + + # Get script directory for relative path resolution + script_dir = Path(__file__).parent.parent.parent # Go up to repo root + + # Default paths + default_input = script_dir / "schema/core/v2-rc2/attributes.yaml" + default_output = script_dir / "schema/core/v2-rc2/attributes.sorted.yaml" + + # Parse command-line arguments + if len(sys.argv) > 1: + input_file = Path(sys.argv[1]) + else: + input_file = default_input + + if len(sys.argv) > 2: + output_file = Path(sys.argv[2]) + else: + output_file = default_output + + # Check if input file exists + if not input_file.exists(): + print(f"Error: Input file not found: {input_file}") + sys.exit(1) + + # Sort and save + try: + sort_schemas_in_yaml(input_file, output_file) + except Exception as e: + print(f"Error: {e}") + import traceback + traceback.print_exc() + sys.exit(1) + + +if __name__ == "__main__": + main()