{
  "openapi": "3.0.0",
  "paths": {
    "/message": {
      "post": {
        "operationId": "sendMessage",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendMessage"
              },
              "examples": {
                "sms-text": {
                  "summary": "SMS Text",
                  "value": {
                    "clientRef": "order-123",
                    "recipientPhoneNumber": "15552223333",
                    "content": {
                      "sms": {
                        "content": "Your order is on its way."
                      }
                    }
                  }
                },
                "rcs-text": {
                  "summary": "RCS Text with SMS Fallback",
                  "value": {
                    "clientRef": "order-123",
                    "recipientPhoneNumber": "15552223333",
                    "content": {
                      "rcs": {
                        "content": {
                          "type": "TEXT",
                          "content": "Your order is on its way."
                        }
                      },
                      "sms": {
                        "content": "Your order is on its way."
                      }
                    }
                  }
                },
                "rich-card": {
                  "summary": "Rich Card",
                  "value": {
                    "clientRef": "order-123",
                    "recipientPhoneNumber": "15552223333",
                    "content": {
                      "rcs": {
                        "content": {
                          "type": "RICH_CARD",
                          "item": {
                            "title": "Your Order Is on Its Way",
                            "description": "Track your delivery for the latest updates."
                          }
                        }
                      }
                    }
                  }
                },
                "send-rich-card": {
                  "summary": "Send Rich Card Message",
                  "description": "Example of sending a rich card message with both RCS and SMS fallback",
                  "value": {
                    "clientRef": "61efac14-961c-4070-a369-04e16578e86f",
                    "recipientPhoneNumber": "15552223333",
                    "content": {
                      "rcs": {
                        "content": {
                          "type": "RICH_CARD",
                          "item": {
                            "title": "Blue Cotton T-Shirt",
                            "description": "Premium comfort with style. Available in S-XL sizes.",
                            "mediaUrl": "https://smobi-public-templates.s3.us-east-1.amazonaws.com/public/products/Product7.png",
                            "orientation": "VERTICAL",
                            "thumbnailPosition": "RIGHT",
                            "height": "SHORT",
                            "localSuggestions": []
                          },
                          "globalSuggestions": [
                            {
                              "id": "reply-1",
                              "text": "Reply to message",
                              "type": "REPLY"
                            },
                            {
                              "id": "url-1",
                              "text": "Visit our website",
                              "type": "OPEN_URL",
                              "url": "https://example.com"
                            },
                            {
                              "id": "phone-1",
                              "text": "Call support",
                              "type": "DIAL_PHONE",
                              "phoneNumber": "+12223334444"
                            },
                            {
                              "id": "location-1",
                              "text": "Show location",
                              "type": "SHOW_LOCATION",
                              "latitude": "37.7749",
                              "longitude": "-122.4194",
                              "label": "San Francisco"
                            }
                          ]
                        }
                      },
                      "sms": {
                        "content": "Check out our Blue Cotton T-Shirt! View it here: https://example.com/products/blue-tshirt. Need help? Reply to this message.",
                        "mediaUrl": "https://smobi-public-templates.s3.us-east-1.amazonaws.com/public/products/Product7.png"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Message accepted for processing. Delivery is reported asynchronously through status webhooks.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SendMessageResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request - Invalid request parameters",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Invalid phone number"
                    },
                    "error": {
                      "type": "string",
                      "example": "Bad Request"
                    },
                    "statusCode": {
                      "type": "number",
                      "example": 400
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Invalid API key"
                    },
                    "error": {
                      "type": "string",
                      "example": "Unauthorized"
                    },
                    "statusCode": {
                      "type": "number",
                      "example": 401
                    }
                  }
                }
              }
            }
          }
        },
        "summary": "Send a Message",
        "tags": [
          "Messaging"
        ],
        "security": [
          {
            "x-api-key": []
          }
        ],
        "description": "Send an SMS or RCS message to a customer. Include SMS content alongside RCS to provide a fallback when RCS is unavailable."
      }
    },
    "/check-channel-support/{phoneNumber}": {
      "post": {
        "operationId": "checkChannelSupport",
        "parameters": [
          {
            "name": "phoneNumber",
            "required": true,
            "in": "path",
            "description": "Phone number to check channel support for",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Channel support information retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CheckChannelCapabilityResponse"
                },
                "examples": {
                  "check-channel-support": {
                    "summary": "Check Channel Support",
                    "description": "Example of checking which channels are supported for a phone number",
                    "value": {
                      "rcs": false,
                      "sms": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request - Invalid phone number",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Invalid phone number"
                    },
                    "error": {
                      "type": "string",
                      "example": "Bad Request"
                    },
                    "statusCode": {
                      "type": "number",
                      "example": 400
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Invalid API key"
                    },
                    "error": {
                      "type": "string",
                      "example": "Unauthorized"
                    },
                    "statusCode": {
                      "type": "number",
                      "example": 401
                    }
                  }
                }
              }
            }
          }
        },
        "summary": "Check Channel Support",
        "tags": [
          "Messaging"
        ],
        "security": [
          {
            "x-api-key": []
          }
        ],
        "description": "Check whether a phone number supports RCS or SMS before choosing a channel. Requires a configured RCS agent. Creates or updates the customer capability record and records API usage."
      }
    },
    "/workflows/{workflowDefinitionId}/execute/{phoneNumber}": {
      "post": {
        "description": "Execute a workflow for a single phone number",
        "operationId": "executeSingle",
        "parameters": [
          {
            "name": "workflowDefinitionId",
            "required": true,
            "in": "path",
            "description": "ID of the workflow definition to execute",
            "schema": {
              "example": "wf_123e4567-e89b-12d3-a456-426614174000",
              "type": "string"
            }
          },
          {
            "name": "phoneNumber",
            "required": true,
            "in": "path",
            "description": "Phone number of the customer to execute the workflow for",
            "schema": {
              "example": "15552223333",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Single workflow execution request",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExecuteSingleWorkflow"
              },
              "examples": {
                "withoutVariables": {
                  "summary": "Without variables",
                  "description": "Execute workflow",
                  "value": {}
                },
                "withVariables": {
                  "summary": "With variables",
                  "description": "Execute workflow with variables",
                  "value": {
                    "variables": {
                      "customerName": "John Doe",
                      "orderId": "12345",
                      "discountCode": "SAVE20"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Single workflow execution result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExecuteSingleWorkflowResponse"
                },
                "example": {
                  "executionId": "run-123",
                  "success": true,
                  "channel": "RCS"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request - Invalid request parameters",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Invalid phone number format"
                    },
                    "error": {
                      "type": "string",
                      "example": "Bad Request"
                    },
                    "statusCode": {
                      "type": "number",
                      "example": 400
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Invalid API key"
                    },
                    "error": {
                      "type": "string",
                      "example": "Unauthorized"
                    },
                    "statusCode": {
                      "type": "number",
                      "example": 401
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found - Workflow not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Workflow not found"
                    },
                    "error": {
                      "type": "string",
                      "example": "Not Found"
                    },
                    "statusCode": {
                      "type": "number",
                      "example": 404
                    }
                  }
                }
              }
            }
          }
        },
        "summary": "Execute a Workflow",
        "tags": [
          "Workflows"
        ],
        "security": [
          {
            "x-api-key": []
          }
        ]
      }
    },
    "/workflows/family/{workflowFamilyId}/execute/{phoneNumber}": {
      "post": {
        "description": "Execute the current version of a workflow family for a single phone number",
        "operationId": "executeFamily",
        "parameters": [
          {
            "name": "workflowFamilyId",
            "required": true,
            "in": "path",
            "description": "ID of the workflow family to execute (will execute the current version)",
            "schema": {
              "example": "wf_123e4567-e89b-12d3-a456-426614174000",
              "type": "string"
            }
          },
          {
            "name": "phoneNumber",
            "required": true,
            "in": "path",
            "description": "Phone number of the customer to execute the workflow for",
            "schema": {
              "example": "15552223333",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Family workflow execution request",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExecuteFamilyWorkflow"
              },
              "examples": {
                "withoutVariables": {
                  "summary": "Without variables",
                  "description": "Execute current version of workflow family",
                  "value": {}
                },
                "withVariables": {
                  "summary": "With variables",
                  "description": "Execute current version of workflow family with variables",
                  "value": {
                    "variables": {
                      "customerName": "John Doe",
                      "orderId": "12345",
                      "discountCode": "SAVE20"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Family workflow execution result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExecuteFamilyWorkflowResponse"
                },
                "example": {
                  "executionId": "run-123",
                  "success": true,
                  "channel": "RCS"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request - Invalid request parameters",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Invalid phone number format"
                    },
                    "error": {
                      "type": "string",
                      "example": "Bad Request"
                    },
                    "statusCode": {
                      "type": "number",
                      "example": 400
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Invalid API key"
                    },
                    "error": {
                      "type": "string",
                      "example": "Unauthorized"
                    },
                    "statusCode": {
                      "type": "number",
                      "example": 401
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found - Workflow family not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Workflow family not found"
                    },
                    "error": {
                      "type": "string",
                      "example": "Not Found"
                    },
                    "statusCode": {
                      "type": "number",
                      "example": 404
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error - No current version set for workflow family",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "No current version set for workflow family"
                    },
                    "error": {
                      "type": "string",
                      "example": "Internal Server Error"
                    },
                    "statusCode": {
                      "type": "number",
                      "example": 500
                    }
                  }
                }
              }
            }
          }
        },
        "summary": "Execute the Current Workflow Version",
        "tags": [
          "Workflows"
        ],
        "security": [
          {
            "x-api-key": []
          }
        ]
      }
    },
    "/workflows/{workflowDefinitionId}/execute": {
      "post": {
        "description": "Triggers workflow execution for a batch of customers. \n    Maximum 25 executions per request.\n    For larger datasets, split into multiple requests.",
        "operationId": "executeBatch",
        "parameters": [
          {
            "name": "workflowDefinitionId",
            "required": true,
            "in": "path",
            "description": "Workflow definition identifier to execute",
            "schema": {
              "example": "wf_123e4567-e89b-12d3-a456-426614174000",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Workflow execution batch request",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "executions"
                ],
                "properties": {
                  "executions": {
                    "type": "array",
                    "description": "One to 25 executions. Duplicate phone-number strings in the same batch are rejected.",
                    "minItems": 1,
                    "maxItems": 25,
                    "items": {
                      "type": "object",
                      "required": [
                        "phoneNumber"
                      ],
                      "properties": {
                        "phoneNumber": {
                          "type": "string",
                          "description": "Phone number in E.164 format (+1234567890) or digits-only format (1234567890)",
                          "pattern": "^(^\\+[1-9]\\d{1,14}$|^[1-9]\\d{1,14}$)$",
                          "examples": [
                            "+14155552222",
                            "14155552222"
                          ]
                        },
                        "variables": {
                          "type": "object",
                          "description": "Variables for the workflow execution",
                          "additionalProperties": {
                            "type": "string"
                          },
                          "example": {
                            "customer.name": "John Doe",
                            "customer.phone": "15552223333",
                            "order.id": "12345"
                          }
                        },
                        "settings": {
                          "type": "object",
                          "description": "Accepted by request validation, but replaced with server-selected routing before the batch is queued. Omit this object. channelOverride is stripped and does not take effect for batches; use single execution for a supported override.",
                          "properties": {
                            "channel": {
                              "type": "string",
                              "enum": [
                                "SMS",
                                "RCS",
                                "MMS"
                              ],
                              "description": "Messaging channel."
                            },
                            "provider": {
                              "type": "string",
                              "enum": [
                                "VONAGE",
                                "VIBES",
                                "TWILIO"
                              ],
                              "description": "Messaging provider."
                            },
                            "agentId": {
                              "type": "string",
                              "description": "Agent identifier."
                            },
                            "agentReferenceId": {
                              "type": "string",
                              "description": "Agent reference identifier."
                            }
                          }
                        }
                      }
                    },
                    "example": [
                      {
                        "phoneNumber": "14155552222",
                        "variables": {
                          "customer.name": "John Doe",
                          "customer.phone": "15552223333",
                          "order.id": "12345"
                        }
                      }
                    ]
                  }
                }
              },
              "examples": {
                "withoutVariables": {
                  "summary": "Without variables",
                  "description": "Execute workflow for multiple customers",
                  "value": {
                    "executions": [
                      {
                        "phoneNumber": "15552223333"
                      },
                      {
                        "phoneNumber": "15552223334"
                      }
                    ]
                  }
                },
                "withVariables": {
                  "summary": "With variables",
                  "description": "Execute workflow for multiple customers with variables",
                  "value": {
                    "executions": [
                      {
                        "phoneNumber": "15552223333",
                        "variables": {
                          "customerName": "John Doe",
                          "orderId": "12345",
                          "discountCode": "SAVE20"
                        }
                      },
                      {
                        "phoneNumber": "15552223334",
                        "variables": {
                          "customerName": "Jane Smith",
                          "orderId": "67890",
                          "discountCode": "SAVE30"
                        }
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Batch accepted for processing",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExecuteWorkflowBatchResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request - batch size exceeded or validation error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "number",
                      "example": 400
                    },
                    "message": {
                      "type": "string",
                      "example": "Batch exceeds maximum allowed 25 executions. Split your request into smaller batches."
                    },
                    "error": {
                      "type": "string",
                      "example": "Bad Request"
                    },
                    "suggestion": {
                      "type": "string",
                      "example": "Split your request into smaller batches or use our bulk import API for large datasets."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid API key or missing authentication",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Invalid API key"
                    },
                    "error": {
                      "type": "string",
                      "example": "Unauthorized"
                    },
                    "statusCode": {
                      "type": "number",
                      "example": 401
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden - Insufficient permissions to access the workflow",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Access denied to workflow"
                    },
                    "error": {
                      "type": "string",
                      "example": "Forbidden"
                    },
                    "statusCode": {
                      "type": "number",
                      "example": 403
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found - Workflow not found or does not exist",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Workflow not found"
                    },
                    "error": {
                      "type": "string",
                      "example": "Not Found"
                    },
                    "statusCode": {
                      "type": "number",
                      "example": 404
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity - Workflow validation errors, circular dependencies, or invalid variable references",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Workflow validation failed"
                    },
                    "error": {
                      "type": "string",
                      "example": "Unprocessable Entity"
                    },
                    "statusCode": {
                      "type": "number",
                      "example": 422
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error - Unexpected server error during workflow execution",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Internal server error"
                    },
                    "error": {
                      "type": "string",
                      "example": "Internal Server Error"
                    },
                    "statusCode": {
                      "type": "number",
                      "example": 500
                    }
                  }
                }
              }
            }
          }
        },
        "summary": "Execute a Workflow Batch",
        "tags": [
          "Workflows"
        ],
        "security": [
          {
            "x-api-key": []
          }
        ]
      }
    },
    "/contacts": {
      "post": {
        "description": "Upserts by phone number: creates the contact if the phone number is new to your brand (201), otherwise applies the provided fields to the existing contact (200). Retries are safe. New contacts start with marketingConsent UNKNOWN — campaigns only send to OPTED_IN contacts, so set marketingConsent once you have collected consent.",
        "operationId": "upsertContact",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateContactDto"
              },
              "examples": {
                "minimal": {
                  "summary": "Minimal — phone only",
                  "description": "Creates the contact with marketingConsent UNKNOWN; set consent later once collected.",
                  "value": {
                    "phoneNumber": "+14155552222"
                  }
                },
                "signup-sync": {
                  "summary": "Sync a new signup with your attributes",
                  "description": "tags and customFields are usable in segment rules — store plans, cohorts, or your own user id here.",
                  "value": {
                    "phoneNumber": "+14155552222",
                    "firstName": "Jane",
                    "lastName": "Doe",
                    "email": "jane@example.com",
                    "tags": [
                      "beta",
                      "plan-pro"
                    ],
                    "customFields": {
                      "externalId": "user_8231",
                      "signupSource": "ios"
                    }
                  }
                },
                "with-consent": {
                  "summary": "Create with collected consent",
                  "description": "Setting OPTED_IN attests that you collected the contact's marketing consent — required before campaigns will send to them.",
                  "value": {
                    "phoneNumber": "+14155552222",
                    "firstName": "Jane",
                    "marketingConsent": "OPTED_IN"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Existing contact updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactDto"
                }
              }
            }
          },
          "201": {
            "description": "Contact created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactDto"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "number",
                      "example": 401
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid API key"
                    },
                    "error": {
                      "type": "string",
                      "example": "Unauthorized"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key is not scoped to a brand",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "number",
                      "example": 403
                    },
                    "message": {
                      "type": "string",
                      "example": "This endpoint requires a brand-scoped API key"
                    },
                    "error": {
                      "type": "string",
                      "example": "Forbidden"
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "Consent transition rejected: a contact that opted out (e.g. texted STOP) cannot be opted back in via the API",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "number",
                      "example": 422
                    },
                    "message": {
                      "type": "string",
                      "example": "Cannot opt in a contact that has opted out; the contact must opt back in themselves (e.g. by texting START)"
                    },
                    "error": {
                      "type": "string",
                      "example": "Unprocessable Entity"
                    }
                  }
                }
              }
            }
          }
        },
        "summary": "Create or Update a Contact",
        "tags": [
          "Contacts"
        ],
        "security": [
          {
            "x-api-key": []
          }
        ]
      },
      "get": {
        "description": "Cursor-paginated list of the brand's contacts, newest first. Archived contacts are hidden by default (status=active).",
        "operationId": "listContacts",
        "parameters": [
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "Default: active",
            "schema": {
              "enum": [
                "active",
                "archived",
                "all"
              ],
              "type": "string",
              "default": "active"
            }
          },
          {
            "name": "tag",
            "required": false,
            "in": "query",
            "description": "Filter by tag; repeat the parameter to require multiple tags",
            "schema": {
              "oneOf": [
                {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  }
                }
              ]
            }
          },
          {
            "name": "email",
            "required": false,
            "in": "query",
            "description": "Exact email lookup (case-insensitive)",
            "schema": {
              "type": "string",
              "format": "email"
            }
          },
          {
            "name": "phoneNumber",
            "required": false,
            "in": "query",
            "description": "Exact phone lookup (E.164 or digits-only)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "Opaque cursor from pagination.nextCursor",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "1-100, default 50",
            "schema": {
              "example": 50,
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of contacts",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactListResponseDto"
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameter or cursor"
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "number",
                      "example": 401
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid API key"
                    },
                    "error": {
                      "type": "string",
                      "example": "Unauthorized"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key is not scoped to a brand",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "number",
                      "example": 403
                    },
                    "message": {
                      "type": "string",
                      "example": "This endpoint requires a brand-scoped API key"
                    },
                    "error": {
                      "type": "string",
                      "example": "Forbidden"
                    }
                  }
                }
              }
            }
          }
        },
        "summary": "List Contacts",
        "tags": [
          "Contacts"
        ],
        "security": [
          {
            "x-api-key": []
          }
        ]
      }
    },
    "/contacts/bulk": {
      "post": {
        "description": "Upserts up to 100 contacts in one request. Items are processed independently: one failing item never aborts the batch — inspect per-item results. Duplicate phone numbers within a batch are rejected as a whole-request 400.",
        "operationId": "bulkUpsertContacts",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkContactsDto"
              },
              "examples": {
                "initial-import": {
                  "summary": "Initial import of your user base",
                  "description": "Chunk larger datasets into batches of 100; each request returns per-item results so you can retry only the failures.",
                  "value": {
                    "contacts": [
                      {
                        "phoneNumber": "+14155552222",
                        "firstName": "Jane",
                        "tags": [
                          "plan-pro"
                        ],
                        "marketingConsent": "OPTED_IN"
                      },
                      {
                        "phoneNumber": "+14155552223",
                        "firstName": "Sam",
                        "customFields": {
                          "externalId": "user_8232"
                        }
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Per-item results with summary counts",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BulkContactsResponseDto"
                },
                "example": {
                  "results": [
                    {
                      "index": 0,
                      "phoneNumber": "+14155552222",
                      "status": "created",
                      "id": "9b2f1c3e-8a4d-4f6b-9c2e-1d3f5a7b9c0e"
                    },
                    {
                      "index": 1,
                      "phoneNumber": "+14155552223",
                      "status": "created",
                      "id": "2c4d6e8f-1234-4567-89ab-123456789abc"
                    }
                  ],
                  "summary": {
                    "total": 2,
                    "created": 2,
                    "updated": 0,
                    "failed": 0
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error (bad envelope, batch too large, or duplicate phone numbers)"
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "number",
                      "example": 401
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid API key"
                    },
                    "error": {
                      "type": "string",
                      "example": "Unauthorized"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key is not scoped to a brand",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "number",
                      "example": 403
                    },
                    "message": {
                      "type": "string",
                      "example": "This endpoint requires a brand-scoped API key"
                    },
                    "error": {
                      "type": "string",
                      "example": "Forbidden"
                    }
                  }
                }
              }
            }
          }
        },
        "summary": "Create or Update Contacts in Bulk",
        "tags": [
          "Contacts"
        ],
        "security": [
          {
            "x-api-key": []
          }
        ]
      }
    },
    "/contacts/{identifier}": {
      "get": {
        "description": "Fetch a single contact by Smobi id or phone number.",
        "operationId": "getContact",
        "parameters": [
          {
            "name": "identifier",
            "required": true,
            "in": "path",
            "description": "Contact id (uuid) or phone number (digits-only recommended in URLs; E.164 requires encoding + as %2B)",
            "schema": {
              "example": "14155552222",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The contact",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactDto"
                }
              }
            }
          },
          "400": {
            "description": "Identifier is neither a uuid nor a phone number"
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "number",
                      "example": 401
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid API key"
                    },
                    "error": {
                      "type": "string",
                      "example": "Unauthorized"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key is not scoped to a brand",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "number",
                      "example": 403
                    },
                    "message": {
                      "type": "string",
                      "example": "This endpoint requires a brand-scoped API key"
                    },
                    "error": {
                      "type": "string",
                      "example": "Forbidden"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No contact with this id or phone number exists for the brand",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "number",
                      "example": 404
                    },
                    "message": {
                      "type": "string",
                      "example": "Contact not found"
                    },
                    "error": {
                      "type": "string",
                      "example": "Not Found"
                    }
                  }
                }
              }
            }
          }
        },
        "summary": "Get a Contact",
        "tags": [
          "Contacts"
        ],
        "security": [
          {
            "x-api-key": []
          }
        ]
      },
      "patch": {
        "description": "Partial update. Scalars: send a value to set it, null to clear it, omit to leave untouched. tags replaces the whole list; customFields merges per key (null deletes a key). phoneNumber is immutable. Set active=true to restore an archived contact.",
        "operationId": "updateContact",
        "parameters": [
          {
            "name": "identifier",
            "required": true,
            "in": "path",
            "description": "Contact id (uuid) or phone number (digits-only recommended in URLs; E.164 requires encoding + as %2B)",
            "schema": {
              "example": "14155552222",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateContactDto"
              },
              "examples": {
                "update-fields": {
                  "summary": "Update attributes",
                  "description": "tags replaces the whole list; customFields merges per key.",
                  "value": {
                    "tags": [
                      "plan-enterprise"
                    ],
                    "customFields": {
                      "seats": 25
                    }
                  }
                },
                "clear-data": {
                  "summary": "Clear personal data",
                  "description": "null clears a scalar field or deletes a customFields key — use before archiving to remove personal data.",
                  "value": {
                    "firstName": null,
                    "lastName": null,
                    "email": null,
                    "customFields": {
                      "externalId": null
                    }
                  }
                },
                "opt-out": {
                  "summary": "Suppress marketing",
                  "value": {
                    "marketingConsent": "OPTED_OUT"
                  }
                },
                "restore": {
                  "summary": "Restore an archived contact",
                  "value": {
                    "active": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated contact",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactDto"
                }
              }
            }
          },
          "400": {
            "description": "Validation error, empty body, or phoneNumber in body"
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "number",
                      "example": 401
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid API key"
                    },
                    "error": {
                      "type": "string",
                      "example": "Unauthorized"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key is not scoped to a brand",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "number",
                      "example": 403
                    },
                    "message": {
                      "type": "string",
                      "example": "This endpoint requires a brand-scoped API key"
                    },
                    "error": {
                      "type": "string",
                      "example": "Forbidden"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No contact with this id or phone number exists for the brand",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "number",
                      "example": 404
                    },
                    "message": {
                      "type": "string",
                      "example": "Contact not found"
                    },
                    "error": {
                      "type": "string",
                      "example": "Not Found"
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "Consent transition rejected: a contact that opted out (e.g. texted STOP) cannot be opted back in via the API",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "number",
                      "example": 422
                    },
                    "message": {
                      "type": "string",
                      "example": "Cannot opt in a contact that has opted out; the contact must opt back in themselves (e.g. by texting START)"
                    },
                    "error": {
                      "type": "string",
                      "example": "Unprocessable Entity"
                    }
                  }
                }
              }
            }
          }
        },
        "summary": "Update a Contact",
        "tags": [
          "Contacts"
        ],
        "security": [
          {
            "x-api-key": []
          }
        ]
      },
      "delete": {
        "description": "Archives the contact (soft delete): it is hidden from lists, excluded from campaign sends and segment syncs, and can be restored with PATCH {\"active\": true}. Idempotent — archiving an archived contact returns 204. Personal data can be cleared beforehand by PATCHing fields to null.",
        "operationId": "archiveContact",
        "parameters": [
          {
            "name": "identifier",
            "required": true,
            "in": "path",
            "description": "Contact id (uuid) or phone number (digits-only recommended in URLs; E.164 requires encoding + as %2B)",
            "schema": {
              "example": "14155552222",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Contact archived"
          },
          "400": {
            "description": "Identifier is neither a uuid nor a phone number"
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "number",
                      "example": 401
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid API key"
                    },
                    "error": {
                      "type": "string",
                      "example": "Unauthorized"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key is not scoped to a brand",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "number",
                      "example": 403
                    },
                    "message": {
                      "type": "string",
                      "example": "This endpoint requires a brand-scoped API key"
                    },
                    "error": {
                      "type": "string",
                      "example": "Forbidden"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No contact with this id or phone number exists for the brand",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "number",
                      "example": 404
                    },
                    "message": {
                      "type": "string",
                      "example": "Contact not found"
                    },
                    "error": {
                      "type": "string",
                      "example": "Not Found"
                    }
                  }
                }
              }
            }
          }
        },
        "summary": "Archive a Contact",
        "tags": [
          "Contacts"
        ],
        "security": [
          {
            "x-api-key": []
          }
        ]
      }
    }
  },
  "info": {
    "title": "Smobi Messaging API",
    "description": "Smobi public API for messaging, contacts and workflow execution. Send a brand-scoped x-api-key header with every request. Guides: /docs. Outbound webhook payloads: /docs/guides/webhooks.",
    "version": "1.0",
    "contact": {}
  },
  "tags": [
    {
      "name": "Contacts",
      "description": "Create and manage your contact base: upsert by phone number, attach tags and custom fields (both usable in segment rules), control marketing consent, and archive contacts to exclude them from campaigns."
    }
  ],
  "servers": [
    {
      "url": "https://api.smobi.com/v1",
      "description": "Current API version (v1)"
    }
  ],
  "components": {
    "securitySchemes": {
      "x-api-key": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "API key for authentication"
      }
    },
    "schemas": {
      "RcsContent": {
        "type": "object",
        "properties": {
          "content": {
            "description": "Rendered RCS message content",
            "oneOf": [
              {
                "$ref": "#/components/schemas/TextMessage"
              },
              {
                "$ref": "#/components/schemas/ContentMessage"
              },
              {
                "$ref": "#/components/schemas/RichCardMessage"
              },
              {
                "$ref": "#/components/schemas/CarouselMessage"
              }
            ]
          }
        },
        "required": [
          "content"
        ]
      },
      "SmsContent": {
        "type": "object",
        "properties": {
          "content": {
            "type": "string",
            "description": "Content of the SMS message. Optional if mediaUrl is provided (content becomes caption).",
            "example": "Hello, this is your message text",
            "minLength": 1
          },
          "mediaUrl": {
            "type": "string",
            "description": "Optional media URL. When provided, content becomes the caption for the media.",
            "example": "https://example.com/image.jpg"
          }
        },
        "description": "Provide non-empty text content, a media URL, or both. When media is supplied, text is the caption.",
        "anyOf": [
          {
            "title": "SMS Text",
            "required": [
              "content"
            ]
          },
          {
            "title": "SMS Media",
            "required": [
              "mediaUrl"
            ],
            "properties": {
              "mediaUrl": {
                "minLength": 1
              }
            }
          }
        ]
      },
      "RenderedTemplateContent": {
        "type": "object",
        "properties": {
          "rcs": {
            "description": "Rendered RCS content, used if RCS is supported by the recipientPhoneNumber.",
            "allOf": [
              {
                "$ref": "#/components/schemas/RcsContent"
              }
            ]
          },
          "sms": {
            "description": "SMS text or media, also used as an RCS fallback. Provide non-empty text, a media URL, or both. Select a variant to inspect its required fields.",
            "allOf": [
              {
                "$ref": "#/components/schemas/SmsContent"
              }
            ]
          }
        },
        "required": [],
        "additionalProperties": false,
        "description": "Message content for RCS, SMS, or both. Supply content for at least one configured channel. RCS is not required for SMS-only messages."
      },
      "SendMessage": {
        "type": "object",
        "properties": {
          "clientRef": {
            "type": "string",
            "description": "Client reference ID",
            "example": "client-ref-123"
          },
          "recipientPhoneNumber": {
            "type": "string",
            "description": "Recipient phone number, string of all digits, for example, 12223334444",
            "example": "15552223333"
          },
          "content": {
            "description": "Message content",
            "example": {
              "rcs": {
                "content": {
                  "type": "TEXT",
                  "content": "Hello, world!",
                  "globalSuggestions": [
                    {
                      "type": "REPLY",
                      "text": "Reply",
                      "id": "reply-1"
                    }
                  ]
                }
              },
              "sms": {
                "content": "Check out this image!",
                "mediaUrl": "https://example.com/image.jpg"
              }
            },
            "allOf": [
              {
                "$ref": "#/components/schemas/RenderedTemplateContent"
              }
            ]
          }
        },
        "required": [
          "clientRef",
          "recipientPhoneNumber",
          "content"
        ]
      },
      "SendMessageResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "description": "Status of the message processing",
            "example": "PROCESSING"
          },
          "smobiMessageId": {
            "type": "string",
            "description": "Unique identifier for the message in Smobi system",
            "example": "123e4567-e89b-12d3-a456-426614174000"
          }
        },
        "required": [
          "status",
          "smobiMessageId"
        ]
      },
      "CheckChannelCapabilityResponse": {
        "type": "object",
        "properties": {
          "rcs": {
            "type": "boolean",
            "description": "Whether the channel supports RCS",
            "example": true
          },
          "sms": {
            "type": "boolean",
            "description": "Whether the channel supports SMS",
            "example": true
          }
        },
        "required": [
          "rcs",
          "sms"
        ]
      },
      "WorkflowExecutionSettings": {
        "type": "object",
        "properties": {
          "channelOverride": {
            "type": "string",
            "description": "Channel override for the workflow execution",
            "enum": [
              "RCS",
              "SMS"
            ],
            "example": "RCS"
          }
        }
      },
      "ExecuteSingleWorkflow": {
        "type": "object",
        "properties": {
          "variables": {
            "type": "object",
            "description": "Map of workflow variable names to string values. Keys must match the selected workflow. Omit when no variables are needed.",
            "example": {
              "customerName": "John Doe",
              "orderId": "12345",
              "discountCode": "SAVE20"
            },
            "additionalProperties": {
              "type": "string"
            }
          },
          "settings": {
            "description": "Workflow execution settings including channel overrides",
            "example": {
              "channelOverride": "RCS"
            },
            "allOf": [
              {
                "$ref": "#/components/schemas/WorkflowExecutionSettings"
              }
            ]
          }
        }
      },
      "ExecuteSingleWorkflowResponse": {
        "type": "object",
        "properties": {
          "executionId": {
            "type": "string",
            "description": "Generated workflow run ID",
            "example": "run-123"
          },
          "success": {
            "type": "boolean",
            "description": "Whether the execution was successful",
            "example": true
          },
          "channel": {
            "type": "string",
            "description": "Channel that will be used for message delivery (RCS, SMS, or MMS)",
            "example": "RCS"
          },
          "error": {
            "type": "string",
            "description": "Error message if execution failed",
            "example": "Invalid phone number"
          },
          "errorCode": {
            "type": "string",
            "description": "Error code if execution failed",
            "enum": [
              "INVALID_ARGUMENT",
              "RESOURCE_EXHAUSTED",
              "WORKFLOW_ALREADY_STARTED",
              "PAYLOAD_CONVERSION",
              "UNKNOWN",
              "WORKFLOW_NOT_FOUND",
              "SAVE_FAILED",
              "PREPARATION_FAILED",
              "USER_ENGAGED"
            ]
          },
          "details": {
            "type": "object",
            "description": "Error-specific diagnostic object. Keys and value types vary by failure; no fixed set of properties is guaranteed.",
            "additionalProperties": true,
            "example": {
              "workflowStatus": "DRAFT",
              "requiredStatus": "ACTIVE"
            }
          }
        },
        "required": [
          "success"
        ]
      },
      "ExecuteFamilyWorkflow": {
        "type": "object",
        "properties": {
          "variables": {
            "type": "object",
            "description": "Map of workflow variable names to string values. Keys must match the selected workflow. Omit when no variables are needed.",
            "example": {
              "customerName": "John Doe",
              "orderId": "12345",
              "discountCode": "SAVE20"
            },
            "additionalProperties": {
              "type": "string"
            }
          },
          "settings": {
            "description": "Workflow execution settings including channel overrides",
            "example": {
              "channelOverride": "RCS"
            },
            "allOf": [
              {
                "$ref": "#/components/schemas/WorkflowExecutionSettings"
              }
            ]
          }
        }
      },
      "ExecuteFamilyWorkflowResponse": {
        "type": "object",
        "properties": {
          "executionId": {
            "type": "string",
            "description": "Generated workflow run ID",
            "example": "run-123"
          },
          "success": {
            "type": "boolean",
            "description": "Whether the execution was successful",
            "example": true
          },
          "channel": {
            "type": "string",
            "description": "Channel that will be used for message delivery (RCS, SMS, or MMS)",
            "example": "RCS"
          },
          "error": {
            "type": "string",
            "description": "Error message if execution failed",
            "example": "Invalid phone number"
          },
          "errorCode": {
            "type": "string",
            "description": "Error code if execution failed",
            "enum": [
              "INVALID_ARGUMENT",
              "RESOURCE_EXHAUSTED",
              "WORKFLOW_ALREADY_STARTED",
              "PAYLOAD_CONVERSION",
              "UNKNOWN",
              "WORKFLOW_NOT_FOUND",
              "SAVE_FAILED",
              "PREPARATION_FAILED",
              "USER_ENGAGED"
            ]
          },
          "details": {
            "type": "object",
            "description": "Error-specific diagnostic object. Keys and value types vary by failure; no fixed set of properties is guaranteed.",
            "additionalProperties": true,
            "example": {
              "workflowStatus": "DRAFT",
              "requiredStatus": "ACTIVE"
            }
          }
        },
        "required": [
          "success"
        ]
      },
      "BatchExecutionResponseItem": {
        "type": "object",
        "properties": {
          "phoneNumber": {
            "type": "string",
            "description": "Phone number for this execution",
            "example": "15552223333"
          },
          "executionId": {
            "type": "string",
            "description": "Generated execution ID for this workflow run",
            "example": "123e4567-e89b-12d3-a456-426614174000"
          },
          "channel": {
            "type": "string",
            "description": "Channel that will be used for message delivery (RCS, SMS, or MMS)",
            "example": "RCS"
          }
        },
        "required": [
          "phoneNumber",
          "executionId"
        ]
      },
      "ExecuteWorkflowBatchResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Whether the batch was successfully queued",
            "example": true
          },
          "executions": {
            "description": "List of executions with their generated IDs",
            "example": [
              {
                "phoneNumber": "15552223333",
                "executionId": "123e4567-e89b-12d3-a456-426614174000"
              },
              {
                "phoneNumber": "15552223334",
                "executionId": "987fcdeb-51a2-43d7-8f9e-123456789abc"
              }
            ],
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BatchExecutionResponseItem"
            }
          }
        },
        "required": [
          "success",
          "executions"
        ]
      },
      "CreateContactDto": {
        "type": "object",
        "properties": {
          "phoneNumber": {
            "type": "string",
            "example": "+14155552222",
            "description": "E.164 (+1234567890) or digits-only (1234567890) format"
          },
          "firstName": {
            "type": "string",
            "example": "Jane",
            "nullable": true,
            "minLength": 1,
            "maxLength": 255
          },
          "lastName": {
            "type": "string",
            "example": "Doe",
            "nullable": true,
            "minLength": 1,
            "maxLength": 255
          },
          "email": {
            "type": "string",
            "example": "jane@example.com",
            "nullable": true,
            "format": "email",
            "maxLength": 255
          },
          "state": {
            "type": "string",
            "example": "CA",
            "nullable": true,
            "minLength": 1,
            "maxLength": 255
          },
          "country": {
            "type": "string",
            "example": "US",
            "nullable": true,
            "minLength": 1,
            "maxLength": 255
          },
          "dob": {
            "type": "string",
            "example": "1990-04-12",
            "description": "Date of birth in YYYY-MM-DD format. Must be a valid date in the past; null clears the value.",
            "nullable": true,
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "gender": {
            "type": "string",
            "nullable": true,
            "minLength": 1,
            "maxLength": 255
          },
          "preferredLanguage": {
            "type": "string",
            "example": "en",
            "nullable": true,
            "minLength": 1,
            "maxLength": 255
          },
          "tags": {
            "example": [
              "vip"
            ],
            "description": "Full replace on updates; usable in segment rules",
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 100
            },
            "maxItems": 100
          },
          "customFields": {
            "type": "object",
            "additionalProperties": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 1000,
                  "nullable": true
                },
                {
                  "type": "number"
                },
                {
                  "type": "boolean"
                },
                {
                  "type": "array",
                  "maxItems": 100,
                  "items": {
                    "type": "string",
                    "maxLength": 1000
                  }
                }
              ]
            },
            "example": {
              "loyaltyTier": "gold"
            },
            "description": "Map of up to 50 fields. Values may be strings (up to 1,000 characters), numbers, booleans, arrays of up to 100 strings, or null. Nested objects are not accepted. Keys must match ^[a-zA-Z_][a-zA-Z0-9_]{0,63}$; `__proto__`, `constructor`, and `prototype` are reserved. A null value deletes that key on update.",
            "maxProperties": 50
          },
          "marketingConsent": {
            "type": "string",
            "enum": [
              "OPTED_IN",
              "OPTED_OUT"
            ],
            "description": "Setting OPTED_IN attests that you collected the contact's marketing consent. OPTED_IN is rejected (422) when the contact previously opted out (e.g. texted STOP); OPTED_OUT is always accepted. Contacts default to UNKNOWN, and campaigns only send to OPTED_IN contacts."
          }
        },
        "required": [
          "phoneNumber"
        ],
        "additionalProperties": false
      },
      "ContactMarketingConsentDto": {
        "type": "object",
        "properties": {
          "channel": {
            "type": "string",
            "enum": [
              "MOBILE"
            ],
            "example": "MOBILE"
          },
          "status": {
            "type": "string",
            "enum": [
              "UNKNOWN",
              "SENT",
              "OPTED_IN",
              "OPTED_OUT"
            ],
            "example": "OPTED_IN",
            "description": "Campaigns are only sent to OPTED_IN contacts. Contacts created via the API start as UNKNOWN until consent is set."
          },
          "updatedAt": {
            "type": "string",
            "nullable": true,
            "example": "2026-07-07T12:00:00.000Z"
          }
        },
        "required": [
          "channel",
          "status",
          "updatedAt"
        ]
      },
      "ContactDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "9b2f1c3e-8a4d-4f6b-9c2e-1d3f5a7b9c0e"
          },
          "phoneNumber": {
            "type": "string",
            "example": "+14155552222",
            "description": "Always returned in E.164 format"
          },
          "active": {
            "type": "boolean",
            "example": true,
            "description": "false when the contact has been archived (DELETE)"
          },
          "firstName": {
            "type": "string",
            "nullable": true,
            "example": "Jane"
          },
          "lastName": {
            "type": "string",
            "nullable": true,
            "example": "Doe"
          },
          "email": {
            "type": "string",
            "nullable": true,
            "example": "jane@example.com"
          },
          "state": {
            "type": "string",
            "nullable": true,
            "example": "CA"
          },
          "country": {
            "type": "string",
            "nullable": true,
            "example": "US"
          },
          "dob": {
            "type": "string",
            "nullable": true,
            "example": "1990-04-12",
            "description": "Date of birth (YYYY-MM-DD)"
          },
          "gender": {
            "type": "string",
            "nullable": true,
            "example": null
          },
          "preferredLanguage": {
            "type": "string",
            "nullable": true,
            "example": "en"
          },
          "tags": {
            "example": [
              "vip",
              "spring-sale"
            ],
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "customFields": {
            "type": "object",
            "additionalProperties": true,
            "example": {
              "loyaltyTier": "gold",
              "storeIds": [
                "s1",
                "s2"
              ]
            },
            "description": "Stored custom-field values keyed by field name. See create/update request schemas for accepted write types and limits."
          },
          "marketingConsent": {
            "$ref": "#/components/schemas/ContactMarketingConsentDto"
          },
          "createdAt": {
            "type": "string",
            "example": "2026-07-07T12:00:00.000Z"
          },
          "updatedAt": {
            "type": "string",
            "example": "2026-07-07T12:00:00.000Z"
          }
        },
        "required": [
          "id",
          "phoneNumber",
          "active",
          "firstName",
          "lastName",
          "email",
          "state",
          "country",
          "dob",
          "gender",
          "preferredLanguage",
          "tags",
          "customFields",
          "marketingConsent",
          "createdAt",
          "updatedAt"
        ]
      },
      "BulkContactsDto": {
        "type": "object",
        "properties": {
          "contacts": {
            "description": "1-100 contacts; duplicate phone numbers in one batch are rejected",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreateContactDto"
            },
            "minItems": 1,
            "maxItems": 100
          }
        },
        "required": [
          "contacts"
        ],
        "additionalProperties": false
      },
      "BulkContactItemResultDto": {
        "type": "object",
        "properties": {
          "index": {
            "type": "number",
            "example": 0
          },
          "phoneNumber": {
            "type": "string",
            "example": "+14155552222"
          },
          "status": {
            "type": "string",
            "enum": [
              "created",
              "updated",
              "error"
            ]
          },
          "id": {
            "type": "string",
            "example": "9b2f1c3e-8a4d-4f6b-9c2e-1d3f5a7b9c0e"
          },
          "error": {
            "type": "string",
            "example": "Cannot opt in a contact that has opted out; the contact must opt back in themselves (e.g. by texting START)"
          }
        },
        "required": [
          "index",
          "phoneNumber",
          "status"
        ]
      },
      "BulkContactsSummaryDto": {
        "type": "object",
        "properties": {
          "total": {
            "type": "number",
            "example": 3
          },
          "created": {
            "type": "number",
            "example": 2
          },
          "updated": {
            "type": "number",
            "example": 0
          },
          "failed": {
            "type": "number",
            "example": 1
          }
        },
        "required": [
          "total",
          "created",
          "updated",
          "failed"
        ]
      },
      "BulkContactsResponseDto": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkContactItemResultDto"
            }
          },
          "summary": {
            "$ref": "#/components/schemas/BulkContactsSummaryDto"
          }
        },
        "required": [
          "results",
          "summary"
        ]
      },
      "ContactListPaginationDto": {
        "type": "object",
        "properties": {
          "limit": {
            "type": "number",
            "example": 50
          },
          "hasMore": {
            "type": "boolean",
            "example": true
          },
          "nextCursor": {
            "type": "string",
            "nullable": true,
            "example": "eyJjIjoiMjAyNi0wNy0wN1QxMjowMDowMC4wMDBaIiwiaSI6IjliMmYifQ",
            "description": "Opaque cursor for the next page; null on the last page"
          }
        },
        "required": [
          "limit",
          "hasMore",
          "nextCursor"
        ]
      },
      "ContactListResponseDto": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ContactDto"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/ContactListPaginationDto"
          }
        },
        "required": [
          "data",
          "pagination"
        ]
      },
      "UpdateContactDto": {
        "type": "object",
        "properties": {
          "firstName": {
            "type": "string",
            "example": "Jane",
            "nullable": true,
            "minLength": 1,
            "maxLength": 255
          },
          "lastName": {
            "type": "string",
            "example": "Doe",
            "nullable": true,
            "minLength": 1,
            "maxLength": 255
          },
          "email": {
            "type": "string",
            "example": "jane@example.com",
            "nullable": true,
            "format": "email",
            "maxLength": 255
          },
          "state": {
            "type": "string",
            "example": "CA",
            "nullable": true,
            "minLength": 1,
            "maxLength": 255
          },
          "country": {
            "type": "string",
            "example": "US",
            "nullable": true,
            "minLength": 1,
            "maxLength": 255
          },
          "dob": {
            "type": "string",
            "example": "1990-04-12",
            "description": "Date of birth in YYYY-MM-DD format. Must be a valid date in the past; null clears the value.",
            "nullable": true,
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "gender": {
            "type": "string",
            "nullable": true,
            "minLength": 1,
            "maxLength": 255
          },
          "preferredLanguage": {
            "type": "string",
            "example": "en",
            "nullable": true,
            "minLength": 1,
            "maxLength": 255
          },
          "tags": {
            "example": [
              "vip"
            ],
            "description": "Full replace on updates; usable in segment rules",
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 100
            },
            "maxItems": 100
          },
          "customFields": {
            "type": "object",
            "additionalProperties": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 1000,
                  "nullable": true
                },
                {
                  "type": "number"
                },
                {
                  "type": "boolean"
                },
                {
                  "type": "array",
                  "maxItems": 100,
                  "items": {
                    "type": "string",
                    "maxLength": 1000
                  }
                }
              ]
            },
            "example": {
              "loyaltyTier": "gold"
            },
            "description": "Map of up to 50 fields. Values may be strings (up to 1,000 characters), numbers, booleans, arrays of up to 100 strings, or null. Nested objects are not accepted. Keys must match ^[a-zA-Z_][a-zA-Z0-9_]{0,63}$; `__proto__`, `constructor`, and `prototype` are reserved. A null value deletes that key on update.",
            "maxProperties": 50
          },
          "marketingConsent": {
            "type": "string",
            "enum": [
              "OPTED_IN",
              "OPTED_OUT"
            ],
            "description": "Setting OPTED_IN attests that you collected the contact's marketing consent. OPTED_IN is rejected (422) when the contact previously opted out (e.g. texted STOP); OPTED_OUT is always accepted. Contacts default to UNKNOWN, and campaigns only send to OPTED_IN contacts."
          },
          "active": {
            "type": "boolean",
            "example": true,
            "description": "Set true to restore an archived contact"
          }
        },
        "additionalProperties": false,
        "minProperties": 1
      },
      "BaseAction": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique identifier for the action",
            "minLength": 1
          },
          "text": {
            "type": "string",
            "description": "Text to display for the action, Maximum 25 characters",
            "minLength": 1,
            "maxLength": 25
          },
          "type": {
            "type": "string",
            "enum": [
              "REPLY",
              "OPEN_URL",
              "DIAL_PHONE",
              "SHOW_LOCATION",
              "REQUEST_LOCATION",
              "CALENDAR_EVENT"
            ],
            "description": "Type of action"
          }
        },
        "required": [
          "id",
          "text",
          "type"
        ]
      },
      "BaseMessage": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "TEXT",
              "CONTENT",
              "RICH_CARD",
              "CAROUSEL"
            ],
            "description": "Type of message"
          },
          "globalSuggestions": {
            "type": "array",
            "description": "Global suggestions associated with the message. Limit 11 suggestions, max 25 characters each.",
            "items": {
              "oneOf": [
                {
                  "$ref": "#/components/schemas/ReplyAction"
                },
                {
                  "$ref": "#/components/schemas/OpenUrlAction"
                },
                {
                  "$ref": "#/components/schemas/DialPhoneAction"
                },
                {
                  "$ref": "#/components/schemas/ShowLocationAction"
                },
                {
                  "$ref": "#/components/schemas/RequestLocationAction"
                },
                {
                  "$ref": "#/components/schemas/CalendarEventAction"
                }
              ],
              "discriminator": {
                "propertyName": "type",
                "mapping": {
                  "REPLY": "#/components/schemas/ReplyAction",
                  "OPEN_URL": "#/components/schemas/OpenUrlAction",
                  "DIAL_PHONE": "#/components/schemas/DialPhoneAction",
                  "SHOW_LOCATION": "#/components/schemas/ShowLocationAction",
                  "REQUEST_LOCATION": "#/components/schemas/RequestLocationAction",
                  "CALENDAR_EVENT": "#/components/schemas/CalendarEventAction"
                }
              }
            },
            "maxItems": 11
          }
        },
        "required": [
          "type"
        ]
      },
      "TextMessage": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "TEXT"
            ],
            "description": "Type of message"
          },
          "globalSuggestions": {
            "type": "array",
            "description": "Global suggestions associated with the message. Limit 11 suggestions, max 25 characters each.",
            "items": {
              "oneOf": [
                {
                  "$ref": "#/components/schemas/ReplyAction"
                },
                {
                  "$ref": "#/components/schemas/OpenUrlAction"
                },
                {
                  "$ref": "#/components/schemas/DialPhoneAction"
                },
                {
                  "$ref": "#/components/schemas/ShowLocationAction"
                },
                {
                  "$ref": "#/components/schemas/RequestLocationAction"
                },
                {
                  "$ref": "#/components/schemas/CalendarEventAction"
                }
              ],
              "discriminator": {
                "propertyName": "type",
                "mapping": {
                  "REPLY": "#/components/schemas/ReplyAction",
                  "OPEN_URL": "#/components/schemas/OpenUrlAction",
                  "DIAL_PHONE": "#/components/schemas/DialPhoneAction",
                  "SHOW_LOCATION": "#/components/schemas/ShowLocationAction",
                  "REQUEST_LOCATION": "#/components/schemas/RequestLocationAction",
                  "CALENDAR_EVENT": "#/components/schemas/CalendarEventAction"
                }
              }
            },
            "maxItems": 11
          },
          "content": {
            "type": "string",
            "description": "Text content of the message",
            "minLength": 1
          }
        },
        "required": [
          "type",
          "content"
        ]
      },
      "ContentMessage": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "CONTENT"
            ],
            "description": "Type of message"
          },
          "globalSuggestions": {
            "type": "array",
            "description": "Global suggestions associated with the message. Limit 11 suggestions, max 25 characters each.",
            "items": {
              "oneOf": [
                {
                  "$ref": "#/components/schemas/ReplyAction"
                },
                {
                  "$ref": "#/components/schemas/OpenUrlAction"
                },
                {
                  "$ref": "#/components/schemas/DialPhoneAction"
                },
                {
                  "$ref": "#/components/schemas/ShowLocationAction"
                },
                {
                  "$ref": "#/components/schemas/RequestLocationAction"
                },
                {
                  "$ref": "#/components/schemas/CalendarEventAction"
                }
              ],
              "discriminator": {
                "propertyName": "type",
                "mapping": {
                  "REPLY": "#/components/schemas/ReplyAction",
                  "OPEN_URL": "#/components/schemas/OpenUrlAction",
                  "DIAL_PHONE": "#/components/schemas/DialPhoneAction",
                  "SHOW_LOCATION": "#/components/schemas/ShowLocationAction",
                  "REQUEST_LOCATION": "#/components/schemas/RequestLocationAction",
                  "CALENDAR_EVENT": "#/components/schemas/CalendarEventAction"
                }
              }
            },
            "maxItems": 11
          },
          "contentUrl": {
            "type": "string",
            "description": "The publicly accessible URL of the file, for example, https://www.example.com/content.jpg",
            "minLength": 1
          }
        },
        "required": [
          "type",
          "contentUrl"
        ]
      },
      "RichCardBaseMessage": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "description": "Title of the rich card, Maximum 200 characters",
            "minLength": 1
          },
          "description": {
            "type": "string",
            "description": "Description of the rich card, Maximum 2000 characters"
          },
          "mediaUrl": {
            "type": "string",
            "description": "The publicly accessible URL of the image attachment. Supported types are .jpg, .jpeg, and .png"
          },
          "orientation": {
            "type": "string",
            "enum": [
              "VERTICAL",
              "HORIZONTAL"
            ],
            "description": "Orientation of the rich card"
          },
          "thumbnailPosition": {
            "type": "string",
            "enum": [
              "LEFT",
              "RIGHT"
            ],
            "description": "Position of the thumbnail"
          },
          "height": {
            "type": "string",
            "enum": [
              "SHORT",
              "MEDIUM",
              "TALL"
            ],
            "description": "Height of the rich card"
          },
          "localSuggestions": {
            "type": "array",
            "description": "Local suggestions associated with the rich card. Limit 4 suggestions, max 25 characters each.",
            "items": {
              "oneOf": [
                {
                  "$ref": "#/components/schemas/ReplyAction"
                },
                {
                  "$ref": "#/components/schemas/OpenUrlAction"
                },
                {
                  "$ref": "#/components/schemas/DialPhoneAction"
                },
                {
                  "$ref": "#/components/schemas/ShowLocationAction"
                },
                {
                  "$ref": "#/components/schemas/RequestLocationAction"
                },
                {
                  "$ref": "#/components/schemas/CalendarEventAction"
                }
              ],
              "discriminator": {
                "propertyName": "type",
                "mapping": {
                  "REPLY": "#/components/schemas/ReplyAction",
                  "OPEN_URL": "#/components/schemas/OpenUrlAction",
                  "DIAL_PHONE": "#/components/schemas/DialPhoneAction",
                  "SHOW_LOCATION": "#/components/schemas/ShowLocationAction",
                  "REQUEST_LOCATION": "#/components/schemas/RequestLocationAction",
                  "CALENDAR_EVENT": "#/components/schemas/CalendarEventAction"
                }
              }
            },
            "maxItems": 4
          }
        },
        "required": [
          "title"
        ]
      },
      "RichCardMessage": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "RICH_CARD"
            ],
            "description": "Type of message"
          },
          "globalSuggestions": {
            "type": "array",
            "description": "Global suggestions associated with the message. Limit 11 suggestions, max 25 characters each.",
            "items": {
              "oneOf": [
                {
                  "$ref": "#/components/schemas/ReplyAction"
                },
                {
                  "$ref": "#/components/schemas/OpenUrlAction"
                },
                {
                  "$ref": "#/components/schemas/DialPhoneAction"
                },
                {
                  "$ref": "#/components/schemas/ShowLocationAction"
                },
                {
                  "$ref": "#/components/schemas/RequestLocationAction"
                },
                {
                  "$ref": "#/components/schemas/CalendarEventAction"
                }
              ],
              "discriminator": {
                "propertyName": "type",
                "mapping": {
                  "REPLY": "#/components/schemas/ReplyAction",
                  "OPEN_URL": "#/components/schemas/OpenUrlAction",
                  "DIAL_PHONE": "#/components/schemas/DialPhoneAction",
                  "SHOW_LOCATION": "#/components/schemas/ShowLocationAction",
                  "REQUEST_LOCATION": "#/components/schemas/RequestLocationAction",
                  "CALENDAR_EVENT": "#/components/schemas/CalendarEventAction"
                }
              }
            },
            "maxItems": 11
          },
          "item": {
            "description": "Rich card content",
            "allOf": [
              {
                "$ref": "#/components/schemas/RichCardBaseMessage"
              }
            ]
          }
        },
        "required": [
          "type",
          "item"
        ]
      },
      "CarouselMessage": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "CAROUSEL"
            ],
            "description": "Type of message"
          },
          "globalSuggestions": {
            "type": "array",
            "description": "Global suggestions associated with the message. Limit 11 suggestions, max 25 characters each.",
            "items": {
              "oneOf": [
                {
                  "$ref": "#/components/schemas/ReplyAction"
                },
                {
                  "$ref": "#/components/schemas/OpenUrlAction"
                },
                {
                  "$ref": "#/components/schemas/DialPhoneAction"
                },
                {
                  "$ref": "#/components/schemas/ShowLocationAction"
                },
                {
                  "$ref": "#/components/schemas/RequestLocationAction"
                },
                {
                  "$ref": "#/components/schemas/CalendarEventAction"
                }
              ],
              "discriminator": {
                "propertyName": "type",
                "mapping": {
                  "REPLY": "#/components/schemas/ReplyAction",
                  "OPEN_URL": "#/components/schemas/OpenUrlAction",
                  "DIAL_PHONE": "#/components/schemas/DialPhoneAction",
                  "SHOW_LOCATION": "#/components/schemas/ShowLocationAction",
                  "REQUEST_LOCATION": "#/components/schemas/RequestLocationAction",
                  "CALENDAR_EVENT": "#/components/schemas/CalendarEventAction"
                }
              }
            },
            "maxItems": 11
          },
          "width": {
            "type": "string",
            "enum": [
              "SMALL",
              "MEDIUM"
            ],
            "description": "Width of the carousel"
          },
          "items": {
            "type": "array",
            "description": "Items in the carousel",
            "items": {
              "$ref": "#/components/schemas/RichCardBaseMessage"
            },
            "minItems": 2,
            "maxItems": 10
          }
        },
        "required": [
          "type",
          "width",
          "items"
        ]
      },
      "WebhookStatusReasonV1": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string",
            "description": "The reason for the status",
            "enum": [
              "REJECTED",
              "OPTED_OUT",
              "UNDELIVERABLE"
            ],
            "example": "REJECTED"
          },
          "description": {
            "type": "string",
            "description": "The description of the status reason",
            "example": "Resource size is too large"
          }
        },
        "required": [
          "reason"
        ]
      },
      "OutboundStatusV1": {
        "type": "object",
        "properties": {
          "smobiMessageId": {
            "type": "string",
            "description": "The reference number of the message in the Smobi system",
            "example": "123e4567-e89b-12d3-a456-426614174000"
          },
          "clientRef": {
            "type": "string",
            "description": "The reference number of the message in the client system",
            "example": "client-ref-123"
          },
          "to": {
            "type": "string",
            "description": "The phone number of the recipient",
            "example": "15552223333"
          },
          "from": {
            "type": "string",
            "description": "The phone number of the sender",
            "example": "15551234567"
          },
          "status": {
            "type": "string",
            "description": "The status of the message",
            "enum": [
              "PROCESSING",
              "SENT",
              "FAILED",
              "DELIVERED",
              "READ"
            ],
            "example": "DELIVERED"
          },
          "channel": {
            "type": "string",
            "description": "The channel of the message",
            "enum": [
              "SMS",
              "RCS"
            ],
            "example": "SMS"
          },
          "timestamp": {
            "type": "string",
            "description": "The timestamp of the status update",
            "example": "2021-01-01T00:00:00.000Z"
          },
          "failureDetails": {
            "description": "Additional details about the status (for failed messages)",
            "allOf": [
              {
                "$ref": "#/components/schemas/WebhookStatusReasonV1"
              }
            ]
          }
        },
        "required": [
          "smobiMessageId",
          "clientRef",
          "to",
          "from",
          "status",
          "channel",
          "timestamp"
        ]
      },
      "SmobiOutboundSmsMessageContentV2": {
        "type": "object",
        "properties": {
          "content": {
            "type": "string",
            "description": "Text content of the message",
            "example": "Hello, world!"
          },
          "downloadUrl": {
            "type": "string",
            "description": "Download URL of media content",
            "example": "https://api-us.nexmo.com/v3/media/ae1467c0-1485-4fe5-b627-2a82e6eb856b"
          },
          "fileExtension": {
            "type": "string",
            "description": "File extension of the media content",
            "example": "PNG"
          }
        }
      },
      "BaseOutboundMessageV2": {
        "type": "object",
        "properties": {
          "smobiMessageId": {
            "type": "string",
            "description": "The reference number of the message in the Smobi system",
            "example": "123e4567-e89b-12d3-a456-426614174000"
          },
          "to": {
            "type": "string",
            "description": "The phone number of the recipient",
            "example": "15552223333"
          },
          "from": {
            "type": "string",
            "description": "The phone number of the sender",
            "example": "15551234567"
          },
          "channel": {
            "type": "string",
            "description": "The channel of the message - indicates which payload field to access",
            "enum": [
              "SMS",
              "RCS"
            ],
            "example": "SMS"
          },
          "timestamp": {
            "type": "string",
            "description": "The timestamp of the message",
            "example": "2021-01-01T00:00:00.000Z"
          },
          "sms": {
            "description": "SMS message content (present when channel is SMS)",
            "allOf": [
              {
                "$ref": "#/components/schemas/SmobiOutboundSmsMessageContentV2"
              }
            ]
          },
          "rcs": {
            "description": "RCS message content (present when channel is RCS)",
            "oneOf": [
              {
                "$ref": "#/components/schemas/SmobiTextMessageContentV2",
                "title": "Text"
              },
              {
                "$ref": "#/components/schemas/SmobiContentMessageContentV2",
                "title": "Content"
              },
              {
                "$ref": "#/components/schemas/SmobiLocationMessageContentV2",
                "title": "Location"
              },
              {
                "$ref": "#/components/schemas/SmobiSuggestionMessageContentV2",
                "title": "Suggestion"
              }
            ]
          }
        },
        "required": [
          "smobiMessageId",
          "to",
          "from",
          "channel",
          "timestamp"
        ]
      },
      "SmobiTextMessageContentV2": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "TEXT"
            ],
            "description": "Type of message content",
            "example": "TEXT"
          },
          "content": {
            "type": "string",
            "description": "Text content",
            "example": "Hello, world!"
          }
        },
        "required": [
          "type",
          "content"
        ]
      },
      "SmobiContentDetailsV2": {
        "type": "object",
        "properties": {
          "downloadUrl": {
            "type": "string",
            "description": "Download URL of the content",
            "example": "https://api-us.nexmo.com/v3/media/ae1467c0-1485-4fe5-b627-2a82e6eb856b"
          },
          "fileExtension": {
            "type": "string",
            "description": "File extension of the content, always present when downloadUrl is present",
            "example": "PNG"
          }
        },
        "required": [
          "downloadUrl",
          "fileExtension"
        ]
      },
      "SmobiContentMessageContentV2": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "CONTENT"
            ],
            "description": "Type of message content",
            "example": "CONTENT"
          },
          "content": {
            "description": "Content details",
            "allOf": [
              {
                "$ref": "#/components/schemas/SmobiContentDetailsV2"
              }
            ]
          }
        },
        "required": [
          "type",
          "content"
        ]
      },
      "SmobiLocationDetailsV2": {
        "type": "object",
        "properties": {
          "latitude": {
            "type": "number",
            "description": "Latitude of the location",
            "example": 37.7749
          },
          "longitude": {
            "type": "number",
            "description": "Longitude of the location",
            "example": -122.4194
          }
        },
        "required": [
          "latitude",
          "longitude"
        ]
      },
      "SmobiLocationMessageContentV2": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "LOCATION"
            ],
            "description": "Type of message content",
            "example": "LOCATION"
          },
          "content": {
            "description": "Location details",
            "allOf": [
              {
                "$ref": "#/components/schemas/SmobiLocationDetailsV2"
              }
            ]
          }
        },
        "required": [
          "type",
          "content"
        ]
      },
      "SmobiSuggestionDetailsV2": {
        "type": "object",
        "properties": {
          "parentSmobiMessageId": {
            "type": "string",
            "description": "The ID of the parent message in the Smobi system",
            "example": "123e4567-e89b-12d3-a456-426614174000"
          },
          "parentClientRef": {
            "type": "string",
            "description": "The client reference of the parent message",
            "example": "client-ref-123"
          },
          "suggestionId": {
            "type": "string",
            "description": "The ID of the selected suggestion",
            "example": "suggestion-123"
          },
          "text": {
            "type": "string",
            "description": "The text of the selected suggestion",
            "example": "Yes, I agree"
          }
        },
        "required": [
          "parentSmobiMessageId",
          "parentClientRef",
          "suggestionId",
          "text"
        ]
      },
      "SmobiSuggestionMessageContentV2": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "SUGGESTION"
            ],
            "description": "Type of message content - represents user interactions (reply/button)",
            "example": "SUGGESTION"
          },
          "content": {
            "description": "Suggestion interaction details",
            "allOf": [
              {
                "$ref": "#/components/schemas/SmobiSuggestionDetailsV2"
              }
            ]
          }
        },
        "required": [
          "type",
          "content"
        ]
      },
      "ReplyAction": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique identifier for the action",
            "minLength": 1
          },
          "text": {
            "type": "string",
            "description": "Text to display for the action, Maximum 25 characters",
            "minLength": 1,
            "maxLength": 25
          },
          "type": {
            "type": "string",
            "enum": [
              "REPLY"
            ],
            "description": "Type of action"
          }
        },
        "required": [
          "id",
          "text",
          "type"
        ]
      },
      "OpenUrlAction": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique identifier for the action",
            "minLength": 1
          },
          "text": {
            "type": "string",
            "description": "Text to display for the action, Maximum 25 characters",
            "minLength": 1,
            "maxLength": 25
          },
          "type": {
            "type": "string",
            "enum": [
              "OPEN_URL"
            ],
            "description": "Type of action"
          },
          "url": {
            "type": "string",
            "description": "The publicly accessible URL to open, for example, https://www.example.com"
          }
        },
        "required": [
          "id",
          "text",
          "type",
          "url"
        ]
      },
      "DialPhoneAction": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique identifier for the action",
            "minLength": 1
          },
          "text": {
            "type": "string",
            "description": "Text to display for the action, Maximum 25 characters",
            "minLength": 1,
            "maxLength": 25
          },
          "type": {
            "type": "string",
            "enum": [
              "DIAL_PHONE"
            ],
            "description": "Type of action"
          },
          "phoneNumber": {
            "type": "string",
            "description": "The phone number in E.164 format, for example, +12223334444"
          }
        },
        "required": [
          "id",
          "text",
          "type",
          "phoneNumber"
        ]
      },
      "ShowLocationAction": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique identifier for the action",
            "minLength": 1
          },
          "text": {
            "type": "string",
            "description": "Text to display for the action, Maximum 25 characters",
            "minLength": 1,
            "maxLength": 25
          },
          "type": {
            "type": "string",
            "enum": [
              "SHOW_LOCATION"
            ],
            "description": "Type of action"
          },
          "latitude": {
            "type": "string",
            "description": "The latitude in degrees. It must be in the range [-90.0, +90.0]."
          },
          "longitude": {
            "type": "string",
            "description": "The longitude in degrees. It must be in the range [-180.0, +180.0]."
          },
          "label": {
            "type": "string",
            "description": "The label of the location, for example, \"Home\", \"Work\", \"School\", etc."
          }
        },
        "required": [
          "id",
          "text",
          "type",
          "latitude",
          "longitude"
        ]
      },
      "RequestLocationAction": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique identifier for the action",
            "minLength": 1
          },
          "text": {
            "type": "string",
            "description": "Text to display for the action, Maximum 25 characters",
            "minLength": 1,
            "maxLength": 25
          },
          "type": {
            "type": "string",
            "enum": [
              "REQUEST_LOCATION"
            ],
            "description": "Type of action"
          }
        },
        "required": [
          "id",
          "text",
          "type"
        ]
      },
      "CalendarEventAction": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique identifier for the action",
            "minLength": 1
          },
          "text": {
            "type": "string",
            "description": "Text to display for the action, Maximum 25 characters",
            "minLength": 1,
            "maxLength": 25
          },
          "type": {
            "type": "string",
            "enum": [
              "CALENDAR_EVENT"
            ],
            "description": "Type of action"
          },
          "eventTitle": {
            "type": "string",
            "description": "Event title. Maximum 100 characters"
          },
          "eventDescription": {
            "type": "string",
            "description": "Event description. Maximum 500 characters"
          },
          "startDate": {
            "format": "date-time",
            "type": "string",
            "description": "The start date of the event, in RFC 3339 format"
          },
          "endDate": {
            "format": "date-time",
            "type": "string",
            "description": "The end date of the event, in RFC 3339 format"
          }
        },
        "required": [
          "id",
          "text",
          "type",
          "eventTitle",
          "startDate",
          "endDate"
        ]
      }
    }
  },
  "externalDocs": {
    "description": "Smobi guides",
    "url": "https://docs.smobi.com/docs"
  }
}
