{
  "openapi": "3.0.3",
  "info": {
    "title": "Ravi API",
    "version": "1.0.0",
    "description": "Identity provider for AI agents \u2014 provisioned phone numbers, email addresses, TOTP, OTP extraction, and E2E-encrypted passwords and secrets."
  },
  "paths": {
    "/api/email-messages/": {
      "get": {
        "operationId": "email_messages_list",
        "description": "List email messages for the authenticated user, sorted oldest-first. Designed for cursor-based polling: pass created_after (ISO 8601 datetime) to fetch only messages newer than the cursor. Also filterable by direction (incoming/outgoing), is_read, thread_id, and from_email. Returns paginated results with limit/offset pagination (default limit: 50, max: 200).",
        "parameters": [
          {
            "in": "query",
            "name": "created_after",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "in": "query",
            "name": "direction",
            "schema": {
              "type": "string",
              "x-spec-enum-id": "0f9b1c9d69d835bd",
              "enum": [
                "incoming",
                "outgoing"
              ]
            },
            "description": "Whether this message was received (incoming) or sent (outgoing)\n\n* `incoming` - Incoming\n* `outgoing` - Outgoing"
          },
          {
            "in": "query",
            "name": "from_email",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "is_read",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Number of results to return per page.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "offset",
            "required": false,
            "in": "query",
            "description": "The initial index from which to return the results.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "thread_id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "Messages"
        ],
        "security": [
          {
            "identityKeyAuth": []
          },
          {
            "managementKeyAuth": []
          },
          {
            "jwtAuth": []
          },
          {
            "cookieAuth": []
          },
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedRaviEmailList"
                }
              }
            },
            "description": ""
          }
        }
      }
    },
    "/api/email-messages/compose/": {
      "post": {
        "operationId": "email_messages_compose_create",
        "description": "Compose and send a new email from the specified inbox. Requires the 'inbox' query parameter (inbox ID). Supports to_email, subject, content, cc, bcc, and attachment_uuids. Returns 400 if the inbox parameter is missing or validation fails, 404 if the inbox is not found.",
        "tags": [
          "Messages"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RaviEmailRequest"
              },
              "examples": {
                "ComposeEmail": {
                  "value": {
                    "to_email": "alice@example.com",
                    "subject": "Meeting tomorrow",
                    "content": "Hi Alice, are we still on for tomorrow at 3pm?"
                  },
                  "summary": "Compose email"
                },
                "ComposeEmailWithCCAndAttachments": {
                  "value": {
                    "to_email": "alice@example.com",
                    "subject": "Q4 Report",
                    "content": "Please find the Q4 report attached.",
                    "cc": [
                      "bob@example.com"
                    ],
                    "bcc": [
                      "manager@example.com"
                    ],
                    "attachment_uuids": [
                      "f47ac10b-58cc-4372-a567-0e02b2c3d479"
                    ]
                  },
                  "summary": "Compose email with CC and attachments"
                }
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/RaviEmailRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/RaviEmailRequest"
              }
            }
          }
        },
        "security": [
          {
            "identityKeyAuth": []
          },
          {
            "managementKeyAuth": []
          },
          {
            "jwtAuth": []
          },
          {
            "cookieAuth": []
          },
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RaviEmailSent"
                },
                "examples": {
                  "EmailSent": {
                    "value": {
                      "id": 42,
                      "url": "https://api.ravi.id/api/messages/42/",
                      "from_email": "shopping@example.com",
                      "from_display_name": null,
                      "to_email": "alice@example.com",
                      "cc": [],
                      "direction": "outgoing",
                      "is_read": true,
                      "message_id": "<abc123@example.com>",
                      "thread_id": null,
                      "attachments": [],
                      "created_dt": "2025-06-01T12:00:00Z"
                    },
                    "summary": "Email sent"
                  }
                }
              }
            },
            "description": ""
          }
        }
      }
    },
    "/api/email-messages/{id}/": {
      "get": {
        "operationId": "email_messages_retrieve",
        "description": "Retrieve a single email message by ID. Returns full message details including content and attachments.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this Email Message.",
            "required": true
          }
        ],
        "tags": [
          "Messages"
        ],
        "security": [
          {
            "identityKeyAuth": []
          },
          {
            "managementKeyAuth": []
          },
          {
            "jwtAuth": []
          },
          {
            "cookieAuth": []
          },
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RaviEmail"
                }
              }
            },
            "description": ""
          }
        }
      },
      "put": {
        "operationId": "email_messages_update",
        "description": "Update a message's mutable fields (e.g. is_read). Replaces all mutable fields with the provided values.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this Email Message.",
            "required": true
          }
        ],
        "tags": [
          "Messages"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RaviEmailRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/RaviEmailRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/RaviEmailRequest"
              }
            }
          }
        },
        "security": [
          {
            "identityKeyAuth": []
          },
          {
            "managementKeyAuth": []
          },
          {
            "jwtAuth": []
          },
          {
            "cookieAuth": []
          },
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RaviEmail"
                }
              }
            },
            "description": ""
          }
        }
      },
      "patch": {
        "operationId": "email_messages_partial_update",
        "description": "Partially update a message's mutable fields (e.g. mark as read). Only the provided fields are changed.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this Email Message.",
            "required": true
          }
        ],
        "tags": [
          "Messages"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchedRaviEmailRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/PatchedRaviEmailRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/PatchedRaviEmailRequest"
              }
            }
          }
        },
        "security": [
          {
            "identityKeyAuth": []
          },
          {
            "managementKeyAuth": []
          },
          {
            "jwtAuth": []
          },
          {
            "cookieAuth": []
          },
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RaviEmail"
                }
              }
            },
            "description": ""
          }
        }
      }
    },
    "/api/email-messages/{id}/forward/": {
      "post": {
        "operationId": "email_messages_forward_create",
        "description": "Forward an email message to a new recipient. Requires to_email and content. Subject is always derived server-side from the original message. Supports optional cc, bcc, and attachment_uuids. Returns 400 if validation fails.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this Email Message.",
            "required": true
          }
        ],
        "tags": [
          "Messages"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RaviEmailRequest"
              },
              "examples": {
                "ForwardEmail": {
                  "value": {
                    "to_email": "bob@example.com",
                    "content": "FYI \u2014 see the original message below."
                  },
                  "summary": "Forward email"
                }
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/RaviEmailRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/RaviEmailRequest"
              }
            }
          }
        },
        "security": [
          {
            "identityKeyAuth": []
          },
          {
            "managementKeyAuth": []
          },
          {
            "jwtAuth": []
          },
          {
            "cookieAuth": []
          },
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RaviEmailSent"
                }
              }
            },
            "description": ""
          }
        }
      }
    },
    "/api/email-messages/{id}/reply-all/": {
      "post": {
        "operationId": "email_messages_reply_all_create",
        "description": "Reply-all to an email message, sending to the original sender and all recipients. Subject is always derived server-side from the original message. Supports optional cc, bcc, and attachment_uuids. Returns 400 if validation fails.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this Email Message.",
            "required": true
          }
        ],
        "tags": [
          "Messages"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RaviEmailRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/RaviEmailRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/RaviEmailRequest"
              }
            }
          }
        },
        "security": [
          {
            "identityKeyAuth": []
          },
          {
            "managementKeyAuth": []
          },
          {
            "jwtAuth": []
          },
          {
            "cookieAuth": []
          },
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RaviEmailSent"
                }
              }
            },
            "description": ""
          }
        }
      }
    },
    "/api/email-messages/{id}/reply/": {
      "post": {
        "operationId": "email_messages_reply_create",
        "description": "Reply to a single email message. Sends the reply only to the original sender. Subject is always derived server-side from the original message. Supports optional cc, bcc, and attachment_uuids. Returns 400 if validation fails.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this Email Message.",
            "required": true
          }
        ],
        "tags": [
          "Messages"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RaviEmailRequest"
              },
              "examples": {
                "ReplyToEmail": {
                  "value": {
                    "content": "Thanks, see you at 3pm!"
                  },
                  "summary": "Reply to email"
                }
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/RaviEmailRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/RaviEmailRequest"
              }
            }
          }
        },
        "security": [
          {
            "identityKeyAuth": []
          },
          {
            "managementKeyAuth": []
          },
          {
            "jwtAuth": []
          },
          {
            "cookieAuth": []
          },
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RaviEmailSent"
                }
              }
            },
            "description": ""
          }
        }
      }
    },
    "/api/messages/": {
      "get": {
        "operationId": "messages_list",
        "description": "List SMS messages for the authenticated user, newest first. Filterable by direction (incoming/outgoing) and is_read.",
        "parameters": [
          {
            "in": "query",
            "name": "direction",
            "schema": {
              "type": "string",
              "x-spec-enum-id": "0f9b1c9d69d835bd",
              "enum": [
                "incoming",
                "outgoing"
              ]
            },
            "description": "Whether this message was received (incoming) or sent (outgoing)\n\n* `incoming` - Incoming\n* `outgoing` - Outgoing"
          },
          {
            "in": "query",
            "name": "is_read",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "tags": [
          "Messages"
        ],
        "security": [
          {
            "identityKeyAuth": []
          },
          {
            "managementKeyAuth": []
          },
          {
            "jwtAuth": []
          },
          {
            "cookieAuth": []
          },
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/RaviPhoneMessage"
                  }
                }
              }
            },
            "description": ""
          }
        }
      }
    },
    "/api/messages/send/": {
      "post": {
        "operationId": "messages_send_create",
        "description": "Send an SMS from the identity's provisioned phone number. Requires an identity-scoped token and an identity with a phone number. The message body is encrypted at the storage layer. Returns 400 if the token has no identity claim, 404 if the identity has no phone.",
        "tags": [
          "Messages"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SmsSendRequest"
              },
              "examples": {
                "SendSMS": {
                  "value": {
                    "to_number": "+14155559876",
                    "body": "Your verification code is 483920"
                  },
                  "summary": "Send SMS"
                }
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/SmsSendRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/SmsSendRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "identityKeyAuth": []
          },
          {
            "managementKeyAuth": []
          },
          {
            "jwtAuth": []
          },
          {
            "cookieAuth": []
          },
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RaviPhoneMessage"
                },
                "examples": {
                  "SMSSent": {
                    "value": {
                      "id": 15,
                      "url": "https://api.ravi.id/api/sms/15/",
                      "from_number": "+15551234567",
                      "to_number": "+14155559876",
                      "body": "Your verification code is 483920",
                      "message_sid": "SM1234567890abcdef1234567890abcdef",
                      "phone": "https://api.ravi.id/api/phones/3/",
                      "direction": "outgoing",
                      "is_read": true,
                      "created_dt": "2025-06-01T12:00:00Z"
                    },
                    "summary": "SMS sent"
                  }
                }
              }
            },
            "description": ""
          }
        }
      }
    },
    "/api/messages/{id}/": {
      "get": {
        "operationId": "messages_retrieve",
        "description": "Retrieve a single SMS message by ID, including body and metadata.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this Phone Message.",
            "required": true
          }
        ],
        "tags": [
          "Messages"
        ],
        "security": [
          {
            "identityKeyAuth": []
          },
          {
            "managementKeyAuth": []
          },
          {
            "jwtAuth": []
          },
          {
            "cookieAuth": []
          },
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RaviPhoneMessage"
                }
              }
            },
            "description": ""
          }
        }
      },
      "put": {
        "operationId": "messages_update",
        "description": "Update a message's mutable fields (e.g. is_read). Replaces all mutable fields with the provided values.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this Phone Message.",
            "required": true
          }
        ],
        "tags": [
          "Messages"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RaviPhoneMessageRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/RaviPhoneMessageRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/RaviPhoneMessageRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "identityKeyAuth": []
          },
          {
            "managementKeyAuth": []
          },
          {
            "jwtAuth": []
          },
          {
            "cookieAuth": []
          },
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RaviPhoneMessage"
                }
              }
            },
            "description": ""
          }
        }
      },
      "patch": {
        "operationId": "messages_partial_update",
        "description": "Partially update a message's mutable fields (e.g. mark as read). Only the provided fields are changed.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this Phone Message.",
            "required": true
          }
        ],
        "tags": [
          "Messages"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchedRaviPhoneMessageRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/PatchedRaviPhoneMessageRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/PatchedRaviPhoneMessageRequest"
              }
            }
          }
        },
        "security": [
          {
            "identityKeyAuth": []
          },
          {
            "managementKeyAuth": []
          },
          {
            "jwtAuth": []
          },
          {
            "cookieAuth": []
          },
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RaviPhoneMessage"
                }
              }
            },
            "description": ""
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "EmailAttachment": {
        "type": "object",
        "description": "Full attachment representation including a presigned download URL.",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "readOnly": true
          },
          "filename": {
            "type": "string",
            "description": "Original filename",
            "maxLength": 255
          },
          "content_type": {
            "type": "string",
            "description": "MIME content type",
            "maxLength": 255
          },
          "size": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": 0,
            "description": "File size in bytes"
          },
          "content_id": {
            "type": "string",
            "description": "Content-ID for inline images (RFC 2392)",
            "maxLength": 255
          },
          "is_inline": {
            "type": "boolean",
            "description": "Whether this is an inline image (CID reference)"
          },
          "download_url": {
            "type": "string",
            "readOnly": true
          },
          "created_dt": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          }
        },
        "required": [
          "content_type",
          "created_dt",
          "download_url",
          "filename",
          "size",
          "uuid"
        ]
      },
      "EmailAttachmentMeta": {
        "type": "object",
        "description": "Lightweight attachment serializer without download URL (for list views).",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "readOnly": true
          },
          "filename": {
            "type": "string",
            "description": "Original filename",
            "maxLength": 255
          },
          "content_type": {
            "type": "string",
            "description": "MIME content type",
            "maxLength": 255
          },
          "size": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": 0,
            "description": "File size in bytes"
          },
          "is_inline": {
            "type": "boolean",
            "description": "Whether this is an inline image (CID reference)"
          }
        },
        "required": [
          "content_type",
          "filename",
          "size",
          "uuid"
        ]
      },
      "PaginatedRaviEmailList": {
        "type": "object",
        "required": [
          "count",
          "results"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "example": 123
          },
          "next": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?offset=400&limit=100"
          },
          "previous": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?offset=200&limit=100"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RaviEmail"
            }
          }
        }
      },
      "PatchedRaviEmailRequest": {
        "type": "object",
        "description": "Full email message representation with nested attachments.",
        "properties": {
          "is_read": {
            "type": "boolean",
            "description": "Whether the user has read this message"
          }
        }
      },
      "PatchedRaviPhoneMessageRequest": {
        "type": "object",
        "properties": {
          "phone": {
            "type": "string",
            "format": "uri"
          },
          "is_read": {
            "type": "boolean",
            "description": "Whether the user has read this message"
          }
        }
      },
      "RaviEmail": {
        "type": "object",
        "description": "Full email message representation with nested attachments.",
        "properties": {
          "id": {
            "type": "integer",
            "readOnly": true
          },
          "uuid": {
            "type": "string",
            "format": "uuid",
            "readOnly": true
          },
          "url": {
            "type": "string",
            "nullable": true,
            "readOnly": true
          },
          "from_email": {
            "type": "string",
            "format": "email",
            "readOnly": true,
            "description": "The sender's email address"
          },
          "from_display_name": {
            "type": "string",
            "readOnly": true,
            "description": "The sender's display name from the From header"
          },
          "to_email": {
            "type": "string",
            "format": "email",
            "readOnly": true,
            "description": "The recipient's email address"
          },
          "cc": {
            "type": "string",
            "readOnly": true,
            "description": "CC recipients (comma-separated email addresses)"
          },
          "subject": {
            "type": "string",
            "readOnly": true,
            "description": "The email subject line (server-side encrypted)"
          },
          "text_content": {
            "type": "string",
            "readOnly": true,
            "description": "The plain text content of the email body (server-side encrypted)"
          },
          "html_content": {
            "type": "string",
            "readOnly": true,
            "description": "The HTML content of the email body (server-side encrypted)"
          },
          "direction": {
            "enum": [
              "incoming",
              "outgoing"
            ],
            "type": "string",
            "x-spec-enum-id": "0f9b1c9d69d835bd",
            "readOnly": true,
            "description": "Whether this message was received (incoming) or sent (outgoing)\n\n* `incoming` - Incoming\n* `outgoing` - Outgoing"
          },
          "is_read": {
            "type": "boolean",
            "description": "Whether the user has read this message"
          },
          "sender_type": {
            "type": "string",
            "readOnly": true
          },
          "message_id": {
            "type": "string",
            "readOnly": true,
            "description": "The Message-ID header value (unique identifier for this email)"
          },
          "thread_id": {
            "type": "string",
            "readOnly": true,
            "description": "Thread identifier (root message ID) for grouping conversations"
          },
          "attachments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EmailAttachment"
            },
            "readOnly": true
          },
          "created_dt": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          }
        },
        "required": [
          "attachments",
          "cc",
          "created_dt",
          "direction",
          "from_display_name",
          "from_email",
          "html_content",
          "id",
          "message_id",
          "sender_type",
          "subject",
          "text_content",
          "thread_id",
          "to_email",
          "url",
          "uuid"
        ]
      },
      "RaviEmailRequest": {
        "type": "object",
        "description": "Full email message representation with nested attachments.",
        "properties": {
          "is_read": {
            "type": "boolean",
            "description": "Whether the user has read this message"
          }
        }
      },
      "RaviEmailSent": {
        "type": "object",
        "description": "Slim response for email write actions \u2014 omits content fields for brevity.",
        "properties": {
          "id": {
            "type": "integer",
            "readOnly": true
          },
          "url": {
            "type": "string",
            "nullable": true,
            "readOnly": true
          },
          "from_email": {
            "type": "string",
            "format": "email",
            "readOnly": true,
            "description": "The sender's email address"
          },
          "from_display_name": {
            "type": "string",
            "readOnly": true,
            "description": "The sender's display name from the From header"
          },
          "to_email": {
            "type": "string",
            "format": "email",
            "readOnly": true,
            "description": "The recipient's email address"
          },
          "cc": {
            "type": "string",
            "readOnly": true,
            "description": "CC recipients (comma-separated email addresses)"
          },
          "direction": {
            "enum": [
              "incoming",
              "outgoing"
            ],
            "type": "string",
            "x-spec-enum-id": "0f9b1c9d69d835bd",
            "readOnly": true,
            "description": "Whether this message was received (incoming) or sent (outgoing)\n\n* `incoming` - Incoming\n* `outgoing` - Outgoing"
          },
          "is_read": {
            "type": "boolean",
            "readOnly": true,
            "description": "Whether the user has read this message"
          },
          "message_id": {
            "type": "string",
            "readOnly": true,
            "description": "The Message-ID header value (unique identifier for this email)"
          },
          "thread_id": {
            "type": "string",
            "readOnly": true,
            "description": "Thread identifier (root message ID) for grouping conversations"
          },
          "attachments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EmailAttachmentMeta"
            },
            "readOnly": true
          },
          "created_dt": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          }
        },
        "required": [
          "attachments",
          "cc",
          "created_dt",
          "direction",
          "from_display_name",
          "from_email",
          "id",
          "is_read",
          "message_id",
          "thread_id",
          "to_email",
          "url"
        ]
      },
      "RaviPhoneMessage": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "readOnly": true
          },
          "url": {
            "type": "string",
            "nullable": true,
            "readOnly": true
          },
          "from_number": {
            "type": "string",
            "readOnly": true,
            "maxLength": 16,
            "minLength": 2
          },
          "to_number": {
            "type": "string",
            "readOnly": true,
            "maxLength": 16,
            "minLength": 2
          },
          "body": {
            "type": "string",
            "readOnly": true,
            "description": "Message body (server-side encrypted)."
          },
          "message_sid": {
            "type": "string",
            "readOnly": true,
            "description": "Provider's unique identifier for this message (e.g., Twilio's MessageSid)"
          },
          "phone": {
            "type": "string",
            "format": "uri"
          },
          "direction": {
            "enum": [
              "incoming",
              "outgoing"
            ],
            "type": "string",
            "x-spec-enum-id": "0f9b1c9d69d835bd",
            "readOnly": true,
            "description": "Whether this message was received (incoming) or sent (outgoing)\n\n* `incoming` - Incoming\n* `outgoing` - Outgoing"
          },
          "is_read": {
            "type": "boolean",
            "description": "Whether the user has read this message"
          },
          "created_dt": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          }
        },
        "required": [
          "body",
          "created_dt",
          "direction",
          "from_number",
          "id",
          "message_sid",
          "phone",
          "to_number",
          "url"
        ]
      },
      "RaviPhoneMessageRequest": {
        "type": "object",
        "properties": {
          "phone": {
            "type": "string",
            "format": "uri"
          },
          "is_read": {
            "type": "boolean",
            "description": "Whether the user has read this message"
          }
        },
        "required": [
          "phone"
        ]
      },
      "SmsSendRequest": {
        "type": "object",
        "properties": {
          "to_number": {
            "type": "string",
            "minLength": 2,
            "description": "Destination phone number in E.164 format",
            "maxLength": 16
          },
          "body": {
            "type": "string",
            "minLength": 1,
            "description": "SMS message body",
            "maxLength": 1600
          }
        },
        "required": [
          "body",
          "to_number"
        ]
      }
    }
  }
}
