Swagger is the executable source of truth for the routes and DTO fields in a running build. This document records conventions and route families; it deliberately does not duplicate every generated schema.
- API base path:
/api/v1 - Interactive OpenAPI UI:
/docs - OpenAPI JSON:
/docs/openapi.json - Reviewable OpenAPI snapshot:
openapi/openapi.json - JSON request and response bodies use UTF-8.
- Timestamps are UTC ISO 8601 strings.
- Money is an integer
amountMinorwith an explicit three-lettercurrencysuch asINR. Persisted PrismaBigIntvalues are serialized as base-10 JSON strings to avoid precision loss; request DTOs accept either safe bounded JSON integers or positive digit strings (for potentially large refund amounts) exactly as documented by Swagger.
Breaking transport changes require a new API version. Additive fields and new operations can remain in v1.
pnpm openapi:generate refreshes the checked-in snapshot. CI runs
pnpm openapi:check, which builds the document from Nest metadata without
starting the application or calling external services. Contract changes must
therefore include the generated snapshot diff.
Protected endpoints accept Authorization: Bearer <ZITADEL-access-token>. The global guard introspects the token, validates issuer/audience/subject/expiry, resolves a minimal local user by sub, and preserves organization scope on capability claims. Login, registration, refresh, logout, recovery, verification, and MFA are ZITADEL Hosted Login/account-management concerns; the marketplace API does not accept credentials or issue tokens.
Clients may send X-Request-Id; otherwise the server generates one and returns it. Use Idempotency-Key for retryable critical mutations such as checkout. A key must be opaque, unique per intended operation, and reused only with the identical request.
Successful responses use a stable data envelope, with metadata when relevant:
{
"data": {},
"meta": {},
"requestId": "request-correlation-id"
}Errors are machine-readable and do not expose stack traces, SQL, or provider secrets:
{
"error": {
"code": "PRODUCT_OUT_OF_STOCK",
"message": "Requested quantity is unavailable",
"details": {}
},
"requestId": "request-correlation-id"
}Domain conflicts generally return 409, invalid DTOs 400, failed authentication 401, insufficient permission/ownership 403, missing resources 404, and rate limits 429.
Ordinary collections use bounded offset pagination (page, pageSize) and return page, pageSize, total, and pageCount metadata. pageSize defaults to 20 and is capped at 100. Sort fields are allowlisted; clients cannot pass arbitrary SQL column names. Event/history feeds can move to cursor pagination without changing unrelated collections.
| Prefix | Audience | Purpose |
|---|---|---|
/auth |
public | non-secret OIDC client configuration only |
/users |
authenticated/admin | current profile and explicit user operations |
/vendors or /vendor |
vendor actors | application/profile/verification, owned products, inventory, orders and finance |
/products and /catalog |
public/vendor | published discovery and owned listing commands |
/cart |
customer | authoritative cart mutations and totals |
/checkout |
customer | idempotent reserve/order/payment orchestration |
/orders |
customer | unified customer orders, status history and tracking |
/payments |
customer/admin | safe payment status (never raw provider secrets) |
/shipments, /returns, /refunds, /reviews, /disputes |
scoped actors | controlled post-purchase operations |
/admin |
operations roles | explicit approvals, moderation, refund/settlement/dispute actions and audit views |
/webhooks |
providers | signature-verified, deduplicated provider ingress |
/health/live, /health/ready |
infrastructure | liveness/readiness checks (under /api/v1) |
Vendor and admin operations are separate from public reads even when they refer to the same entity. There is no generic PATCH status or generic admin database-update endpoint.
All paths below are relative to /api/v1. Consult Swagger for DTO fields, filters, response descriptions, and bearer requirements.
| Method | Path(s) | Purpose |
|---|---|---|
GET |
/auth/config |
public Hosted Login/OIDC client settings, never secret |
GET, PATCH |
/users/me |
local preferences and validated identity view |
GET |
/catalog/products, /catalog/products/{productId} |
published products from active vendors |
GET |
/categories, /attributes |
active catalog configuration |
POST |
/categories, /attributes |
capability-protected catalog administration |
GET |
/health/live, /health/ready |
process and dependency health |
| Method | Path(s) | Purpose |
|---|---|---|
GET |
/cart |
authoritative current cart and pricing |
POST |
/cart/items |
add a validated cart line |
PATCH, DELETE |
/cart/items/{itemId} |
change or remove an owned cart line |
POST |
/checkout |
idempotently reserve and initiate payment |
GET |
/checkout/{checkoutId} |
inspect an owned checkout |
GET |
/orders, /orders/{orderId} |
owned parent order, vendor splits and tracking |
GET |
/payments |
owned payments, attempts and refunds |
POST |
/payments/{paymentId}/mock-capture |
non-production signed mock capture helper |
GET |
/shipments/{shipmentId} |
tracking for a shipment on an owned order |
POST |
/returns |
create an eligible return request |
GET |
/returns, /returns/{returnRequestId} |
list/read owned return requests |
POST |
/refunds |
idempotent full/partial refund request |
GET |
/refunds, /refunds/{refundId} |
list/read owned refund state |
POST |
/reviews |
eligible verified-purchase review submission |
GET |
/reviews/mine, /reviews/products/{productId}, /reviews/vendors/{vendorId} |
owned/public review reads |
POST |
/disputes |
open a scoped dispute |
GET |
/disputes, /disputes/{disputeId} |
list/read an accessible dispute |
POST |
/disputes/{disputeId}/messages, /disputes/{disputeId}/evidence |
dispute participation and evidence metadata |
POST |
/support/cases, /support/cases/{id}/close |
create a support reference or explicitly close |
GET |
/support/cases, /support/cases/{id} |
list/read accessible support references |
GET |
/notifications |
paginated current-user delivery history |
| Method | Path(s) | Purpose |
|---|---|---|
POST |
/vendors/applications |
seller creates a vendor application |
GET |
/vendors/mine, /vendors/{vendorId} |
organization-scoped vendor detail |
PATCH |
/vendors/{vendorId} |
owned vendor profile update |
POST |
/vendors/{vendorId}/verification/submit, /vendors/{vendorId}/staff |
verification and ZITADEL staff assignment |
DELETE |
/vendors/{vendorId}/staff/{zitadelUserId} |
revoke a ZITADEL vendor-staff role assignment |
POST |
/vendor/products |
create an owned product draft |
GET |
/vendor/products, /vendor/products/{productId} |
list/read owned product drafts |
PATCH |
/vendor/products/{productId} |
update an owned mutable product |
POST |
/vendor/products/{productId}/variants, /vendor/products/{productId}/media, /vendor/products/{productId}/submit |
listing composition and moderation submission |
GET, PUT |
/vendor/inventory/{variantId} |
owned stock read/set |
POST |
/vendor/inventory/{variantId}/adjustments |
audited stock delta |
GET |
/vendor/orders, /vendor/orders/{vendorOrderId} |
organization-scoped seller splits |
POST |
/vendor/orders/{vendorOrderId}/accept, /vendor/orders/{vendorOrderId}/process, /vendor/orders/{vendorOrderId}/mark-ready |
controlled fulfillment commands |
POST |
/shipments/vendor-orders/{vendorOrderId} |
idempotent shipment/AWB/pickup creation |
POST |
/shipments/{shipmentId}/mock-advance |
non-production owned mock tracking helper |
GET |
/vendor/ledger/{vendorId}, /vendor/settlements/{vendorId} |
derived balance/history and settlements |
| Method | Path(s) | Purpose |
|---|---|---|
GET |
/admin/users, /admin/vendors, /admin/products |
inspect users, vendor applications and product queue |
POST |
/admin/users/{userId}/platform-capabilities |
assign platform-scoped capabilities in ZITADEL |
GET |
/admin/iam/provisioning |
inspect durable ZITADEL provisioning operations |
POST |
/admin/iam/provisioning/{operationId}/retry |
retry a corrected failed provisioning operation |
POST |
/admin/vendors/{vendorId}/approve, /admin/vendors/{vendorId}/reject, /admin/vendors/{vendorId}/suspend, /admin/vendors/{vendorId}/reactivate |
explicit vendor lifecycle decisions |
POST |
/admin/products/{productId}/approve, /admin/products/{productId}/request-changes, /admin/products/{productId}/reject, /admin/products/{productId}/suspend |
explicit moderation decisions |
GET |
/admin/orders, /admin/payments, /admin/settlements, /admin/audit-logs |
operational inspection |
POST |
/admin/settlements/{settlementId}/process, /admin/settlements/{settlementId}/mock-complete |
payout lifecycle; completion helper is non-production |
POST |
/admin/ledger/adjustments |
idempotent audited manual adjustment |
GET |
/admin/returns |
inspect the return queue |
POST |
/admin/returns/{returnRequestId}/review, /admin/returns/{returnRequestId}/approve, /admin/returns/{returnRequestId}/reject |
return review decisions |
GET |
/admin/refunds, /admin/refunds/{refundId} |
inspect refund requests |
POST |
/admin/refunds/{refundId}/review, /admin/refunds/{refundId}/approve, /admin/refunds/{refundId}/reject |
refund accounting decisions |
GET |
/admin/reviews |
inspect the review moderation queue |
POST |
/admin/reviews/{reviewId}/publish, /admin/reviews/{reviewId}/reject, /admin/reviews/{reviewId}/hide |
review moderation |
GET |
/admin/disputes, /admin/disputes/{disputeId} |
inspect disputes |
POST |
/admin/disputes/{disputeId}/messages, /admin/disputes/{disputeId}/resolve |
dispute operations |
POST |
/admin/reconciliation/runs |
start a reconciliation run |
GET |
/admin/reconciliation/runs, /admin/reconciliation/runs/{runId} |
inspect reconciliation runs/results |
POST |
/admin/reconciliation/runs/{runId}/complete, /admin/reconciliation/runs/{runId}/fail |
finalize a reconciliation run |
POST |
/admin/reconciliation/runs/{runId}/items/{itemId}/resolve |
audited mismatch resolution |
| Method | Path | Purpose |
|---|---|---|
POST |
/webhooks/payments/{provider} |
signed payment capture and order confirmation |
POST |
/webhooks/shipping/{provider} |
signed normalized tracking event |
Webhooks have provider-specific signature headers documented in Swagger/configuration. When a provider signs bytes, verification uses the raw request body. The handler persists the provider event ID before applying effects. Successfully processed duplicates return a 2xx response without repeating side effects; invalid signatures return 401/403 and are never processed.
The global validation pipe strips or rejects unknown properties, transforms supported primitive query values, and validates UUIDs, enums, quantities, money ranges, pagination, and nested addresses. TypeScript types alone are not treated as runtime validation.