{"name":"WhatSaaS API","version":"v1","baseUrl":"https://nakwasap.my","authentication":{"type":"Bearer Token","header":"Authorization","format":"Bearer sk_live_...","description":"Generate API keys from Settings > Developers. Include in the Authorization header for all requests."},"notes":{"instanceTypes":"Instances can be WHATSAPP-BAILEYS (Web) or WHATSAPP-BUSINESS (WABA/Meta Cloud API). The /send endpoint auto-detects the type.","wabaLimitation":"WABA instances only support sending outside the 24h window via template messages. Text/media sends require an active conversation.","rateLimiting":"Baileys instances: if anti-ban is configured, messages are queued with delay (queued: true, queueId). WABA instances always send directly (no queue)."},"endpoints":[{"method":"GET","path":"/api/v1/instances","description":"List all WhatsApp instances for your team, with live connection status.","parameters":{"query":[{"name":"instanceName","type":"string","required":false,"description":"Filter by specific instance name"}]},"response":{"200":{"description":"List of instances","body":{"instances":[{"instanceName":"my-instance","integration":"WHATSAPP-BAILEYS | WHATSAPP-BUSINESS","status":"open | connecting | close | not_found | error","profileName":"John Doe","profilePictureUrl":"https://...","number":"60123456789"}]}},"401":{"description":"Unauthorized — invalid or missing API key"}}},{"method":"GET","path":"/api/v1/groups","description":"List WhatsApp groups for a Baileys instance. Supports search by group name or JID.","parameters":{"query":[{"name":"instanceName","type":"string","required":true,"description":"Name of the WhatsApp instance"},{"name":"search","type":"string","required":false,"description":"Search keyword to filter groups by name or JID"}]},"response":{"200":{"description":"List of groups","body":{"groups":[{"jid":"120363001234567890@g.us","name":"My Group","participantCount":25}],"total":1}},"400":{"description":"Missing instanceName or not a Baileys instance"},"401":{"description":"Unauthorized"},"404":{"description":"Instance not found"}}},{"method":"GET","path":"/api/v1/instances/qr","description":"Get QR code to connect a WhatsApp Web (Baileys) instance. Returns base64-encoded PNG image.","parameters":{"query":[{"name":"instanceName","type":"string","required":true,"description":"Name of the instance to connect"}]},"response":{"200":{"description":"QR code image","body":{"qr":"data:image/png;base64,..."}},"400":{"description":"Missing instanceName or not a Baileys instance"},"401":{"description":"Unauthorized"},"200_connected":{"description":"Instance already connected","body":{"qr":null,"message":"Instance already connected."}}}},{"method":"POST","path":"/api/v1/send","description":"Send a message via WhatsApp. Auto-detects instance type (Baileys or WABA) and routes accordingly.","parameters":{"body":[{"name":"instanceName","type":"string","required":true,"description":"Name of the WhatsApp instance to send from"},{"name":"number","type":"string","required":false,"description":"Recipient phone number (e.g. \"60123456789\"). Required if groupJid not provided."},{"name":"groupJid","type":"string","required":false,"description":"Group JID (Baileys only). Required if number not provided."},{"name":"type","type":"string","required":true,"description":"Message type","enum":["text","image","video","document","audio","template"]},{"name":"message","type":"string","required":false,"description":"Text content or caption for media. Required for type \"text\"."},{"name":"mediaUrl","type":"string","required":false,"description":"URL of media file. Required for image/video/document/audio."},{"name":"fileName","type":"string","required":false,"description":"Filename for document type (Baileys only)"},{"name":"mimetype","type":"string","required":false,"description":"MIME type of media"},{"name":"templateName","type":"string","required":false,"description":"WABA template name. Required when type is \"template\"."},{"name":"templateLanguage","type":"string","required":false,"description":"Template language code (e.g. \"en\"). Defaults to first available."},{"name":"variables","type":"object","required":false,"description":"Template variables as key-value pairs. Keys: \"1\", \"2\" for body vars, \"header_image\"/\"header_video\"/\"header_document\" for media headers, \"header_document_filename\" to override doc name, \"card_N_image\" for carousel cards."},{"name":"typing","type":"string","required":false,"description":"Show the \"typing...\" indicator and pause before sending, scaled to the text length: normal 1.5-7s, slow 3-12s. Default \"off\". Baileys instances only (WABA cannot show presence to recipients). Messages held by the anti-ban queue also show typing, with the pause capped at 6s there.","enum":["off","normal","slow"]}]},"examples":[{"title":"Send text (Baileys)","body":{"instanceName":"my-instance","number":"60123456789","type":"text","message":"Hello from API!"}},{"title":"Send text (WABA)","body":{"instanceName":"my-waba","number":"60123456789","type":"text","message":"Hello from WABA!"}},{"title":"Send image with caption","body":{"instanceName":"my-instance","number":"60123456789","type":"image","mediaUrl":"https://example.com/photo.jpg","message":"Check this out!"}},{"title":"Send document","body":{"instanceName":"my-instance","number":"60123456789","type":"document","mediaUrl":"https://example.com/report.pdf","fileName":"report.pdf","mimetype":"application/pdf"}},{"title":"Send text with typing indicator (Baileys)","body":{"instanceName":"my-instance","number":"60123456789","type":"text","message":"Sekejap ya, saya semak dulu...","typing":"slow"}},{"title":"Send audio","body":{"instanceName":"my-instance","number":"60123456789","type":"audio","mediaUrl":"https://example.com/voice.mp3"}},{"title":"Send to group (Baileys)","body":{"instanceName":"my-instance","groupJid":"120363001234567890@g.us","type":"text","message":"Hello group!"}},{"title":"Send template (WABA)","body":{"instanceName":"my-waba","number":"60123456789","type":"template","templateName":"order_confirmation","templateLanguage":"en","variables":{"1":"John","2":"ORD-123"}}}],"response":{"200":{"description":"Message sent","body":{"success":true,"data":{}}},"400":{"description":"Invalid payload or WABA group not supported"},"401":{"description":"Unauthorized"},"404":{"description":"Instance or template not found"},"429":{"description":"Daily send limit reached"},"200_queued":{"description":"Baileys only — message queued (anti-ban enabled)","body":{"success":true,"queued":true,"queueId":42}}}},{"method":"POST","path":"/api/v1/send-template","description":"Send a WABA template message. Supports all template types: Interactive, Carousel, LTO, Catalog, MPM, Order Details, Order Status.","parameters":{"body":[{"name":"instanceName","type":"string","required":true,"description":"Name of the WABA instance"},{"name":"number","type":"string","required":true,"description":"Recipient phone number"},{"name":"templateName","type":"string","required":true,"description":"Approved template name"},{"name":"language","type":"string","required":false,"description":"Template language code (default: \"en\")"},{"name":"variables","type":"object","required":false,"description":"Variables as key-value pairs. See variable keys below."}],"variableKeys":{"description":"Special variable keys supported in the variables object:","keys":[{"key":"1, 2, 3...","description":"Body text variables — replaces {{1}}, {{2}}, etc. in template body"},{"key":"header_image","description":"Image URL for templates with IMAGE header"},{"key":"header_video","description":"Video URL for templates with VIDEO header"},{"key":"header_document","description":"Document URL for templates with DOCUMENT header"},{"key":"header_document_filename","description":"Override filename for DOCUMENT header (default: extracted from URL)"},{"key":"card_1_image, card_2_image...","description":"Image URL for each carousel card (card_1_image for first card, etc.)"},{"key":"card_1_video, card_2_video...","description":"Video URL for carousel cards with VIDEO headers"},{"key":"catalog_product_id","description":"Product retailer ID for Catalog template thumbnail"},{"key":"mpm_thumbnail_id","description":"Thumbnail product retailer ID for MPM template"},{"key":"mpm_product_id","description":"Product retailer ID for MPM template (simple mode)"},{"key":"mpm_sections","description":"JSON string of product sections for MPM template (advanced)"},{"key":"coupon_code","description":"Coupon code for LTO templates with COPY_CODE button"},{"key":"lto_expiry_hours","description":"Offer expiration in hours from send time (default: 24)"},{"key":"button_url, button_0, button_1","description":"Dynamic URL parameter for URL buttons with {{1}} placeholder"}]}},"examples":[{"title":"Send template with body variables","body":{"instanceName":"my-waba","number":"60123456789","templateName":"order_confirmation","language":"en","variables":{"1":"John","2":"ORD-123"}}},{"title":"Send template with header image","body":{"instanceName":"my-waba","number":"60123456789","templateName":"promo_banner","language":"en","variables":{"1":"Flash Sale!","header_image":"https://example.com/banner.jpg"}}},{"title":"Send template with document + custom filename","body":{"instanceName":"my-waba","number":"60123456789","templateName":"invoice_template","language":"en","variables":{"1":"INV-001","header_document":"https://example.com/invoice.pdf","header_document_filename":"Invoice-001.pdf"}}},{"title":"Send carousel template","body":{"instanceName":"my-waba","number":"60123456789","templateName":"product_showcase","language":"en","variables":{"card_1_image":"https://example.com/product1.jpg","card_2_image":"https://example.com/product2.jpg","card_3_image":"https://example.com/product3.jpg"}}},{"title":"Send catalog/MPM template (no extra variables needed)","body":{"instanceName":"my-waba","number":"60123456789","templateName":"our_catalog","language":"en"}}],"response":{"200":{"description":"Template sent (always direct, no queue for WABA)","body":{"success":true,"data":{"messages":[{"id":"wamid.xxx"}]}}},"400":{"description":"Not a WABA instance or invalid payload"},"404":{"description":"Instance or template not found"},"429":{"description":"Daily send limit reached"}}},{"method":"GET","path":"/api/v1/templates","description":"List approved WABA templates for an instance.","parameters":{"query":[{"name":"instanceName","type":"string","required":true,"description":"Name of the WABA instance"}]},"response":{"200":{"description":"List of templates","body":{"templates":[{"id":1,"name":"order_confirmation","language":"en","category":"UTILITY","status":"APPROVED","components":[]}],"total":1}},"400":{"description":"Missing instanceName or not a WABA instance"},"401":{"description":"Unauthorized"},"404":{"description":"Instance not found"}}},{"method":"GET","path":"/api/v1/contacts","description":"List contacts with pagination and search.","parameters":{"query":[{"name":"offset","type":"number","required":false,"description":"Pagination offset (default: 0)"},{"name":"limit","type":"number","required":false,"description":"Results per page (default: 50, max: 100)"},{"name":"search","type":"string","required":false,"description":"Search by name or phone number"}]},"response":{"200":{"description":"Paginated contacts","body":{"contacts":[{"id":1,"name":"John Doe","phone":"60123456789","notes":"VIP","assignedUser":{"id":5,"name":"Agent"},"funnelStage":{"id":2,"name":"Qualified","emoji":"🔥"},"tags":[{"id":1,"name":"VIP"}],"createdAt":"2026-01-15T10:30:00Z","updatedAt":"2026-02-01T14:00:00Z"}],"total":150,"offset":0,"limit":50}},"401":{"description":"Unauthorized"}}},{"method":"GET","path":"/api/v1/chats","description":"List chats with pagination. Optionally filter by instance.","parameters":{"query":[{"name":"offset","type":"number","required":false,"description":"Pagination offset (default: 0)"},{"name":"limit","type":"number","required":false,"description":"Results per page (default: 50, max: 100)"},{"name":"instanceName","type":"string","required":false,"description":"Filter by instance name"}]},"response":{"200":{"description":"Paginated chats","body":{"chats":[{"id":42,"remoteJid":"60123456789@s.whatsapp.net","name":"John Doe","lastMessageText":"Hello!","lastMessageTimestamp":"2026-02-06T10:00:00Z","lastMessageFromMe":false,"unreadCount":3,"instance":{"instanceName":"my-instance","integration":"WHATSAPP-BAILEYS"},"contact":{"id":1,"name":"John Doe","phone":"60123456789"}}],"total":150,"offset":0,"limit":50}},"401":{"description":"Unauthorized"},"404":{"description":"Instance not found (when filter provided)"}}},{"method":"GET","path":"/api/v1/session-window","description":"Check if the 24-hour WABA conversation window is open for a specific number. Window opens when customer sends a message and expires after 24h.","parameters":{"query":[{"name":"instanceName","type":"string","required":true,"description":"Name of the WABA instance"},{"name":"number","type":"string","required":true,"description":"Phone number to check (e.g. \"60123456789\")"}]},"response":{"200":{"description":"Session window status","body":{"number":"60123456789","chatFound":true,"contactName":"John Doe","isWindowOpen":true,"openedAt":"2026-02-06T08:00:00Z","expiresAt":"2026-02-07T08:00:00Z","timeRemainingMs":43200000,"timeRemainingHuman":"12h 0m","message":"Window is open. You can send text/media messages."}},"400":{"description":"Missing params or not a WABA instance"},"401":{"description":"Unauthorized"},"404":{"description":"Instance not found"}}},{"method":"POST","path":"/api/v1/templates/sync","description":"Sync WABA templates from Meta. Fetches all templates and upserts into the database.","parameters":{"body":[{"name":"instanceName","type":"string","required":true,"description":"Name of the WABA instance"}]},"response":{"200":{"description":"Templates synced","body":{"success":true,"synced":15,"summary":{"total":15,"approved":12,"pending":2,"rejected":1},"message":"Synced 15 templates from Meta."}},"400":{"description":"Missing instanceName or not configured"},"401":{"description":"Unauthorized"},"404":{"description":"WABA instance not found"}}},{"method":"GET","path":"/api/v1/status","description":"Check WABA account status including verification, quality rating, messaging limits, and token validity.","parameters":{"query":[{"name":"instanceName","type":"string","required":true,"description":"Name of the WABA instance"}]},"response":{"200":{"description":"Account status","body":{"instanceName":"my-waba","phoneNumber":"+60123456789","verifiedName":"My Business","status":"CONNECTED","nameStatus":"APPROVED","qualityRating":"GREEN","messagingLimitTier":"TIER_1K","isOfficialBusinessAccount":false,"tokenValid":true,"tokenExpired":false,"tokenExpiresAt":"2026-04-01T00:00:00Z","lastWebhookAt":"2026-02-06T12:00:00Z","consecutiveFailures":0,"dailySendLimit":1000}},"400":{"description":"Not a WABA instance or not configured"},"401":{"description":"Unauthorized"},"404":{"description":"Instance not found"}}}]}