openapi: 3.0.1 info: title: Modica WhatsApp Business Messaging API description: Developer Documentation for using the Modica WhatsApp Business Messaging API version: 1.2.0 termsOfService: https://www.modicagroup.com/privacy-policy contact: name: API Support email: support@modicagroup.com url: https://www.modicagroup.com license: name: Modica API - Terms Of Use url: https://confluence.modicagroup.com/download/attachments/12386319/Modica%20Group%20-%20Terms%20of%20Use.pdf?version=1&modificationDate=1500544212144&api=v2 servers: - url: "https://api.modicagroup.com/rest/wab/v1" security: - BasicAuth: [] tags: - name: messages description: WhatsApp Messaging endpoints. - name: media description: WhatsApp Media endpoints. - name: status description: WhatsApp Status endpoints. paths: /media: summary: Endpoint for uploading and downloading media post: operationId: PostMedia tags: - media summary: uploading media description: uploading media requestBody: $ref: '#/components/requestBodies/RequestMediaPost' responses: '200': $ref: '#/components/responses/ResponseMediaPost' '401': $ref: '#/components/responses/Unauthorized' 4XX: $ref: '#/components/responses/4XXError' '429': $ref: '#/components/responses/TooManyRequests' '500': $ref: '#/components/responses/InternalServerError' get: operationId: GetMedia tags: - media summary: downloading media description: Download message media. parameters: - name: media_id in: query description: The ID for the media item. required: true schema: type: string pattern: '^[a-zA-Z0-9]+$' maxLength: 255 responses: '200': $ref: '#/components/responses/ResponseMediaGet' '401': $ref: '#/components/responses/Unauthorized' 4XX: $ref: '#/components/responses/4XXError' '429': $ref: '#/components/responses/TooManyRequests' '500': $ref: '#/components/responses/InternalServerError' /messages: summary: Endpoint for sending Whatsapp messages post: operationId: PostMessages tags: - messages summary: Send a message to a customer description: Send a message to a customer. requestBody: $ref: '#/components/requestBodies/RequestMessagesPost' responses: '202': $ref: '#/components/responses/ResponseMessagesPost' '401': $ref: '#/components/responses/Unauthorized' 4XX: $ref: '#/components/responses/4XXError' '429': $ref: '#/components/responses/TooManyRequests' '500': $ref: '#/components/responses/InternalServerError' callbacks: messageCallback: '{$statusCallbackUrl}': post: summary: Status/DLR callback description: Sent when the status of a MT message is updated requestBody: $ref: '#/components/requestBodies/RequestMessageStatusCallback' responses: '200': description: callback successfully processed headers: X-RateLimit-Limit: $ref: '#/components/headers/X-RateLimit-Limit' '401': $ref: '#/components/responses/Unauthorized' 4XX: $ref: '#/components/responses/4XXError' '429': $ref: '#/components/responses/TooManyRequests' '500': $ref: '#/components/responses/InternalServerError' '{$replyCallbackUrl}': post: summary: Reply/MO callback description: Sent when a MO message is received requestBody: $ref: '#/components/requestBodies/RequestMessageReplyCallback' responses: '200': description: callback successfully processed headers: X-RateLimit-Limit: $ref: '#/components/headers/X-RateLimit-Limit' '401': $ref: '#/components/responses/Unauthorized' 4XX: $ref: '#/components/responses/4XXError' '429': $ref: '#/components/responses/TooManyRequests' '500': $ref: '#/components/responses/InternalServerError' patch: operationId: PatchMessages tags: - messages summary: Update an existing message status description: Update an existing message status e.g. mark as read. requestBody: $ref: '#/components/requestBodies/RequestMessagesPatch' responses: '200': description: OK headers: Content-Security-Policy: $ref: '#/components/headers/Content-Security-Policy' Strict-Transport-Security: $ref: '#/components/headers/Strict-Transport-Security' X-RateLimit-Limit: $ref: '#/components/headers/X-RateLimit-Limit' '401': $ref: '#/components/responses/Unauthorized' 4XX: $ref: '#/components/responses/4XXError' '429': $ref: '#/components/responses/TooManyRequests' '500': $ref: '#/components/responses/InternalServerError' get: operationId: GetMessages tags: - messages summary: Get message by message ID description: Get a message by the message ID parameters: - name: id in: query description: The message ID required: true schema: $ref: '#/components/schemas/Uuid' responses: '200': $ref: '#/components/responses/ResponseMessageGet' '401': $ref: '#/components/responses/Unauthorized' 4XX: $ref: '#/components/responses/4XXError' '429': $ref: '#/components/responses/TooManyRequests' '500': $ref: '#/components/responses/InternalServerError' /messages/broadcast: post: operationId: messages_broadcast_post summary: Send a broadcast message to customers description: Send a broadcast message to customers. requestBody: $ref: '#/components/requestBodies/RequestMessagesBroadcastPost' responses: '202': $ref: '#/components/responses/ResponseMessagesBroadcastPost' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' '500': $ref: '#/components/responses/InternalServerError' callbacks: messageCallback: '{$statusCallbackUrl}': post: summary: Status/DLR callback description: Sent when the status of a MT message is updated requestBody: $ref: '#/components/requestBodies/RequestMessageStatusCallback' responses: '200': description: callback successfully processed headers: X-RateLimit-Limit: $ref: '#/components/headers/X-RateLimit-Limit' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' '500': $ref: '#/components/responses/InternalServerError' '{$replyCallbackUrl}': post: summary: Reply/MO callback description: Sent when a MO message is received requestBody: $ref: '#/components/requestBodies/RequestMessageReplyCallback' responses: '200': description: callback successfully processed headers: X-RateLimit-Limit: $ref: '#/components/headers/X-RateLimit-Limit' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' '500': $ref: '#/components/responses/InternalServerError' tags: - messages /source: post: operationId: PostSource tags: - source summary: Adding a source description: Adding a source requestBody: $ref: '#/components/requestBodies/RequestSourcePost' responses: '200': $ref: '#/components/responses/ResponseSourcePost' '401': $ref: '#/components/responses/Unauthorized' 4XX: $ref: '#/components/responses/4XXError' '429': $ref: '#/components/responses/TooManyRequests' '500': $ref: '#/components/responses/InternalServerError' components: parameters: {} schemas: APIErrorResponse: description: Top-level structure wrapping error objects. type: object properties: errors: type: array items: $ref: '#/components/schemas/APIError' maxItems: 50 APIError: description: An API error structure. type: object properties: field: type: string maxLength: 100 pattern: '^[ -_.a-zA-Z0-9]*$' code: type: string maxLength: 100 pattern: '^[ -_.a-zA-Z0-9]*$' description: type: string maxLength: 100 pattern: '^[ -_.a-zA-Z0-9!$^*()\\[\\]`+,\''\\\\]*$' additionalProperties: false required: - field - code - description MediaMimeType: description: Supported media mime types. type: string enum: - image/png - image/jpeg - text/plain - application/pdf - audio/mp3 - video/mp4 E164: description: The destination number in E.164 format. type: string maxLength: 16 pattern: ^\+[1-9]\d{1,14}$ Uuid: description: A string with UUID format. type: string maxLength: 36 pattern: ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$ MessageDestination: description: Message destination fields. type: object properties: to: description: The destination number in E.164 format. type: string pattern: ^\+[1-9]\d{1,14}$ maxLength: 15 deprecated: true destination: $ref: '#/components/schemas/E164' BroadcastMessageDestination: description: Broadcast message destination fields. type: object properties: destination: description: Array of destination numbers in E.164 format. type: array items: $ref: '#/components/schemas/E164' maxItems: 1000 required: - destination MessageCommon: description: Common message fields. type: object properties: source: description: The whatsapp business number id. type: string pattern: ^\[1-9]\d{1,19}$ maxLength: 50 scheduled: description: Allows scheduling of messages with an upper limit of 60 days. type: string format: date-time maxLength: 30 type: type: string enum: - text - template - media reference: type: string format: none maxLength: 255 required: - type MessageText: description: Message of Text type. allOf: - $ref: '#/components/schemas/MessageDestination' - $ref: '#/components/schemas/MessageCommon' - type: object properties: text: type: object properties: body: type: string format: none maxLength: 255 required: - body required: - text MessageMedia: description: Message of Media type. allOf: - $ref: '#/components/schemas/MessageDestination' - $ref: '#/components/schemas/MessageCommon' - type: object properties: media: type: object properties: type: type: string enum: - audio - document - image - video url: type: string format: url maxLength: 255 required: - type - url required: - media MessageTemplate: description: Message of Template type. allOf: - $ref: '#/components/schemas/MessageDestination' - $ref: '#/components/schemas/MessageCommon' - type: object properties: template: type: object properties: name: type: string format: none maxLength: 255 language: type: string format: none default: en_US maxLength: 255 header_params: type: array items: type: string format: none maxLength: 255 maxItems: 3 body_params: type: array items: type: string format: none maxLength: 255 maxItems: 3 media: type: object properties: type: type: string format: none maxLength: 255 url: type: string format: url maxLength: 255 buttons: type: array items: type: object properties: index: type: number format: int32 type: type: string format: none maxLength: 255 payload: type: string format: none maxLength: 255 maxItems: 3 required: - name - language required: - template BroadcastMessageText: description: Message of Text type. allOf: - $ref: '#/components/schemas/BroadcastMessageDestination' - $ref: '#/components/schemas/MessageCommon' - type: object properties: text: type: object properties: body: type: string format: none maxLength: 255 required: - body required: - text BroadcastMessageMedia: description: Message of Media type. allOf: - $ref: '#/components/schemas/BroadcastMessageDestination' - $ref: '#/components/schemas/MessageCommon' - type: object properties: media: type: object properties: type: type: string enum: - audio - document - image - video url: type: string format: url maxLength: 255 required: - type - url required: - media BroadcastMessageTemplate: description: Message of Template type. allOf: - $ref: '#/components/schemas/BroadcastMessageDestination' - $ref: '#/components/schemas/MessageCommon' - type: object properties: template: type: object properties: name: type: string format: none maxLength: 255 language: type: string format: none default: en_US maxLength: 255 header_params: type: array items: type: string format: none maxLength: 255 maxItems: 3 body_params: type: array items: type: string format: none maxLength: 255 maxItems: 3 media: type: object properties: type: type: string format: none maxLength: 255 url: type: string format: url maxLength: 255 buttons: type: array items: type: object properties: index: type: number format: int32 type: type: string format: none maxLength: 255 payload: type: string format: none maxLength: 255 maxItems: 3 required: - name - language required: - template StatusCallback: description: Status callback structure. type: object properties: id: type: string format: uuid maxLength: 36 reference: type: string format: none maxLength: 255 status: type: string enum: - accepted - submitted - sent - received - read - frozen - rejected - failed - dead - expired ReplyCallback: description: Reply callback structure. type: object properties: id: type: string format: uuid maxLength: 36 source: description: The customer number type: string format: none maxLength: 255 destination: description: The business number type: string format: none maxLength: 255 content: $ref: '#/components/schemas/ReplyCallbackContent' ReplyCallbackContent: description: Reply callback content encoded as a JSON string. type: object properties: type: type: string enum: - audio - button - document - image - sticker - text - video audio: type: object properties: id: type: string format: none maxLength: 255 mime_type: $ref: '#/components/schemas/MediaMimeType' button: type: object properties: payload: type: string format: none maxLength: 2048 text: type: string format: none maxLength: 255 document: type: object properties: caption: type: string format: none maxLength: 255 filename: type: string format: none maxLength: 255 sha256: type: string format: none maxLength: 255 id: type: string format: none maxLength: 255 mime_type: $ref: '#/components/schemas/MediaMimeType' image: type: object properties: caption: type: string format: none maxLength: 255 sha256: type: string format: none maxLength: 255 id: type: string format: none maxLength: 255 mime_type: $ref: '#/components/schemas/MediaMimeType' sticker: type: object properties: sha256: type: string format: none maxLength: 255 id: type: string format: none maxLength: 255 mime_type: $ref: '#/components/schemas/MediaMimeType' text: type: object properties: body: type: string format: none maxLength: 255 preview_url: type: string format: none maxLength: 255 video: type: object properties: caption: type: string format: none maxLength: 255 filename: type: string format: none maxLength: 255 sha256: type: string format: none maxLength: 255 id: type: string format: none maxLength: 255 mime_type: $ref: '#/components/schemas/MediaMimeType' MessageDetails: description: Message details structure. type: object properties: id: type: string format: uuid maxLength: 36 reference: type: string format: string maxLength: 255 application_id: type: string format: string maxLength: 255 status: type: string enum: - accepted - submitted - sent - received - read - frozen - rejected - failed - dead - expired business_number_id: type: string format: none maxLength: 255 customer_number_id: type: string format: none maxLength: 255 timestamp: type: integer format: int64 maximum: 9223372036854775807 minimum: 0 direction: type: string format: string maxLength: 255 type: type: string enum: - text - template - media attributes: type: object properties: header: type: string format: string maxLength: 255 media: type: object properties: id: type: string format: string maxLength: 255 type: type: string enum: - image - audio - video - document body: type: string format: string maxLength: 1024 footer: type: string format: string maxLength: 10 buttons: type: array items: type: object properties: text: type: string format: string maxLength: 10 maxItems: 3 Source: description: Source structure. type: object properties: business_number_id: type: string minLength: 1 maxLength: 30 business_id: type: string minLength: 1 maxLength: 30 omni_customer_id: type: string format: uuid maxLength: 36 waba_id: type: string format: string minLength: 1 maxLength: 30 gw_application_id: type: string format: string minLength: 1 maxLength: 256 pin: type: string format: string minLength: 6 maxLength: 6 required: - business_number_id - business_id - omni_customer_id - waba_id - gw_application_id headers: Content-Security-Policy: description: Content Security Policy to prevent certain types of attacks. schema: type: string pattern: ^['-_ a-zA-Z0-9]+$ maxLength: 255 example: frame-ancestors 'none' Strict-Transport-Security: description: HSTS header to enforce HTTPS schema: type: string pattern: '^max-age=[0-9]+(; includeSubDomains)?(; preload)?$' maxLength: 255 example: max-age=31536000; includeSubDomains; preload X-RateLimit-Limit: schema: type: integer format: int32 maximum: 100 minimum: 0 description: Requests per second limit. RetryAfter: schema: type: integer format: int32 maximum: 1000 minimum: 10 description: The number of seconds to wait before allowing a follow-up request. requestBodies: RequestMessageStatusCallback: description: Status callback payload content: application/json: schema: $ref: '#/components/schemas/StatusCallback' examples: received: value: id: 2af85f64-3645-1078-b3fc-2c963f66afa6 reference: ref-abc123 status: received read: value: id: 3fa85f64-5717-4562-b3fc-2c963f66afa6 reference: ref-def456 status: read RequestMessageReplyCallback: description: Reply callback payload content: application/json: schema: $ref: '#/components/schemas/ReplyCallback' examples: audio: value: id: 3fa85f64-5717-4562-b3fc-2c963f66afa7 source: '64123456789' destination: '102046588645210' content: audio: id: abc123456 mime_type: audio/mp3 type: audio button: value: id: 3fa85f64-5717-4562-b3fc-2c963f66afa6 source: '64123456789' destination: '102046588645210' content: button: payload: 'YES' text: Click to join type: button document: value: id: 3fa85f64-5717-4562-b3fc-2c963f66afa6 source: '64123456789' destination: '102046588645210' content: document: id: abc123456 filename: cat.doc caption: A document about a cat mime_type: application/pdf sha256: the_sha256 type: document image: value: id: 3fa85f64-5717-4562-b3fc-2c963f66afa6 source: '64123456789' destination: '102046588645210' content: image: id: abc123456 caption: An image of a cat mime_type: image/jpeg sha256: the_sha256 type: image text: value: id: 3fa85f64-5717-4562-b3fc-2c963f66afa6 source: '64123456789' destination: '102046588645210' content: text: body: Hello World type: text video: value: id: 3fa85f64-5717-4562-b3fc-2c963f66afa6 source: '64123456789' destination: '102046588645210' content: type: video video: id: abc123456 filename: cat.mp4 caption: A video about a cat mime_type: video/mp4 sha256: the_sha256 RequestMessagesPost: content: application/json: schema: oneOf: - $ref: '#/components/schemas/MessageText' - $ref: '#/components/schemas/MessageTemplate' - $ref: '#/components/schemas/MessageMedia' examples: text: value: to: '+64123456789' type: text text: body: Hello template: value: to: '+64123456789' type: template template: name: hello_world language: en_US template-params: value: to: '+64123456789' type: template template: name: sample_flight_confirmation language: en_US body_params: - Home - Away - December 23rd media: type: document url: 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf' media-image: value: to: '+64123456789' type: media media: type: image url: 'https://static.whatsapp.net/rsrc.php/v3/y7/r/DSxOAUB0raA.png' media-document: value: to: '+64123456789' type: media media: type: document url: 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf' RequestMessagesPatch: content: application/json: schema: type: object properties: message_id: $ref: '#/components/schemas/Uuid' required: - message_id RequestMessagesBroadcastPost: content: application/json: schema: oneOf: - $ref: '#/components/schemas/BroadcastMessageText' - $ref: '#/components/schemas/BroadcastMessageTemplate' - $ref: '#/components/schemas/BroadcastMessageMedia' examples: text: value: destination: ['+64123456789', '+64223456789'] type: text text: body: Hello template: value: destination: ['+64123456789', '+64223456789'] type: template template: name: hello_world language: en_US template-params: value: destination: ['+64123456789', '+64223456789'] type: template template: name: sample_flight_confirmation language: en_US body_params: - Home - Away - December 23rd media: type: document url: 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf' media-image: value: destination: ['+64123456789', '+64223456789'] type: media media: type: image url: 'https://static.whatsapp.net/rsrc.php/v3/y7/r/DSxOAUB0raA.png' media-document: value: destination: ['+64123456789', '+64223456789'] type: media media: type: document url: 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf' RequestMediaPost: content: multipart/form-data: schema: type: object properties: file: type: string format: base64 maxLength: 1000000 encoding: file: contentType: 'image/png, image/jpeg, text/plain, application/pdf, audio/mp4, video/mp4' RequestSourcePost: content: application/json: schema: $ref: '#/components/schemas/Source' responses: Unauthorized: description: Unauthorized access error. headers: Content-Security-Policy: $ref: '#/components/headers/Content-Security-Policy' Strict-Transport-Security: $ref: '#/components/headers/Strict-Transport-Security' X-RateLimit-Limit: $ref: '#/components/headers/X-RateLimit-Limit' content: application/json: schema: $ref: '#/components/schemas/APIErrorResponse' example: message: Whatsapp Cloud API error statusCode: 401 error: unauthorized error message TooManyRequests: description: Too many requests error. headers: Content-Security-Policy: $ref: '#/components/headers/Content-Security-Policy' Strict-Transport-Security: $ref: '#/components/headers/Strict-Transport-Security' X-RateLimit-Limit: $ref: '#/components/headers/X-RateLimit-Limit' Retry-After: $ref: '#/components/headers/RetryAfter' content: application/json: schema: $ref: '#/components/schemas/APIErrorResponse' example: message: Whatsapp Cloud API error statusCode: 500 error: too many requests error message InternalServerError: description: Internal Server Error. headers: Content-Security-Policy: $ref: '#/components/headers/Content-Security-Policy' Strict-Transport-Security: $ref: '#/components/headers/Strict-Transport-Security' X-RateLimit-Limit: $ref: '#/components/headers/X-RateLimit-Limit' content: application/json: schema: $ref: '#/components/schemas/APIErrorResponse' example: message: Whatsapp Cloud API error statusCode: 500 error: internal server error message 4XXError: description: API Error Response. headers: X-RateLimit-Limit: $ref: '#/components/headers/X-RateLimit-Limit' content: application/json: schema: $ref: '#/components/schemas/APIErrorResponse' examples: bad_request: value: message: Whatsapp Cloud API error statusCode: 400 error: bad request error message forbidden: value: message: Whatsapp Cloud API error statusCode: 403 error: forbidden error message not_found: value: message: Whatsapp Cloud API error statusCode: 404 error: not found error message unprocessable_entity: value: message: Whatsapp Cloud API error statusCode: 422 error: unprocessable entity error message ResponseMediaGet: description: Get Media response structure. headers: Content-Security-Policy: $ref: '#/components/headers/Content-Security-Policy' Strict-Transport-Security: $ref: '#/components/headers/Strict-Transport-Security' X-RateLimit-Limit: $ref: '#/components/headers/X-RateLimit-Limit' content: application/octet-stream: schema: type: string format: binary maxLength: 2048 ResponseMediaPost: description: Upload Media response structure. headers: Content-Security-Policy: $ref: '#/components/headers/Content-Security-Policy' Strict-Transport-Security: $ref: '#/components/headers/Strict-Transport-Security' X-RateLimit-Limit: $ref: '#/components/headers/X-RateLimit-Limit' content: application/json: schema: type: object properties: id: type: string format: string maxLength: 255 example: id: abcd1234xyz ResponseMessageGet: description: Get Message response structure. headers: Content-Security-Policy: $ref: '#/components/headers/Content-Security-Policy' Strict-Transport-Security: $ref: '#/components/headers/Strict-Transport-Security' X-RateLimit-Limit: $ref: '#/components/headers/X-RateLimit-Limit' content: application/json: schema: $ref: '#/components/schemas/MessageDetails' examples: message: value: id: 3fa85f64-5717-4562-b3fc-2c963f66afa6 reference: abcd-1234-xyz-987 application_id: wab_customer_a status: received business_number_id: '102046588645210' customer_number_id: '64123456789' timestamp: 123456789 direction: MT type: text attributes: body: The body of the message ResponseMessagesPost: description: Post Message response structure. headers: Content-Security-Policy: $ref: '#/components/headers/Content-Security-Policy' Strict-Transport-Security: $ref: '#/components/headers/Strict-Transport-Security' X-RateLimit-Limit: $ref: '#/components/headers/X-RateLimit-Limit' content: application/json: schema: type: object properties: message_id: $ref: '#/components/schemas/Uuid' status: type: string enum: - accepted example: message_id: 3fa85f64-5717-4562-b3fc-2c963f66afa6 status: accepted ResponseMessagesBroadcastPost: description: Broadcast Message response structure. headers: Content-Security-Policy: $ref: '#/components/headers/Content-Security-Policy' Strict-Transport-Security: $ref: '#/components/headers/Strict-Transport-Security' X-RateLimit-Limit: $ref: '#/components/headers/X-RateLimit-Limit' content: application/json: schema: type: array maxItems: 1000 items: type: object properties: destination: $ref: '#/components/schemas/E164' id: $ref: '#/components/schemas/Uuid' status: type: string enum: - accepted - failed examples: accepted: value: - id: 3fa85f64-5717-4562-b3fc-2c963f66afa6 status: accepted - id: 6fa85f64-5717-4562-b3fc-2c963f66afa6 status: accepted failed: value: - id: 3fa85f64-5717-4562-b3fc-2c963f66afa6 status: failed message: error_message - id: 6fa85f64-5717-4562-b3fc-2c963f66afa6 status: failed message: error_message ResponseSourcePost: description: Post source response structure. headers: Content-Security-Policy: $ref: '#/components/headers/Content-Security-Policy' Strict-Transport-Security: $ref: '#/components/headers/Strict-Transport-Security' X-RateLimit-Limit: $ref: '#/components/headers/X-RateLimit-Limit' securitySchemes: BasicAuth: type: http scheme: basic