{"openapi": "3.0.3", "info": {"title": "MENA Trade API", "version": "1.0", "description": "Connect your ERP (VLUERP, Odoo, SAP, Oracle, Microsoft Dynamics, Zoho…) to MENA Trade. Factories (Premium plan) sync products and answer requests for quotation; buyers send requests and accept quotes. Create API keys in your account under 'API & ERP'. Human guide: https://mena-trade.com/developers/", "contact": {"name": "MENA Trade", "url": "https://mena-trade.com/legal/contact/"}}, "servers": [{"url": "https://mena-trade.com/api/v1"}], "security": [{"bearer": []}], "components": {"securitySchemes": {"bearer": {"type": "http", "scheme": "bearer", "bearerFormat": "mt_<prefix>_<secret>"}}, "schemas": {"Error": {"type": "object", "properties": {"error": {"type": "string", "example": "invalid"}, "message": {"type": "string"}, "fields": {"type": "object", "additionalProperties": {"type": "string"}}}}, "Company": {"type": "object", "properties": {"id": {"type": "integer"}, "name": {"type": "string"}, "name_ar": {"type": "string"}, "kind": {"type": "string", "enum": ["factory", "buyer"]}, "country": {"type": "string"}, "city": {"type": "string"}, "verified": {"type": "boolean"}, "contacts": {"type": "array", "items": {"type": "object"}, "description": "Only once contact details are shared"}}}, "PriceTier": {"type": "object", "required": ["min_qty", "price"], "properties": {"min_qty": {"type": "integer", "minimum": 1}, "price": {"type": "number", "minimum": 0}}}, "ProductInput": {"type": "object", "description": "All fields optional on PATCH. Codes come from GET /reference.", "properties": {"sku": {"type": "string", "maxLength": 64}, "name_en": {"type": "string"}, "name_ar": {"type": "string"}, "name_tr": {"type": "string"}, "description_en": {"type": "string"}, "description_ar": {"type": "string"}, "description_tr": {"type": "string"}, "sector": {"type": "string"}, "unit": {"type": "string"}, "moq": {"type": "integer"}, "currency": {"type": "string", "enum": ["USD", "SAR", "EGP"]}, "price_on_request": {"type": "boolean"}, "price_tiers": {"type": "array", "items": {"$ref": "#/components/schemas/PriceTier"}}, "lead_time_days": {"type": "integer"}, "capacity_month": {"type": "integer"}, "hs_code": {"type": "string"}, "barcode": {"type": "string"}, "units_per_carton": {"type": "integer"}, "carton_length_cm": {"type": "number"}, "carton_width_cm": {"type": "number"}, "carton_height_cm": {"type": "number"}, "carton_gross_kg": {"type": "number"}, "storage": {"type": "string"}, "dangerous_goods": {"type": "boolean"}, "status": {"type": "string", "enum": ["draft", "published", "hidden"], "description": "Publishing needs at least one photo."}}}, "Product": {"allOf": [{"$ref": "#/components/schemas/ProductInput"}, {"type": "object", "properties": {"id": {"type": "integer"}, "images": {"type": "array", "items": {"type": "object"}}, "public_url": {"type": "string", "nullable": true}, "created_at": {"type": "string"}, "updated_at": {"type": "string"}}}]}, "RFQInput": {"type": "object", "required": ["title", "description", "quantity", "unit"], "properties": {"title": {"type": "string"}, "description": {"type": "string"}, "sector": {"type": "string"}, "quantity": {"type": "number"}, "unit": {"type": "string"}, "target_price": {"type": "number"}, "currency": {"type": "string"}, "incoterm": {"type": "string"}, "delivery_country": {"type": "string"}, "delivery_city": {"type": "string"}, "supplier_country": {"type": "string", "default": "any"}, "needed_by": {"type": "string", "format": "date"}, "closes_on": {"type": "string", "format": "date"}, "factory_id": {"type": "integer", "description": "Send directly to one factory"}}}, "RFQ": {"type": "object", "properties": {"id": {"type": "integer"}, "title": {"type": "string"}, "status": {"type": "string"}, "accepting_quotes": {"type": "boolean"}, "direct": {"type": "boolean"}, "buyer": {"$ref": "#/components/schemas/Company"}, "items": {"type": "array", "items": {"type": "object"}}, "quotes": {"type": "array", "items": {"$ref": "#/components/schemas/Quote"}}, "my_quote": {"allOf": [{"$ref": "#/components/schemas/Quote"}], "nullable": true}}}, "QuoteInput": {"type": "object", "properties": {"unit_price": {"type": "number"}, "quantity": {"type": "number"}, "moq": {"type": "number"}, "currency": {"type": "string"}, "incoterm": {"type": "string"}, "lead_time_days": {"type": "integer"}, "valid_until": {"type": "string", "format": "date"}, "notes": {"type": "string"}, "items": {"type": "array", "description": "For multi-product requests: a unit_price per item_id", "items": {"type": "object", "properties": {"item_id": {"type": "integer"}, "unit_price": {"type": "number"}}}}}}, "Quote": {"type": "object", "properties": {"id": {"type": "integer"}, "rfq_id": {"type": "integer"}, "status": {"type": "string"}, "unit_price": {"type": "number"}, "total": {"type": "number"}, "currency": {"type": "string"}, "lead_time_days": {"type": "integer"}, "valid_until": {"type": "string"}, "factory": {"$ref": "#/components/schemas/Company"}}}, "Conversation": {"type": "object", "properties": {"id": {"type": "integer"}, "rfq_id": {"type": "integer"}, "with": {"type": "object"}, "unread": {"type": "integer"}}}, "Message": {"type": "object", "properties": {"id": {"type": "integer"}, "from_me": {"type": "boolean"}, "kind": {"type": "string"}, "body": {"type": "string"}, "contact_details_hidden": {"type": "boolean"}, "created_at": {"type": "string"}}}, "Webhook": {"type": "object", "properties": {"id": {"type": "integer"}, "url": {"type": "string"}, "events": {"type": "array", "items": {"type": "string"}}, "secret": {"type": "string", "description": "Shown once, at creation"}, "active": {"type": "boolean"}, "last_status": {"type": "string"}}}}}, "paths": {"/me": {"get": {"summary": "Your company, plan and key", "tags": ["Account"], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "400": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/reference": {"get": {"summary": "Code lists: sectors, units, currencies, incoterms, countries, storage, events", "tags": ["Account"], "security": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "400": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/products": {"get": {"summary": "List your products", "tags": ["Products (factories)"], "parameters": [{"name": "page", "in": "query", "schema": {"type": "integer", "default": 1}}, {"name": "page_size", "in": "query", "schema": {"type": "integer", "default": 50, "maximum": 100}}, {"name": "updated_since", "in": "query", "schema": {"type": "string", "format": "date-time"}, "description": "Only rows changed since this time (ISO 8601) — use for incremental sync."}, {"name": "sku", "in": "query", "schema": {"type": "string"}}, {"name": "status", "in": "query", "schema": {"type": "string"}}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object", "properties": {"count": {"type": "integer"}, "page": {"type": "integer"}, "page_size": {"type": "integer"}, "next_page": {"type": "integer", "nullable": true}, "results": {"type": "array", "items": {"$ref": "#/components/schemas/Product"}}}}}}}, "400": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}, "post": {"summary": "Create a product (as draft unless status is given)", "tags": ["Products (factories)"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProductInput"}}}}, "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Product"}}}}, "400": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/products/{id}": {"parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "get": {"summary": "Get a product", "tags": ["Products (factories)"], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Product"}}}}, "400": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}, "patch": {"summary": "Update some fields", "tags": ["Products (factories)"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProductInput"}}}}, "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Product"}}}}, "400": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}, "delete": {"summary": "Delete a product", "tags": ["Products (factories)"], "responses": {"200": {"description": "Deleted"}, "400": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/products/sku/{sku}": {"parameters": [{"name": "sku", "in": "path", "required": true, "schema": {"type": "string"}}], "get": {"summary": "Get a product by your item code", "tags": ["Products (factories)"], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Product"}}}}, "400": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}, "put": {"summary": "Create or update by item code (upsert) — recommended for ERP sync", "tags": ["Products (factories)"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProductInput"}}}}, "responses": {"200": {"description": "Updated (201 when created)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Product"}}}}, "400": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/products/{id}/images": {"parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}, {"name": "main", "in": "query", "schema": {"type": "integer", "enum": [1]}}], "post": {"summary": "Upload a photo (multipart field 'image', JPG/PNG/WebP, 5 MB)", "tags": ["Products (factories)"], "requestBody": {"required": true, "content": {"multipart/form-data": {"schema": {"type": "object", "properties": {"image": {"type": "string", "format": "binary"}}}}}}, "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Product"}}}}, "400": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/products/{id}/images/{image_id}": {"parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}, {"name": "image_id", "in": "path", "required": true, "schema": {"type": "integer"}}], "delete": {"summary": "Delete an extra photo", "tags": ["Products (factories)"], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Product"}}}}, "400": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/rfqs": {"get": {"summary": "Factories: open requests for you and those you quoted. Buyers: your requests with quotes.", "tags": ["Requests for quotation"], "parameters": [{"name": "page", "in": "query", "schema": {"type": "integer", "default": 1}}, {"name": "page_size", "in": "query", "schema": {"type": "integer", "default": 50, "maximum": 100}}, {"name": "updated_since", "in": "query", "schema": {"type": "string", "format": "date-time"}, "description": "Only rows changed since this time (ISO 8601) — use for incremental sync."}, {"name": "status", "in": "query", "schema": {"type": "string"}}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object", "properties": {"count": {"type": "integer"}, "page": {"type": "integer"}, "page_size": {"type": "integer"}, "next_page": {"type": "integer", "nullable": true}, "results": {"type": "array", "items": {"$ref": "#/components/schemas/RFQ"}}}}}}}, "400": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}, "post": {"summary": "Buyers: publish a request (all matching factories, or one with factory_id)", "tags": ["Requests for quotation"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RFQInput"}}}}, "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RFQ"}}}}, "400": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/rfqs/{id}": {"parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "get": {"summary": "Get a request", "tags": ["Requests for quotation"], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RFQ"}}}}, "400": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/rfqs/{id}/quote": {"parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "put": {"summary": "Factories: send or update your quote", "tags": ["Requests for quotation"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/QuoteInput"}}}}, "responses": {"200": {"description": "OK (201 when first sent)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Quote"}}}}, "400": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}, "delete": {"summary": "Factories: withdraw your quote", "tags": ["Requests for quotation"], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Quote"}}}}, "400": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/rfqs/{id}/accept": {"parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "post": {"summary": "Buyers: accept one quote (others are declined)", "tags": ["Requests for quotation"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "required": ["quote_id"], "properties": {"quote_id": {"type": "integer"}}}}}}, "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RFQ"}}}}, "400": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/rfqs/{id}/close": {"parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "post": {"summary": "Buyers: close without accepting", "tags": ["Requests for quotation"], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RFQ"}}}}, "400": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/quotes": {"get": {"summary": "Factories: your quotes. Buyers: quotes you received.", "tags": ["Requests for quotation"], "parameters": [{"name": "page", "in": "query", "schema": {"type": "integer", "default": 1}}, {"name": "page_size", "in": "query", "schema": {"type": "integer", "default": 50, "maximum": 100}}, {"name": "updated_since", "in": "query", "schema": {"type": "string", "format": "date-time"}, "description": "Only rows changed since this time (ISO 8601) — use for incremental sync."}, {"name": "status", "in": "query", "schema": {"type": "string"}}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object", "properties": {"count": {"type": "integer"}, "page": {"type": "integer"}, "page_size": {"type": "integer"}, "next_page": {"type": "integer", "nullable": true}, "results": {"type": "array", "items": {"$ref": "#/components/schemas/Quote"}}}}}}}, "400": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/conversations": {"get": {"summary": "Your chats", "tags": ["Chat"], "parameters": [{"name": "page", "in": "query", "schema": {"type": "integer", "default": 1}}, {"name": "page_size", "in": "query", "schema": {"type": "integer", "default": 50, "maximum": 100}}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object", "properties": {"count": {"type": "integer"}, "page": {"type": "integer"}, "page_size": {"type": "integer"}, "next_page": {"type": "integer", "nullable": true}, "results": {"type": "array", "items": {"$ref": "#/components/schemas/Conversation"}}}}}}}, "400": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}, "post": {"summary": "Open the chat for a request (buyers also give factory_id)", "tags": ["Chat"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "required": ["rfq_id"], "properties": {"rfq_id": {"type": "integer"}, "factory_id": {"type": "integer"}}}}}}, "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Conversation"}}}}, "400": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/conversations/{id}/messages": {"parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}, {"name": "after_id", "in": "query", "schema": {"type": "integer"}}], "get": {"summary": "Messages (up to 200 after after_id)", "tags": ["Chat"], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object", "properties": {"results": {"type": "array", "items": {"$ref": "#/components/schemas/Message"}}}}}}}, "400": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}, "post": {"summary": "Send a message (contact details hidden until the factory quotes)", "tags": ["Chat"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "required": ["body"], "properties": {"body": {"type": "string"}}}}}}, "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Message"}}}}, "400": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/webhooks": {"get": {"summary": "Your webhooks", "tags": ["Webhooks"], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "400": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}, "post": {"summary": "Add a webhook (public https URL). The signing secret is returned once.", "tags": ["Webhooks"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "required": ["url"], "properties": {"url": {"type": "string"}, "events": {"type": "array", "items": {"type": "string"}, "description": "Empty = all events"}}}}}}, "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Webhook"}}}}, "400": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/webhooks/{id}": {"parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "delete": {"summary": "Remove a webhook", "tags": ["Webhooks"], "responses": {"200": {"description": "Deleted"}, "400": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/webhooks/{id}/test": {"parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "post": {"summary": "Send a signed 'ping' now", "tags": ["Webhooks"], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "400": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}}}