FASHIONISTAR CI/CD
🔄 Celery Queues Deploy: d915798567b1052828794606dda8e62b4500f337 [GitHub Actions]
607bf71
Raw
History Blame Contribute Delete
439 kB
openapi: 3.0.3
info:
title: Fashionistar API
version: 1.0.0
description: |-
Nigeria's Premier AI-Powered Fashion E-Commerce Platform API.
**v1 (DRF/Sync):** Standard REST endpoints, WSGI-safe, Celery-backed.
**v1 (Ninja/Async):** High-concurrency async endpoints, ASGI-native.
**Authentication:** Bearer JWT (SimpleJWT). Get tokens via `/api/v1/auth/login/`.
**Register first:** `POST /api/v1/auth/register/` verify OTP login.
paths:
/api/v1/admin_backend/auth/users/{user_id}/:
get:
operationId: v1_admin_backend_auth_users_retrieve
parameters:
- in: path
name: user_id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
put:
operationId: v1_admin_backend_auth_users_update
parameters:
- in: path
name: user_id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/auth/users/{user_id}/force-password-reset/:
post:
operationId: v1_admin_backend_auth_users_force_password_reset_create
parameters:
- in: path
name: user_id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/auth/users/{user_id}/reactivate/:
post:
operationId: v1_admin_backend_auth_users_reactivate_create
parameters:
- in: path
name: user_id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/auth/users/{user_id}/suspend/:
post:
operationId: v1_admin_backend_auth_users_suspend_create
parameters:
- in: path
name: user_id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/auth/users/{user_id}/update-role/:
post:
operationId: v1_admin_backend_auth_users_update_role_create
parameters:
- in: path
name: user_id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/auth/users/{user_id}/verify/:
post:
operationId: v1_admin_backend_auth_users_verify_create
parameters:
- in: path
name: user_id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/catalog/blog/{post_id}/archive/:
post:
operationId: v1_admin_backend_catalog_blog_archive_create
parameters:
- in: path
name: post_id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/catalog/blog/{post_id}/update/:
patch:
operationId: v1_admin_backend_catalog_blog_update_partial_update
parameters:
- in: path
name: post_id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/catalog/blog/create/:
post:
operationId: v1_admin_backend_catalog_blog_create_create
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/catalog/brands/{brand_id}/archive/:
post:
operationId: v1_admin_backend_catalog_brands_archive_create
parameters:
- in: path
name: brand_id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/catalog/brands/{brand_id}/update/:
patch:
operationId: v1_admin_backend_catalog_brands_update_partial_update
parameters:
- in: path
name: brand_id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/catalog/brands/create/:
post:
operationId: v1_admin_backend_catalog_brands_create_create
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/catalog/categories/{category_id}/archive/:
post:
operationId: v1_admin_backend_catalog_categories_archive_create
parameters:
- in: path
name: category_id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/catalog/categories/{category_id}/update/:
patch:
operationId: v1_admin_backend_catalog_categories_update_partial_update
parameters:
- in: path
name: category_id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/catalog/categories/create/:
post:
operationId: v1_admin_backend_catalog_categories_create_create
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/catalog/collections/{collection_id}/archive/:
post:
operationId: v1_admin_backend_catalog_collections_archive_create
parameters:
- in: path
name: collection_id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/catalog/collections/{collection_id}/update/:
patch:
operationId: v1_admin_backend_catalog_collections_update_partial_update
parameters:
- in: path
name: collection_id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/catalog/collections/create/:
post:
operationId: v1_admin_backend_catalog_collections_create_create
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/chat/escalations/{escalation_id}/resolve/:
post:
operationId: v1_admin_backend_chat_escalations_resolve_create
parameters:
- in: path
name: escalation_id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/client/profiles/{profile_id}/:
put:
operationId: v1_admin_backend_client_profiles_update
parameters:
- in: path
name: profile_id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
patch:
operationId: v1_admin_backend_client_profiles_partial_update
parameters:
- in: path
name: profile_id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/delivery/{order_id}/update/:
post:
operationId: v1_admin_backend_delivery_update_create
description: Updates delivery status for legacy orders while apps/order migration
is pending.
summary: Update Delivery Status
parameters:
- in: path
name: order_id
schema:
type: string
required: true
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/DeliveryStatusUpdateRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/DeliveryStatusUpdateRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/DeliveryStatusUpdateRequest'
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/DeliveryStatusUpdate'
description: ''
/api/v1/admin_backend/measurements/{profile_id}/verify/:
post:
operationId: v1_admin_backend_measurements_verify_create
parameters:
- in: path
name: profile_id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/notification/broadcast/:
post:
operationId: v1_admin_backend_notification_broadcast_create
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/order/{id}/cancel/:
post:
operationId: v1_admin_backend_order_cancel_create
parameters:
- in: path
name: id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/order/{id}/release-escrow/:
post:
operationId: v1_admin_backend_order_release_escrow_create
parameters:
- in: path
name: id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/order/{id}/transition/:
post:
operationId: v1_admin_backend_order_transition_create
parameters:
- in: path
name: id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/payment/{payment_intent_id}/refund/:
post:
operationId: v1_admin_backend_payment_refund_create
parameters:
- in: path
name: payment_intent_id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/providers/cloudinary/update/:
post:
operationId: v1_admin_backend_providers_cloudinary_update_create
description: POST /api/admin/providers/cloudinary/update/
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/providers/email/update/:
post:
operationId: v1_admin_backend_providers_email_update_create
description: POST /api/admin/providers/email/update/
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/providers/kyc/update/:
post:
operationId: v1_admin_backend_providers_kyc_update_create
description: POST /api/admin/providers/kyc/update/
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/providers/sms/update/:
post:
operationId: v1_admin_backend_providers_sms_update_create
description: POST /api/admin/providers/sms/update/
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/settings/update/:
post:
operationId: v1_admin_backend_settings_update_create
description: POST /api/admin/settings/update/
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/support/{ticket_id}/assign/:
post:
operationId: v1_admin_backend_support_assign_create
parameters:
- in: path
name: ticket_id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/support/{ticket_id}/resolve/:
post:
operationId: v1_admin_backend_support_resolve_create
parameters:
- in: path
name: ticket_id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/vendor/{vendor_id}/approve/:
post:
operationId: v1_admin_backend_vendor_approve_create
description: POST /api/admin/vendor/{vendor_id}/approve/
parameters:
- in: path
name: vendor_id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/vendor/{vendor_id}/commission/:
patch:
operationId: v1_admin_backend_vendor_commission_partial_update
description: PATCH /api/admin/vendor/{vendor_id}/commission/
parameters:
- in: path
name: vendor_id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/vendor/{vendor_id}/featured/:
patch:
operationId: v1_admin_backend_vendor_featured_partial_update
description: PATCH /api/admin/vendor/{vendor_id}/featured/
parameters:
- in: path
name: vendor_id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/vendor/{vendor_id}/reactivate/:
post:
operationId: v1_admin_backend_vendor_reactivate_create
description: POST /api/admin/vendor/{vendor_id}/reactivate/
parameters:
- in: path
name: vendor_id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/vendor/{vendor_id}/reject/:
post:
operationId: v1_admin_backend_vendor_reject_create
description: POST /api/admin/vendor/{vendor_id}/reject/
parameters:
- in: path
name: vendor_id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/admin_backend/vendor/{vendor_id}/suspend/:
post:
operationId: v1_admin_backend_vendor_suspend_create
description: POST /api/admin/vendor/{vendor_id}/suspend/
parameters:
- in: path
name: vendor_id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/analytics/alert-rules/:
get:
operationId: v1_analytics_alert_rules_list
description: ViewSet for managing alert rules (admin only).
parameters:
- name: page
required: false
in: query
description: A page number within the paginated result set.
schema:
type: integer
- name: page_size
required: false
in: query
description: Number of results to return per page.
schema:
type: integer
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedAlertRuleList'
description: ''
post:
operationId: v1_analytics_alert_rules_create
description: ViewSet for managing alert rules (admin only).
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/AlertRuleRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/AlertRuleRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/AlertRuleRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/AlertRule'
description: ''
/api/v1/analytics/alert-rules/{id}/:
get:
operationId: v1_analytics_alert_rules_retrieve
description: ViewSet for managing alert rules (admin only).
parameters:
- in: path
name: id
schema:
type: integer
description: A unique integer value identifying this Alert Rule.
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/AlertRule'
description: ''
put:
operationId: v1_analytics_alert_rules_update
description: ViewSet for managing alert rules (admin only).
parameters:
- in: path
name: id
schema:
type: integer
description: A unique integer value identifying this Alert Rule.
required: true
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/AlertRuleRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/AlertRuleRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/AlertRuleRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/AlertRule'
description: ''
patch:
operationId: v1_analytics_alert_rules_partial_update
description: ViewSet for managing alert rules (admin only).
parameters:
- in: path
name: id
schema:
type: integer
description: A unique integer value identifying this Alert Rule.
required: true
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PatchedAlertRuleRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/PatchedAlertRuleRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/PatchedAlertRuleRequest'
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/AlertRule'
description: ''
delete:
operationId: v1_analytics_alert_rules_destroy
description: ViewSet for managing alert rules (admin only).
parameters:
- in: path
name: id
schema:
type: integer
description: A unique integer value identifying this Alert Rule.
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'204':
description: No response body
/api/v1/analytics/alerts/:
get:
operationId: v1_analytics_alerts_list
description: ViewSet for viewing fired alerts.
parameters:
- name: page
required: false
in: query
description: A page number within the paginated result set.
schema:
type: integer
- name: page_size
required: false
in: query
description: Number of results to return per page.
schema:
type: integer
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedAlertList'
description: ''
/api/v1/analytics/alerts/{id}/:
get:
operationId: v1_analytics_alerts_retrieve
description: ViewSet for viewing fired alerts.
parameters:
- in: path
name: id
schema:
type: integer
description: A unique integer value identifying this Alert.
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Alert'
description: ''
/api/v1/analytics/alerts/resolve_all/:
post:
operationId: v1_analytics_alerts_resolve_all_create
description: Resolve all currently firing alerts.
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/AlertRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/AlertRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/AlertRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Alert'
description: ''
/api/v1/analytics/business-metrics/:
get:
operationId: v1_analytics_business_metrics_list
description: ViewSet for viewing business aggregates (admin only).
parameters:
- name: page
required: false
in: query
description: A page number within the paginated result set.
schema:
type: integer
- name: page_size
required: false
in: query
description: Number of results to return per page.
schema:
type: integer
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedBusinessMetricList'
description: ''
/api/v1/analytics/business-metrics/{id}/:
get:
operationId: v1_analytics_business_metrics_retrieve
description: ViewSet for viewing business aggregates (admin only).
parameters:
- in: path
name: id
schema:
type: integer
description: A unique integer value identifying this Business Metric.
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/BusinessMetric'
description: ''
/api/v1/analytics/calculate-business-metrics/:
post:
operationId: v1_analytics_calculate_business_metrics_create
description: Calculate e-commerce aggregates.
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/analytics/check-alerts/:
post:
operationId: v1_analytics_check_alerts_create
description: Evaluate alert rules.
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/analytics/metrics/:
get:
operationId: v1_analytics_metrics_list
description: ViewSet for viewing system telemetry metrics.
parameters:
- name: page
required: false
in: query
description: A page number within the paginated result set.
schema:
type: integer
- name: page_size
required: false
in: query
description: Number of results to return per page.
schema:
type: integer
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedMetricList'
description: ''
/api/v1/analytics/metrics/{id}/:
get:
operationId: v1_analytics_metrics_retrieve
description: ViewSet for viewing system telemetry metrics.
parameters:
- in: path
name: id
schema:
type: integer
description: A unique integer value identifying this Metric.
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Metric'
description: ''
/api/v1/analytics/performance-analytics/:
get:
operationId: v1_analytics_performance_analytics_retrieve
description: Retrieve API latency analytics.
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/analytics/performance-metrics/:
get:
operationId: v1_analytics_performance_metrics_list
description: ViewSet for checking API latencies.
parameters:
- name: page
required: false
in: query
description: A page number within the paginated result set.
schema:
type: integer
- name: page_size
required: false
in: query
description: Number of results to return per page.
schema:
type: integer
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedPerformanceMetricList'
description: ''
/api/v1/analytics/performance-metrics/{id}/:
get:
operationId: v1_analytics_performance_metrics_retrieve
description: ViewSet for checking API latencies.
parameters:
- in: path
name: id
schema:
type: integer
description: A unique integer value identifying this Performance Metric.
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PerformanceMetric'
description: ''
/api/v1/analytics/record-metric/:
post:
operationId: v1_analytics_record_metric_create
description: Record a new telemetry metric.
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/analytics/system-overview/:
get:
operationId: v1_analytics_system_overview_retrieve
description: Retrieve a system-wide overview of active indicators.
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/analytics/user-activities/:
get:
operationId: v1_analytics_user_activities_list
description: ViewSet for auditing user activities.
parameters:
- name: page
required: false
in: query
description: A page number within the paginated result set.
schema:
type: integer
- name: page_size
required: false
in: query
description: Number of results to return per page.
schema:
type: integer
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedUserActivityList'
description: ''
/api/v1/analytics/user-activities/{id}/:
get:
operationId: v1_analytics_user_activities_retrieve
description: ViewSet for auditing user activities.
parameters:
- in: path
name: id
schema:
type: integer
description: A unique integer value identifying this User Activity.
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/UserActivity'
description: ''
/api/v1/analytics/user-analytics/:
get:
operationId: v1_analytics_user_analytics_retrieve
description: Retrieve user activity statistics.
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/auth/google/:
post:
operationId: v1_auth_google_create
description: |-
Authenticate a user via Google OAuth2 ID Token.
Flow:
1. Verify the provided 'id_token' with Google's public keys.
2. Identify or register the user based on email (is_new flag returned).
3. Provision defaults for new client users asynchronously.
4. Record UserSession and LoginEvent for audit tracking.
5. Issue JWT tokens and profile state for frontend routing.
Status Codes:
- 201 Created: New user registered.
- 200 OK: Returning user logged in.
- 401 Unauthorized: Invalid or expired token.
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/AuthGoogleAuthRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/AuthGoogleAuthRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/AuthGoogleAuthRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
- {}
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/AuthGoogleAuth'
description: ''
/api/v1/auth/login/:
post:
operationId: v1_auth_login_create
description: |-
POST /api/v1/auth/login/
Synchronous Login email/phone + password JWT tokens.
Success Response 200:
{ "access": "<JWT>", "refresh": "<JWT>", "user_id": "...", "role": "..." }
Cookie:
fashionistar_rt (HttpOnly) refresh token
Status Codes:
- 200 OK: Authentication successful.
- 401 Unauthorized: Invalid credentials.
- 403 Forbidden: Account unverified or deactivated.
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/AuthLoginRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/AuthLoginRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/AuthLoginRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
- {}
responses:
'200':
description: No response body
/api/v1/auth/login-events/:
get:
operationId: v1_auth_login_events_list
description: Return recent login-event audit entries for the authenticated user.
parameters:
- name: page
required: false
in: query
description: A page number within the paginated result set.
schema:
type: integer
- name: page_size
required: false
in: query
description: Number of results to return per page.
schema:
type: integer
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedLoginEventList'
description: ''
/api/v1/auth/logout/:
post:
operationId: v1_auth_logout_create
description: |-
POST /api/v1/auth/logout/
Terminate the user session and blacklist the refresh token.
Flow:
1. Accept current refresh token.
2. Blacklist the token in the database to prevent reuse.
3. Clear the HttpOnly session cookie.
4. Dispatch log_logout() audit event on commit (compliance).
Status Codes:
- 200 OK: Logout successful.
- 400 Bad Request: Token already invalid.
- 401 Unauthorized: Not authenticated.
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/AuthLogoutRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/AuthLogoutRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/AuthLogoutRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/AuthLogout'
description: ''
/api/v1/auth/me/:
get:
operationId: v1_auth_me_retrieve
description: |-
GET /api/v1/auth/me/
Returns the authenticated user's full profile via MeSerializer.
Used by useAuthHydration() to rehydrate Zustand on page refresh.
Authorization: Bearer <access_token>
Error 401: Not authenticated / token expired.
Response shape (stable contract with frontend):
{
"user_id": "uuid-string",
"identifying_info": "email@example.com" | "+2348012345678",
"member_id": "FASTAR000001" | null,
"email": "email@example.com" | null,
"phone": "+2348012345678" | null,
"first_name": "John" | "",
"last_name": "Doe" | "",
"role": "client" | "vendor" | "staff" | ...,
"auth_provider": "email" | "phone" | "google",
"is_verified": true | false,
"is_active": true | false,
"is_staff": true | false,
"avatar": "https://res.cloudinary.com/..." | null,
"bio": "..." | "",
"country": "Nigeria" | "",
"state": "Lagos" | "",
"city": "Ikeja" | "",
"address": "..." | "",
"date_joined": "2024-01-15T10:30:00+00:00" | null,
"last_login": "2024-01-15T10:30:00+00:00" | null
}
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/AuthMe'
description: ''
/api/v1/auth/register/:
post:
operationId: v1_auth_register_create
description: |-
POST /api/v1/auth/register/
Synchronous user registration.
Accepts email OR phone + password + role, creates the user inside an
atomic transaction, generates a 6-digit OTP, and dispatches it via
Email (if email provided) or SMS (if phone only).
Mirrors legacy: ``userauths.views.RegisterViewCelery``
Request Body:
email (str, optional) : User email address.
phone (str, optional) : Phone in E.164 format (+234...).
password (str, required) : Min 8 chars.
password2 (str, required) : Must match password.
role (str, required) : 'vendor' or 'client'.
Success Response 201:
{ "message": "...", "user_id": "<uuid>", "email": "...", "phone": null }
Error Responses:
400 Validation error
500 Unexpected server error (transaction rolled back)
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/AuthUserRegistrationRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/AuthUserRegistrationRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/AuthUserRegistrationRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
- {}
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/AuthUserRegistration'
description: ''
/api/v1/auth/resend-otp/:
post:
operationId: v1_auth_resend_otp_create
description: |-
POST /api/v1/auth/resend-otp/
Regenerate and resend a 6-digit OTP code.
Flow:
1. Validate user existence by email or phone.
2. Regenerate a new secure OTP code.
3. Dispatch via the primary communication channel.
Status Codes:
- 200 OK: OTP resent successfully.
- 400 Bad Request: Validation or throttled request.
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/AuthResendOTPRequestRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/AuthResendOTPRequestRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/AuthResendOTPRequestRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
- {}
responses:
'200':
description: No response body
/api/v1/auth/sessions/:
get:
operationId: v1_auth_sessions_list
description: List active sessions for the authenticated user.
parameters:
- name: page
required: false
in: query
description: A page number within the paginated result set.
schema:
type: integer
- name: page_size
required: false
in: query
description: Number of results to return per page.
schema:
type: integer
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedUserSessionList'
description: ''
/api/v1/auth/sessions/{session_id}/:
delete:
operationId: v1_auth_sessions_destroy
description: Revoke a specific active session owned by the authenticated user.
parameters:
- in: path
name: session_id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'204':
description: No response body
/api/v1/auth/sessions/revoke-others/:
post:
operationId: v1_auth_sessions_revoke_others_create
description: Terminates every active session on the account except the current
request's session.
summary: Revoke all other sessions
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/auth/token/refresh/:
post:
operationId: v1_auth_token_refresh_create
description: |-
POST /api/v1/auth/token/refresh/
Refresh JWT access tokens using the stored refresh token.
Flow:
1. Extract refresh token from request body (or HttpOnly cookie).
2. Verify refresh token validity via SimpleJWT.
3. Issue new short-lived access token.
Status Codes:
- 200 OK: Access token refreshed.
- 401 Unauthorized: Invalid or expired refresh token.
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/AuthTokenRefreshRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/AuthTokenRefreshRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/AuthTokenRefreshRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
- {}
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/AuthTokenRefresh'
description: ''
/api/v1/auth/verify-otp/:
post:
operationId: v1_auth_verify_otp_create
description: |-
POST /api/v1/auth/verify-otp/
Verify the 6-digit OTP code and activate the user account.
Flow:
1. Accept OTP code (O(1) Redis lookup by hash).
2. Identify the user ID associated with the OTP.
3. Activate the user (is_verified=True, is_active=True).
4. Auto-issue JWT session tokens on successful verification.
Security:
One-time use. OTP is deleted from Redis immediately upon verification.
Issues JWT tokens immediately on success so the user is logged in.
Status Codes:
- 200 OK: Verification successful, account activated.
- 400 Bad Request: Invalid or expired OTP.
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/AuthOTPRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/AuthOTPRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/AuthOTPRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
- {}
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/AuthOTP'
description: ''
/api/v1/catalog/blog/:
post:
operationId: v1_catalog_blog_create
description: Create a catalog resource through the configured domain service.
parameters:
- in: query
name: format
schema:
type: string
enum:
- html
- json
- multipart
tags:
- v1
requestBody:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/CatalogBlogPostRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/CatalogBlogPostRequest'
application/json:
schema:
$ref: '#/components/schemas/CatalogBlogPostRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CatalogBlogPost'
multipart/form-data:
schema:
$ref: '#/components/schemas/CatalogBlogPost'
text/html:
schema:
$ref: '#/components/schemas/CatalogBlogPost'
description: ''
/api/v1/catalog/blog/{slug}/:
put:
operationId: v1_catalog_blog_update
description: Replace a catalog resource through the configured domain service.
parameters:
- in: query
name: format
schema:
type: string
enum:
- html
- json
- multipart
- in: path
name: slug
schema:
type: string
required: true
tags:
- v1
requestBody:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/CatalogBlogPostRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/CatalogBlogPostRequest'
application/json:
schema:
$ref: '#/components/schemas/CatalogBlogPostRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CatalogBlogPost'
multipart/form-data:
schema:
$ref: '#/components/schemas/CatalogBlogPost'
text/html:
schema:
$ref: '#/components/schemas/CatalogBlogPost'
description: ''
patch:
operationId: v1_catalog_blog_partial_update
description: Partially update a catalog resource through the configured service.
parameters:
- in: query
name: format
schema:
type: string
enum:
- html
- json
- multipart
- in: path
name: slug
schema:
type: string
required: true
tags:
- v1
requestBody:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/PatchedCatalogBlogPostRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/PatchedCatalogBlogPostRequest'
application/json:
schema:
$ref: '#/components/schemas/PatchedCatalogBlogPostRequest'
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CatalogBlogPost'
multipart/form-data:
schema:
$ref: '#/components/schemas/CatalogBlogPost'
text/html:
schema:
$ref: '#/components/schemas/CatalogBlogPost'
description: ''
delete:
operationId: v1_catalog_blog_destroy
description: Archive a catalog resource through the configured domain service.
parameters:
- in: query
name: format
schema:
type: string
enum:
- html
- json
- multipart
- in: path
name: slug
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'204':
description: No response body
/api/v1/catalog/brands/:
post:
operationId: v1_catalog_brands_create
description: Create a catalog resource through the configured domain service.
parameters:
- in: query
name: format
schema:
type: string
enum:
- html
- json
- multipart
tags:
- v1
requestBody:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/CatalogBrandRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/CatalogBrandRequest'
application/json:
schema:
$ref: '#/components/schemas/CatalogBrandRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CatalogBrand'
multipart/form-data:
schema:
$ref: '#/components/schemas/CatalogBrand'
text/html:
schema:
$ref: '#/components/schemas/CatalogBrand'
description: ''
/api/v1/catalog/brands/{slug}/:
put:
operationId: v1_catalog_brands_update
description: Replace a catalog resource through the configured domain service.
parameters:
- in: query
name: format
schema:
type: string
enum:
- html
- json
- multipart
- in: path
name: slug
schema:
type: string
required: true
tags:
- v1
requestBody:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/CatalogBrandRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/CatalogBrandRequest'
application/json:
schema:
$ref: '#/components/schemas/CatalogBrandRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CatalogBrand'
multipart/form-data:
schema:
$ref: '#/components/schemas/CatalogBrand'
text/html:
schema:
$ref: '#/components/schemas/CatalogBrand'
description: ''
patch:
operationId: v1_catalog_brands_partial_update
description: Partially update a catalog resource through the configured service.
parameters:
- in: query
name: format
schema:
type: string
enum:
- html
- json
- multipart
- in: path
name: slug
schema:
type: string
required: true
tags:
- v1
requestBody:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/PatchedCatalogBrandRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/PatchedCatalogBrandRequest'
application/json:
schema:
$ref: '#/components/schemas/PatchedCatalogBrandRequest'
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CatalogBrand'
multipart/form-data:
schema:
$ref: '#/components/schemas/CatalogBrand'
text/html:
schema:
$ref: '#/components/schemas/CatalogBrand'
description: ''
delete:
operationId: v1_catalog_brands_destroy
description: Archive a catalog resource through the configured domain service.
parameters:
- in: query
name: format
schema:
type: string
enum:
- html
- json
- multipart
- in: path
name: slug
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'204':
description: No response body
/api/v1/catalog/categories/:
post:
operationId: v1_catalog_categories_create
description: Create a catalog resource through the configured domain service.
parameters:
- in: query
name: format
schema:
type: string
enum:
- html
- json
- multipart
tags:
- v1
requestBody:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/CatalogCategoryRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/CatalogCategoryRequest'
application/json:
schema:
$ref: '#/components/schemas/CatalogCategoryRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CatalogCategory'
multipart/form-data:
schema:
$ref: '#/components/schemas/CatalogCategory'
text/html:
schema:
$ref: '#/components/schemas/CatalogCategory'
description: ''
/api/v1/catalog/categories/{slug}/:
put:
operationId: v1_catalog_categories_update
description: Replace a catalog resource through the configured domain service.
parameters:
- in: query
name: format
schema:
type: string
enum:
- html
- json
- multipart
- in: path
name: slug
schema:
type: string
required: true
tags:
- v1
requestBody:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/CatalogCategoryRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/CatalogCategoryRequest'
application/json:
schema:
$ref: '#/components/schemas/CatalogCategoryRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CatalogCategory'
multipart/form-data:
schema:
$ref: '#/components/schemas/CatalogCategory'
text/html:
schema:
$ref: '#/components/schemas/CatalogCategory'
description: ''
patch:
operationId: v1_catalog_categories_partial_update
description: Partially update a catalog resource through the configured service.
parameters:
- in: query
name: format
schema:
type: string
enum:
- html
- json
- multipart
- in: path
name: slug
schema:
type: string
required: true
tags:
- v1
requestBody:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/PatchedCatalogCategoryRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/PatchedCatalogCategoryRequest'
application/json:
schema:
$ref: '#/components/schemas/PatchedCatalogCategoryRequest'
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CatalogCategory'
multipart/form-data:
schema:
$ref: '#/components/schemas/CatalogCategory'
text/html:
schema:
$ref: '#/components/schemas/CatalogCategory'
description: ''
delete:
operationId: v1_catalog_categories_destroy
description: Archive a catalog resource through the configured domain service.
parameters:
- in: query
name: format
schema:
type: string
enum:
- html
- json
- multipart
- in: path
name: slug
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'204':
description: No response body
/api/v1/catalog/collections/:
post:
operationId: v1_catalog_collections_create
description: Create a catalog resource through the configured domain service.
parameters:
- in: query
name: format
schema:
type: string
enum:
- html
- json
- multipart
tags:
- v1
requestBody:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/CatalogCollectionRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/CatalogCollectionRequest'
application/json:
schema:
$ref: '#/components/schemas/CatalogCollectionRequest'
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CatalogCollection'
multipart/form-data:
schema:
$ref: '#/components/schemas/CatalogCollection'
text/html:
schema:
$ref: '#/components/schemas/CatalogCollection'
description: ''
/api/v1/catalog/collections/{slug}/:
put:
operationId: v1_catalog_collections_update
description: Replace a catalog resource through the configured domain service.
parameters:
- in: query
name: format
schema:
type: string
enum:
- html
- json
- multipart
- in: path
name: slug
schema:
type: string
required: true
tags:
- v1
requestBody:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/CatalogCollectionRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/CatalogCollectionRequest'
application/json:
schema:
$ref: '#/components/schemas/CatalogCollectionRequest'
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CatalogCollection'
multipart/form-data:
schema:
$ref: '#/components/schemas/CatalogCollection'
text/html:
schema:
$ref: '#/components/schemas/CatalogCollection'
description: ''
patch:
operationId: v1_catalog_collections_partial_update
description: Partially update a catalog resource through the configured service.
parameters:
- in: query
name: format
schema:
type: string
enum:
- html
- json
- multipart
- in: path
name: slug
schema:
type: string
required: true
tags:
- v1
requestBody:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/PatchedCatalogCollectionRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/PatchedCatalogCollectionRequest'
application/json:
schema:
$ref: '#/components/schemas/PatchedCatalogCollectionRequest'
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CatalogCollection'
multipart/form-data:
schema:
$ref: '#/components/schemas/CatalogCollection'
text/html:
schema:
$ref: '#/components/schemas/CatalogCollection'
description: ''
delete:
operationId: v1_catalog_collections_destroy
description: Archive a catalog resource through the configured domain service.
parameters:
- in: query
name: format
schema:
type: string
enum:
- html
- json
- multipart
- in: path
name: slug
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'204':
description: No response body
/api/v1/chat/conversations/:
get:
operationId: v1_chat_conversations_retrieve
description: |-
GET /api/v1/chat/conversations/
Returns all conversations for the authenticated user.
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/chat/conversations/{conversation_id}/:
get:
operationId: v1_chat_conversations_retrieve_2
description: |-
GET /api/v1/chat/conversations/<conversation_id>/
GET messages for a conversation (paginated, newest-first).
Also marks all messages as read for the requesting participant.
parameters:
- in: path
name: conversation_id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/chat/conversations/{conversation_id}/flag/:
post:
operationId: v1_chat_conversations_flag_create
description: |-
POST /api/v1/chat/conversations/<conversation_id>/flag/
File a moderation report for a conversation.
parameters:
- in: path
name: conversation_id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/chat/conversations/{conversation_id}/messages/:
post:
operationId: v1_chat_conversations_messages_create
description: |-
POST /api/v1/chat/conversations/<conversation_id>/messages/
Send a text message in a conversation.
parameters:
- in: path
name: conversation_id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/chat/conversations/{conversation_id}/offers/:
post:
operationId: v1_chat_conversations_offers_create
description: |-
POST /api/v1/chat/conversations/<conversation_id>/offers/
Vendor creates a price offer for the buyer.
parameters:
- in: path
name: conversation_id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/chat/conversations/{conversation_id}/read/:
post:
operationId: v1_chat_conversations_read_create
description: |-
POST /api/v1/chat/conversations/<conversation_id>/read/
Mark all messages in a conversation as read for the requesting participant.
parameters:
- in: path
name: conversation_id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/chat/conversations/start/:
post:
operationId: v1_chat_conversations_start_create
description: |-
POST /api/v1/chat/conversations/start/
Buyer starts a new conversation with a vendor.
Idempotent — returns existing active thread if one exists.
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/chat/offers/{offer_id}/{action}/:
post:
operationId: v1_chat_offers_create
description: |-
POST /api/v1/chat/offers/<offer_id>/accept/
POST /api/v1/chat/offers/<offer_id>/decline/
Buyer accepts or declines an offer.
parameters:
- in: path
name: action
schema:
type: string
required: true
- in: path
name: offer_id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/chatbot/api/client/end-session/:
post:
operationId: v1_chatbot_api_client_end_session_create
description: |-
پایان جلسهٔ فعال چت‌بات برای کاربر جاری.
این اکشن، جلسهٔ فعال چت‌بات مرتبط با کاربر احراز هویت‌شده را از طریق سرویس چت‌بات (get_chatbot_service) خاتمه می‌دهد. فراخوانی سرویس معمولاً شامل عملیات‌های زیر است:
- علامت‌گذاری جلسه به‌عنوان "پایان‌یافته" در پایگاه‌داده.
- ذخیره/همگام‌سازی وضعیت نهایی جلسه و گفتگوها.
- انجام پاک‌سازی زمینه‌های مرتبط در حافظه یا صف‌های پردازشی که ممکن است برای نگهداری کانتکست مکالمه استفاده شده باشند.
- در صورت وجود وظایف پس‌زمینه (مثل انتها دادن به پردازش‌های هوش‌مصنوعی یا آزادسازی منابع مدل)، راه‌اندازی یا برنامه‌ریزی آن‌ها.
پاسخ:
- موفقیت: JSON با کلید `message` و مقدار متنی تایید (HTTP 200).
- خطا: در صورت بروز استثنا، JSON با کلید `error` و پیام خطا بازگردانده شده و کد وضعیت HTTP 500 برگردانده می‌شود.
توجه: پیاده‌سازی دقیق رفتارهای دخیل در سرویس چت‌بات (ذخیره‌سازی، همگام‌سازی مدل/وظایف پس‌زمینه و ...) در لایهٔ سرویس قرار دارد و این اکشن صرفاً درگاه فراخوانی و مدیریت پاسخ/خطا برای آن سرویس است.
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/chatbot/api/client/request-consultation/:
post:
operationId: v1_chatbot_api_client_request_consultation_create
description: Initiate request for custom tailoring consultation
summary: Request bespoke consultation
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/BespokeConsultationRequestRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/BespokeConsultationRequestRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/BespokeConsultationRequestRequest'
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
type: object
additionalProperties: {}
description: ''
/api/v1/chatbot/api/client/send-message/:
post:
operationId: v1_chatbot_api_client_send_message_create
description: Send client message and get chatbot response
summary: Send message to chatbot
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/SendMessageRequestRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/SendMessageRequestRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/SendMessageRequestRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/SendMessageResponse'
description: ''
/api/v1/chatbot/api/client/start-session/:
post:
operationId: v1_chatbot_api_client_start_session_create
description: Initialize or get active chatbot session for client
summary: Start client chatbot session
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/StartSessionResponse'
description: ''
/api/v1/chatbot/api/client/style-assessment/:
post:
operationId: v1_chatbot_api_client_style_assessment_create
description: Initialize style assessment questionnaire for the client
summary: Start style assessment
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
type: object
additionalProperties: {}
description: ''
/api/v1/chatbot/api/client/submit-assessment/:
post:
operationId: v1_chatbot_api_client_submit_assessment_create
description: Submit style preferences and get outfits recommendations
summary: Submit style assessment responses
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/StyleAssessmentRequestRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/StyleAssessmentRequestRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/StyleAssessmentRequestRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
type: object
additionalProperties: {}
description: ''
/api/v1/chatbot/api/conversations/:
get:
operationId: v1_chatbot_api_conversations_list
parameters:
- name: page
required: false
in: query
description: A page number within the paginated result set.
schema:
type: integer
- name: page_size
required: false
in: query
description: Number of results to return per page.
schema:
type: integer
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedConversationList'
description: ''
post:
operationId: v1_chatbot_api_conversations_create
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/ConversationRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/ConversationRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/ConversationRequest'
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/Conversation'
description: ''
/api/v1/chatbot/api/conversations/{id}/:
get:
operationId: v1_chatbot_api_conversations_retrieve
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this Conversation.
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Conversation'
description: ''
put:
operationId: v1_chatbot_api_conversations_update
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this Conversation.
required: true
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/ConversationRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/ConversationRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/ConversationRequest'
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Conversation'
description: ''
patch:
operationId: v1_chatbot_api_conversations_partial_update
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this Conversation.
required: true
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PatchedConversationRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/PatchedConversationRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/PatchedConversationRequest'
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Conversation'
description: ''
delete:
operationId: v1_chatbot_api_conversations_destroy
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this Conversation.
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'204':
description: No response body
/api/v1/chatbot/api/conversations/{id}/history/:
get:
operationId: v1_chatbot_api_conversations_history_retrieve
description: |-
بازگرداندن تاریخچه یک مکالمه مشخص.
این اکشن تاریخچه پیام‌های یک گفت‌وگو را برمی‌گرداند: ابتدا شیء conversation با self.get_object() واکشی می‌شود، سپس پیام‌ها بر اساس `created_at` نزولی مرتب و تا تعداد `limit` برش داده می‌شوند. پاسخ JSON شامل نسخه‌ی سریالایز شده‌ی گفت‌وگو، لیست پیام‌ها (جدیدترین ابتدا)، تعداد کل پیام‌ها و یک فِلَگ `has_more` برای نشان دادن وجود پیام‌های بیش‌تر است.
پارامترهای کوئری:
limit (int, اختیاری): حداکثر تعداد پیام‌هایی که برگردانده می‌شوند. مقدار پیش‌فرض 50 است.
مقدار بازگشتی:
rest_framework.response.Response: بدنه‌ی JSON با کلیدهای:
- conversation: داده‌های سریالایز شدهٔ گفت‌وگو (ConversationListSerializer).
- messages: فهرست پیام‌های سریالایز شده (MessageSerializer) مرتب‌شده به صورت نزولی بر اساس `created_at`.
- total_messages: تعداد کل پیام‌های موجود در آن گفت‌وگو.
- has_more: بولین که نشان می‌دهد آیا پیام‌های بیشتری نسبت به `limit` وجود دارد یا خیر.
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this Conversation.
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Conversation'
description: ''
/api/v1/chatbot/api/messages/:
get:
operationId: v1_chatbot_api_messages_list
parameters:
- name: page
required: false
in: query
description: A page number within the paginated result set.
schema:
type: integer
- name: page_size
required: false
in: query
description: Number of results to return per page.
schema:
type: integer
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedMessageList'
description: ''
post:
operationId: v1_chatbot_api_messages_create
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/MessageRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/MessageRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/MessageRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/Message'
description: ''
/api/v1/chatbot/api/messages/{id}/:
get:
operationId: v1_chatbot_api_messages_retrieve
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this Message.
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Message'
description: ''
put:
operationId: v1_chatbot_api_messages_update
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this Message.
required: true
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/MessageRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/MessageRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/MessageRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Message'
description: ''
patch:
operationId: v1_chatbot_api_messages_partial_update
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this Message.
required: true
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PatchedMessageRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/PatchedMessageRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/PatchedMessageRequest'
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Message'
description: ''
delete:
operationId: v1_chatbot_api_messages_destroy
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this Message.
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'204':
description: No response body
/api/v1/chatbot/api/sessions/:
get:
operationId: v1_chatbot_api_sessions_list
description: مدیریت جلسات چت‌بات
parameters:
- name: page
required: false
in: query
description: A page number within the paginated result set.
schema:
type: integer
- name: page_size
required: false
in: query
description: Number of results to return per page.
schema:
type: integer
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedChatbotSessionList'
description: ''
post:
operationId: v1_chatbot_api_sessions_create
description: مدیریت جلسات چت‌بات
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/ChatbotSessionRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/ChatbotSessionRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/ChatbotSessionRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/ChatbotSession'
description: ''
/api/v1/chatbot/api/sessions/{id}/:
get:
operationId: v1_chatbot_api_sessions_retrieve
description: مدیریت جلسات چت‌بات
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this Chatbot Session.
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/ChatbotSession'
description: ''
put:
operationId: v1_chatbot_api_sessions_update
description: مدیریت جلسات چت‌بات
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this Chatbot Session.
required: true
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/ChatbotSessionRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/ChatbotSessionRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/ChatbotSessionRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/ChatbotSession'
description: ''
patch:
operationId: v1_chatbot_api_sessions_partial_update
description: مدیریت جلسات چت‌بات
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this Chatbot Session.
required: true
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PatchedChatbotSessionRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/PatchedChatbotSessionRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/PatchedChatbotSessionRequest'
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/ChatbotSession'
description: ''
delete:
operationId: v1_chatbot_api_sessions_destroy
description: مدیریت جلسات چت‌بات
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this Chatbot Session.
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'204':
description: No response body
/api/v1/chatbot/api/vendor/catalog-support/:
post:
operationId: v1_chatbot_api_vendor_catalog_support_create
description: Get recommendation and categorization for new products
summary: Request product catalog support
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/SizeRecommendationRequestRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/SizeRecommendationRequestRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/SizeRecommendationRequestRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
type: object
additionalProperties: {}
description: ''
/api/v1/chatbot/api/vendor/product-info/:
post:
operationId: v1_chatbot_api_vendor_product_info_create
description: Get fabric, pricing and packaging details
summary: Request product specifications
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/ProductInquiryRequestRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/ProductInquiryRequestRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/ProductInquiryRequestRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
type: object
additionalProperties: {}
description: ''
/api/v1/chatbot/api/vendor/search-references/:
get:
operationId: v1_chatbot_api_vendor_search_references_retrieve
description: Search design ideas, trends and fabric references
summary: Search fashion references
parameters:
- in: query
name: query
schema:
type: string
description: Search Query
- in: query
name: specialty
schema:
type: string
description: Specialty Niche
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
type: object
additionalProperties: {}
description: ''
/api/v1/chatbot/api/vendor/send-message/:
post:
operationId: v1_chatbot_api_vendor_send_message_create
description: Send vendor message and get chatbot response
summary: Send message to chatbot
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/SendMessageRequestRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/SendMessageRequestRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/SendMessageRequestRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/SendMessageResponse'
description: ''
/api/v1/chatbot/api/vendor/start-session/:
post:
operationId: v1_chatbot_api_vendor_start_session_create
description: Initialize or get active chatbot session for vendor
summary: Start vendor chatbot session
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/StartSessionResponse'
description: ''
/api/v1/chatbot/api/vendor/tailoring-guideline/:
get:
operationId: v1_chatbot_api_vendor_tailoring_guideline_retrieve
description: Fetch custom tailoring assembly and pattern details
summary: Get tailoring guideline
parameters:
- in: query
name: condition
schema:
type: string
description: Garment Type
- in: query
name: severity
schema:
type: string
default: moderate
description: Complexity
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
type: object
additionalProperties: {}
description: ''
/api/v1/client/addresses/:
get:
operationId: v1_client_addresses_list
description: |-
GET /api/v1/client/addresses/ — list saved addresses
POST /api/v1/client/addresses/ — add new address
parameters:
- name: page
required: false
in: query
description: A page number within the paginated result set.
schema:
type: integer
- name: page_size
required: false
in: query
description: Number of results to return per page.
schema:
type: integer
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedClientAddressList'
description: ''
post:
operationId: v1_client_addresses_create
description: |-
GET /api/v1/client/addresses/ — list saved addresses
POST /api/v1/client/addresses/ — add new address
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/AddressCreateRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/AddressCreateRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/AddressCreateRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/AddressCreate'
description: ''
/api/v1/client/addresses/{address_id}/:
delete:
operationId: v1_client_addresses_destroy
description: DELETE /api/v1/client/addresses/{id}/ soft-delete address
parameters:
- in: path
name: address_id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'204':
description: No response body
/api/v1/client/addresses/{address_id}/set-default/:
post:
operationId: v1_client_addresses_set_default_create
description: |-
POST /api/v1/client/addresses/{id}/set-default/
Set a specific address as the default shipping address.
parameters:
- in: path
name: address_id
schema:
type: string
format: uuid
required: true
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/ClientAddressRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/ClientAddressRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/ClientAddressRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/ClientAddress'
description: ''
/api/v1/client/orders/:
get:
operationId: v1_client_orders_list
description: |-
GET /api/v1/client/orders/
Return all paid orders for the authenticated client.
Prefetches orderitems to avoid N+1 on order detail pages.
Returns a list of all successful orders placed by the client.
Validation Logic:
- Filter: Only returns orders where payment_status is 'paid'.
- Ordering: Date-descending (most recent first).
Security:
- Requires IsAuthenticated + IsClient.
Status Codes:
200 OK: List of orders returned.
parameters:
- name: page
required: false
in: query
description: A page number within the paginated result set.
schema:
type: integer
- name: page_size
required: false
in: query
description: Number of results to return per page.
schema:
type: integer
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedClientCartOrderList'
description: ''
/api/v1/client/orders/{oid}/:
get:
operationId: v1_client_orders_retrieve
description: |-
GET /api/v1/client/orders/<str:oid>/
Return detail for a single paid order scoped to this client.
Uses oid (order identifier) not PK for public safety.
Status Codes:
200 OK: Order details returned.
404 Not Found: Order missing or unauthorized.
parameters:
- in: path
name: oid
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/ClientCartOrder'
description: ''
/api/v1/client/profile/:
get:
operationId: v1_client_profile_retrieve
description: |-
GET /api/v1/client/profile/ — retrieve profile
PATCH /api/v1/client/profile/ — update profile
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/ClientProfileOutput'
description: ''
put:
operationId: v1_client_profile_update
description: |-
GET /api/v1/client/profile/ — retrieve profile
PATCH /api/v1/client/profile/ — update profile
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/ClientProfileUpdateRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/ClientProfileUpdateRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/ClientProfileUpdateRequest'
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/ClientProfileUpdate'
description: ''
patch:
operationId: v1_client_profile_partial_update
description: |-
GET /api/v1/client/profile/ — retrieve profile
PATCH /api/v1/client/profile/ — update profile
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PatchedClientProfileUpdateRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/PatchedClientProfileUpdateRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/PatchedClientProfileUpdateRequest'
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/ClientProfileUpdate'
description: ''
/api/v1/client/reviews/create/:
post:
operationId: v1_client_reviews_create_create
description: |-
POST /api/v1/client/reviews/create/
Submits a new rating and review for a product.
Validation Logic:
- Payload: Validates product_id presence and rating (1–5 scale).
- Duplication: Enforced at serializer / model level.
Security:
- Requires IsAuthenticated + IsClient.
Status Codes:
201 Created: Review successfully recorded.
400 Bad Request: Missing product_id or invalid rating.
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/ClientReviewRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/ClientReviewRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/ClientReviewRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/ClientReview'
description: ''
/api/v1/client/wallet/balance/:
get:
operationId: v1_client_wallet_balance_retrieve
description: |-
GET /api/v1/client/wallet/balance/
Retrieves the authenticated client's current Fashionistar wallet balance.
Auto-provisions a wallet via WalletProvisioningService if none exists.
Security: IsAuthenticated + IsClient
Status: 200 OK balance data returned.
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Wallet'
description: ''
/api/v1/client/wallet/topup/initiate/:
post:
operationId: v1_client_wallet_topup_initiate_create
description: |-
POST /api/v1/client/wallet/topup/initiate/
Initiates a Paystack wallet top-up payment intent.
Returns a payment_url the client redirects to for card payment.
Body:
{
"amount": 5000, // NGN amount (number)
"payment_method": "card", // card | bank_transfer
"callback_url": "https://.../verify" // optional redirect URL
}
Response (200):
{
"status": "pending",
"payment_url": "https://paystack.com/...",
"reference": "..."
}
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/client/wallet/transfer/:
post:
operationId: v1_client_wallet_transfer_create
description: |-
POST /api/v1/client/wallet/transfer/
Executes an atomic wallet-to-wallet transfer to another Fashionistar user.
Body:
{
"receiver_id": "<uuid>",
"amount": "500.00",
"transaction_password": "1234"
}
Security:
- Verifies the 4-digit Transaction PIN via WalletBalanceService.transfer().
- KYC gate enforced in the service (sender must be KYC-approved).
- Idempotency-Key header is forwarded to prevent duplicate transactions.
Status:
200 OK: Transfer completed.
400 Bad Request: Insufficient funds, invalid PIN, or validation error.
404 Not Found: Receiver not found.
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/WalletTransferRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/WalletTransferRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/WalletTransferRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/WalletTransfer'
description: ''
/api/v1/client/wallet/withdraw/:
post:
operationId: v1_client_wallet_withdraw_create
description: |-
POST /api/v1/client/wallet/withdraw/
Create a KYC-gated, PIN-protected bank withdrawal request.
This is the correct financial-exit endpoint for the WithdrawalForm UI.
It uses WalletWithdrawalService.request_withdrawal() which:
- Asserts the user has an approved KYC submission.
- Verifies the 4-digit transaction PIN.
- Moves funds from available_balance pending_balance (atomic DB txn).
- Creates an immutable PAYOUT ledger entry (CBN compliance).
- Writes a compliance audit trail (CBN/GDPR permanent retention).
- Supports idempotency via Idempotency-Key header.
Body:
{
"amount": "5000.00", // min ₦1,000 enforced in Zod (frontend)
"pin": "1234", // 4-digit wallet PIN
"bank_code": "057", // Nigerian bank code (e.g. Zenith = "057")
"account_number": "0123456789", // 10-digit NUBAN
"account_name": "Jane Doe" // beneficiary name
}
Response (200):
{
"transaction_id": "<uuid>",
"reference": "wallet-withdrawal:...",
"status": "processing",
"amount": "5000.00",
"available_balance": "15000.00",
"pending_balance": "5000.00"
}
Error Codes:
400 Invalid PIN / insufficient balance / validation errors.
403 KYC not approved (assert_kyc_approved gate).
422 Idempotent duplicate detected (returns existing transaction).
Security:
- IsAuthenticated + IsClient
- KYC approved (enforced by WalletWithdrawalService)
- PIN verified (bcrypt check via wallet.verify_pin())
- Idempotency-Key prevents double-submission on network retry
CBN Compliance:
- Funds remain in pending_balance until the payment provider confirms
the bank transfer (async execution by Celery payout task).
- The immutable PAYOUT ledger row is created before this response returns.
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/client/wishlist/:
get:
operationId: v1_client_wishlist_retrieve
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/ClientWishlist'
description: ''
/api/v1/client/wishlist/toggle/:
post:
operationId: v1_client_wishlist_toggle_create
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/WishlistToggleRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/WishlistToggleRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/WishlistToggleRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/WishlistToggle'
description: ''
/api/v1/common/reference/banks/:
get:
operationId: v1_common_reference_banks_list
description: Returns banks for the specified country. Nigeria defaults to Paystack-backed
bank metadata.
summary: List banks
parameters:
- name: page
required: false
in: query
description: A page number within the paginated result set.
schema:
type: integer
- name: page_size
required: false
in: query
description: Number of results to return per page.
schema:
type: integer
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
- {}
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedReferenceBankList'
description: ''
/api/v1/common/reference/countries/:
get:
operationId: v1_common_reference_countries_list
description: Returns static supported country metadata for web, admin, and mobile
clients.
summary: List supported countries
parameters:
- name: page
required: false
in: query
description: A page number within the paginated result set.
schema:
type: integer
- name: page_size
required: false
in: query
description: Number of results to return per page.
schema:
type: integer
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
- {}
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedReferenceCountryList'
description: ''
/api/v1/common/reference/countries/{country_code}/cities/:
get:
operationId: v1_common_reference_countries_cities_list
description: Returns cities for the selected country, optionally filtered by
state and LGA.
summary: List cities for a country
parameters:
- in: path
name: country_code
schema:
type: string
required: true
- name: page
required: false
in: query
description: A page number within the paginated result set.
schema:
type: integer
- name: page_size
required: false
in: query
description: Number of results to return per page.
schema:
type: integer
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
- {}
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedReferenceCityList'
description: ''
/api/v1/common/reference/countries/{country_code}/states/:
get:
operationId: v1_common_reference_countries_states_list
description: Returns states configured for the selected country.
summary: List states for a country
parameters:
- in: path
name: country_code
schema:
type: string
required: true
- name: page
required: false
in: query
description: A page number within the paginated result set.
schema:
type: integer
- name: page_size
required: false
in: query
description: Number of results to return per page.
schema:
type: integer
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
- {}
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedReferenceStateList'
description: ''
/api/v1/common/reference/countries/{country_code}/states/{state_code}/lgas/:
get:
operationId: v1_common_reference_countries_states_lgas_list
description: Returns local government areas for the selected country and state.
summary: List LGAs for a state
parameters:
- in: path
name: country_code
schema:
type: string
required: true
- name: page
required: false
in: query
description: A page number within the paginated result set.
schema:
type: integer
- name: page_size
required: false
in: query
description: Number of results to return per page.
schema:
type: integer
- in: path
name: state_code
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
- {}
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedReferenceLgaList'
description: ''
/api/v1/common/reference/countries/{country_code}/states/{state_code}/lgas/{lga_code}/cities/:
get:
operationId: v1_common_reference_countries_states_lgas_cities_list
description: Returns cities for the selected country, state, and LGA.
summary: List cities in an LGA
parameters:
- in: path
name: country_code
schema:
type: string
required: true
- in: path
name: lga_code
schema:
type: string
required: true
- name: page
required: false
in: query
description: A page number within the paginated result set.
schema:
type: integer
- name: page_size
required: false
in: query
description: Number of results to return per page.
schema:
type: integer
- in: path
name: state_code
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
- {}
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedReferenceCityList'
description: ''
/api/v1/integrations/ai/generate/:
post:
operationId: v1_integrations_ai_generate_create
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/integrations/credentials/:
get:
operationId: v1_integrations_credentials_list
parameters:
- name: page
required: false
in: query
description: A page number within the paginated result set.
schema:
type: integer
- name: page_size
required: false
in: query
description: Number of results to return per page.
schema:
type: integer
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedIntegrationCredentialList'
description: ''
post:
operationId: v1_integrations_credentials_create
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/IntegrationCredentialRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/IntegrationCredentialRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/IntegrationCredentialRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/IntegrationCredential'
description: ''
/api/v1/integrations/credentials/{id}/:
get:
operationId: v1_integrations_credentials_retrieve
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this Integration Credential.
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/IntegrationCredential'
description: ''
put:
operationId: v1_integrations_credentials_update
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this Integration Credential.
required: true
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/IntegrationCredentialRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/IntegrationCredentialRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/IntegrationCredentialRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/IntegrationCredential'
description: ''
patch:
operationId: v1_integrations_credentials_partial_update
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this Integration Credential.
required: true
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PatchedIntegrationCredentialRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/PatchedIntegrationCredentialRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/PatchedIntegrationCredentialRequest'
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/IntegrationCredential'
description: ''
delete:
operationId: v1_integrations_credentials_destroy
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this Integration Credential.
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'204':
description: No response body
/api/v1/integrations/credentials/{id}/rotate/:
post:
operationId: v1_integrations_credentials_rotate_create
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this Integration Credential.
required: true
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/IntegrationCredentialRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/IntegrationCredentialRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/IntegrationCredentialRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/IntegrationCredential'
description: ''
/api/v1/integrations/logs/:
get:
operationId: v1_integrations_logs_list
parameters:
- name: page
required: false
in: query
description: A page number within the paginated result set.
schema:
type: integer
- name: page_size
required: false
in: query
description: Number of results to return per page.
schema:
type: integer
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedIntegrationLogList'
description: ''
/api/v1/integrations/logs/{id}/:
get:
operationId: v1_integrations_logs_retrieve
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this Integration Log.
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/IntegrationLog'
description: ''
/api/v1/integrations/providers/:
get:
operationId: v1_integrations_providers_list
description: ViewSet for managing external Integration Providers.
parameters:
- name: page
required: false
in: query
description: A page number within the paginated result set.
schema:
type: integer
- name: page_size
required: false
in: query
description: Number of results to return per page.
schema:
type: integer
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedIntegrationProviderList'
description: ''
post:
operationId: v1_integrations_providers_create
description: ViewSet for managing external Integration Providers.
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/IntegrationProviderRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/IntegrationProviderRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/IntegrationProviderRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/IntegrationProvider'
description: ''
/api/v1/integrations/providers/{slug}/:
get:
operationId: v1_integrations_providers_retrieve
description: ViewSet for managing external Integration Providers.
parameters:
- in: path
name: slug
schema:
type: string
title: Unique Slug
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/IntegrationProvider'
description: ''
put:
operationId: v1_integrations_providers_update
description: ViewSet for managing external Integration Providers.
parameters:
- in: path
name: slug
schema:
type: string
title: Unique Slug
required: true
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/IntegrationProviderRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/IntegrationProviderRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/IntegrationProviderRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/IntegrationProvider'
description: ''
patch:
operationId: v1_integrations_providers_partial_update
description: ViewSet for managing external Integration Providers.
parameters:
- in: path
name: slug
schema:
type: string
title: Unique Slug
required: true
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PatchedIntegrationProviderRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/PatchedIntegrationProviderRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/PatchedIntegrationProviderRequest'
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/IntegrationProvider'
description: ''
delete:
operationId: v1_integrations_providers_destroy
description: ViewSet for managing external Integration Providers.
parameters:
- in: path
name: slug
schema:
type: string
title: Unique Slug
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'204':
description: No response body
/api/v1/integrations/providers/{slug}/health_check/:
get:
operationId: v1_integrations_providers_health_check_retrieve
description: ViewSet for managing external Integration Providers.
parameters:
- in: path
name: slug
schema:
type: string
title: Unique Slug
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/IntegrationProvider'
description: ''
/api/v1/integrations/providers/{slug}/statistics/:
get:
operationId: v1_integrations_providers_statistics_retrieve
description: ViewSet for managing external Integration Providers.
parameters:
- in: path
name: slug
schema:
type: string
title: Unique Slug
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/IntegrationProvider'
description: ''
/api/v1/integrations/rate-limits/:
get:
operationId: v1_integrations_rate_limits_list
parameters:
- name: page
required: false
in: query
description: A page number within the paginated result set.
schema:
type: integer
- name: page_size
required: false
in: query
description: Number of results to return per page.
schema:
type: integer
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedRateLimitRuleList'
description: ''
post:
operationId: v1_integrations_rate_limits_create
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/RateLimitRuleRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/RateLimitRuleRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/RateLimitRuleRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/RateLimitRule'
description: ''
/api/v1/integrations/rate-limits/{id}/:
get:
operationId: v1_integrations_rate_limits_retrieve
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this Rate Limit Rule.
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/RateLimitRule'
description: ''
put:
operationId: v1_integrations_rate_limits_update
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this Rate Limit Rule.
required: true
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/RateLimitRuleRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/RateLimitRuleRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/RateLimitRuleRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/RateLimitRule'
description: ''
patch:
operationId: v1_integrations_rate_limits_partial_update
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this Rate Limit Rule.
required: true
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PatchedRateLimitRuleRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/PatchedRateLimitRuleRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/PatchedRateLimitRuleRequest'
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/RateLimitRule'
description: ''
delete:
operationId: v1_integrations_rate_limits_destroy
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this Rate Limit Rule.
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'204':
description: No response body
/api/v1/integrations/sms/send/:
post:
operationId: v1_integrations_sms_send_create
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/integrations/webhook-events/:
get:
operationId: v1_integrations_webhook_events_list
parameters:
- name: page
required: false
in: query
description: A page number within the paginated result set.
schema:
type: integer
- name: page_size
required: false
in: query
description: Number of results to return per page.
schema:
type: integer
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedWebhookEventList'
description: ''
/api/v1/integrations/webhook-events/{id}/:
get:
operationId: v1_integrations_webhook_events_retrieve
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this Webhook Event.
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/WebhookEvent'
description: ''
/api/v1/integrations/webhook-events/{id}/retry/:
post:
operationId: v1_integrations_webhook_events_retry_create
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this Webhook Event.
required: true
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/WebhookEventRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/WebhookEventRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/WebhookEventRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/WebhookEvent'
description: ''
/api/v1/integrations/webhook/{endpoint_url}/:
post:
operationId: v1_integrations_webhook_create
parameters:
- in: path
name: endpoint_url
schema:
type: string
required: true
tags:
- v1
security:
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/integrations/webhooks/:
get:
operationId: v1_integrations_webhooks_list
parameters:
- name: page
required: false
in: query
description: A page number within the paginated result set.
schema:
type: integer
- name: page_size
required: false
in: query
description: Number of results to return per page.
schema:
type: integer
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedWebhookEndpointList'
description: ''
post:
operationId: v1_integrations_webhooks_create
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/WebhookEndpointRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/WebhookEndpointRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/WebhookEndpointRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/WebhookEndpoint'
description: ''
/api/v1/integrations/webhooks/{id}/:
get:
operationId: v1_integrations_webhooks_retrieve
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this Webhook Endpoint.
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/WebhookEndpoint'
description: ''
put:
operationId: v1_integrations_webhooks_update
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this Webhook Endpoint.
required: true
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/WebhookEndpointRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/WebhookEndpointRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/WebhookEndpointRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/WebhookEndpoint'
description: ''
patch:
operationId: v1_integrations_webhooks_partial_update
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this Webhook Endpoint.
required: true
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PatchedWebhookEndpointRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/PatchedWebhookEndpointRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/PatchedWebhookEndpointRequest'
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/WebhookEndpoint'
description: ''
delete:
operationId: v1_integrations_webhooks_destroy
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this Webhook Endpoint.
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'204':
description: No response body
/api/v1/integrations/webhooks/{id}/test/:
post:
operationId: v1_integrations_webhooks_test_create
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this Webhook Endpoint.
required: true
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/WebhookEndpointRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/WebhookEndpointRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/WebhookEndpointRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/WebhookEndpoint'
description: ''
/api/v1/kyc/admin/{submission_id}/approve/:
post:
operationId: v1_kyc_admin_approve_create
description: |-
POST /api/v1/kyc/admin/<submission_id>/approve/
Staff action: approve a KYC submission.
Side effects:
- Sets submission.status = APPROVED.
- Sets VendorSetupState.id_verified = True (if user is a vendor).
- Sends approval notification to the user.
Body (optional):
{ "provider_reference": "smile_identity_job_123" }
parameters:
- in: path
name: submission_id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/kyc/admin/{submission_id}/reject/:
post:
operationId: v1_kyc_admin_reject_create
description: |-
POST /api/v1/kyc/admin/<submission_id>/reject/
Staff action: reject a KYC submission with review notes.
Body:
{
"review_notes": "NIN document is blurry. Please resubmit a clearer photo.",
"allow_resubmit": true
}
parameters:
- in: path
name: submission_id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/kyc/admin/submissions/:
get:
operationId: v1_kyc_admin_submissions_list
description: |-
GET /api/v1/kyc/admin/submissions/
Staff-only endpoint to list all KYC submissions with users and documents.
parameters:
- name: page
required: false
in: query
description: A page number within the paginated result set.
schema:
type: integer
- name: page_size
required: false
in: query
description: Number of results to return per page.
schema:
type: integer
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedKycSubmissionList'
description: ''
/api/v1/kyc/documents/upload/:
post:
operationId: v1_kyc_documents_upload_create
description: |-
POST /api/v1/kyc/documents/upload/
Record a KYC document Cloudinary upload against the user's active submission.
Documents must be uploaded client-side to Cloudinary first using a
presigned token from GET /api/v1/common/cloudinary/presign/?preset=kyc_docs.
This endpoint records the resulting Cloudinary asset reference.
Body:
{
"document_type": "nin_card",
"document_number": "12345678901",
"secure_url": "https://res.cloudinary.com/.../...",
"public_id": "fashionistar/kyc/<user_id>/..."
}
Idempotent per (submission, document_type): re-uploading the same
document type updates the existing record.
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/kyc/status/:
get:
operationId: v1_kyc_status_retrieve
description: |-
GET /api/v1/kyc/status/
Returns the authenticated user's KYC submission with all documents.
Delegates to get_kyc_submission_for_user selector (prefetch_related).
Returns 200 with status='not_started' if no submission exists.
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/kyc/submit/:
post:
operationId: v1_kyc_submit_create
description: |-
POST /api/v1/kyc/submit/
Initiate or reopen a KYC submission.
- If no submission exists creates PENDING submission.
- If submission is REJECTED / RESUBMIT resets to PENDING.
- If submission is APPROVED / PENDING / IN_REVIEW returns current state (idempotent).
Body (optional):
{ "nin": "12345678901", "bvn": "12345678901" }
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/kyc/webhook/{provider_slug}/:
post:
operationId: v1_kyc_webhook_create
description: |-
Receive and process inbound KYC provider webhook callbacks.
Workflow:
1. Extract provider_slug from URL.
2. Load KYCProviderConfig from cache.
3. Validate HMAC signature using provider's signing secret.
4. Dispatch to KycService.reconcile_webhook() for idempotent reconciliation.
5. Audit-log the outcome (compliance=True, 7-year retention).
6. Return HTTP 200 immediately (provider expects fast acknowledgement).
parameters:
- in: path
name: provider_slug
schema:
type: string
required: true
tags:
- v1
security:
- BearerAuth: []
- {}
responses:
'200':
description: No response body
/api/v1/measurements/:
get:
operationId: v1_measurements_retrieve
description: |-
GET /api/v1/measurements/ — List all profiles for the authenticated user.
POST /api/v1/measurements/ — Create a new measurement profile.
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
post:
operationId: v1_measurements_create
description: |-
GET /api/v1/measurements/ — List all profiles for the authenticated user.
POST /api/v1/measurements/ — Create a new measurement profile.
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/measurements/{profile_id}/:
get:
operationId: v1_measurements_retrieve_2
description: |-
GET /api/v1/measurements/<id>/
PUT /api/v1/measurements/<id>/
PATCH /api/v1/measurements/<id>/
DELETE /api/v1/measurements/<id>/
parameters:
- in: path
name: profile_id
schema:
type: integer
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
put:
operationId: v1_measurements_update
description: |-
GET /api/v1/measurements/<id>/
PUT /api/v1/measurements/<id>/
PATCH /api/v1/measurements/<id>/
DELETE /api/v1/measurements/<id>/
parameters:
- in: path
name: profile_id
schema:
type: integer
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
patch:
operationId: v1_measurements_partial_update
description: |-
GET /api/v1/measurements/<id>/
PUT /api/v1/measurements/<id>/
PATCH /api/v1/measurements/<id>/
DELETE /api/v1/measurements/<id>/
parameters:
- in: path
name: profile_id
schema:
type: integer
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
delete:
operationId: v1_measurements_destroy
description: |-
GET /api/v1/measurements/<id>/
PUT /api/v1/measurements/<id>/
PATCH /api/v1/measurements/<id>/
DELETE /api/v1/measurements/<id>/
parameters:
- in: path
name: profile_id
schema:
type: integer
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'204':
description: No response body
/api/v1/measurements/{profile_id}/set-default/:
post:
operationId: v1_measurements_set_default_create
description: POST /api/v1/measurements/<id>/set-default/
parameters:
- in: path
name: profile_id
schema:
type: integer
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/measurements/scan/{session_id}/submit-landmarks/:
post:
operationId: v1_measurements_scan_submit_landmarks_create
description: |-
POST /api/v1/measurements/scan/<session_id>/submit-landmarks/
Accepts MediaPipe world-coordinate landmarks from the browser.
Fires the process_body_scan Celery task and returns immediately.
Frontend should poll:
GET /api/v1/ninja/measurements/scan/<session_id>/status/
until status = 'completed' or 'failed'.
Expected body:
{
"user_height_cm": 175.5,
"user_weight_kg": 70.0, // optional
"landmarks": [<33 landmark objects>]
}
Success response (202 Accepted):
{
"session_id": "...",
"status": "processing",
"message": "Scan submitted. Processing in progress..."
}
parameters:
- in: path
name: session_id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/measurements/scan/initiate/:
post:
operationId: v1_measurements_scan_initiate_create
description: |-
POST /api/v1/measurements/scan/initiate/
Creates a BodyScanSession with status=PENDING.
Returns session_id the frontend uses this to:
1. Display a "session ready" indicator to the user
2. Submit landmark data via SubmitLandmarksView
3. Poll Ninja API for processing status
No body required. Optionally accepts:
{ "device_type": "web" | "ios" | "android" }
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/notifications/:
get:
operationId: v1_notifications_retrieve
description: |-
GET /api/v1/notifications/
Returns the authenticated user's in-app notification feed.
Supports ?unread_only=true to filter unread.
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/notifications/{notification_id}/:
get:
operationId: v1_notifications_retrieve_2
description: |-
GET /api/v1/notifications/<id>/
Returns a single notification without mutating read state.
parameters:
- in: path
name: notification_id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/notifications/mark-all-read/:
post:
operationId: v1_notifications_mark_all_read_create
description: POST /api/v1/notifications/mark-all-read/
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/notifications/mark-read/{notification_id}/:
post:
operationId: v1_notifications_mark_read_create
description: POST /api/v1/notifications/mark-read/<id>/
parameters:
- in: path
name: notification_id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/notifications/preferences/:
get:
operationId: v1_notifications_preferences_retrieve
description: |-
GET /api/v1/notifications/preferences/ — List current preferences
POST /api/v1/notifications/preferences/ — Set/update a preference
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
post:
operationId: v1_notifications_preferences_create
description: |-
GET /api/v1/notifications/preferences/ — List current preferences
POST /api/v1/notifications/preferences/ — Set/update a preference
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/notifications/unread-count/:
get:
operationId: v1_notifications_unread_count_retrieve
description: GET /api/v1/notifications/unread-count/
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/orders/:
get:
operationId: v1_orders_retrieve
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/orders/{order_id}/:
get:
operationId: v1_orders_retrieve_2
parameters:
- in: path
name: order_id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/orders/{order_id}/cancel/:
post:
operationId: v1_orders_cancel_create
parameters:
- in: path
name: order_id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/orders/{order_id}/confirm-delivery/:
post:
operationId: v1_orders_confirm_delivery_create
description: Client confirms delivery releases escrow.
parameters:
- in: path
name: order_id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/orders/admin/{order_id}/delivery-status/:
patch:
operationId: v1_orders_admin_delivery_status_partial_update
description: |-
Admin/staff delivery-status update endpoint.
This is a DRF sync mutation because it changes order state and may trigger
later escrow/provider reconciliation. The service performs the row lock;
the view only validates input, checks high-trust staff access, and returns
the serialized order.
parameters:
- in: path
name: order_id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/orders/place/:
post:
operationId: v1_orders_place_create
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/orders/vendor/:
get:
operationId: v1_orders_vendor_retrieve
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/orders/vendor/{order_id}/:
get:
operationId: v1_orders_vendor_retrieve_2
parameters:
- in: path
name: order_id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/orders/vendor/{order_id}/production-status/:
post:
operationId: v1_orders_vendor_production_status_create
parameters:
- in: path
name: order_id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
patch:
operationId: v1_orders_vendor_production_status_partial_update
description: PATCH alias used by the frontend production-status mutation.
parameters:
- in: path
name: order_id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/orders/vendor/{order_id}/transition/:
post:
operationId: v1_orders_vendor_transition_create
parameters:
- in: path
name: order_id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
patch:
operationId: v1_orders_vendor_transition_partial_update
description: PATCH alias used by the frontend production-status mutation.
parameters:
- in: path
name: order_id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/orders/verify-pickup/:
put:
operationId: v1_orders_verify_pickup_update
description: Verify order pickup token, release escrow, and transition to Completed
status.
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/password/change/:
post:
operationId: v1_password_change_create
description: |-
Authenticates current password and updates to a new one.
Args:
request (Request): The DRF request with old and new passwords.
Returns:
Response: Success confirmation or detailed error.
tags:
- Authentication
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PasswordChangeRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/PasswordChangeRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/PasswordChangeRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/password/reset-confirm/{uidb64}/{token}/:
post:
operationId: v1_password_reset_confirm_create
description: |-
Updates the user's password if the token and uidb64 are valid.
Args:
request (Request): The DRF request containing the new password.
uidb64 (str): Base64 encoded user ID from the URL.
token (str): One-time use token from the URL.
Returns:
Response: Success confirmation or a 400 Bad Request if validation fails.
parameters:
- in: path
name: token
schema:
type: string
required: true
- in: path
name: uidb64
schema:
type: string
required: true
tags:
- Authentication
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/AuthPasswordResetConfirmEmailRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/AuthPasswordResetConfirmEmailRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/AuthPasswordResetConfirmEmailRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
- {}
responses:
'200':
description: No response body
/api/v1/password/reset-phone-confirm/:
post:
operationId: v1_password_reset_phone_confirm_create
description: |-
Verifies the OTP and updates the user's password.
Args:
request (Request): The DRF request containing OTP and new password.
Returns:
Response: Success confirmation or a 400 Bad Request if verification fails.
tags:
- Authentication
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/AuthPasswordResetConfirmPhoneRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/AuthPasswordResetConfirmPhoneRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/AuthPasswordResetConfirmPhoneRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
- {}
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/AuthPasswordResetConfirmPhone'
description: ''
/api/v1/password/reset-request/:
post:
operationId: v1_password_reset_request_create
description: |-
Processes the reset request and triggers background notification.
Args:
request (Request): The incoming DRF request object.
Returns:
Response: A standardized success response, regardless of account existence.
tags:
- Authentication
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/AuthPasswordResetRequestRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/AuthPasswordResetRequestRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/AuthPasswordResetRequestRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
- {}
responses:
'200':
description: No response body
/api/v1/payment/banks/:
get:
operationId: v1_payment_banks_retrieve
description: |-
Retrieves the list of supported Nigerian banks for transfers.
Flow:
1. Query Paystack Banks list endpoint.
2. Filter or format as needed.
3. Return to frontend for bank selection in withdrawal flows.
Status Codes:
200 OK: Returns list of banks.
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaystackBanksResponse'
description: ''
/api/v1/payment/cash/confirm/:
post:
operationId: v1_payment_cash_confirm_create
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/CashConfirmationConfirmRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/CashConfirmationConfirmRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/CashConfirmationConfirmRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CashConfirmationConfirm'
description: ''
/api/v1/payment/cash/create/:
post:
operationId: v1_payment_cash_create_create
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/CashConfirmationCreateRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/CashConfirmationCreateRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/CashConfirmationCreateRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CashConfirmationCreate'
description: ''
/api/v1/payment/cash/resend-token/:
post:
operationId: v1_payment_cash_resend_token_create
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/CashConfirmationResendRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/CashConfirmationResendRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/CashConfirmationResendRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CashConfirmationResend'
description: ''
/api/v1/payment/paystack/initialize/:
post:
operationId: v1_payment_paystack_initialize_create
description: |-
Initializes a Paystack transaction and creates a PaymentIntent record.
Flow:
1. Receive amount and metadata from frontend.
2. Check idempotency to prevent double-charging.
3. Call Paystack API to get an authorization URL.
4. Store the reference and link it to the current User.
Status Codes:
201 Created: Initialization successful, returns Paystack URL.
400 Bad Request: Invalid payload or Paystack provider error.
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PaystackInitializeRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/PaystackInitializeRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/PaystackInitializeRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaystackInitialize'
description: ''
/api/v1/payment/paystack/verify/{reference}/:
get:
operationId: v1_payment_paystack_verify_retrieve
description: |-
Verifies the status of a specific Paystack transaction reference.
Flow:
1. Frontend provides the reference after user payment.
2. Backend queries Paystack Verify API.
3. If success, updates PaymentIntent and associated Wallet/Order.
4. Returns final state to the frontend.
Status Codes:
200 OK: Payment confirmed and processed.
400 Bad Request: Payment failed or reference not found.
parameters:
- in: path
name: reference
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaystackVerify'
description: ''
/api/v1/payment/paystack/webhook/:
post:
operationId: v1_payment_paystack_webhook_create
description: |-
Asynchronous handler for Paystack webhook notifications.
Flow:
1. Paystack sends a signed POST request.
2. Verify signature using environment secret.
3. Process the event (charge.success, transfer.success, etc.).
4. Ensure idempotency via reference tracking.
Status Codes:
200 OK: Webhook accepted.
401 Unauthorized: Invalid signature.
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PaystackWebhookRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/PaystackWebhookRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/PaystackWebhookRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
- {}
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaystackWebhook'
description: ''
/api/v1/payment/transfer-recipient/:
post:
operationId: v1_payment_transfer_recipient_create
description: |-
Creates a Transfer Recipient on Paystack for withdrawals.
Flow:
1. User provides bank code and account number.
2. Backend calls Paystack to create a recipient.
3. Store the recipient code for future transfer operations.
Status Codes:
201 Created: Recipient successfully registered.
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/TransferRecipientCreateRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/TransferRecipientCreateRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/TransferRecipientCreateRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/TransferRecipientCreate'
description: ''
/api/v1/payment/wallet/fund/:
post:
operationId: v1_payment_wallet_fund_create
description: Shared order-payment and wallet-topup entrypoint.
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/WalletFundPaymentRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/WalletFundPaymentRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/WalletFundPaymentRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/WalletFundPayment'
description: ''
/api/v1/platform/settings/public/:
get:
operationId: v1_platform_settings_public_retrieve
description: |-
GET /api/v1/platform/settings/public/
Returns public-safe platform configuration values for frontend use.
Does NOT require authentication these are public limits and branding.
Response is backed by Redis (60s TTL) so it is cheap to call on every
payout modal open.
Response schema:
{
"platform_name": "Fashionistar",
"min_withdrawal_ngn": "1000.00",
"max_withdrawal_ngn": "2000000.00",
"max_daily_withdrawal_ngn": "5000000.00",
"min_wallet_topup_ngn": "500.00",
"max_wallet_topup_ngn": "5000000.00",
"support_email": "support@fashionistar.net",
"support_phone": "+234 913 7654 300",
"terms_url": "https://fashionistar.net/terms",
"privacy_url": "https://fashionistar.net/privacy"
}
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
- {}
responses:
'200':
description: No response body
/api/v1/products/:
get:
operationId: v1_products_retrieve
description: |-
GET /api/v1/products/
Public. Query params:
q, category, brand, vendor, min_price, max_price,
in_stock, featured, ordering, page, page_size
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
- {}
responses:
'200':
description: No response body
/api/v1/products/{product_slug}/reviews/:
get:
operationId: v1_products_reviews_retrieve
description: |-
GET /api/v1/products/<product_slug>/reviews/ — Public list (paginated).
POST /api/v1/products/<product_slug>/reviews/ — Authenticated client submission.
parameters:
- in: path
name: product_slug
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
- {}
responses:
'200':
description: No response body
post:
operationId: v1_products_reviews_create
description: |-
GET /api/v1/products/<product_slug>/reviews/ — Public list (paginated).
POST /api/v1/products/<product_slug>/reviews/ — Authenticated client submission.
parameters:
- in: path
name: product_slug
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/products/{slug}/:
get:
operationId: v1_products_retrieve_2
description: GET /api/v1/products/<slug>/ Public. Includes ETag cache headers.
parameters:
- in: path
name: slug
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
- {}
responses:
'200':
description: No response body
/api/v1/products/{slug}/wishlist/toggle/:
post:
operationId: v1_products_wishlist_toggle_create_2
description: POST /api/v1/products/wishlist/<slug>/toggle/
parameters:
- in: path
name: slug
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
- {}
responses:
'200':
description: No response body
/api/v1/products/admin/{slug}/approve/:
post:
operationId: v1_products_admin_approve_create
description: POST /api/v1/admin/products/<slug>/approve/
parameters:
- in: path
name: slug
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/products/admin/{slug}/reject/:
post:
operationId: v1_products_admin_reject_create
description: POST /api/v1/admin/products/<slug>/reject/
parameters:
- in: path
name: slug
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/products/category/{category_id}/:
get:
operationId: v1_products_category_retrieve
description: GET /api/v1/products/category/<category_id>/ Public.
parameters:
- in: path
name: category_id
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
- {}
responses:
'200':
description: No response body
/api/v1/products/commission-snapshots/:
get:
operationId: v1_products_commission_snapshots_retrieve
description: |-
Return commission snapshot list with optional filters.
Query params:
product_id (str): Filter by product.
vendor_id (str): Filter by vendor (via product).
Args:
request: DRF request.
Returns:
200 success_response with list of snapshot dicts.
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
post:
operationId: v1_products_commission_snapshots_create
description: |-
Create a new commission snapshot for a product.
Commission snapshots are append-only. To change a rate, create a new
snapshot with the updated commission_rate and a new effective_from date.
Args:
request: DRF request with JSON body containing:
product_id (str, required): Product UUID.
commission_rate (str/Decimal, required): Rate as decimal (e.g. "12.50").
effective_from (str, required): ISO 8601 datetime string.
effective_to (str, optional): ISO 8601 end date.
note (str, optional): Reason / notes for this rate change.
Returns:
201 success_response with snapshot id.
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/products/commission-snapshots/{id}/:
get:
operationId: v1_products_commission_snapshots_retrieve_2
description: Return a single commission snapshot row.
parameters:
- in: path
name: id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
patch:
operationId: v1_products_commission_snapshots_partial_update
description: |-
Update mutable fields: note and effective_to only.
Commission rate changes must create a new snapshot row (append-only policy).
Args:
request: DRF request with partial JSON body.
pk: Snapshot PK string.
Returns:
200 success_response or error.
parameters:
- in: path
name: id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/products/coupons/:
get:
operationId: v1_products_coupons_retrieve
description: |-
GET /api/v1/products/coupons/
POST /api/v1/products/coupons/
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
post:
operationId: v1_products_coupons_create
description: |-
GET /api/v1/products/coupons/
POST /api/v1/products/coupons/
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/products/coupons/{coupon_id}/:
delete:
operationId: v1_products_coupons_destroy
description: DELETE /api/v1/products/coupons/<uuid:coupon_id>/
parameters:
- in: path
name: coupon_id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'204':
description: No response body
/api/v1/products/featured/:
get:
operationId: v1_products_featured_retrieve
description: GET /api/v1/products/featured/ Public.
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
- {}
responses:
'200':
description: No response body
/api/v1/products/shipping-profiles/:
get:
operationId: v1_products_shipping_profiles_retrieve
description: |-
Return shipping profile list scoped by caller role.
Args:
request: DRF request.
Returns:
200 success_response with list of profile dicts.
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
post:
operationId: v1_products_shipping_profiles_create
description: |-
Create a new shipping profile for the calling vendor.
Args:
request: DRF request with JSON body.
Returns:
201 success_response with created profile id.
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/products/shipping-profiles/{id}/:
get:
operationId: v1_products_shipping_profiles_retrieve_2
description: Return a single shipping profile.
parameters:
- in: path
name: id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
patch:
operationId: v1_products_shipping_profiles_partial_update
description: Partially update a shipping profile.
parameters:
- in: path
name: id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/products/size-guides/:
get:
operationId: v1_products_size_guides_retrieve
description: |-
Return size guide list scoped by role.
Args:
request: DRF request with authenticated user.
Returns:
200 success_response with list of guide dicts.
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
post:
operationId: v1_products_size_guides_create
description: |-
Create a new size guide template.
Args:
request: DRF request with JSON body.
Returns:
201 success_response with created guide id.
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/products/size-guides/{id}/:
get:
operationId: v1_products_size_guides_retrieve_2
description: Return a single size guide row.
parameters:
- in: path
name: id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
patch:
operationId: v1_products_size_guides_partial_update
description: Partially update a size guide template.
parameters:
- in: path
name: id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
delete:
operationId: v1_products_size_guides_destroy
description: Soft-delete a size guide template.
parameters:
- in: path
name: id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'204':
description: No response body
/api/v1/products/vendor/:
get:
operationId: v1_products_vendor_retrieve
description: |-
GET /api/v1/products/vendor/ — List vendor's own products (paginated).
POST /api/v1/products/vendor/ — Create product (idempotency key supported).
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
post:
operationId: v1_products_vendor_create
description: |-
GET /api/v1/products/vendor/ — List vendor's own products (paginated).
POST /api/v1/products/vendor/ — Create product (idempotency key supported).
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/products/vendor/{slug}/:
get:
operationId: v1_products_vendor_retrieve_2
description: |-
GET /api/v1/products/vendor/<slug>/
PATCH /api/v1/products/vendor/<slug>/
DELETE /api/v1/products/vendor/<slug>/
parameters:
- in: path
name: slug
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
patch:
operationId: v1_products_vendor_partial_update
description: |-
GET /api/v1/products/vendor/<slug>/
PATCH /api/v1/products/vendor/<slug>/
DELETE /api/v1/products/vendor/<slug>/
parameters:
- in: path
name: slug
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
delete:
operationId: v1_products_vendor_destroy
description: |-
GET /api/v1/products/vendor/<slug>/
PATCH /api/v1/products/vendor/<slug>/
DELETE /api/v1/products/vendor/<slug>/
parameters:
- in: path
name: slug
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'204':
description: No response body
/api/v1/products/vendor/{slug}/inventory/:
get:
operationId: v1_products_vendor_inventory_retrieve
description: |-
GET /api/v1/products/vendor/<slug>/inventory/
POST /api/v1/products/vendor/<slug>/inventory/ — Manual stock adjustment
Best-practice #5: dedicated inventory log endpoint.
parameters:
- in: path
name: slug
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
post:
operationId: v1_products_vendor_inventory_create
description: |-
GET /api/v1/products/vendor/<slug>/inventory/
POST /api/v1/products/vendor/<slug>/inventory/ — Manual stock adjustment
Best-practice #5: dedicated inventory log endpoint.
parameters:
- in: path
name: slug
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/products/vendor/{slug}/media/:
get:
operationId: v1_products_vendor_media_retrieve
description: |-
GET /api/v1/products/vendor/<slug>/media/
POST /api/v1/products/vendor/<slug>/media/
parameters:
- in: path
name: slug
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
post:
operationId: v1_products_vendor_media_create
description: |-
GET /api/v1/products/vendor/<slug>/media/
POST /api/v1/products/vendor/<slug>/media/
parameters:
- in: path
name: slug
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/products/vendor/{slug}/media/{gid}/:
delete:
operationId: v1_products_vendor_media_destroy
description: DELETE /api/v1/products/vendor/<slug>/media/<gid>/
parameters:
- in: path
name: gid
schema:
type: string
format: uuid
required: true
- in: path
name: slug
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'204':
description: No response body
/api/v1/products/vendor/{slug}/publish/:
post:
operationId: v1_products_vendor_publish_create
description: POST /api/v1/products/vendor/<slug>/publish/
parameters:
- in: path
name: slug
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/products/vendor/reviews/{review_id}/reply/:
post:
operationId: v1_products_vendor_reviews_reply_create
description: POST /api/v1/products/vendor/reviews/<review_id>/reply/
parameters:
- in: path
name: review_id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/products/wishlist/:
get:
operationId: v1_products_wishlist_retrieve
description: GET /api/v1/products/wishlist/ Full wishlist with embedded products.
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
- {}
responses:
'200':
description: No response body
/api/v1/products/wishlist/{slug}/toggle/:
post:
operationId: v1_products_wishlist_toggle_create
description: POST /api/v1/products/wishlist/<slug>/toggle/
parameters:
- in: path
name: slug
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
- {}
responses:
'200':
description: No response body
/api/v1/products/wishlist/merge/:
post:
operationId: v1_products_wishlist_merge_create
description: |-
POST /api/v1/products/wishlist/merge/
Promotes anonymous wishlist rows into the authenticated account after login
and before checkout. The view only resolves request identity; all merge
behavior lives in the product service layer.
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/profile/me/:
get:
operationId: v1_profile_me_retrieve
description: |-
GET /api/v1/profile/me/ — Return authenticated user's full profile.
PATCH /api/v1/profile/me/ — Partial update of authenticated user profile.
GET uses: UserProfileSerializer (all readable fields)
PATCH uses: update_user_profile() service (guarded, validated writes)
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/AuthUserProfile'
description: ''
put:
operationId: v1_profile_me_update
description: |-
GET /api/v1/profile/me/ — Return authenticated user's full profile.
PATCH /api/v1/profile/me/ — Partial update of authenticated user profile.
GET uses: UserProfileSerializer (all readable fields)
PATCH uses: update_user_profile() service (guarded, validated writes)
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/AuthUserProfileRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/AuthUserProfileRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/AuthUserProfileRequest'
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/AuthUserProfile'
description: ''
patch:
operationId: v1_profile_me_partial_update
description: |-
GET /api/v1/profile/me/ — Return authenticated user's full profile.
PATCH /api/v1/profile/me/ — Partial update of authenticated user profile.
GET uses: UserProfileSerializer (all readable fields)
PATCH uses: update_user_profile() service (guarded, validated writes)
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PatchedAuthUserProfileRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/PatchedAuthUserProfileRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/PatchedAuthUserProfileRequest'
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/AuthUserProfile'
description: ''
/api/v1/profile/users/:
get:
operationId: v1_profile_users_list
description: |-
GET /api/v1/profile/users/ — Admin-only list of all registered users.
Returns ProtectedUserSerializer shape no sensitive fields exposed.
parameters:
- name: page
required: false
in: query
description: A page number within the paginated result set.
schema:
type: integer
- name: page_size
required: false
in: query
description: Number of results to return per page.
schema:
type: integer
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedAuthProtectedUserList'
description: ''
/api/v1/public/contact/:
post:
operationId: v1_public_contact_create
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/CommonContactSubmissionRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/CommonContactSubmissionRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/CommonContactSubmissionRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
- {}
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CommonContactSubmission'
description: ''
/api/v1/public/newsletter/:
post:
operationId: v1_public_newsletter_create
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/CommonNewsletterSignupRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/CommonNewsletterSignupRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/CommonNewsletterSignupRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
- {}
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CommonNewsletterSignup'
description: ''
/api/v1/public/waitlist/:
post:
operationId: v1_public_waitlist_create
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/CommonWaitlistSignupRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/CommonWaitlistSignupRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/CommonWaitlistSignupRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
- {}
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CommonWaitlistSignup'
description: ''
/api/v1/support/admin/queue/:
get:
operationId: v1_support_admin_queue_retrieve
description: |-
GET /api/v1/support/admin/queue/
Staff-only: full ticket queue (all open tickets, any user).
Supports ?status=&priority= filters.
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/support/tickets/:
get:
operationId: v1_support_tickets_retrieve
description: |-
GET /api/v1/support/tickets/ — Return authenticated user's ticket feed.
POST /api/v1/support/tickets/ — Open a new ticket (idempotent per order_id).
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
post:
operationId: v1_support_tickets_create
description: |-
GET /api/v1/support/tickets/ — Return authenticated user's ticket feed.
POST /api/v1/support/tickets/ — Open a new ticket (idempotent per order_id).
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/support/tickets/{ticket_id}/:
get:
operationId: v1_support_tickets_retrieve_2
description: |-
GET /api/v1/support/tickets/<ticket_id>/
Returns full ticket detail including message thread and escalation.
Scoped to the authenticated user (staff sees all via admin queue).
parameters:
- in: path
name: ticket_id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/support/tickets/{ticket_id}/escalate/:
post:
operationId: v1_support_tickets_escalate_create
description: |-
POST /api/v1/support/tickets/<ticket_id>/escalate/
Staff-only endpoint: create or return a TicketEscalation.
Idempotent — safe to call twice.
parameters:
- in: path
name: ticket_id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/support/tickets/{ticket_id}/messages/:
post:
operationId: v1_support_tickets_messages_create
description: |-
POST /api/v1/support/tickets/<ticket_id>/messages/
Add a threaded reply to a ticket.
Staff replies are differentiated via is_staff_reply flag.
parameters:
- in: path
name: ticket_id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/support/tickets/{ticket_id}/status/:
patch:
operationId: v1_support_tickets_status_partial_update
description: |-
PATCH /api/v1/support/tickets/<ticket_id>/status/
Staff-only endpoint: transition ticket status with optional notes.
parameters:
- in: path
name: ticket_id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/transactions/:
get:
operationId: v1_transactions_list
description: |-
Retrieves a paginated list of transactions for the authenticated user.
Flow:
1. Filter transactions where user is either the initiator or recipient.
2. Order by most recent first.
3. Return standardized transaction objects.
Status Codes:
200 OK: Returns transaction list.
parameters:
- name: page
required: false
in: query
description: A page number within the paginated result set.
schema:
type: integer
- name: page_size
required: false
in: query
description: Number of results to return per page.
schema:
type: integer
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedTransactionList'
description: ''
/api/v1/transactions/{transaction_id}/:
get:
operationId: v1_transactions_retrieve
description: |-
GET /api/v1/transactions/<transaction_id>/
Retrieve details of a specific transaction.
Retrieves granular details of a specific transaction ID.
Security:
- Enforces ownership check (user must be party to the transaction).
Status Codes:
200 OK: Returns transaction details.
404 Not Found: Transaction doesn't exist or user lacks access.
parameters:
- in: path
name: transaction_id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Transaction'
description: ''
/api/v1/transactions/{transaction_id}/dispute/:
post:
operationId: v1_transactions_dispute_create
description: |-
Opens a formal dispute case for a specific transaction.
POST /api/v1/transactions/<transaction_id>/refund/
Initiate a refund for a transaction on escrow hold.
Flow:
1. Client submits reason and disputed amount.
2. Backend freezes related escrow funds if applicable.
3. Notify admin/vendor of the open dispute.
Status Codes:
201 Created: Dispute case opened.
parameters:
- in: path
name: transaction_id
schema:
type: string
format: uuid
required: true
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/DisputeCreateRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/DisputeCreateRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/DisputeCreateRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/DisputeCreate'
description: ''
/api/v1/transactions/{transaction_id}/refund/:
post:
operationId: v1_transactions_refund_create
description: |-
Initiates a manual refund for an escrowed payment.
POST /api/v1/transactions/<transaction_id>/refund/
Initiate a refund for a transaction on escrow hold.
Flow:
1. Verify the transaction is currently held in Escrow.
2. Reverse the hold back to the client's available balance.
3. Log the refund event in the transaction history.
Status Codes:
200 OK: Refund successfully processed.
400 Bad Request: Transaction not eligible for refund.
parameters:
- in: path
name: transaction_id
schema:
type: string
format: uuid
required: true
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/RefundRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/RefundRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/RefundRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Refund'
description: ''
/api/v1/transactions/summary/:
get:
operationId: v1_transactions_summary_retrieve
description: |-
Aggregates financial performance statistics for the user's wallet.
GET /api/v1/transactions/summary/
Get a summary of transactions (inflow, outflow, count).
Flow:
1. Sum all credits (inflow).
2. Sum all debits (outflow).
3. Count total volume of transactions.
Status Codes:
200 OK: Returns summary statistics.
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/TransactionSummary'
description: ''
/api/v1/upload/presign/:
post:
operationId: v1_upload_presign_create
description: |-
POST /api/v1/upload/presign/
Generate a time-limited, HMAC-SHA256–signed Cloudinary upload token.
The frontend uses this to POST a file DIRECTLY to Cloudinary without
routing the upload data through the Django server.
Authentication: Bearer JWT (IsAuthenticated).
Request body (validated by PresignRequestSerializer):
{ "asset_type": "avatar" | "product_image" | "product_video" | "measurement" }
Response 200:
{
"success": true,
"cloud_name": "your_cloud",
"api_key": "...",
"signature": "hex-sha256",
"timestamp": 1712345678,
"folder": "fashionistar/users/avatars/user_UUID",
"upload_preset": "fashionistar_avatars",
"resource_type": "image",
"eager": [...],
"eager_async": true
}
Response 400 invalid asset_type (serializer validation error).
Response 500 signature generation failed.
parameters:
- in: query
name: format
schema:
type: string
enum:
- html
- json
- multipart
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/CommonPresignRequestRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/CommonPresignRequestRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/CommonPresignRequestRequest'
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CommonPresignRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/CommonPresignRequest'
text/html:
schema:
$ref: '#/components/schemas/CommonPresignRequest'
description: ''
/api/v1/vendor/bank-accounts/:
get:
operationId: v1_vendor_bank_accounts_retrieve
description: |-
GET /api/v1/vendor/bank-accounts/ — list saved bank accounts
POST /api/v1/vendor/bank-accounts/ — create a new bank account
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/BankAccountOutput'
description: ''
post:
operationId: v1_vendor_bank_accounts_create
description: |-
GET /api/v1/vendor/bank-accounts/ — list saved bank accounts
POST /api/v1/vendor/bank-accounts/ — create a new bank account
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/BankAccountCreateRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/BankAccountCreateRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/BankAccountCreateRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/BankAccountCreate'
description: ''
/api/v1/vendor/bank-accounts/{id}/:
delete:
operationId: v1_vendor_bank_accounts_destroy
description: |-
DELETE /api/v1/vendor/bank-accounts/<uuid:pk>/
Soft-delete the bank account and clean up the Paystack recipient.
parameters:
- in: path
name: id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'204':
description: No response body
/api/v1/vendor/bank-accounts/{id}/default/:
patch:
operationId: v1_vendor_bank_accounts_default_partial_update
description: |-
PATCH /api/v1/vendor/bank-accounts/<uuid:pk>/default/
Set the specified bank account as the vendor's default payout account.
parameters:
- in: path
name: id
schema:
type: string
format: uuid
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/vendor/bank-accounts/resolve/:
post:
operationId: v1_vendor_bank_accounts_resolve_create
description: |-
POST /api/v1/vendor/bank-accounts/resolve/
Proxy Paystack /bank/resolve to retrieve the account holder name.
This endpoint is called by the frontend "Resolve Name" button in the
Add Bank Account modal.
Request body:
account_number (str): 10-digit NUBAN
bank_code (str): Paystack bank code (e.g. "044")
Response (200):
{ account_name: str, account_number: str }
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/BankAccountResolveRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/BankAccountResolveRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/BankAccountResolveRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/BankAccountResolve'
description: ''
/api/v1/vendor/orders/{order_id}/status/:
put:
operationId: v1_vendor_orders_status_update
description: |-
PATCH /api/v1/vendor/orders/<int:order_id>/status/
Update order_status for a vendor's own order.
Allowed values: Pending, Processing, Shipped, Fulfilled, Cancelled.
Payment status (paid/unpaid) is immutable here managed by payment gateway.
parameters:
- in: path
name: order_id
schema:
type: integer
required: true
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/VendorOrderStatusRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/VendorOrderStatusRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/VendorOrderStatusRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VendorOrderStatus'
description: ''
patch:
operationId: v1_vendor_orders_status_partial_update
description: |-
PATCH /api/v1/vendor/orders/<int:order_id>/status/
Update order_status for a vendor's own order.
Allowed values: Pending, Processing, Shipped, Fulfilled, Cancelled.
Payment status (paid/unpaid) is immutable here managed by payment gateway.
parameters:
- in: path
name: order_id
schema:
type: integer
required: true
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PatchedVendorOrderStatusRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/PatchedVendorOrderStatusRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/PatchedVendorOrderStatusRequest'
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VendorOrderStatus'
description: ''
/api/v1/vendor/payout/:
post:
operationId: v1_vendor_payout_create
description: POST /api/v1/vendor/payout/ save bank / payout account details
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/VendorPayoutDetailsRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/VendorPayoutDetailsRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/VendorPayoutDetailsRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VendorPayoutDetails'
description: ''
/api/v1/vendor/payout/request/:
post:
operationId: v1_vendor_payout_request_create
description: |-
POST /api/v1/vendor/payout/request/
Initiate a bank transfer payout from the vendor's Fashionistar wallet
to one of their saved bank accounts.
Request body:
bank_account_id (UUID): The VendorBankAccount UUID to pay into.
amount (Decimal): Amount in NGN (min ₦1,000).
narration (str, optional): Bank transfer description.
Response (200):
{
"status": "success",
"reference": "PAYOUT-XXXXXXXX-XXXXXXXXXXXXXXXXXXXX",
"transfer_code": "TRF_xxxxx",
"amount": "5000.00",
"currency": "NGN",
"message": "Payout initiated successfully. Funds will arrive within 1–2 business days."
}
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PayoutRequestRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/PayoutRequestRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/PayoutRequestRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PayoutRequest'
description: ''
/api/v1/vendor/pin/set/:
post:
operationId: v1_vendor_pin_set_create
description: POST /api/v1/vendor/pin/set/ set 4-digit payout confirmation
PIN
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/VendorTransactionPinRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/VendorTransactionPinRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/VendorTransactionPinRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VendorTransactionPin'
description: ''
/api/v1/vendor/pin/verify/:
post:
operationId: v1_vendor_pin_verify_create
description: POST /api/v1/vendor/pin/verify/ verify payout PIN before withdrawal
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/VendorTransactionPinRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/VendorTransactionPinRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/VendorTransactionPinRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VendorTransactionPin'
description: ''
/api/v1/vendor/products/{slug}/delete/:
get:
operationId: v1_vendor_products_delete_retrieve
description: |-
GET /api/v1/products/vendor/<slug>/
PATCH /api/v1/products/vendor/<slug>/
DELETE /api/v1/products/vendor/<slug>/
parameters:
- in: path
name: slug
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
patch:
operationId: v1_vendor_products_delete_partial_update
description: |-
GET /api/v1/products/vendor/<slug>/
PATCH /api/v1/products/vendor/<slug>/
DELETE /api/v1/products/vendor/<slug>/
parameters:
- in: path
name: slug
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
delete:
operationId: v1_vendor_products_delete_destroy
description: |-
GET /api/v1/products/vendor/<slug>/
PATCH /api/v1/products/vendor/<slug>/
DELETE /api/v1/products/vendor/<slug>/
parameters:
- in: path
name: slug
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'204':
description: No response body
/api/v1/vendor/products/{slug}/edit/:
get:
operationId: v1_vendor_products_edit_retrieve
description: |-
GET /api/v1/products/vendor/<slug>/
PATCH /api/v1/products/vendor/<slug>/
DELETE /api/v1/products/vendor/<slug>/
parameters:
- in: path
name: slug
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
patch:
operationId: v1_vendor_products_edit_partial_update
description: |-
GET /api/v1/products/vendor/<slug>/
PATCH /api/v1/products/vendor/<slug>/
DELETE /api/v1/products/vendor/<slug>/
parameters:
- in: path
name: slug
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
delete:
operationId: v1_vendor_products_edit_destroy
description: |-
GET /api/v1/products/vendor/<slug>/
PATCH /api/v1/products/vendor/<slug>/
DELETE /api/v1/products/vendor/<slug>/
parameters:
- in: path
name: slug
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'204':
description: No response body
/api/v1/vendor/products/create/:
get:
operationId: v1_vendor_products_create_retrieve
description: |-
GET /api/v1/products/vendor/ — List vendor's own products (paginated).
POST /api/v1/products/vendor/ — Create product (idempotency key supported).
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
post:
operationId: v1_vendor_products_create_create
description: |-
GET /api/v1/products/vendor/ — List vendor's own products (paginated).
POST /api/v1/products/vendor/ — Create product (idempotency key supported).
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/vendor/products/filter/:
get:
operationId: v1_vendor_products_filter_retrieve
description: |-
GET /api/v1/products/vendor/ — List vendor's own products (paginated).
POST /api/v1/products/vendor/ — Create product (idempotency key supported).
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
post:
operationId: v1_vendor_products_filter_create
description: |-
GET /api/v1/products/vendor/ — List vendor's own products (paginated).
POST /api/v1/products/vendor/ — Create product (idempotency key supported).
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
description: No response body
/api/v1/vendor/profile/:
get:
operationId: v1_vendor_profile_retrieve
description: |-
GET /api/v1/vendor/profile/ — retrieve vendor store profile
PATCH /api/v1/vendor/profile/ — update store profile
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VendorProfileOutput'
description: ''
patch:
operationId: v1_vendor_profile_partial_update
description: |-
GET /api/v1/vendor/profile/ — retrieve vendor store profile
PATCH /api/v1/vendor/profile/ — update store profile
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PatchedVendorProfileUpdateRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/PatchedVendorProfileUpdateRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/PatchedVendorProfileUpdateRequest'
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VendorProfileUpdate'
description: ''
/api/v1/vendor/public/:
get:
operationId: v1_vendor_public_retrieve
description: |-
GET /api/v1/vendor/public/
Public listing of active vendors for the home/vendors marketplace page.
Permissions: AllowAny (no auth required publicly browsable).
Filters (query params):
?is_featured=true featured vendors only
?city=Lagos filter by city
?search=bespoke search store_name / tagline
?limit=24 page size (default 24, max 100)
?offset=0 pagination offset
Response: { status, count, data: [VendorCard...] }
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
- {}
responses:
'200':
description: No response body
/api/v1/vendor/public/{store_slug}/:
get:
operationId: v1_vendor_public_retrieve_2
description: |-
GET /api/v1/vendor/public/{store_slug}/
Public vendor profile detail for the /vendors/[slug] page.
Permissions: AllowAny.
Returns full vendor profile plus top 12 products.
parameters:
- in: path
name: store_slug
schema:
type: string
required: true
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
- {}
responses:
'200':
description: No response body
/api/v1/vendor/setup/:
get:
operationId: v1_vendor_setup_retrieve
description: |-
GET /api/v1/vendor/setup/ — retrieve onboarding setup state
POST /api/v1/vendor/setup/ — create/update the first vendor setup record
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VendorSetupState'
description: ''
post:
operationId: v1_vendor_setup_create
description: |-
GET /api/v1/vendor/setup/ — retrieve onboarding setup state
POST /api/v1/vendor/setup/ — create/update the first vendor setup record
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/VendorSetupRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/VendorSetupRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/VendorSetupRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VendorSetup'
description: ''
/api/v1/wallet/balance/:
get:
operationId: v1_wallet_balance_retrieve
description: |-
Alias for MyWalletView, specifically focusing on the current balance state.
Legacy Context:
Previously served as a simple balance-only endpoint.
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Wallet'
description: ''
/api/v1/wallet/escrow/hold/:
post:
operationId: v1_wallet_escrow_hold_create
description: |-
Places funds on escrow hold when a new order is initialized.
Flow:
1. Verify user has sufficient balance.
2. Deduct amount from available balance.
3. Create a Hold record with PENDING status.
4. Increment 'held_balance'.
Status Codes:
201 Created: Funds successfully locked in escrow.
400 Bad Request: Insufficient balance.
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/EscrowHoldRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/EscrowHoldRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/EscrowHoldRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/EscrowHold'
description: ''
/api/v1/wallet/escrow/release/:
post:
operationId: v1_wallet_escrow_release_create
description: |-
Releases escrowed funds to the vendor after order completion.
Flow:
1. Locate the Hold record by reference.
2. Verify client authorization (or automated release trigger).
3. Calculate and deduct platform commission.
4. Credit vendor's available balance.
5. Mark Hold as RELEASED.
Status Codes:
200 OK: Vendor successfully credited.
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/EscrowReleaseRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/EscrowReleaseRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/EscrowReleaseRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/EscrowRelease'
description: ''
/api/v1/wallet/me/:
get:
operationId: v1_wallet_me_retrieve
description: |-
Retrieves the authenticated user's digital wallet profile.
Flow:
1. Check if wallet exists for the user.
2. If not, provision a new wallet with zero balance.
3. Return balance and hold statistics.
Status Codes:
200 OK: Returns wallet details.
tags:
- v1
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Wallet'
description: ''
/api/v1/wallet/pin/change/:
post:
operationId: v1_wallet_pin_change_create
description: |-
Updates an existing transaction PIN after verifying the current one.
Security:
Requires 'current_pin' to prevent unauthorized changes.
Status Codes:
200 OK: PIN updated.
400 Bad Request: Invalid current PIN or weak new PIN.
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/WalletPinChangeRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/WalletPinChangeRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/WalletPinChangeRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/WalletPinChange'
description: ''
/api/v1/wallet/pin/set/:
post:
operationId: v1_wallet_pin_set_create
description: |-
Establishes a 4-digit transaction PIN for wallet authorization.
Flow:
1. User provides a 4-digit numeric string.
2. Service hashes the PIN for secure storage.
3. Enables transaction capabilities for the wallet.
Status Codes:
200 OK: PIN established.
400 Bad Request: Invalid format or PIN already set.
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/WalletPinSetRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/WalletPinSetRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/WalletPinSetRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/WalletPinSet'
description: ''
/api/v1/wallet/pin/verify/:
post:
operationId: v1_wallet_pin_verify_create
description: |-
Validates a transaction PIN without performing a financial operation.
Use Case:
Frontend checks PIN before showing "Confirm Transfer" buttons.
Status Codes:
200 OK: returns {"valid": bool}
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/WalletPinVerifyRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/WalletPinVerifyRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/WalletPinVerifyRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/WalletPinVerify'
description: ''
/api/v1/wallet/refund/:
post:
operationId: v1_wallet_refund_create
description: |-
Refunds escrowed funds back to the client available balance.
Use Case:
Order cancellation or dispute resolution in favor of the client.
Flow:
1. Move funds from held_balance back to available_balance.
2. Mark Hold as REFUNDED.
Status Codes:
200 OK: Client successfully refunded.
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/EscrowRefundRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/EscrowRefundRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/EscrowRefundRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/EscrowRefund'
description: ''
/api/v1/wallet/withdraw/:
post:
operationId: v1_wallet_withdraw_create
description: |-
Create a KYC-gated wallet withdrawal request.
The service blocks before debit if KYC is incomplete, then moves funds from
available to pending balance and writes a processing payout ledger row.
tags:
- v1
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/WalletWithdrawalRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/WalletWithdrawalRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/WalletWithdrawalRequest'
required: true
security:
- jwtAuth: []
- tokenAuth: []
- cookieAuth: []
- basicAuth: []
- BearerAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/WalletWithdrawal'
description: ''
components:
schemas:
AddressCreate:
type: object
description: Input serializer for POST /addresses/.
properties:
label:
type: string
description: 'Short label: ''Home'', ''Office'', or ''Mum\''s place''.'
maxLength: 80
full_name:
type: string
maxLength: 150
phone:
type: string
maxLength: 30
street_address:
type: string
description: Street, house number, landmark.
city:
type: string
maxLength: 100
state:
type: string
maxLength: 100
country:
type: string
maxLength: 100
postal_code:
type: string
maxLength: 20
is_default:
type: boolean
description: True if this is the primary address shown at checkout.
required:
- city
- state
- street_address
AddressCreateRequest:
type: object
description: Input serializer for POST /addresses/.
properties:
label:
type: string
description: 'Short label: ''Home'', ''Office'', or ''Mum\''s place''.'
maxLength: 80
full_name:
type: string
maxLength: 150
phone:
type: string
maxLength: 30
street_address:
type: string
minLength: 1
description: Street, house number, landmark.
city:
type: string
minLength: 1
maxLength: 100
state:
type: string
minLength: 1
maxLength: 100
country:
type: string
minLength: 1
maxLength: 100
postal_code:
type: string
maxLength: 20
is_default:
type: boolean
description: True if this is the primary address shown at checkout.
required:
- city
- state
- street_address
Alert:
type: object
properties:
id:
type: integer
readOnly: true
rule:
type: integer
title: Alert Rule
rule_name:
type: string
readOnly: true
rule_severity:
type: string
readOnly: true
status:
$ref: '#/components/schemas/AlertStatusEnum'
metric_value:
type: number
format: double
title: Current Value
message:
type: string
title: Alert Message
metadata: {}
fired_at:
type: string
format: date-time
readOnly: true
title: Triggered At
resolved_at:
type: string
format: date-time
nullable: true
required:
- fired_at
- id
- message
- metric_value
- rule
- rule_name
- rule_severity
AlertRequest:
type: object
properties:
rule:
type: integer
title: Alert Rule
status:
$ref: '#/components/schemas/AlertStatusEnum'
metric_value:
type: number
format: double
title: Current Value
message:
type: string
minLength: 1
title: Alert Message
metadata: {}
resolved_at:
type: string
format: date-time
nullable: true
required:
- message
- metric_value
- rule
AlertRule:
type: object
properties:
id:
type: integer
readOnly: true
name:
type: string
title: Rule Name
maxLength: 100
metric_name:
type: string
maxLength: 255
operator:
allOf:
- $ref: '#/components/schemas/OperatorEnum'
title: Comparison Operator
threshold:
type: number
format: double
severity:
$ref: '#/components/schemas/SeverityEnum'
is_active:
type: boolean
description:
type: string
created_at:
type: string
format: date-time
readOnly: true
updated_at:
type: string
format: date-time
readOnly: true
required:
- created_at
- id
- metric_name
- name
- operator
- threshold
- updated_at
AlertRuleRequest:
type: object
properties:
name:
type: string
minLength: 1
title: Rule Name
maxLength: 100
metric_name:
type: string
minLength: 1
maxLength: 255
operator:
allOf:
- $ref: '#/components/schemas/OperatorEnum'
title: Comparison Operator
threshold:
type: number
format: double
severity:
$ref: '#/components/schemas/SeverityEnum'
is_active:
type: boolean
description:
type: string
required:
- metric_name
- name
- operator
- threshold
AlertStatusEnum:
enum:
- firing
- resolved
- suppressed
type: string
AssetTypeEnum:
enum:
- avatar
- blog
- brand
- category
- chat_file
- collection
- generic_image
- generic_video
- kyc_document
- measurement
- product_color
- product_gallery
- product_image
- product_video
- profile
- vendor_shop
type: string
AuthGoogleAuth:
type: object
description: |-
Serializer for Google ID Token authentication.
Flow:
Login (existing user): { id_token } role is optional, ignored
Register (new user): { id_token, role: 'vendor'|'client' }
properties:
id_token:
type: string
description: Google ID Token (JWT) returned by @react-oauth/google on the
frontend.
role:
default: client
description: User's role required for new registrations, ignored for existing
users.
oneOf:
- $ref: '#/components/schemas/RoleC2fEnum'
- $ref: '#/components/schemas/BlankEnum'
required:
- id_token
AuthGoogleAuthRequest:
type: object
description: |-
Serializer for Google ID Token authentication.
Flow:
Login (existing user): { id_token } role is optional, ignored
Register (new user): { id_token, role: 'vendor'|'client' }
properties:
id_token:
type: string
minLength: 1
description: Google ID Token (JWT) returned by @react-oauth/google on the
frontend.
role:
default: client
description: User's role required for new registrations, ignored for existing
users.
oneOf:
- $ref: '#/components/schemas/RoleC2fEnum'
- $ref: '#/components/schemas/BlankEnum'
required:
- id_token
AuthLoginRequest:
type: object
description: |-
Serializer for authenticating users with either email or phone.
Enterprise-grade auth flow (priority order):
1. Alive-only lookup (is_deleted=False)
2. Soft-deleted pool check SoftDeletedUserError (403)
3. Password check InvalidCredentialsError (401)
4a. is_verified check FIRST AccountNotVerifiedError (403) with OTP URLs
4b. is_active check SECOND AccountDeactivatedError (403) with support URL
Serializer for user authentication via Email or Phone.
Validation Logic:
1. Normalise input identifier (email to lowercase).
2. Verify user exists and is not soft-deleted.
3. Verify password hash matches.
4. Check account lifecycle status (verified, active).
Security:
- Uses Django's `check_password` for constant-time comparison.
- Throttled at the View level to prevent brute-force.
properties:
email_or_phone:
type: string
writeOnly: true
minLength: 1
description: User's email or phone for login
password:
type: string
writeOnly: true
minLength: 1
description: User's password
required:
- email_or_phone
- password
AuthLogout:
type: object
description: Accepts the refresh token to blacklist on logout.
properties:
refresh:
type: string
description: Refresh token to blacklist on logout.
required:
- refresh
AuthLogoutRequest:
type: object
description: Accepts the refresh token to blacklist on logout.
properties:
refresh:
type: string
minLength: 1
description: Refresh token to blacklist on logout.
required:
- refresh
AuthMe:
type: object
description: |-
Serializes the authenticated user's profile for the /auth/me/ endpoint.
This serializer's output shape is the authoritative contract between
the backend and the frontend Zustand auth store (useAuthHydration).
Field-by-field null/blank behaviour:
user_id str (UUID)
identifying_info str (email or phone or fallback string)
member_id str | null (null only before first save race, practically never)
email str | null (null for phone-only accounts)
phone str | null (null for email-only accounts, E.164 format)
first_name str (empty string "" when not set model blank=True)
last_name str (empty string "" when not set model blank=True)
role str (choices: client | vendor | staff | admin | …)
auth_provider str (choices: email | phone | google)
is_verified bool
is_active bool
is_staff bool
avatar str | null (full Cloudinary HTTPS URL or null)
bio str (empty string "" when not set)
country str (empty string "" when not set)
state str (empty string "" when not set)
city str (empty string "" when not set)
address str (empty string "" when not set)
date_joined str | null (ISO-8601 datetime string or null)
last_login str | null (ISO-8601 datetime string or null)
properties:
user_id:
type: string
readOnly: true
identifying_info:
type: string
readOnly: true
member_id:
type: string
readOnly: true
nullable: true
description: Unique human-readable brand ID (e.g. FASTAR000062). Auto-generated
on user creation. Cannot be changed.
email:
type: string
format: email
readOnly: true
nullable: true
title: Email address
description: Primary unique identifier for email-based auth.
phone:
type: string
readOnly: true
first_name:
type: string
readOnly: true
default: ''
last_name:
type: string
readOnly: true
default: ''
role:
allOf:
- $ref: '#/components/schemas/RoleC2fEnum'
readOnly: true
description: RBAC Role. Cannot be changed after creation.
auth_provider:
allOf:
- $ref: '#/components/schemas/AuthProviderEnum'
readOnly: true
description: Authentication provider used at signup.
is_verified:
type: boolean
readOnly: true
description: True if email/phone OTP is verified.
is_active:
type: boolean
readOnly: true
description: True if user account is active.
is_staff:
type: boolean
readOnly: true
title: Staff status
description: Designates whether the user can log into this admin site.
has_client_profile:
type: string
readOnly: true
has_vendor_profile:
type: string
readOnly: true
vendor_onboarding_status:
type: string
readOnly: true
dashboard_entrypoint:
type: string
readOnly: true
avatar:
type: string
readOnly: true
bio:
type: string
readOnly: true
description: User's biography.
country:
type: string
readOnly: true
description: User's country.
state:
type: string
readOnly: true
description: User's state or province.
city:
type: string
readOnly: true
description: User's city.
address:
type: string
readOnly: true
description: User's street address.
date_joined:
type: string
format: date-time
readOnly: true
last_login:
type: string
format: date-time
readOnly: true
required:
- address
- auth_provider
- avatar
- bio
- city
- country
- dashboard_entrypoint
- date_joined
- email
- first_name
- has_client_profile
- has_vendor_profile
- identifying_info
- is_active
- is_staff
- is_verified
- last_login
- last_name
- member_id
- phone
- role
- state
- user_id
- vendor_onboarding_status
AuthMethodEnum:
enum:
- email
- phone
- google
- biometric
type: string
AuthOTP:
type: object
description: |-
Serializer for OTP verification.
Validation Logic:
- Required: 6-digit string.
- Numeric only.
Security:
- Max length enforced to prevent buffer/memory attacks.
properties:
otp:
type: string
description: One-Time Password (OTP) for verification.
maxLength: 6
required:
- otp
AuthOTPRequest:
type: object
description: |-
Serializer for OTP verification.
Validation Logic:
- Required: 6-digit string.
- Numeric only.
Security:
- Max length enforced to prevent buffer/memory attacks.
properties:
otp:
type: string
minLength: 1
description: One-Time Password (OTP) for verification.
maxLength: 6
required:
- otp
AuthPasswordResetConfirmEmailRequest:
type: object
description: |-
Serializer for confirming password reset via email magic link.
Validates the new password and confirmation match.
The uidb64 + token URL params are merged in by the view.
properties:
password:
type: string
writeOnly: true
minLength: 1
description: New password
password2:
type: string
writeOnly: true
minLength: 1
description: Confirm new password
required:
- password
- password2
AuthPasswordResetConfirmPhone:
type: object
description: |-
Serializer for confirming password reset via phone OTP.
OTP-ONLY design (mirrors VerifyOTPView pattern exactly):
- Client sends ONLY: otp + new_password + new_password_confirm.
- phone is NOT required in the body the service discovers the user
via OTPService.verify_by_otp_sync(otp, purpose='password_reset'),
which uses an O(1) SHA-256 hash index lookup in Redis:
otp_hash:{sha256(otp)} otp:{user_id}:password_reset:{snippet}
- This prevents account enumeration: an attacker cannot test whether
a phone number has an account by observing different error responses.
Redis key schema (written during reset-request):
Primary : otp:{user_id}:password_reset:{snippet}
Value = "{encrypted_otp}|{sha256_hex}"
Secondary: otp_hash:{sha256_hex} primary_key (TTL = 300 s)
Field names match Zod PasswordResetConfirmPhoneSchema exactly:
Frontend sends: { otp, new_password, new_password_confirm }
properties:
otp:
type: string
description: 6-digit OTP received via SMS
maxLength: 6
required:
- otp
AuthPasswordResetConfirmPhoneRequest:
type: object
description: |-
Serializer for confirming password reset via phone OTP.
OTP-ONLY design (mirrors VerifyOTPView pattern exactly):
- Client sends ONLY: otp + new_password + new_password_confirm.
- phone is NOT required in the body the service discovers the user
via OTPService.verify_by_otp_sync(otp, purpose='password_reset'),
which uses an O(1) SHA-256 hash index lookup in Redis:
otp_hash:{sha256(otp)} otp:{user_id}:password_reset:{snippet}
- This prevents account enumeration: an attacker cannot test whether
a phone number has an account by observing different error responses.
Redis key schema (written during reset-request):
Primary : otp:{user_id}:password_reset:{snippet}
Value = "{encrypted_otp}|{sha256_hex}"
Secondary: otp_hash:{sha256_hex} primary_key (TTL = 300 s)
Field names match Zod PasswordResetConfirmPhoneSchema exactly:
Frontend sends: { otp, new_password, new_password_confirm }
properties:
otp:
type: string
minLength: 1
description: 6-digit OTP received via SMS
maxLength: 6
new_password:
type: string
writeOnly: true
minLength: 1
description: New password
new_password_confirm:
type: string
writeOnly: true
minLength: 1
description: Confirm new password
required:
- new_password
- new_password_confirm
- otp
AuthPasswordResetRequestRequest:
type: object
description: |-
Serializer for requesting password reset.
Uses all_with_deleted() so soft-deleted users can still trigger a reset.
Anti-enumeration: always returns 200 regardless of whether user exists.
properties:
email_or_phone:
type: string
writeOnly: true
minLength: 1
description: User's email or phone for password reset
required:
- email_or_phone
AuthProtectedUser:
type: object
description: |-
Expose safe, non-sensitive user information for authenticated profile reads.
Used by endpoints that share user data with other users or services.
Never exposes: password, groups, permissions, auth_provider, is_staff,
internal timestamps, or any security-sensitive field.
Fields returned:
user_id str (UUID)
member_id str | null
email str | null
phone str | null (E.164)
first_name str
last_name str
role str
is_verified bool
is_active bool
avatar str | null (Cloudinary URL)
bio str
country str
state str
city str
address str
date_joined ISO-8601 | null
properties:
user_id:
type: string
readOnly: true
member_id:
type: string
readOnly: true
nullable: true
description: Unique human-readable brand ID (e.g. FASTAR000062). Auto-generated
on user creation. Cannot be changed.
email:
type: string
format: email
readOnly: true
nullable: true
title: Email address
description: Primary unique identifier for email-based auth.
phone:
type: string
readOnly: true
first_name:
type: string
readOnly: true
default: ''
last_name:
type: string
readOnly: true
default: ''
role:
allOf:
- $ref: '#/components/schemas/RoleC2fEnum'
readOnly: true
description: RBAC Role. Cannot be changed after creation.
is_verified:
type: boolean
readOnly: true
description: True if email/phone OTP is verified.
is_active:
type: boolean
readOnly: true
description: True if user account is active.
avatar:
type: string
readOnly: true
bio:
type: string
readOnly: true
description: User's biography.
country:
type: string
readOnly: true
description: User's country.
state:
type: string
readOnly: true
description: User's state or province.
city:
type: string
readOnly: true
description: User's city.
address:
type: string
readOnly: true
description: User's street address.
date_joined:
type: string
format: date-time
readOnly: true
required:
- address
- avatar
- bio
- city
- country
- date_joined
- email
- first_name
- is_active
- is_verified
- last_name
- member_id
- phone
- role
- state
- user_id
AuthProviderEnum:
enum:
- email
- phone
- google
type: string
AuthResendOTPRequestRequest:
type: object
description: |-
Serializer for requesting OTP resend by email or phone.
CRITICAL FIX: Uses ``all_with_deleted()`` manager so that users who
just registered (is_active=False, is_verified=False) are found.
A newly-registered unverified user IS alive they just haven't
been activated yet.
properties:
email_or_phone:
type: string
writeOnly: true
minLength: 1
description: User's email or phone for resend OTP
required:
- email_or_phone
AuthTokenRefresh:
type: object
description: Wraps SimpleJWT token refresh for drf-yasg Swagger schema generation.
properties:
refresh:
type: string
description: A valid refresh token previously issued by the login endpoint.
required:
- refresh
AuthTokenRefreshRequest:
type: object
description: Wraps SimpleJWT token refresh for drf-yasg Swagger schema generation.
properties:
refresh:
type: string
minLength: 1
description: A valid refresh token previously issued by the login endpoint.
required:
- refresh
AuthUserProfile:
type: object
description: |-
Full profile serializer for self-update (PATCH /api/v1/profile/me/).
Read-only fields:
id, member_id, email, phone, role, auth_provider,
is_verified, is_active, is_staff, is_superuser,
date_joined, last_login, password, groups, user_permissions
Writable fields (matches PROFILE_EDITABLE_FIELDS in profile_service):
first_name, last_name, bio, country, state, city, address, avatar
Extra output fields (computed):
user_id str(uuid)
identifying_info str
phone_display E.164 string | null (read-only convenience field)
avatar_url Cloudinary URL string | null
properties:
user_id:
type: string
readOnly: true
identifying_info:
type: string
readOnly: true
id:
type: string
format: uuid
readOnly: true
description: UUID7 globally unique, time-ordered primary key.
member_id:
type: string
readOnly: true
nullable: true
description: Unique human-readable brand ID (e.g. FASTAR000062). Auto-generated
on user creation. Cannot be changed.
email:
type: string
format: email
readOnly: true
nullable: true
title: Email address
description: Primary unique identifier for email-based auth.
phone_display:
type: string
readOnly: true
role:
allOf:
- $ref: '#/components/schemas/RoleC2fEnum'
readOnly: true
description: RBAC Role. Cannot be changed after creation.
auth_provider:
allOf:
- $ref: '#/components/schemas/AuthProviderEnum'
readOnly: true
description: Authentication provider used at signup.
is_verified:
type: boolean
readOnly: true
description: True if email/phone OTP is verified.
is_active:
type: boolean
readOnly: true
description: True if user account is active.
is_staff:
type: boolean
readOnly: true
title: Staff status
description: Designates whether the user can log into this admin site.
first_name:
type: string
nullable: true
last_name:
type: string
nullable: true
bio:
type: string
description: User's biography.
country:
type: string
description: User's country.
maxLength: 100
state:
type: string
description: User's state or province.
maxLength: 100
city:
type: string
description: User's city.
maxLength: 100
address:
type: string
description: User's street address.
maxLength: 255
avatar:
type: string
nullable: true
description: 'Cloudinary image public_id. Set via the /api/v1/upload/presign/
→ direct upload → webhook flow. Use .url in serializers to retrieve the
full HTTPS secure_url. In admin: use the file picker widget to upload
directly to Cloudinary.'
avatar_url:
type: string
readOnly: true
date_joined:
type: string
format: date-time
readOnly: true
last_login:
type: string
format: date-time
readOnly: true
required:
- auth_provider
- avatar_url
- date_joined
- email
- id
- identifying_info
- is_active
- is_staff
- is_verified
- last_login
- member_id
- phone_display
- role
- user_id
AuthUserProfileRequest:
type: object
description: |-
Full profile serializer for self-update (PATCH /api/v1/profile/me/).
Read-only fields:
id, member_id, email, phone, role, auth_provider,
is_verified, is_active, is_staff, is_superuser,
date_joined, last_login, password, groups, user_permissions
Writable fields (matches PROFILE_EDITABLE_FIELDS in profile_service):
first_name, last_name, bio, country, state, city, address, avatar
Extra output fields (computed):
user_id str(uuid)
identifying_info str
phone_display E.164 string | null (read-only convenience field)
avatar_url Cloudinary URL string | null
properties:
first_name:
type: string
nullable: true
last_name:
type: string
nullable: true
bio:
type: string
description: User's biography.
country:
type: string
description: User's country.
maxLength: 100
state:
type: string
description: User's state or province.
maxLength: 100
city:
type: string
description: User's city.
maxLength: 100
address:
type: string
description: User's street address.
maxLength: 255
avatar:
type: string
minLength: 1
nullable: true
description: 'Cloudinary image public_id. Set via the /api/v1/upload/presign/
→ direct upload → webhook flow. Use .url in serializers to retrieve the
full HTTPS secure_url. In admin: use the file picker widget to upload
directly to Cloudinary.'
AuthUserRegistration:
type: object
description: |-
Serializer for creating a new user account.
Validation Logic:
- Enforces One-of-Email-or-Phone.
- Password strength validation via Django standard.
- Duplicate check against active and soft-deleted pools.
Security:
- Atomic transaction check to prevent race-condition duplicates.
properties:
email:
type: string
format: email
description: User's email address
phone:
type: string
description: User's phone number
role:
allOf:
- $ref: '#/components/schemas/Role09fEnum'
description: 'User''s role: ''vendor'' or ''client'''
first_name:
type: string
description: User's first name
maxLength: 150
last_name:
type: string
description: User's last name
maxLength: 150
required:
- role
AuthUserRegistrationRequest:
type: object
description: |-
Serializer for creating a new user account.
Validation Logic:
- Enforces One-of-Email-or-Phone.
- Password strength validation via Django standard.
- Duplicate check against active and soft-deleted pools.
Security:
- Atomic transaction check to prevent race-condition duplicates.
properties:
email:
type: string
format: email
description: User's email address
phone:
type: string
description: User's phone number
role:
allOf:
- $ref: '#/components/schemas/Role09fEnum'
description: 'User''s role: ''vendor'' or ''client'''
first_name:
type: string
description: User's first name
maxLength: 150
last_name:
type: string
description: User's last name
maxLength: 150
password:
type: string
writeOnly: true
minLength: 1
description: User's password
password2:
type: string
writeOnly: true
minLength: 1
description: Confirm user's password
required:
- password
- password2
- role
BankAccountCreate:
type: object
properties:
account_number:
type: string
pattern: ^\d{10}$
bank_code:
type: string
maxLength: 10
bank_name:
type: string
maxLength: 150
account_name:
type: string
description: Account holder name as resolved by Paystack.
maxLength: 200
required:
- account_name
- account_number
- bank_code
- bank_name
BankAccountCreateRequest:
type: object
properties:
account_number:
type: string
minLength: 1
pattern: ^\d{10}$
bank_code:
type: string
minLength: 1
maxLength: 10
bank_name:
type: string
minLength: 1
maxLength: 150
account_name:
type: string
minLength: 1
description: Account holder name as resolved by Paystack.
maxLength: 200
required:
- account_name
- account_number
- bank_code
- bank_name
BankAccountOutput:
type: object
description: Safe serializer never returns full account_number or enc bytes.
properties:
id:
type: string
format: uuid
bank_name:
type: string
bank_code:
type: string
account_name:
type: string
account_last4:
type: string
masked_account:
type: string
paystack_recipient_code:
type: string
kyc_name_matched:
type: boolean
is_default:
type: boolean
verification_status:
type: string
is_verified:
type: boolean
created_at:
type: string
format: date-time
required:
- account_last4
- account_name
- bank_code
- bank_name
- created_at
- id
- is_default
- is_verified
- kyc_name_matched
- masked_account
- paystack_recipient_code
- verification_status
BankAccountResolve:
type: object
properties:
account_number:
type: string
pattern: ^\d{10}$
bank_code:
type: string
pattern: ^\d{3,10}$
required:
- account_number
- bank_code
BankAccountResolveRequest:
type: object
properties:
account_number:
type: string
minLength: 1
pattern: ^\d{10}$
bank_code:
type: string
minLength: 1
pattern: ^\d{3,10}$
required:
- account_number
- bank_code
BespokeConsultationRequestRequest:
type: object
description: Serializer for booking bespoke tailoring consultation.
properties:
tailoring_type:
type: string
minLength: 1
description: Required bespoke item type (e.g. suit, gown, coat)
preferred_date:
type: string
format: date
description: Preferred date
preferred_time:
type: string
minLength: 1
description: Preferred time slot
urgency:
allOf:
- $ref: '#/components/schemas/UrgencyEnum'
default: medium
description: Urgency level
design_details:
type: string
minLength: 1
description: Details of design ideas or reference requests
BlankEnum:
enum:
- ''
BusinessMetric:
type: object
properties:
id:
type: integer
readOnly: true
metric_name:
type: string
title: Business Metric Name
maxLength: 100
value:
type: number
format: double
period_start:
type: string
format: date-time
period_end:
type: string
format: date-time
metadata: {}
created_at:
type: string
format: date-time
readOnly: true
required:
- created_at
- id
- metric_name
- period_end
- period_start
- value
CashConfirmationConfirm:
type: object
properties:
order_id:
type: string
maxLength: 120
client_token:
type: string
maxLength: 255
required:
- client_token
- order_id
CashConfirmationConfirmRequest:
type: object
properties:
order_id:
type: string
minLength: 1
maxLength: 120
client_token:
type: string
minLength: 1
maxLength: 255
required:
- client_token
- order_id
CashConfirmationCreate:
type: object
properties:
order_id:
type: string
maxLength: 120
required:
- order_id
CashConfirmationCreateRequest:
type: object
properties:
order_id:
type: string
minLength: 1
maxLength: 120
required:
- order_id
CashConfirmationResend:
type: object
properties:
order_id:
type: string
maxLength: 120
required:
- order_id
CashConfirmationResendRequest:
type: object
properties:
order_id:
type: string
minLength: 1
maxLength: 120
required:
- order_id
CashPaymentModeEnum:
enum:
- disabled
- cod
- pay_at_shop
- both
type: string
CatalogBlogMedia:
type: object
description: |-
Read-optimised serialiser for BlogMedia gallery items.
Exposes derived `public_id` and `image_url` fields sourced from
the Cloudinary CloudinaryField. The raw `image` (CloudinaryField)
is intentionally omitted from `fields` to avoid the DRF assertion
that fires when a model property shares a name with a declared
SerializerMethodField (image_url).
Architecture note:
Uploads use the two-phase direct-upload pattern:
1. Frontend POST /api/v1/upload/presign/ signed token
2. Frontend POSTs file directly to Cloudinary (bypasses Django)
3. Cloudinary webhook Celery task reconciles public_id here
`image_url` returns the full HTTPS secure_url from Cloudinary.
properties:
id:
type: string
format: uuid
readOnly: true
description: UUID7 globally unique, time-ordered primary key.
public_id:
type: string
readOnly: true
image_url:
type: string
readOnly: true
alt_text:
type: string
maxLength: 180
sort_order:
type: integer
maximum: 9223372036854775807
minimum: 0
format: int64
created_at:
type: string
format: date-time
readOnly: true
description: Timestamp when the record was created.
updated_at:
type: string
format: date-time
readOnly: true
description: Timestamp when the record was last updated.
required:
- created_at
- id
- image_url
- public_id
- updated_at
CatalogBlogMediaRequest:
type: object
description: |-
Read-optimised serialiser for BlogMedia gallery items.
Exposes derived `public_id` and `image_url` fields sourced from
the Cloudinary CloudinaryField. The raw `image` (CloudinaryField)
is intentionally omitted from `fields` to avoid the DRF assertion
that fires when a model property shares a name with a declared
SerializerMethodField (image_url).
Architecture note:
Uploads use the two-phase direct-upload pattern:
1. Frontend POST /api/v1/upload/presign/ signed token
2. Frontend POSTs file directly to Cloudinary (bypasses Django)
3. Cloudinary webhook Celery task reconciles public_id here
`image_url` returns the full HTTPS secure_url from Cloudinary.
properties:
alt_text:
type: string
maxLength: 180
sort_order:
type: integer
maximum: 9223372036854775807
minimum: 0
format: int64
CatalogBlogPost:
type: object
properties:
id:
type: string
format: uuid
readOnly: true
description: UUID7 globally unique, time-ordered primary key.
author:
type: string
format: uuid
description: Author is retained as nullable to preserve published history.
readOnly: true
nullable: true
author_name:
type: string
readOnly: true
category:
type: string
format: uuid
description: Optional catalog category used for discovery and SEO.
nullable: true
category_name:
type: string
readOnly: true
title:
type: string
maxLength: 255
slug:
type: string
readOnly: true
pattern: ^[-a-zA-Z0-9_]+$
excerpt:
type: string
content:
type: string
featured_image:
type: string
nullable: true
description: Featured post image (public_id).
featured_image_url:
type: string
readOnly: true
image_url:
type: string
readOnly: true
gallery_media:
type: array
items:
$ref: '#/components/schemas/CatalogBlogMedia'
readOnly: true
status:
$ref: '#/components/schemas/CatalogBlogPostStatusEnum'
tags: {}
seo_title:
type: string
maxLength: 180
seo_description:
type: string
maxLength: 320
is_featured:
type: boolean
published_at:
type: string
format: date-time
readOnly: true
nullable: true
view_count:
type: integer
readOnly: true
created_at:
type: string
format: date-time
readOnly: true
description: Timestamp when the record was created.
updated_at:
type: string
format: date-time
readOnly: true
description: Timestamp when the record was last updated.
required:
- author
- author_name
- category_name
- content
- created_at
- featured_image_url
- gallery_media
- id
- image_url
- published_at
- slug
- title
- updated_at
- view_count
CatalogBlogPostRequest:
type: object
properties:
category:
type: string
format: uuid
description: Optional catalog category used for discovery and SEO.
nullable: true
title:
type: string
minLength: 1
maxLength: 255
excerpt:
type: string
content:
type: string
minLength: 1
featured_image:
type: string
minLength: 1
nullable: true
description: Featured post image (public_id).
status:
$ref: '#/components/schemas/CatalogBlogPostStatusEnum'
tags: {}
seo_title:
type: string
maxLength: 180
seo_description:
type: string
maxLength: 320
is_featured:
type: boolean
required:
- content
- title
CatalogBlogPostStatusEnum:
enum:
- draft
- review
- published
- archived
type: string
CatalogBrand:
type: object
properties:
id:
type: string
format: uuid
readOnly: true
description: UUID7 globally unique, time-ordered primary key.
name:
type: string
readOnly: true
title:
type: string
maxLength: 100
slug:
type: string
readOnly: true
nullable: true
pattern: ^[-a-zA-Z0-9_]+$
description:
type: string
nullable: true
image:
type: string
nullable: true
description: Cloudinary image public_id. Set via the /api/v1/upload/presign/
direct upload webhook flow. Use .url in serializers to retrieve the
full HTTPS secure_url.
image_url:
type: string
readOnly: true
active:
type: boolean
created_at:
type: string
format: date-time
readOnly: true
description: Timestamp when the record was created.
updated_at:
type: string
format: date-time
readOnly: true
description: Timestamp when the record was last updated.
required:
- created_at
- id
- image_url
- name
- slug
- title
- updated_at
CatalogBrandRequest:
type: object
properties:
title:
type: string
minLength: 1
maxLength: 100
description:
type: string
nullable: true
image:
type: string
minLength: 1
nullable: true
description: Cloudinary image public_id. Set via the /api/v1/upload/presign/
direct upload webhook flow. Use .url in serializers to retrieve the
full HTTPS secure_url.
active:
type: boolean
required:
- title
CatalogCategory:
type: object
properties:
id:
type: string
format: uuid
readOnly: true
description: UUID7 globally unique, time-ordered primary key.
name:
type: string
maxLength: 100
title:
type: string
readOnly: true
slug:
type: string
readOnly: true
nullable: true
pattern: ^[-a-zA-Z0-9_]+$
image:
type: string
nullable: true
description: Cloudinary image public_id. Set via the /api/v1/upload/presign/
direct upload webhook flow. Use .url in serializers to retrieve the
full HTTPS secure_url.
image_url:
type: string
readOnly: true
is_deleted:
type: boolean
description: Flag indicating if the record is soft-deleted.
created_at:
type: string
format: date-time
readOnly: true
description: Timestamp when the record was created.
updated_at:
type: string
format: date-time
readOnly: true
description: Timestamp when the record was last updated.
required:
- created_at
- id
- image_url
- name
- slug
- title
- updated_at
CatalogCategoryRequest:
type: object
properties:
name:
type: string
minLength: 1
maxLength: 100
image:
type: string
minLength: 1
nullable: true
description: Cloudinary image public_id. Set via the /api/v1/upload/presign/
direct upload webhook flow. Use .url in serializers to retrieve the
full HTTPS secure_url.
is_deleted:
type: boolean
description: Flag indicating if the record is soft-deleted.
required:
- name
CatalogCollection:
type: object
properties:
id:
type: string
format: uuid
readOnly: true
description: UUID7 globally unique, time-ordered primary key.
name:
type: string
readOnly: true
title:
type: string
nullable: true
maxLength: 255
slug:
type: string
readOnly: true
nullable: true
pattern: ^[-a-zA-Z0-9_]+$
sub_title:
type: string
nullable: true
maxLength: 255
description:
type: string
nullable: true
image:
type: string
nullable: true
description: Main collection thumbnail image (public_id).
image_url:
type: string
readOnly: true
background_image:
type: string
nullable: true
description: Hero background image (public_id).
background_image_url:
type: string
readOnly: true
created_at:
type: string
format: date-time
readOnly: true
description: Timestamp when the record was created.
updated_at:
type: string
format: date-time
readOnly: true
description: Timestamp when the record was last updated.
required:
- background_image_url
- created_at
- id
- image_url
- name
- slug
- updated_at
CatalogCollectionRequest:
type: object
properties:
title:
type: string
nullable: true
maxLength: 255
sub_title:
type: string
nullable: true
maxLength: 255
description:
type: string
nullable: true
image:
type: string
minLength: 1
nullable: true
description: Main collection thumbnail image (public_id).
background_image:
type: string
minLength: 1
nullable: true
description: Hero background image (public_id).
ChatbotResponseData:
type: object
description: Serializer for formatted chatbot responses.
properties:
content:
type: string
description: Response content
message_type:
type: string
description: Message type
response_data:
description: Structured response data
ai_confidence:
type: number
format: double
description: AI confidence score
processing_time:
type: number
format: double
description: Processing time in seconds
quick_replies:
type: array
items:
type: object
additionalProperties: {}
description: Suggested quick replies
required:
- content
- message_type
ChatbotSession:
type: object
description: Serializer for chatbot sessions.
properties:
id:
type: string
format: uuid
readOnly: true
user:
allOf:
- $ref: '#/components/schemas/UserBasic'
readOnly: true
session_type:
$ref: '#/components/schemas/SessionTypeEnum'
status:
$ref: '#/components/schemas/ChatbotSessionStatusEnum'
context_data:
description: Contextual info to maintain conversation state
started_at:
type: string
format: date-time
readOnly: true
last_activity:
type: string
format: date-time
readOnly: true
ended_at:
type: string
format: date-time
nullable: true
expires_at:
type: string
format: date-time
nullable: true
duration:
type: string
readOnly: true
is_active:
type: string
readOnly: true
conversation_count:
type: string
readOnly: true
metadata: {}
required:
- conversation_count
- duration
- id
- is_active
- last_activity
- session_type
- started_at
- user
ChatbotSessionRequest:
type: object
description: Serializer for chatbot sessions.
properties:
session_type:
$ref: '#/components/schemas/SessionTypeEnum'
status:
$ref: '#/components/schemas/ChatbotSessionStatusEnum'
context_data:
description: Contextual info to maintain conversation state
ended_at:
type: string
format: date-time
nullable: true
expires_at:
type: string
format: date-time
nullable: true
metadata: {}
required:
- session_type
ChatbotSessionStatusEnum:
enum:
- active
- paused
- completed
- expired
type: string
ClientAddress:
type: object
description: Read/Write serializer for ClientAddress.
properties:
id:
type: string
format: uuid
readOnly: true
description: UUID7 globally unique, time-ordered primary key.
label:
type: string
description: 'Short label: ''Home'', ''Office'', or ''Mum\''s place''.'
maxLength: 80
full_name:
type: string
maxLength: 150
phone:
type: string
maxLength: 30
street_address:
type: string
description: Street, house number, landmark.
city:
type: string
maxLength: 100
state:
type: string
maxLength: 100
country:
type: string
maxLength: 100
postal_code:
type: string
maxLength: 20
is_default:
type: boolean
description: True if this is the primary address shown at checkout.
created_at:
type: string
format: date-time
readOnly: true
description: Timestamp when the record was created.
required:
- city
- created_at
- id
- state
- street_address
ClientAddressRequest:
type: object
description: Read/Write serializer for ClientAddress.
properties:
label:
type: string
description: 'Short label: ''Home'', ''Office'', or ''Mum\''s place''.'
maxLength: 80
full_name:
type: string
maxLength: 150
phone:
type: string
maxLength: 30
street_address:
type: string
minLength: 1
description: Street, house number, landmark.
city:
type: string
minLength: 1
maxLength: 100
state:
type: string
minLength: 1
maxLength: 100
country:
type: string
minLength: 1
maxLength: 100
postal_code:
type: string
maxLength: 20
is_default:
type: boolean
description: True if this is the primary address shown at checkout.
required:
- city
- state
- street_address
ClientCartOrder:
type: object
properties:
id:
type: string
readOnly: true
oid:
type: string
readOnly: true
sub_total:
type: string
format: decimal
pattern: ^-?\d{0,10}(?:\.\d{0,2})?$
readOnly: true
shipping_amount:
type: string
format: decimal
pattern: ^-?\d{0,10}(?:\.\d{0,2})?$
readOnly: true
service_fee:
type: string
format: decimal
pattern: ^-?\d{0,10}(?:\.\d{0,2})?$
readOnly: true
total:
type: string
format: decimal
pattern: ^-?\d{0,10}(?:\.\d{0,2})?$
readOnly: true
payment_status:
type: string
readOnly: true
order_status:
type: string
readOnly: true
delivery_status:
type: string
readOnly: true
tracking_id:
type: string
readOnly: true
date:
type: string
format: date-time
readOnly: true
orderitem:
type: array
items:
$ref: '#/components/schemas/ClientOrderItem'
readOnly: true
required:
- date
- delivery_status
- id
- oid
- order_status
- orderitem
- payment_status
- service_fee
- shipping_amount
- sub_total
- total
- tracking_id
ClientOrderItem:
type: object
properties:
id:
type: string
readOnly: true
product:
type: string
readOnly: true
product_title:
type: string
readOnly: true
product_image:
type: string
readOnly: true
qty:
type: integer
readOnly: true
price:
type: string
format: decimal
pattern: ^-?\d{0,10}(?:\.\d{0,2})?$
readOnly: true
sub_total:
type: string
format: decimal
pattern: ^-?\d{0,10}(?:\.\d{0,2})?$
readOnly: true
shipping_amount:
type: string
format: decimal
pattern: ^-?\d{0,10}(?:\.\d{0,2})?$
readOnly: true
service_fee:
type: string
format: decimal
pattern: ^-?\d{0,10}(?:\.\d{0,2})?$
readOnly: true
total:
type: string
format: decimal
pattern: ^-?\d{0,10}(?:\.\d{0,2})?$
readOnly: true
date:
type: string
format: date-time
readOnly: true
required:
- date
- id
- price
- product
- product_image
- product_title
- qty
- service_fee
- shipping_amount
- sub_total
- total
ClientProfileOutput:
type: object
description: Full read-only profile serializer used in GET /profile/ responses.
properties:
id:
type: string
format: uuid
readOnly: true
description: UUID7 globally unique, time-ordered primary key.
user_id:
type: string
readOnly: true
user_email:
type: string
readOnly: true
bio:
type: string
readOnly: true
description: Short personal bio (max 500 chars).
default_shipping_address:
type: string
readOnly: true
description: Default shipping address for checkout.
state:
type: string
readOnly: true
country:
type: string
readOnly: true
preferred_size:
allOf:
- $ref: '#/components/schemas/PreferredSizeEnum'
readOnly: true
description: Preferred clothing size.
style_preferences:
readOnly: true
description: 'Style tags: ["casual", "afrocentric", "formal"]. Used by AI
engine.'
favourite_colours:
readOnly: true
description: Favourite colour hex codes or names.
total_orders:
type: integer
readOnly: true
total_spent_ngn:
type: string
format: decimal
pattern: ^-?\d{0,12}(?:\.\d{0,2})?$
readOnly: true
is_profile_complete:
type: boolean
readOnly: true
description: True once size, address, and style preferences are filled in.
email_notifications_enabled:
type: boolean
readOnly: true
description: Receive order and promo email notifications.
sms_notifications_enabled:
type: boolean
readOnly: true
description: Receive SMS alerts for order updates.
created_at:
type: string
format: date-time
readOnly: true
description: Timestamp when the record was created.
updated_at:
type: string
format: date-time
readOnly: true
description: Timestamp when the record was last updated.
addresses:
type: array
items: {}
readOnly: true
required:
- addresses
- bio
- country
- created_at
- default_shipping_address
- email_notifications_enabled
- favourite_colours
- id
- is_profile_complete
- preferred_size
- sms_notifications_enabled
- state
- style_preferences
- total_orders
- total_spent_ngn
- updated_at
- user_email
- user_id
ClientProfileUpdate:
type: object
description: |-
Input-only serializer for PATCH /profile/ requests.
All fields are optional clients send only what they want to change.
properties:
bio:
type: string
maxLength: 500
default_shipping_address:
type: string
state:
type: string
maxLength: 100
country:
type: string
maxLength: 100
preferred_size:
oneOf:
- $ref: '#/components/schemas/PreferredSizeEnum'
- $ref: '#/components/schemas/BlankEnum'
style_preferences:
type: array
items:
type: string
favourite_colours:
type: array
items:
type: string
email_notifications_enabled:
type: boolean
sms_notifications_enabled:
type: boolean
ClientProfileUpdateRequest:
type: object
description: |-
Input-only serializer for PATCH /profile/ requests.
All fields are optional clients send only what they want to change.
properties:
bio:
type: string
maxLength: 500
default_shipping_address:
type: string
state:
type: string
maxLength: 100
country:
type: string
maxLength: 100
preferred_size:
oneOf:
- $ref: '#/components/schemas/PreferredSizeEnum'
- $ref: '#/components/schemas/BlankEnum'
style_preferences:
type: array
items:
type: string
minLength: 1
favourite_colours:
type: array
items:
type: string
minLength: 1
email_notifications_enabled:
type: boolean
sms_notifications_enabled:
type: boolean
ClientReview:
type: object
properties:
id:
type: string
readOnly: true
user:
type: string
readOnly: true
user_full_name:
type: string
readOnly: true
user_avatar:
type: string
readOnly: true
product:
type: string
readOnly: true
product_title:
type: string
readOnly: true
review:
type: string
maxLength: 2000
rating:
type: integer
maximum: 5
minimum: 1
active:
type: boolean
readOnly: true
date:
type: string
format: date-time
readOnly: true
required:
- active
- date
- id
- product
- product_title
- rating
- review
- user
- user_avatar
- user_full_name
ClientReviewRequest:
type: object
properties:
product_id:
type: string
format: uuid
writeOnly: true
review:
type: string
minLength: 1
maxLength: 2000
rating:
type: integer
maximum: 5
minimum: 1
required:
- rating
- review
ClientWishlist:
type: object
properties:
id:
type: string
readOnly: true
product:
allOf:
- $ref: '#/components/schemas/WishlistProduct'
readOnly: true
date:
type: string
format: date-time
readOnly: true
required:
- date
- id
- product
CommonContactSubmission:
type: object
description: Input serializer for POST /api/v1/public/contact/.
properties:
full_name:
type: string
maxLength: 120
minLength: 2
email:
type: string
format: email
phone:
type: string
maxLength: 40
subject:
type: string
maxLength: 120
message:
type: string
maxLength: 5000
minLength: 10
vendor:
type: string
maxLength: 120
inquiry_type:
type: string
maxLength: 60
page_url:
type: string
format: uri
maxLength: 500
required:
- email
- full_name
- message
CommonContactSubmissionRequest:
type: object
description: Input serializer for POST /api/v1/public/contact/.
properties:
full_name:
type: string
minLength: 2
maxLength: 120
email:
type: string
format: email
minLength: 1
phone:
type: string
maxLength: 40
subject:
type: string
maxLength: 120
message:
type: string
minLength: 10
maxLength: 5000
vendor:
type: string
maxLength: 120
inquiry_type:
type: string
maxLength: 60
page_url:
type: string
format: uri
maxLength: 500
required:
- email
- full_name
- message
CommonNewsletterSignup:
type: object
description: Input serializer for POST /api/v1/public/newsletter/.
properties:
email:
type: string
format: email
source:
type: string
default: newsletter
maxLength: 80
required:
- email
CommonNewsletterSignupRequest:
type: object
description: Input serializer for POST /api/v1/public/newsletter/.
properties:
email:
type: string
format: email
minLength: 1
source:
type: string
default: newsletter
maxLength: 80
required:
- email
CommonPresignRequest:
type: object
description: |-
Input serializer for POST /api/v1/upload/presign/
Validates the ``asset_type`` field before passing to
``generate_cloudinary_upload_params()``. Replaces the previous raw
``request.data.get("asset_type", "avatar")`` pattern with typed DRF
validation that surfaces a proper 400 with field-level errors.
Valid asset_types are derived dynamically from _ASSET_CONFIGS so the
serializer stays in sync if new asset types are added.
properties:
asset_type:
allOf:
- $ref: '#/components/schemas/AssetTypeEnum'
default: avatar
description: 'Type of Cloudinary asset to upload. One of: avatar, product_image,
product_video, measurement.'
CommonPresignRequestRequest:
type: object
description: |-
Input serializer for POST /api/v1/upload/presign/
Validates the ``asset_type`` field before passing to
``generate_cloudinary_upload_params()``. Replaces the previous raw
``request.data.get("asset_type", "avatar")`` pattern with typed DRF
validation that surfaces a proper 400 with field-level errors.
Valid asset_types are derived dynamically from _ASSET_CONFIGS so the
serializer stays in sync if new asset types are added.
properties:
asset_type:
allOf:
- $ref: '#/components/schemas/AssetTypeEnum'
default: avatar
description: 'Type of Cloudinary asset to upload. One of: avatar, product_image,
product_video, measurement.'
CommonWaitlistSignup:
type: object
description: Input serializer for POST /api/v1/public/waitlist/.
properties:
email:
type: string
format: email
source:
type: string
default: waitlist
maxLength: 80
required:
- email
CommonWaitlistSignupRequest:
type: object
description: Input serializer for POST /api/v1/public/waitlist/.
properties:
email:
type: string
format: email
minLength: 1
source:
type: string
default: waitlist
maxLength: 80
required:
- email
Conversation:
type: object
description: Serializer for conversations including message history.
properties:
id:
type: string
format: uuid
readOnly: true
session:
allOf:
- $ref: '#/components/schemas/ChatbotSession'
readOnly: true
conversation_type:
$ref: '#/components/schemas/ConversationTypeEnum'
title:
type: string
maxLength: 200
is_active:
type: boolean
started_at:
type: string
format: date-time
readOnly: true
updated_at:
type: string
format: date-time
readOnly: true
summary:
type: string
tags: {}
messages:
type: array
items:
$ref: '#/components/schemas/Message'
readOnly: true
message_count:
type: string
readOnly: true
last_message_time:
type: string
readOnly: true
metadata: {}
required:
- id
- last_message_time
- message_count
- messages
- session
- started_at
- updated_at
ConversationRequest:
type: object
description: Serializer for conversations including message history.
properties:
conversation_type:
$ref: '#/components/schemas/ConversationTypeEnum'
title:
type: string
maxLength: 200
is_active:
type: boolean
summary:
type: string
tags: {}
metadata: {}
ConversationTypeEnum:
enum:
- style_advice
- size_recommendation
- product_search
- order_inquiry
- general_support
- general
type: string
DeliveryStatusEnum:
enum:
- pending
- processing
- shipped
- fulfilled
- cancelled
type: string
DeliveryStatusUpdate:
type: object
properties:
delivery_status:
type: string
maxLength: 100
tracking_id:
type: string
maxLength: 255
DeliveryStatusUpdateRequest:
type: object
properties:
delivery_status:
type: string
minLength: 1
maxLength: 100
tracking_id:
type: string
minLength: 1
maxLength: 255
DirectionEnum:
enum:
- inbound
- outbound
- internal
type: string
DisputeCreate:
type: object
properties:
reason:
type: string
amount:
type: string
format: decimal
pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
required:
- amount
- reason
DisputeCreateRequest:
type: object
properties:
reason:
type: string
minLength: 1
amount:
type: string
format: decimal
pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
required:
- amount
- reason
DocumentTypeEnum:
enum:
- nin_card
- bvn_slip
- passport
- drivers_license
- voters_card
- selfie
- cac_certificate
- utility_bill
type: string
EnvironmentEnum:
enum:
- development
- staging
- production
type: string
EscrowHold:
type: object
properties:
amount:
type: string
format: decimal
pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
reference:
type: string
maxLength: 120
order_id:
type: string
maxLength: 120
provider_reference:
type: string
maxLength: 120
required:
- amount
- reference
EscrowHoldRequest:
type: object
properties:
amount:
type: string
format: decimal
pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
reference:
type: string
minLength: 1
maxLength: 120
order_id:
type: string
maxLength: 120
provider_reference:
type: string
maxLength: 120
required:
- amount
- reference
EscrowRefund:
type: object
properties:
hold_reference:
type: string
maxLength: 120
required:
- hold_reference
EscrowRefundRequest:
type: object
properties:
hold_reference:
type: string
minLength: 1
maxLength: 120
required:
- hold_reference
EscrowRelease:
type: object
properties:
hold_reference:
type: string
maxLength: 120
vendor_user_id:
type: string
format: uuid
commission_rate:
type: string
format: decimal
pattern: ^-?\d{0,1}(?:\.\d{0,4})?$
default: '0.1000'
required:
- hold_reference
EscrowReleaseRequest:
type: object
properties:
hold_reference:
type: string
minLength: 1
maxLength: 120
vendor_user_id:
type: string
format: uuid
commission_rate:
type: string
format: decimal
pattern: ^-?\d{0,1}(?:\.\d{0,4})?$
default: '0.1000'
required:
- hold_reference
GenderEnum:
enum:
- M
- F
- O
type: string
IntegrationCredential:
type: object
properties:
id:
type: string
format: uuid
readOnly: true
provider:
type: string
format: uuid
provider_name:
type: string
readOnly: true
key_name:
type: string
maxLength: 100
masked_value:
type: string
readOnly: true
is_encrypted:
type: boolean
environment:
allOf:
- $ref: '#/components/schemas/EnvironmentEnum'
default: production
is_active:
type: boolean
is_valid:
type: boolean
readOnly: true
expires_at:
type: string
format: date-time
nullable: true
created_at:
type: string
format: date-time
readOnly: true
updated_at:
type: string
format: date-time
readOnly: true
created_by:
type: string
format: uuid
description: UUID7 globally unique, time-ordered primary key.
readOnly: true
nullable: true
required:
- created_at
- created_by
- id
- is_valid
- key_name
- masked_value
- provider
- provider_name
- updated_at
IntegrationCredentialRequest:
type: object
properties:
provider:
type: string
format: uuid
key_name:
type: string
minLength: 1
maxLength: 100
key_value:
type: string
writeOnly: true
minLength: 1
description: Stored in encrypted format.
is_encrypted:
type: boolean
environment:
allOf:
- $ref: '#/components/schemas/EnvironmentEnum'
default: production
is_active:
type: boolean
expires_at:
type: string
format: date-time
nullable: true
required:
- key_name
- key_value
- provider
IntegrationLog:
type: object
properties:
id:
type: string
format: uuid
readOnly: true
provider:
type: string
format: uuid
provider_name:
type: string
readOnly: true
log_level:
$ref: '#/components/schemas/LogLevelEnum'
service_name:
type: string
maxLength: 100
action:
type: string
maxLength: 100
request_data: {}
response_data: {}
error_message:
type: string
status_code:
type: integer
maximum: 9223372036854775807
minimum: -9223372036854775808
format: int64
nullable: true
duration_ms:
type: integer
maximum: 9223372036854775807
minimum: -9223372036854775808
format: int64
nullable: true
title: Duration (ms)
user:
type: string
format: uuid
description: UUID7 globally unique, time-ordered primary key.
nullable: true
user_name:
type: string
nullable: true
readOnly: true
ip_address:
type: string
nullable: true
created_at:
type: string
format: date-time
readOnly: true
title: Logged At
required:
- action
- created_at
- id
- provider
- provider_name
- service_name
- user_name
IntegrationProvider:
type: object
properties:
id:
type: string
format: uuid
readOnly: true
name:
type: string
title: Provider Name
maxLength: 100
slug:
type: string
title: Unique Slug
maxLength: 50
pattern: ^[-a-zA-Z0-9_]+$
provider_type:
allOf:
- $ref: '#/components/schemas/ProviderTypeEnum'
title: Service Type
status:
$ref: '#/components/schemas/IntegrationProviderStatusEnum'
description:
type: string
api_base_url:
type: string
format: uri
maxLength: 200
documentation_url:
type: string
format: uri
maxLength: 200
credentials_count:
type: integer
readOnly: true
logs_count:
type: integer
readOnly: true
created_at:
type: string
format: date-time
readOnly: true
updated_at:
type: string
format: date-time
readOnly: true
required:
- created_at
- credentials_count
- id
- logs_count
- name
- provider_type
- slug
- updated_at
IntegrationProviderRequest:
type: object
properties:
name:
type: string
minLength: 1
title: Provider Name
maxLength: 100
slug:
type: string
minLength: 1
title: Unique Slug
maxLength: 50
pattern: ^[-a-zA-Z0-9_]+$
provider_type:
allOf:
- $ref: '#/components/schemas/ProviderTypeEnum'
title: Service Type
status:
$ref: '#/components/schemas/IntegrationProviderStatusEnum'
description:
type: string
api_base_url:
type: string
format: uri
maxLength: 200
documentation_url:
type: string
format: uri
maxLength: 200
required:
- name
- provider_type
- slug
IntegrationProviderStatusEnum:
enum:
- active
- inactive
- maintenance
type: string
KycDocument:
type: object
description: Read serializer for a single KYC document.
properties:
id:
type: string
format: uuid
readOnly: true
description: UUID7 globally unique, time-ordered primary key.
document_type:
allOf:
- $ref: '#/components/schemas/DocumentTypeEnum'
readOnly: true
document_number:
type: string
readOnly: true
description: The actual document number, e.g. NIN (11 digits), BVN, passport
number. Encrypt at-rest in production.
secure_url:
type: string
format: uri
readOnly: true
description: Cloudinary secure_url returned after client-side upload.
public_id:
type: string
readOnly: true
description: Cloudinary public_id returned after client-side upload.
provider_verified:
type: boolean
readOnly: true
description: True if the external KYC provider confirms this document is
valid.
provider_response:
readOnly: true
description: Raw JSON result from external KYC provider for this document.
created_at:
type: string
format: date-time
readOnly: true
description: Timestamp when the record was created.
required:
- created_at
- document_number
- document_type
- id
- provider_response
- provider_verified
- public_id
- secure_url
KycSubmission:
type: object
description: |-
Read serializer for a KycSubmission including nested documents.
Used for GET /api/v1/kyc/status/ and detail views.
properties:
id:
type: string
format: uuid
readOnly: true
description: UUID7 globally unique, time-ordered primary key.
user:
type: string
readOnly: true
status:
allOf:
- $ref: '#/components/schemas/KycSubmissionStatusEnum'
readOnly: true
is_approved:
type: boolean
readOnly: true
is_pending:
type: boolean
readOnly: true
is_rejected:
type: boolean
readOnly: true
can_resubmit:
type: boolean
readOnly: true
review_notes:
type: string
readOnly: true
provider_reference:
type: string
readOnly: true
description: External KYC provider job/session reference ID.
submitted_at:
type: string
format: date-time
readOnly: true
reviewed_at:
type: string
format: date-time
readOnly: true
nullable: true
documents:
type: array
items:
$ref: '#/components/schemas/KycDocument'
readOnly: true
created_at:
type: string
format: date-time
readOnly: true
description: Timestamp when the record was created.
updated_at:
type: string
format: date-time
readOnly: true
description: Timestamp when the record was last updated.
required:
- can_resubmit
- created_at
- documents
- id
- is_approved
- is_pending
- is_rejected
- provider_reference
- review_notes
- reviewed_at
- status
- submitted_at
- updated_at
- user
KycSubmissionStatusEnum:
enum:
- pending
- in_review
- approved
- rejected
- resubmit
type: string
LogLevelEnum:
enum:
- debug
- info
- warning
- error
- critical
type: string
LoginEvent:
type: object
description: |-
Read serializer for LoginEvent — used by the login activity list.
Analogous to Binance's "Login Activity" or Google's
"Recent Security Events" dashboard panel.
All UUID7 primary keys are serialized as strings.
``timestamp`` is an alias for ``created_at`` (audit-log convention).
properties:
id:
type: string
readOnly: true
outcome:
allOf:
- $ref: '#/components/schemas/OutcomeEnum'
readOnly: true
description: Result of the login attempt.
is_successful:
type: boolean
readOnly: true
description: True iff the login attempt succeeded and tokens were issued.
failure_reason:
type: string
readOnly: true
description: 'Short machine-readable failure code: ''invalid_credentials'',
''account_inactive'', ''account_deleted'', ''rate_limited'', ''mfa_required'',
etc.'
auth_method:
allOf:
- $ref: '#/components/schemas/AuthMethodEnum'
readOnly: true
description: Authentication method used for this attempt.
ip_address:
type: string
readOnly: true
description: Client IP address (supports IPv4 and IPv6).
country:
type: string
readOnly: true
description: Country name derived from IP (via MaxMind / ipapi).
country_code:
type: string
readOnly: true
description: ISO 3166-1 alpha-2 country code (e.g. 'NG', 'US').
city:
type: string
readOnly: true
description: City name (e.g. 'Lagos', 'San Francisco').
client_type:
allOf:
- $ref: '#/components/schemas/LoginEventClientTypeEnum'
readOnly: true
description: 'Derived from User-Agent: web / mobile / api / curl.'
browser:
type: string
readOnly: true
os:
type: string
readOnly: true
device_type:
type: string
readOnly: true
description: 'Device category: desktop, mobile, tablet, bot, etc.'
risk_score:
type: integer
readOnly: true
description: Risk score 0-100. ≥70 triggers a security alert.
is_new_device:
type: boolean
readOnly: true
description: True if this is the first time this device fingerprint was
seen.
is_new_country:
type: boolean
readOnly: true
description: True if the login country is new for this user.
is_tor_exit_node:
type: boolean
readOnly: true
description: True if the IP is a known Tor exit node.
timestamp:
type: string
format: date-time
readOnly: true
required:
- auth_method
- browser
- city
- client_type
- country
- country_code
- device_type
- failure_reason
- id
- ip_address
- is_new_country
- is_new_device
- is_successful
- is_tor_exit_node
- os
- outcome
- risk_score
- timestamp
LoginEventClientTypeEnum:
enum:
- web
- mobile
- api
- curl
- unknown
type: string
Message:
type: object
description: Serializer for messages.
properties:
id:
type: string
format: uuid
readOnly: true
sender_type:
$ref: '#/components/schemas/SenderTypeEnum'
message_type:
$ref: '#/components/schemas/MessageTypeEnum'
content:
type: string
minLength: 1
response_data:
description: Structured options or response details
ai_confidence:
type: number
format: double
nullable: true
description: Confidence score of AI response (0.0 to 1.0)
processing_time:
type: number
format: double
nullable: true
description: Processing time in seconds
is_sensitive:
type: boolean
description: Does the message contain sensitive info?
created_at:
type: string
format: date-time
readOnly: true
edited_at:
type: string
format: date-time
readOnly: true
nullable: true
is_from_user:
type: string
readOnly: true
is_from_bot:
type: string
readOnly: true
metadata: {}
required:
- content
- created_at
- edited_at
- id
- is_from_bot
- is_from_user
- sender_type
MessageRequest:
type: object
description: Serializer for messages.
properties:
sender_type:
$ref: '#/components/schemas/SenderTypeEnum'
message_type:
$ref: '#/components/schemas/MessageTypeEnum'
content:
type: string
minLength: 1
response_data:
description: Structured options or response details
ai_confidence:
type: number
format: double
nullable: true
description: Confidence score of AI response (0.0 to 1.0)
processing_time:
type: number
format: double
nullable: true
description: Processing time in seconds
is_sensitive:
type: boolean
description: Does the message contain sensitive info?
metadata: {}
required:
- content
- sender_type
MessageTypeEnum:
enum:
- text
- quick_reply
- attachment
- card
- carousel
- typing
type: string
Metric:
type: object
properties:
id:
type: integer
readOnly: true
name:
type: string
title: Metric Name
description: Name identifier of the metric.
maxLength: 255
metric_type:
$ref: '#/components/schemas/MetricTypeEnum'
value:
type: number
format: double
description: Numeric value of the metric.
tags:
description: Categorization tags.
timestamp:
type: string
format: date-time
readOnly: true
required:
- id
- name
- timestamp
- value
MetricTypeEnum:
enum:
- counter
- gauge
- histogram
- timer
type: string
OperatorEnum:
enum:
- gt
- gte
- lt
- lte
- eq
- ne
type: string
OutcomeEnum:
enum:
- success
- failed
- blocked
- suspicious
type: string
OwnerTypeEnum:
enum:
- client
- vendor
- support
- editor
- moderator
- admin
- company
type: string
PaginatedAlertList:
type: object
required:
- count
- results
properties:
count:
type: integer
example: 123
next:
type: string
nullable: true
format: uri
example: http://api.example.org/accounts/?page=4
previous:
type: string
nullable: true
format: uri
example: http://api.example.org/accounts/?page=2
results:
type: array
items:
$ref: '#/components/schemas/Alert'
PaginatedAlertRuleList:
type: object
properties:
success:
type: boolean
example: true
count:
type: integer
nullable: true
pages:
type: integer
nullable: true
page:
type: integer
nullable: true
page_size:
type: integer
next:
type: string
format: uri
nullable: true
previous:
type: string
format: uri
nullable: true
results:
type: array
items:
$ref: '#/components/schemas/AlertRule'
required:
- success
- count
- next
- previous
- results
PaginatedAuthProtectedUserList:
type: object
properties:
success:
type: boolean
example: true
count:
type: integer
nullable: true
pages:
type: integer
nullable: true
page:
type: integer
nullable: true
page_size:
type: integer
next:
type: string
format: uri
nullable: true
previous:
type: string
format: uri
nullable: true
results:
type: array
items:
$ref: '#/components/schemas/AuthProtectedUser'
required:
- success
- count
- next
- previous
- results
PaginatedBusinessMetricList:
type: object
required:
- count
- results
properties:
count:
type: integer
example: 123
next:
type: string
nullable: true
format: uri
example: http://api.example.org/accounts/?page=4
previous:
type: string
nullable: true
format: uri
example: http://api.example.org/accounts/?page=2
results:
type: array
items:
$ref: '#/components/schemas/BusinessMetric'
PaginatedChatbotSessionList:
type: object
required:
- count
- results
properties:
count:
type: integer
example: 123
next:
type: string
nullable: true
format: uri
example: http://api.example.org/accounts/?page=4
previous:
type: string
nullable: true
format: uri
example: http://api.example.org/accounts/?page=2
results:
type: array
items:
$ref: '#/components/schemas/ChatbotSession'
PaginatedClientAddressList:
type: object
properties:
success:
type: boolean
example: true
count:
type: integer
nullable: true
pages:
type: integer
nullable: true
page:
type: integer
nullable: true
page_size:
type: integer
next:
type: string
format: uri
nullable: true
previous:
type: string
format: uri
nullable: true
results:
type: array
items:
$ref: '#/components/schemas/ClientAddress'
required:
- success
- count
- next
- previous
- results
PaginatedClientCartOrderList:
type: object
properties:
success:
type: boolean
example: true
count:
type: integer
nullable: true
pages:
type: integer
nullable: true
page:
type: integer
nullable: true
page_size:
type: integer
next:
type: string
format: uri
nullable: true
previous:
type: string
format: uri
nullable: true
results:
type: array
items:
$ref: '#/components/schemas/ClientCartOrder'
required:
- success
- count
- next
- previous
- results
PaginatedConversationList:
type: object
required:
- count
- results
properties:
count:
type: integer
example: 123
next:
type: string
nullable: true
format: uri
example: http://api.example.org/accounts/?page=4
previous:
type: string
nullable: true
format: uri
example: http://api.example.org/accounts/?page=2
results:
type: array
items:
$ref: '#/components/schemas/Conversation'
PaginatedIntegrationCredentialList:
type: object
properties:
success:
type: boolean
example: true
count:
type: integer
nullable: true
pages:
type: integer
nullable: true
page:
type: integer
nullable: true
page_size:
type: integer
next:
type: string
format: uri
nullable: true
previous:
type: string
format: uri
nullable: true
results:
type: array
items:
$ref: '#/components/schemas/IntegrationCredential'
required:
- success
- count
- next
- previous
- results
PaginatedIntegrationLogList:
type: object
properties:
success:
type: boolean
example: true
count:
type: integer
nullable: true
pages:
type: integer
nullable: true
page:
type: integer
nullable: true
page_size:
type: integer
next:
type: string
format: uri
nullable: true
previous:
type: string
format: uri
nullable: true
results:
type: array
items:
$ref: '#/components/schemas/IntegrationLog'
required:
- success
- count
- next
- previous
- results
PaginatedIntegrationProviderList:
type: object
properties:
success:
type: boolean
example: true
count:
type: integer
nullable: true
pages:
type: integer
nullable: true
page:
type: integer
nullable: true
page_size:
type: integer
next:
type: string
format: uri
nullable: true
previous:
type: string
format: uri
nullable: true
results:
type: array
items:
$ref: '#/components/schemas/IntegrationProvider'
required:
- success
- count
- next
- previous
- results
PaginatedKycSubmissionList:
type: object
properties:
success:
type: boolean
example: true
count:
type: integer
nullable: true
pages:
type: integer
nullable: true
page:
type: integer
nullable: true
page_size:
type: integer
next:
type: string
format: uri
nullable: true
previous:
type: string
format: uri
nullable: true
results:
type: array
items:
$ref: '#/components/schemas/KycSubmission'
required:
- success
- count
- next
- previous
- results
PaginatedLoginEventList:
type: object
properties:
success:
type: boolean
example: true
count:
type: integer
nullable: true
pages:
type: integer
nullable: true
page:
type: integer
nullable: true
page_size:
type: integer
next:
type: string
format: uri
nullable: true
previous:
type: string
format: uri
nullable: true
results:
type: array
items:
$ref: '#/components/schemas/LoginEvent'
required:
- success
- count
- next
- previous
- results
PaginatedMessageList:
type: object
required:
- count
- results
properties:
count:
type: integer
example: 123
next:
type: string
nullable: true
format: uri
example: http://api.example.org/accounts/?page=4
previous:
type: string
nullable: true
format: uri
example: http://api.example.org/accounts/?page=2
results:
type: array
items:
$ref: '#/components/schemas/Message'
PaginatedMetricList:
type: object
required:
- count
- results
properties:
count:
type: integer
example: 123
next:
type: string
nullable: true
format: uri
example: http://api.example.org/accounts/?page=4
previous:
type: string
nullable: true
format: uri
example: http://api.example.org/accounts/?page=2
results:
type: array
items:
$ref: '#/components/schemas/Metric'
PaginatedPerformanceMetricList:
type: object
required:
- count
- results
properties:
count:
type: integer
example: 123
next:
type: string
nullable: true
format: uri
example: http://api.example.org/accounts/?page=4
previous:
type: string
nullable: true
format: uri
example: http://api.example.org/accounts/?page=2
results:
type: array
items:
$ref: '#/components/schemas/PerformanceMetric'
PaginatedRateLimitRuleList:
type: object
properties:
success:
type: boolean
example: true
count:
type: integer
nullable: true
pages:
type: integer
nullable: true
page:
type: integer
nullable: true
page_size:
type: integer
next:
type: string
format: uri
nullable: true
previous:
type: string
format: uri
nullable: true
results:
type: array
items:
$ref: '#/components/schemas/RateLimitRule'
required:
- success
- count
- next
- previous
- results
PaginatedReferenceBankList:
type: object
properties:
success:
type: boolean
example: true
count:
type: integer
nullable: true
pages:
type: integer
nullable: true
page:
type: integer
nullable: true
page_size:
type: integer
next:
type: string
format: uri
nullable: true
previous:
type: string
format: uri
nullable: true
results:
type: array
items:
$ref: '#/components/schemas/ReferenceBank'
required:
- success
- count
- next
- previous
- results
PaginatedReferenceCityList:
type: object
properties:
success:
type: boolean
example: true
count:
type: integer
nullable: true
pages:
type: integer
nullable: true
page:
type: integer
nullable: true
page_size:
type: integer
next:
type: string
format: uri
nullable: true
previous:
type: string
format: uri
nullable: true
results:
type: array
items:
$ref: '#/components/schemas/ReferenceCity'
required:
- success
- count
- next
- previous
- results
PaginatedReferenceCountryList:
type: object
properties:
success:
type: boolean
example: true
count:
type: integer
nullable: true
pages:
type: integer
nullable: true
page:
type: integer
nullable: true
page_size:
type: integer
next:
type: string
format: uri
nullable: true
previous:
type: string
format: uri
nullable: true
results:
type: array
items:
$ref: '#/components/schemas/ReferenceCountry'
required:
- success
- count
- next
- previous
- results
PaginatedReferenceLgaList:
type: object
properties:
success:
type: boolean
example: true
count:
type: integer
nullable: true
pages:
type: integer
nullable: true
page:
type: integer
nullable: true
page_size:
type: integer
next:
type: string
format: uri
nullable: true
previous:
type: string
format: uri
nullable: true
results:
type: array
items:
$ref: '#/components/schemas/ReferenceLga'
required:
- success
- count
- next
- previous
- results
PaginatedReferenceStateList:
type: object
properties:
success:
type: boolean
example: true
count:
type: integer
nullable: true
pages:
type: integer
nullable: true
page:
type: integer
nullable: true
page_size:
type: integer
next:
type: string
format: uri
nullable: true
previous:
type: string
format: uri
nullable: true
results:
type: array
items:
$ref: '#/components/schemas/ReferenceState'
required:
- success
- count
- next
- previous
- results
PaginatedTransactionList:
type: object
properties:
success:
type: boolean
example: true
count:
type: integer
nullable: true
pages:
type: integer
nullable: true
page:
type: integer
nullable: true
page_size:
type: integer
next:
type: string
format: uri
nullable: true
previous:
type: string
format: uri
nullable: true
results:
type: array
items:
$ref: '#/components/schemas/Transaction'
required:
- success
- count
- next
- previous
- results
PaginatedUserActivityList:
type: object
required:
- count
- results
properties:
count:
type: integer
example: 123
next:
type: string
nullable: true
format: uri
example: http://api.example.org/accounts/?page=4
previous:
type: string
nullable: true
format: uri
example: http://api.example.org/accounts/?page=2
results:
type: array
items:
$ref: '#/components/schemas/UserActivity'
PaginatedUserSessionList:
type: object
properties:
success:
type: boolean
example: true
count:
type: integer
nullable: true
pages:
type: integer
nullable: true
page:
type: integer
nullable: true
page_size:
type: integer
next:
type: string
format: uri
nullable: true
previous:
type: string
format: uri
nullable: true
results:
type: array
items:
$ref: '#/components/schemas/UserSession'
required:
- success
- count
- next
- previous
- results
PaginatedWebhookEndpointList:
type: object
properties:
success:
type: boolean
example: true
count:
type: integer
nullable: true
pages:
type: integer
nullable: true
page:
type: integer
nullable: true
page_size:
type: integer
next:
type: string
format: uri
nullable: true
previous:
type: string
format: uri
nullable: true
results:
type: array
items:
$ref: '#/components/schemas/WebhookEndpoint'
required:
- success
- count
- next
- previous
- results
PaginatedWebhookEventList:
type: object
properties:
success:
type: boolean
example: true
count:
type: integer
nullable: true
pages:
type: integer
nullable: true
page:
type: integer
nullable: true
page_size:
type: integer
next:
type: string
format: uri
nullable: true
previous:
type: string
format: uri
nullable: true
results:
type: array
items:
$ref: '#/components/schemas/WebhookEvent'
required:
- success
- count
- next
- previous
- results
PasswordChangeRequest:
type: object
description: |-
Serializer for authenticated password change from the dashboard.
Validates old password + new password match.
properties:
old_password:
type: string
writeOnly: true
minLength: 1
description: Current password
new_password:
type: string
writeOnly: true
minLength: 1
description: New password
confirm_password:
type: string
writeOnly: true
minLength: 1
description: Confirm new password
required:
- confirm_password
- new_password
- old_password
PatchedAlertRuleRequest:
type: object
properties:
name:
type: string
minLength: 1
title: Rule Name
maxLength: 100
metric_name:
type: string
minLength: 1
maxLength: 255
operator:
allOf:
- $ref: '#/components/schemas/OperatorEnum'
title: Comparison Operator
threshold:
type: number
format: double
severity:
$ref: '#/components/schemas/SeverityEnum'
is_active:
type: boolean
description:
type: string
PatchedAuthUserProfileRequest:
type: object
description: |-
Full profile serializer for self-update (PATCH /api/v1/profile/me/).
Read-only fields:
id, member_id, email, phone, role, auth_provider,
is_verified, is_active, is_staff, is_superuser,
date_joined, last_login, password, groups, user_permissions
Writable fields (matches PROFILE_EDITABLE_FIELDS in profile_service):
first_name, last_name, bio, country, state, city, address, avatar
Extra output fields (computed):
user_id str(uuid)
identifying_info str
phone_display E.164 string | null (read-only convenience field)
avatar_url Cloudinary URL string | null
properties:
first_name:
type: string
nullable: true
last_name:
type: string
nullable: true
bio:
type: string
description: User's biography.
country:
type: string
description: User's country.
maxLength: 100
state:
type: string
description: User's state or province.
maxLength: 100
city:
type: string
description: User's city.
maxLength: 100
address:
type: string
description: User's street address.
maxLength: 255
avatar:
type: string
minLength: 1
nullable: true
description: 'Cloudinary image public_id. Set via the /api/v1/upload/presign/
→ direct upload → webhook flow. Use .url in serializers to retrieve the
full HTTPS secure_url. In admin: use the file picker widget to upload
directly to Cloudinary.'
PatchedCatalogBlogPostRequest:
type: object
properties:
category:
type: string
format: uuid
description: Optional catalog category used for discovery and SEO.
nullable: true
title:
type: string
minLength: 1
maxLength: 255
excerpt:
type: string
content:
type: string
minLength: 1
featured_image:
type: string
minLength: 1
nullable: true
description: Featured post image (public_id).
status:
$ref: '#/components/schemas/CatalogBlogPostStatusEnum'
tags: {}
seo_title:
type: string
maxLength: 180
seo_description:
type: string
maxLength: 320
is_featured:
type: boolean
PatchedCatalogBrandRequest:
type: object
properties:
title:
type: string
minLength: 1
maxLength: 100
description:
type: string
nullable: true
image:
type: string
minLength: 1
nullable: true
description: Cloudinary image public_id. Set via the /api/v1/upload/presign/
direct upload webhook flow. Use .url in serializers to retrieve the
full HTTPS secure_url.
active:
type: boolean
PatchedCatalogCategoryRequest:
type: object
properties:
name:
type: string
minLength: 1
maxLength: 100
image:
type: string
minLength: 1
nullable: true
description: Cloudinary image public_id. Set via the /api/v1/upload/presign/
direct upload webhook flow. Use .url in serializers to retrieve the
full HTTPS secure_url.
is_deleted:
type: boolean
description: Flag indicating if the record is soft-deleted.
PatchedCatalogCollectionRequest:
type: object
properties:
title:
type: string
nullable: true
maxLength: 255
sub_title:
type: string
nullable: true
maxLength: 255
description:
type: string
nullable: true
image:
type: string
minLength: 1
nullable: true
description: Main collection thumbnail image (public_id).
background_image:
type: string
minLength: 1
nullable: true
description: Hero background image (public_id).
PatchedChatbotSessionRequest:
type: object
description: Serializer for chatbot sessions.
properties:
session_type:
$ref: '#/components/schemas/SessionTypeEnum'
status:
$ref: '#/components/schemas/ChatbotSessionStatusEnum'
context_data:
description: Contextual info to maintain conversation state
ended_at:
type: string
format: date-time
nullable: true
expires_at:
type: string
format: date-time
nullable: true
metadata: {}
PatchedClientProfileUpdateRequest:
type: object
description: |-
Input-only serializer for PATCH /profile/ requests.
All fields are optional clients send only what they want to change.
properties:
bio:
type: string
maxLength: 500
default_shipping_address:
type: string
state:
type: string
maxLength: 100
country:
type: string
maxLength: 100
preferred_size:
oneOf:
- $ref: '#/components/schemas/PreferredSizeEnum'
- $ref: '#/components/schemas/BlankEnum'
style_preferences:
type: array
items:
type: string
minLength: 1
favourite_colours:
type: array
items:
type: string
minLength: 1
email_notifications_enabled:
type: boolean
sms_notifications_enabled:
type: boolean
PatchedConversationRequest:
type: object
description: Serializer for conversations including message history.
properties:
conversation_type:
$ref: '#/components/schemas/ConversationTypeEnum'
title:
type: string
maxLength: 200
is_active:
type: boolean
summary:
type: string
tags: {}
metadata: {}
PatchedIntegrationCredentialRequest:
type: object
properties:
provider:
type: string
format: uuid
key_name:
type: string
minLength: 1
maxLength: 100
key_value:
type: string
writeOnly: true
minLength: 1
description: Stored in encrypted format.
is_encrypted:
type: boolean
environment:
allOf:
- $ref: '#/components/schemas/EnvironmentEnum'
default: production
is_active:
type: boolean
expires_at:
type: string
format: date-time
nullable: true
PatchedIntegrationProviderRequest:
type: object
properties:
name:
type: string
minLength: 1
title: Provider Name
maxLength: 100
slug:
type: string
minLength: 1
title: Unique Slug
maxLength: 50
pattern: ^[-a-zA-Z0-9_]+$
provider_type:
allOf:
- $ref: '#/components/schemas/ProviderTypeEnum'
title: Service Type
status:
$ref: '#/components/schemas/IntegrationProviderStatusEnum'
description:
type: string
api_base_url:
type: string
format: uri
maxLength: 200
documentation_url:
type: string
format: uri
maxLength: 200
PatchedMessageRequest:
type: object
description: Serializer for messages.
properties:
sender_type:
$ref: '#/components/schemas/SenderTypeEnum'
message_type:
$ref: '#/components/schemas/MessageTypeEnum'
content:
type: string
minLength: 1
response_data:
description: Structured options or response details
ai_confidence:
type: number
format: double
nullable: true
description: Confidence score of AI response (0.0 to 1.0)
processing_time:
type: number
format: double
nullable: true
description: Processing time in seconds
is_sensitive:
type: boolean
description: Does the message contain sensitive info?
metadata: {}
PatchedRateLimitRuleRequest:
type: object
properties:
provider:
type: string
format: uuid
name:
type: string
minLength: 1
title: Rule Name
maxLength: 100
endpoint_pattern:
type: string
minLength: 1
description: Supports wildcards like *
maxLength: 255
max_requests:
type: integer
maximum: 9223372036854775807
minimum: -9223372036854775808
format: int64
time_window_seconds:
type: integer
maximum: 9223372036854775807
minimum: -9223372036854775808
format: int64
title: Time Window (Seconds)
scope:
$ref: '#/components/schemas/ScopeEnum'
is_active:
type: boolean
PatchedVendorOrderStatusRequest:
type: object
properties:
delivery_status:
$ref: '#/components/schemas/DeliveryStatusEnum'
tracking_id:
type: string
PatchedVendorProfileUpdateRequest:
type: object
description: Input-only serializer for PATCH /vendor/profile/.
properties:
store_name:
type: string
maxLength: 150
tagline:
type: string
maxLength: 200
description:
type: string
maxLength: 2000
logo_url:
type: string
format: uri
cover_url:
type: string
format: uri
city:
type: string
maxLength: 100
state:
type: string
maxLength: 100
country:
type: string
maxLength: 100
whatsapp:
type: string
maxLength: 20
opening_time:
type: string
format: time
nullable: true
closing_time:
type: string
format: time
nullable: true
business_hours: {}
instagram_url:
type: string
format: uri
tiktok_url:
type: string
format: uri
twitter_url:
type: string
format: uri
website_url:
type: string
format: uri
cash_payment_mode:
$ref: '#/components/schemas/CashPaymentModeEnum'
collection_ids:
type: array
items:
type: string
minLength: 1
description: 1-15 Collection IDs this store specialises in.
maxItems: 15
PatchedWebhookEndpointRequest:
type: object
properties:
provider:
type: string
format: uuid
name:
type: string
minLength: 1
title: Webhook Name
maxLength: 100
endpoint_url:
type: string
minLength: 1
pattern: ^[a-zA-Z0-9-_/]+$
maxLength: 255
secret_key:
type: string
writeOnly: true
minLength: 1
description: Used to verify webhook payload signatures.
maxLength: 255
events:
title: Subscribed Events
description: List of event slugs this webhook processes.
is_active:
type: boolean
retry_count:
type: integer
maximum: 9223372036854775807
minimum: -9223372036854775808
format: int64
timeout_seconds:
type: integer
maximum: 9223372036854775807
minimum: -9223372036854775808
format: int64
title: Timeout (Seconds)
PaymentPathEnum:
enum:
- wallet
- gateway
- cod
- pay_at_shop
type: string
PayoutRequest:
type: object
properties:
bank_account_id:
type: string
format: uuid
description: UUID of the saved VendorBankAccount to pay into.
amount:
type: string
format: decimal
pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
description: Payout amount in NGN. Minimum determined by platform settings.
narration:
type: string
default: Fashionistar Vendor Payout
description: Bank transfer narration / description.
maxLength: 255
required:
- amount
- bank_account_id
PayoutRequestRequest:
type: object
properties:
bank_account_id:
type: string
format: uuid
description: UUID of the saved VendorBankAccount to pay into.
amount:
type: string
format: decimal
pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
description: Payout amount in NGN. Minimum determined by platform settings.
narration:
type: string
minLength: 1
default: Fashionistar Vendor Payout
description: Bank transfer narration / description.
maxLength: 255
required:
- amount
- bank_account_id
PaystackBank:
type: object
properties:
name:
type: string
slug:
type: string
code:
type: string
longcode:
type: string
nullable: true
gateway:
type: string
nullable: true
pay_with_bank:
type: boolean
active:
type: boolean
is_deleted:
type: boolean
nullable: true
country:
type: string
currency:
type: string
type:
type: string
id:
type: integer
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
required:
- active
- code
- country
- createdAt
- currency
- id
- name
- pay_with_bank
- slug
- type
- updatedAt
PaystackBanksResponse:
type: object
properties:
status:
type: boolean
message:
type: string
data:
type: array
items:
$ref: '#/components/schemas/PaystackBank'
required:
- data
- message
- status
PaystackInitialize:
type: object
properties:
amount:
type: string
format: decimal
pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
purpose:
$ref: '#/components/schemas/PurposeEnum'
currency:
type: string
default: NGN
maxLength: 10
order_id:
type: string
maxLength: 120
measurement_request_id:
type: string
maxLength: 120
metadata: {}
required:
- amount
- purpose
PaystackInitializeRequest:
type: object
properties:
amount:
type: string
format: decimal
pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
purpose:
$ref: '#/components/schemas/PurposeEnum'
currency:
type: string
minLength: 1
default: NGN
maxLength: 10
order_id:
type: string
maxLength: 120
measurement_request_id:
type: string
maxLength: 120
metadata: {}
required:
- amount
- purpose
PaystackVerify:
type: object
properties:
reference:
type: string
maxLength: 120
required:
- reference
PaystackWebhook:
type: object
properties:
event:
type: string
data: {}
required:
- data
- event
PaystackWebhookRequest:
type: object
properties:
event:
type: string
minLength: 1
data: {}
required:
- data
- event
PerformanceMetric:
type: object
properties:
id:
type: integer
readOnly: true
endpoint:
type: string
title: Endpoint Route
description: Request URL pathway.
maxLength: 255
method:
type: string
title: HTTP Method
description: HTTP verb used in the request.
maxLength: 10
response_time_ms:
type: integer
maximum: 9223372036854775807
minimum: 0
format: int64
title: Response Time (ms)
status_code:
type: integer
maximum: 9223372036854775807
minimum: 0
format: int64
title: HTTP Status Code
user:
type: string
format: uuid
description: UUID7 globally unique, time-ordered primary key.
nullable: true
user_username:
type: string
readOnly: true
error_message:
type: string
metadata: {}
timestamp:
type: string
format: date-time
readOnly: true
required:
- endpoint
- id
- method
- response_time_ms
- status_code
- timestamp
- user_username
PreferredSizeEnum:
enum:
- XS
- S
- M
- L
- XL
- XXL
- XXXL
type: string
ProductInquiryRequestRequest:
type: object
description: Serializer for specific product inquiries.
properties:
product_sku:
type: string
minLength: 1
description: Product SKU or Identifier
client_size:
type: string
minLength: 1
description: Preferred size
client_height:
type: number
format: double
description: Client height (cm)
fabric_preferences:
type: array
items:
type: string
minLength: 1
description: Preferred materials or material warnings (e.g. wool allergy)
similar_products:
type: array
items:
type: string
minLength: 1
description: Similar SKUs of interest
required:
- product_sku
ProviderEnum:
enum:
- wallet
- paystack
- flutterwave
- olive_pay
type: string
ProviderTypeEnum:
enum:
- sms
- payment
- ai
- storage
- notification
- analytics
- other
type: string
PurposeEnum:
enum:
- wallet_topup
- order_payment
- measurement_fee
- vendor_service
- advertisement_fee
type: string
RateLimitRule:
type: object
properties:
id:
type: string
format: uuid
readOnly: true
provider:
type: string
format: uuid
provider_name:
type: string
readOnly: true
name:
type: string
title: Rule Name
maxLength: 100
endpoint_pattern:
type: string
description: Supports wildcards like *
maxLength: 255
max_requests:
type: integer
maximum: 9223372036854775807
minimum: -9223372036854775808
format: int64
time_window_seconds:
type: integer
maximum: 9223372036854775807
minimum: -9223372036854775808
format: int64
title: Time Window (Seconds)
scope:
$ref: '#/components/schemas/ScopeEnum'
is_active:
type: boolean
rate_description:
type: string
readOnly: true
created_at:
type: string
format: date-time
readOnly: true
updated_at:
type: string
format: date-time
readOnly: true
required:
- created_at
- endpoint_pattern
- id
- max_requests
- name
- provider
- provider_name
- rate_description
- time_window_seconds
- updated_at
RateLimitRuleRequest:
type: object
properties:
provider:
type: string
format: uuid
name:
type: string
minLength: 1
title: Rule Name
maxLength: 100
endpoint_pattern:
type: string
minLength: 1
description: Supports wildcards like *
maxLength: 255
max_requests:
type: integer
maximum: 9223372036854775807
minimum: -9223372036854775808
format: int64
time_window_seconds:
type: integer
maximum: 9223372036854775807
minimum: -9223372036854775808
format: int64
title: Time Window (Seconds)
scope:
$ref: '#/components/schemas/ScopeEnum'
is_active:
type: boolean
required:
- endpoint_pattern
- max_requests
- name
- provider
- time_window_seconds
ReferenceBank:
type: object
properties:
id:
type: string
code:
type: string
name:
type: string
country_code:
type: string
currency:
type: string
provider:
type: string
is_active:
type: boolean
required:
- code
- country_code
- currency
- id
- is_active
- name
- provider
ReferenceCity:
type: object
properties:
code:
type: string
name:
type: string
lga_code:
type: string
state_code:
type: string
country_code:
type: string
latitude:
type: number
format: double
nullable: true
longitude:
type: number
format: double
nullable: true
is_active:
type: boolean
required:
- code
- country_code
- is_active
- latitude
- lga_code
- longitude
- name
- state_code
ReferenceCountry:
type: object
properties:
id:
type: string
code:
type: string
name:
type: string
flag:
type: string
phone_code:
type: string
is_active:
type: boolean
required:
- code
- flag
- id
- is_active
- name
- phone_code
ReferenceLga:
type: object
properties:
code:
type: string
name:
type: string
state_code:
type: string
country_code:
type: string
is_active:
type: boolean
required:
- code
- country_code
- is_active
- name
- state_code
ReferenceState:
type: object
properties:
code:
type: string
name:
type: string
country_code:
type: string
is_active:
type: boolean
required:
- code
- country_code
- is_active
- name
Refund:
type: object
properties:
hold_reference:
type: string
maxLength: 120
required:
- hold_reference
RefundRequest:
type: object
properties:
hold_reference:
type: string
minLength: 1
maxLength: 120
required:
- hold_reference
Role09fEnum:
enum:
- vendor
- client
type: string
RoleC2fEnum:
enum:
- vendor
- client
- staff
- admin
- editor
- support
- assistant
- moderator
- super_admin
- super_vendor
- super_client
- super_staff
- super_editor
- super_support
- super_assistant
- super_moderator
type: string
ScopeEnum:
enum:
- global
- user
- ip
type: string
SendMessageRequestRequest:
type: object
description: Serializer to validate sending a message.
properties:
message:
type: string
minLength: 1
description: User message content
maxLength: 4000
message_type:
allOf:
- $ref: '#/components/schemas/MessageTypeEnum'
default: text
description: Message type
context:
description: Additional context for message processing
required:
- message
SendMessageResponse:
type: object
description: Serializer for the response of sending a message.
properties:
response:
allOf:
- $ref: '#/components/schemas/ChatbotResponseData'
description: Chatbot response
user_message_id:
type: string
format: uuid
description: User message UUID
bot_message_id:
type: string
format: uuid
description: Bot message UUID
conversation_id:
type: string
format: uuid
description: Conversation UUID
session_id:
type: string
format: uuid
description: Session UUID
required:
- bot_message_id
- conversation_id
- response
- session_id
- user_message_id
SenderTypeEnum:
enum:
- user
- bot
- system
type: string
SessionTypeEnum:
enum:
- client
- vendor
type: string
SeverityEnum:
enum:
- low
- medium
- high
- critical
type: string
SizeRecommendationRequestRequest:
type: object
description: Serializer for sizing and fit recommendation requests.
properties:
measurements:
type: array
items:
type: string
minLength: 1
description: List of body measurements
height_cm:
type: integer
maximum: 250
minimum: 0
description: Client height in cm
gender:
allOf:
- $ref: '#/components/schemas/GenderEnum'
description: Client gender
fit_preference:
type: string
minLength: 1
description: Preferred fit profile (e.g. slim, regular, loose)
prior_purchases:
type: array
items:
type: string
minLength: 1
description: Known comfortable sizing in other brands
required:
- measurements
StartSessionResponse:
type: object
description: Serializer for starting a chatbot session.
properties:
session:
allOf:
- $ref: '#/components/schemas/ChatbotSession'
description: Session info
greeting_message:
allOf:
- $ref: '#/components/schemas/ChatbotResponseData'
description: Greeting message
quick_replies:
type: array
items:
type: object
additionalProperties: {}
description: Initial quick replies
required:
- session
StyleAssessmentRequestRequest:
type: object
description: Serializer for style and aesthetic assessment.
properties:
preferred_style:
type: string
minLength: 1
description: Primary style or aesthetic preference
budget_range:
type: string
minLength: 1
description: Estimated budget range
formality_level:
type: integer
maximum: 10
minimum: 1
description: Formality level (1-10)
size_preferences:
type: array
items:
type: string
minLength: 1
description: Preferred sizing guidelines
sizing_notes:
type: string
minLength: 1
description: Specific details regarding styling/fit history
required:
- budget_range
- formality_level
- preferred_style
Transaction:
type: object
properties:
id:
type: string
format: uuid
readOnly: true
description: UUID7 globally unique, time-ordered primary key.
transaction_type:
$ref: '#/components/schemas/TransactionTypeEnum'
status:
$ref: '#/components/schemas/TransactionStatusEnum'
direction:
$ref: '#/components/schemas/DirectionEnum'
amount:
type: string
format: decimal
pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
fee_amount:
type: string
format: decimal
pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
net_amount:
type: string
format: decimal
pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
reference:
type: string
maxLength: 120
external_reference:
type: string
maxLength: 160
provider_reference:
type: string
maxLength: 160
order_id:
type: string
maxLength: 120
measurement_request_id:
type: string
maxLength: 120
description:
type: string
maxLength: 500
from_wallet_currency:
type: string
readOnly: true
to_wallet_currency:
type: string
readOnly: true
created_at:
type: string
format: date-time
readOnly: true
description: Timestamp when the record was created.
completed_at:
type: string
format: date-time
nullable: true
metadata: {}
required:
- amount
- created_at
- from_wallet_currency
- id
- reference
- to_wallet_currency
- transaction_type
TransactionStatusEnum:
enum:
- pending
- processing
- completed
- failed
- cancelled
- reversed
- disputed
type: string
TransactionSummary:
type: object
properties:
total_inflow:
type: string
format: decimal
pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
total_outflow:
type: string
format: decimal
pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
net_balance:
type: string
format: decimal
pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
count:
type: integer
required:
- count
- net_balance
- total_inflow
- total_outflow
TransactionTypeEnum:
enum:
- order_payment
- escrow_hold
- escrow_release
- commission
- measurement_fee
- vendor_subscription
- platform_usage_fee
- advertisement_fee
- affiliate_revenue
- refund
- payout
- transfer
- reversal
- adjustment
type: string
TransferRecipientCreate:
type: object
properties:
account_number:
type: string
maxLength: 20
account_name:
type: string
maxLength: 180
bank_name:
type: string
maxLength: 180
bank_code:
type: string
maxLength: 20
required:
- account_name
- account_number
- bank_code
- bank_name
TransferRecipientCreateRequest:
type: object
properties:
account_number:
type: string
minLength: 1
maxLength: 20
account_name:
type: string
minLength: 1
maxLength: 180
bank_name:
type: string
minLength: 1
maxLength: 180
bank_code:
type: string
minLength: 1
maxLength: 20
required:
- account_name
- account_number
- bank_code
- bank_name
UrgencyEnum:
enum:
- low
- medium
- high
- rush
type: string
UserActivity:
type: object
properties:
id:
type: integer
readOnly: true
user:
type: string
format: uuid
description: UUID7 globally unique, time-ordered primary key.
user_username:
type: string
readOnly: true
action:
type: string
title: Action Performed
description: Type of action performed by the user.
maxLength: 100
resource:
type: string
title: Resource Name
description: Affected resource or area of interaction.
maxLength: 100
resource_id:
type: integer
maximum: 9223372036854775807
minimum: 0
format: int64
nullable: true
ip_address:
type: string
nullable: true
user_agent:
type: string
session_id:
type: string
maxLength: 40
metadata: {}
timestamp:
type: string
format: date-time
readOnly: true
title: Action Time
required:
- action
- id
- timestamp
- user
- user_username
UserBasic:
type: object
description: Serializer for basic user information.
properties:
id:
type: string
format: uuid
readOnly: true
description: UUID7 globally unique, time-ordered primary key.
first_name:
type: string
nullable: true
maxLength: 150
last_name:
type: string
nullable: true
maxLength: 150
phone:
type: string
readOnly: true
nullable: true
description: Primary unique identifier for phone-based auth.
required:
- id
- phone
UserBasicRequest:
type: object
description: Serializer for basic user information.
properties:
first_name:
type: string
nullable: true
maxLength: 150
last_name:
type: string
nullable: true
maxLength: 150
UserSession:
type: object
description: |-
Read serializer for UserSession — used by the active sessions list.
All UUID7 primary keys are serialized as strings (required for
JavaScript, which cannot safely handle 128-bit integers).
The ``is_current`` flag is computed dynamically at query time
(via the view injecting the current JTI), so it is read-only here.
The ``is_expired`` flag is a computed property (not stored in DB).
properties:
id:
type: string
readOnly: true
device_name:
type: string
readOnly: true
description: Human-readable label such as 'Chrome on Windows'.
client_type:
allOf:
- $ref: '#/components/schemas/UserSessionClientTypeEnum'
readOnly: true
description: Browser / mobile app / API client.
browser:
type: string
readOnly: true
os:
type: string
readOnly: true
ip_address:
type: string
readOnly: true
nullable: true
description: IP address captured at session creation time.
country:
type: string
readOnly: true
city:
type: string
readOnly: true
created_at:
type: string
format: date-time
readOnly: true
last_used_at:
type: string
format: date-time
readOnly: true
expires_at:
type: string
format: date-time
readOnly: true
nullable: true
is_current:
type: boolean
description: |-
True when the session's JTI matches the current request's access token JTI.
The view must pass `current_jti` in serializer context:
serializer = UserSessionSerializer(
sessions, many=True, context={"current_jti": current_jti}
)
readOnly: true
is_expired:
type: boolean
description: True when the session's refresh token has expired.
readOnly: true
required:
- browser
- city
- client_type
- country
- created_at
- device_name
- expires_at
- id
- ip_address
- is_current
- is_expired
- last_used_at
- os
UserSessionClientTypeEnum:
enum:
- web
- mobile
- api
- unknown
type: string
VendorCollection:
type: object
description: Minimal representation of a Collection linked to this vendor.
properties:
id:
type: string
readOnly: true
title:
type: string
readOnly: true
slug:
type: string
readOnly: true
pattern: ^[-a-zA-Z0-9_]+$
required:
- id
- slug
- title
VendorOrderStatus:
type: object
properties:
delivery_status:
$ref: '#/components/schemas/DeliveryStatusEnum'
tracking_id:
type: string
required:
- delivery_status
VendorOrderStatusRequest:
type: object
properties:
delivery_status:
$ref: '#/components/schemas/DeliveryStatusEnum'
tracking_id:
type: string
required:
- delivery_status
VendorPayoutDetails:
type: object
description: Input serializer for POST /vendor/payout/.
properties:
bank_name:
type: string
maxLength: 150
bank_code:
type: string
maxLength: 10
account_name:
type: string
maxLength: 200
account_number:
type: string
description: Bank account number. Will be encrypted before storage.
maxLength: 20
paystack_recipient_code:
type: string
maxLength: 100
required:
- account_name
- account_number
- bank_name
VendorPayoutDetailsRequest:
type: object
description: Input serializer for POST /vendor/payout/.
properties:
bank_name:
type: string
minLength: 1
maxLength: 150
bank_code:
type: string
maxLength: 10
account_name:
type: string
minLength: 1
maxLength: 200
account_number:
type: string
minLength: 1
description: Bank account number. Will be encrypted before storage.
maxLength: 20
paystack_recipient_code:
type: string
maxLength: 100
required:
- account_name
- account_number
- bank_name
VendorProfileOutput:
type: object
properties:
id:
type: string
format: uuid
readOnly: true
description: UUID7 globally unique, time-ordered primary key.
user_id:
type: string
readOnly: true
user_email:
type: string
readOnly: true
store_name:
type: string
readOnly: true
description: Public-facing store name shown on the marketplace.
store_slug:
type: string
readOnly: true
description: URL-safe unique store identifier. Auto-generated from store_name.
pattern: ^[-a-zA-Z0-9_]+$
tagline:
type: string
readOnly: true
description:
type: string
readOnly: true
logo_url:
type: string
readOnly: true
description: Cloudinary store logo URL.
cover_url:
type: string
readOnly: true
description: Cloudinary banner URL.
city:
type: string
readOnly: true
state:
type: string
readOnly: true
country:
type: string
readOnly: true
whatsapp:
type: string
readOnly: true
opening_time:
type: string
format: time
readOnly: true
nullable: true
closing_time:
type: string
format: time
readOnly: true
nullable: true
business_hours:
readOnly: true
description: 'e.g. {''Monday'': ''9:00-17:00'', ''Tuesday'': ''9:00-17:00''}'
instagram_url:
type: string
format: uri
readOnly: true
tiktok_url:
type: string
format: uri
readOnly: true
twitter_url:
type: string
format: uri
readOnly: true
website_url:
type: string
format: uri
readOnly: true
cash_payment_mode:
allOf:
- $ref: '#/components/schemas/CashPaymentModeEnum'
readOnly: true
description: Storefront display preference for COD / Pay At Shop availability.
collections:
type: array
items:
$ref: '#/components/schemas/VendorCollection'
readOnly: true
total_products:
type: integer
readOnly: true
total_sales:
type: integer
readOnly: true
total_revenue:
type: string
format: decimal
pattern: ^-?\d{0,14}(?:\.\d{0,2})?$
readOnly: true
average_rating:
type: string
format: decimal
pattern: ^-?\d{0,1}(?:\.\d{0,2})?$
readOnly: true
review_count:
type: integer
readOnly: true
wallet_balance:
type: string
format: decimal
pattern: ^-?\d{0,12}(?:\.\d{0,2})?$
readOnly: true
is_verified:
type: boolean
readOnly: true
description: Manually verified by Fashionistar staff. Does NOT gate dashboard
access.
is_active:
type: boolean
readOnly: true
is_featured:
type: boolean
readOnly: true
setup_state:
allOf:
- $ref: '#/components/schemas/VendorSetupState'
readOnly: true
created_at:
type: string
format: date-time
readOnly: true
description: Timestamp when the record was created.
updated_at:
type: string
format: date-time
readOnly: true
description: Timestamp when the record was last updated.
required:
- average_rating
- business_hours
- cash_payment_mode
- city
- closing_time
- collections
- country
- cover_url
- created_at
- description
- id
- instagram_url
- is_active
- is_featured
- is_verified
- logo_url
- opening_time
- review_count
- setup_state
- state
- store_name
- store_slug
- tagline
- tiktok_url
- total_products
- total_revenue
- total_sales
- twitter_url
- updated_at
- user_email
- user_id
- wallet_balance
- website_url
- whatsapp
VendorProfileUpdate:
type: object
description: Input-only serializer for PATCH /vendor/profile/.
properties:
store_name:
type: string
maxLength: 150
tagline:
type: string
maxLength: 200
description:
type: string
maxLength: 2000
logo_url:
type: string
format: uri
cover_url:
type: string
format: uri
city:
type: string
maxLength: 100
state:
type: string
maxLength: 100
country:
type: string
maxLength: 100
whatsapp:
type: string
maxLength: 20
opening_time:
type: string
format: time
nullable: true
closing_time:
type: string
format: time
nullable: true
business_hours: {}
instagram_url:
type: string
format: uri
tiktok_url:
type: string
format: uri
twitter_url:
type: string
format: uri
website_url:
type: string
format: uri
cash_payment_mode:
$ref: '#/components/schemas/CashPaymentModeEnum'
collection_ids:
type: array
items:
type: string
description: 1-15 Collection IDs this store specialises in.
maxItems: 15
VendorSetup:
type: object
description: |-
Minimal setup payload to create the first vendor profile.
Called on the POST /vendor/setup/ endpoint.
properties:
store_name:
type: string
maxLength: 150
description:
type: string
maxLength: 2000
tagline:
type: string
maxLength: 200
logo_url:
type: string
format: uri
cover_url:
type: string
format: uri
city:
type: string
maxLength: 100
state:
type: string
maxLength: 100
country:
type: string
default: Nigeria
maxLength: 100
whatsapp:
type: string
maxLength: 20
instagram_url:
type: string
format: uri
tiktok_url:
type: string
format: uri
twitter_url:
type: string
format: uri
website_url:
type: string
format: uri
cash_payment_mode:
allOf:
- $ref: '#/components/schemas/CashPaymentModeEnum'
default: disabled
collection_ids:
type: array
items:
type: string
maxItems: 15
required:
- city
- description
- state
- store_name
VendorSetupRequest:
type: object
description: |-
Minimal setup payload to create the first vendor profile.
Called on the POST /vendor/setup/ endpoint.
properties:
store_name:
type: string
minLength: 1
maxLength: 150
description:
type: string
minLength: 1
maxLength: 2000
tagline:
type: string
maxLength: 200
logo_url:
type: string
format: uri
cover_url:
type: string
format: uri
city:
type: string
minLength: 1
maxLength: 100
state:
type: string
minLength: 1
maxLength: 100
country:
type: string
default: Nigeria
maxLength: 100
whatsapp:
type: string
maxLength: 20
instagram_url:
type: string
format: uri
tiktok_url:
type: string
format: uri
twitter_url:
type: string
format: uri
website_url:
type: string
format: uri
cash_payment_mode:
allOf:
- $ref: '#/components/schemas/CashPaymentModeEnum'
default: disabled
collection_ids:
type: array
items:
type: string
minLength: 1
maxItems: 15
required:
- city
- description
- state
- store_name
VendorSetupState:
type: object
properties:
current_step:
type: integer
readOnly: true
description: Step number (1–4) the vendor is currently on.
profile_complete:
type: boolean
readOnly: true
bank_details:
type: boolean
readOnly: true
id_verified:
type: boolean
readOnly: true
description: 'FUTURE: government ID verified via external KYC API (Youverify/Smile
Identity). Does NOT block dashboard or product creation — informational
only.'
first_product:
type: boolean
readOnly: true
onboarding_done:
type: boolean
readOnly: true
description: True once profile_complete + bank_details + first_product are
all done. Store becomes fully visible on the marketplace.
completion_percentage:
type: integer
description: |-
Return setup completion as an integer percentage 0–100.
Based on the 3 active steps (id_verified excluded from formula).
readOnly: true
required:
- bank_details
- completion_percentage
- current_step
- first_product
- id_verified
- onboarding_done
- profile_complete
VendorTransactionPin:
type: object
description: Input serializer for PIN set/verify endpoints.
properties:
pin:
type: string
description: 4-digit numeric payout confirmation PIN.
maxLength: 4
minLength: 4
required:
- pin
VendorTransactionPinRequest:
type: object
description: Input serializer for PIN set/verify endpoints.
properties:
pin:
type: string
minLength: 4
description: 4-digit numeric payout confirmation PIN.
maxLength: 4
required:
- pin
Wallet:
type: object
properties:
id:
type: string
format: uuid
readOnly: true
description: UUID7 globally unique, time-ordered primary key.
owner_type:
$ref: '#/components/schemas/OwnerTypeEnum'
name:
type: string
maxLength: 120
currency:
type: string
balance:
type: string
format: decimal
pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
available_balance:
type: string
format: decimal
pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
pending_balance:
type: string
format: decimal
pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
escrow_balance:
type: string
format: decimal
pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
status:
$ref: '#/components/schemas/WalletStatusEnum'
has_pin:
type: boolean
readOnly: true
daily_limit:
type: string
format: decimal
pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
nullable: true
monthly_limit:
type: string
format: decimal
pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
nullable: true
last_transaction_at:
type: string
format: date-time
nullable: true
required:
- currency
- has_pin
- id
- name
- owner_type
WalletFundPayment:
type: object
properties:
order_id:
type: string
maxLength: 120
amount:
type: string
format: decimal
pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
purpose:
$ref: '#/components/schemas/PurposeEnum'
provider:
$ref: '#/components/schemas/ProviderEnum'
currency:
type: string
default: NGN
maxLength: 10
selected_percent:
type: integer
maximum: 100
minimum: 1
default: 100
cash_payment_mode:
allOf:
- $ref: '#/components/schemas/CashPaymentModeEnum'
default: disabled
payment_path:
allOf:
- $ref: '#/components/schemas/PaymentPathEnum'
default: gateway
metadata: {}
required:
- provider
- purpose
WalletFundPaymentRequest:
type: object
properties:
order_id:
type: string
maxLength: 120
amount:
type: string
format: decimal
pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
purpose:
$ref: '#/components/schemas/PurposeEnum'
provider:
$ref: '#/components/schemas/ProviderEnum'
currency:
type: string
minLength: 1
default: NGN
maxLength: 10
selected_percent:
type: integer
maximum: 100
minimum: 1
default: 100
cash_payment_mode:
allOf:
- $ref: '#/components/schemas/CashPaymentModeEnum'
default: disabled
payment_path:
allOf:
- $ref: '#/components/schemas/PaymentPathEnum'
default: gateway
metadata: {}
required:
- provider
- purpose
WalletPinChange:
type: object
properties:
current_pin:
type: string
maxLength: 4
minLength: 4
pattern: ^\d{4}$
new_pin:
type: string
maxLength: 4
minLength: 4
pattern: ^\d{4}$
required:
- current_pin
- new_pin
WalletPinChangeRequest:
type: object
properties:
current_pin:
type: string
minLength: 4
maxLength: 4
pattern: ^\d{4}$
new_pin:
type: string
minLength: 4
maxLength: 4
pattern: ^\d{4}$
required:
- current_pin
- new_pin
WalletPinSet:
type: object
properties:
pin:
type: string
maxLength: 4
minLength: 4
pattern: ^\d{4}$
required:
- pin
WalletPinSetRequest:
type: object
properties:
pin:
type: string
minLength: 4
maxLength: 4
pattern: ^\d{4}$
required:
- pin
WalletPinVerify:
type: object
properties:
pin:
type: string
maxLength: 4
minLength: 4
pattern: ^\d{4}$
required:
- pin
WalletPinVerifyRequest:
type: object
properties:
pin:
type: string
minLength: 4
maxLength: 4
pattern: ^\d{4}$
required:
- pin
WalletStatusEnum:
enum:
- active
- inactive
- frozen
- suspended
- closed
type: string
WalletTransfer:
type: object
description: |-
Serializer for P2P fund transfers.
Validates receiver existence, positive amount, and PIN format.
properties:
receiver_id:
type: string
format: uuid
description: ID of the user receiving the funds.
amount:
type: string
format: decimal
pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
description: Amount to transfer (min 0.01).
transaction_password:
type: string
description: 4-digit transaction PIN for authorization.
maxLength: 10
minLength: 4
required:
- amount
- receiver_id
- transaction_password
WalletTransferRequest:
type: object
description: |-
Serializer for P2P fund transfers.
Validates receiver existence, positive amount, and PIN format.
properties:
receiver_id:
type: string
format: uuid
description: ID of the user receiving the funds.
amount:
type: string
format: decimal
pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
description: Amount to transfer (min 0.01).
transaction_password:
type: string
minLength: 4
description: 4-digit transaction PIN for authorization.
maxLength: 10
required:
- amount
- receiver_id
- transaction_password
WalletWithdrawal:
type: object
description: Validate KYC-gated wallet withdrawal requests.
properties:
amount:
type: string
format: decimal
pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
pin:
type: string
maxLength: 4
minLength: 4
pattern: ^\d{4}$
bank_code:
type: string
maxLength: 20
account_number:
type: string
maxLength: 10
minLength: 10
pattern: ^\d{10}$
account_name:
type: string
maxLength: 160
required:
- account_name
- account_number
- amount
- bank_code
- pin
WalletWithdrawalRequest:
type: object
description: Validate KYC-gated wallet withdrawal requests.
properties:
amount:
type: string
format: decimal
pattern: ^-?\d{0,18}(?:\.\d{0,2})?$
pin:
type: string
minLength: 4
maxLength: 4
pattern: ^\d{4}$
bank_code:
type: string
minLength: 1
maxLength: 20
account_number:
type: string
minLength: 10
maxLength: 10
pattern: ^\d{10}$
account_name:
type: string
minLength: 1
maxLength: 160
required:
- account_name
- account_number
- amount
- bank_code
- pin
WebhookEndpoint:
type: object
properties:
id:
type: string
format: uuid
readOnly: true
provider:
type: string
format: uuid
provider_name:
type: string
readOnly: true
name:
type: string
title: Webhook Name
maxLength: 100
endpoint_url:
type: string
pattern: ^[a-zA-Z0-9-_/]+$
maxLength: 255
events:
title: Subscribed Events
description: List of event slugs this webhook processes.
is_active:
type: boolean
retry_count:
type: integer
maximum: 9223372036854775807
minimum: -9223372036854775808
format: int64
timeout_seconds:
type: integer
maximum: 9223372036854775807
minimum: -9223372036854775808
format: int64
title: Timeout (Seconds)
events_count:
type: integer
readOnly: true
pending_events:
type: integer
readOnly: true
created_at:
type: string
format: date-time
readOnly: true
updated_at:
type: string
format: date-time
readOnly: true
required:
- created_at
- endpoint_url
- events_count
- id
- name
- pending_events
- provider
- provider_name
- updated_at
WebhookEndpointRequest:
type: object
properties:
provider:
type: string
format: uuid
name:
type: string
minLength: 1
title: Webhook Name
maxLength: 100
endpoint_url:
type: string
minLength: 1
pattern: ^[a-zA-Z0-9-_/]+$
maxLength: 255
secret_key:
type: string
writeOnly: true
minLength: 1
description: Used to verify webhook payload signatures.
maxLength: 255
events:
title: Subscribed Events
description: List of event slugs this webhook processes.
is_active:
type: boolean
retry_count:
type: integer
maximum: 9223372036854775807
minimum: -9223372036854775808
format: int64
timeout_seconds:
type: integer
maximum: 9223372036854775807
minimum: -9223372036854775808
format: int64
title: Timeout (Seconds)
required:
- endpoint_url
- name
- provider
- secret_key
WebhookEvent:
type: object
properties:
id:
type: string
format: uuid
readOnly: true
webhook:
type: string
format: uuid
webhook_name:
type: string
readOnly: true
provider_name:
type: string
readOnly: true
event_type:
type: string
maxLength: 100
payload: {}
headers: {}
signature:
type: string
maxLength: 255
is_valid:
type: boolean
readOnly: true
title: Is Signature Valid
is_processed:
type: boolean
readOnly: true
processed_at:
type: string
format: date-time
readOnly: true
nullable: true
error_message:
type: string
retry_count:
type: integer
maximum: 9223372036854775807
minimum: -9223372036854775808
format: int64
received_at:
type: string
format: date-time
readOnly: true
required:
- event_type
- id
- is_processed
- is_valid
- processed_at
- provider_name
- received_at
- webhook
- webhook_name
WebhookEventRequest:
type: object
properties:
webhook:
type: string
format: uuid
event_type:
type: string
minLength: 1
maxLength: 100
payload: {}
headers: {}
signature:
type: string
maxLength: 255
error_message:
type: string
retry_count:
type: integer
maximum: 9223372036854775807
minimum: -9223372036854775808
format: int64
required:
- event_type
- webhook
WishlistProduct:
type: object
properties:
id:
type: string
readOnly: true
pid:
type: string
readOnly: true
title:
type: string
readOnly: true
image:
type: string
readOnly: true
price:
type: string
format: decimal
pattern: ^-?\d{0,10}(?:\.\d{0,2})?$
readOnly: true
old_price:
type: string
format: decimal
pattern: ^-?\d{0,10}(?:\.\d{0,2})?$
readOnly: true
stock_qty:
type: integer
readOnly: true
status:
type: string
readOnly: true
category_name:
type: string
readOnly: true
required:
- category_name
- id
- image
- old_price
- pid
- price
- status
- stock_qty
- title
WishlistToggle:
type: object
properties:
product_id:
type: string
format: uuid
required:
- product_id
WishlistToggleRequest:
type: object
properties:
product_id:
type: string
format: uuid
required:
- product_id
securitySchemes:
basicAuth:
type: http
scheme: basic
cookieAuth:
type: apiKey
in: cookie
name: sessionid
jwtAuth:
type: http
scheme: bearer
bearerFormat: JWT
tokenAuth:
type: apiKey
in: header
name: Authorization
description: Token-based authentication with required prefix "Token"
servers:
- url: http://127.0.0.1:8001
description: Development (ASGI/Uvicorn)