{
    "openapi": "3.0.3",
    "info": {
        "title": "Calisero transactional SMS API",
        "version": "1.0.16 - 25.10.2026",
        "description": "API documentation for sending and managing transactional SMS messages via [Calisero](https://calisero.ro).\n\nThe API accepts HTTPS connections with TLS 1.2 or TLS 1.3 only. From 1 November 2026, a client that offers only TLS 1.0 or TLS 1.1 is refused during the TLS handshake: it gets no HTTP response, and nothing is sent or billed. Call `https://` directly: a request to `http://` is redirected, and most HTTP clients turn a redirected `POST` into a `GET` without its body."
    },
    "externalDocs": {
        "description": "Official PHP Library (GitHub)",
        "url": "https://github.com/calisero/calisero-php"
    },
    "servers": [
        {
            "url": "https://rest.calisero.ro/api/v1",
            "description": "Production server"
        }
    ],
    "paths": {
        "/accounts/{accountId}": {
            "get": {
                "summary": "Retrieve account information",
                "operationId": "getAccount",
                "tags": [
                    "Accounts"
                ],
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "accountId",
                        "in": "path",
                        "required": true,
                        "description": "The UUID of the account",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Account details",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/GetAccountResponse"
                                },
                                "example": {
                                    "data": {
                                        "id": "9d0e0bd3-c805-4dd0-bafb-07c5ded0a8e1",
                                        "code": "ABC1234",
                                        "name": "My Company",
                                        "description": "Company description",
                                        "fiscal_code": "RO12345678",
                                        "registry_number": "J40/123456/2023",
                                        "iban": "RO49AAAA1B31007593840000",
                                        "city": "Bucharest",
                                        "state": "Bucharest",
                                        "country": "RO",
                                        "address": "Main Street 123",
                                        "postal_code": 123456,
                                        "email": "contact@company.com",
                                        "phone": "+40721***456",
                                        "contact_person": "John Doe",
                                        "credit": 100.50,
                                        "status": "active",
                                        "sandbox": false,
                                        "daily_limit": 1000,
                                        "daily_remaining": 873,
                                        "sent_today": 127,
                                        "created_at": "2024-09-20T12:48:55.000000Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/401Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/403Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/404NotFound"
                    },
                    "500": {
                        "$ref": "#/components/responses/500InternalServerError"
                    }
                }
            }
        },
        "/messages": {
            "post": {
                "summary": "Create a new message",
                "operationId": "createMessage",
                "description": "Sends an SMS now, or at `schedule_at`.\n\n**Daily sending limit.** Every account has its own daily limit; a new account starts with 200 messages a day and keeps it until we raise it on request. Each real message the account creates counts once, whatever its number of parts: the OTP codes of `POST /verifications` too, and a scheduled message on the day it is created. Test messages (a sandbox account or a sandbox API key) never count and are never refused. The day ends at midnight, Romania time (Europe/Bucharest). While the account has a limit, the answer to a created message carries `X-Daily-Limit` and `X-Daily-Remaining` (what is left today, after this message). Once the limit is reached the answer is `429` with `\"code\": \"daily_limit_exceeded\"`, `Retry-After` and `X-Daily-Remaining: 0` until midnight, Romania time: nothing is sent and nothing is billed. See [Daily sending limit](#daily-limit).\n\n**Request rate limit.** Separately, each API user may make 240 requests a minute. Every answer carries `X-RateLimit-Limit` and `X-RateLimit-Remaining`; above the rate the answer is `429` with `{\"message\": \"Too Many Attempts.\", \"trace_id\": \"…\"}`, no `code`, plus `Retry-After` and `X-RateLimit-Reset`.",
                "tags": [
                    "Messages"
                ],
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/CreateMessageRequest"
                            },
                            "example": {
                                "recipient": "40752******",
                                "body": "Test message",
                                "schedule_at": "2024-11-16 13:21:00",
                                "callback_url": "https://yoursite.com/your-callback-url",
                                "sender": "CALISERO",
                                "validity": 72,
                                "shorten_urls": true
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Message created successfully",
                        "headers": {
                            "X-Daily-Limit": {
                                "$ref": "#/components/headers/X-Daily-Limit"
                            },
                            "X-Daily-Remaining": {
                                "$ref": "#/components/headers/X-Daily-Remaining"
                            },
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/CreateMessageResponse"
                                },
                                "example": {
                                    "data": {
                                        "id": "9e2574e8-3615-4090-9b5a-0fc812079da8",
                                        "recipient": "40752******",
                                        "body": "Test message!",
                                        "parts": 1,
                                        "created_at": "2025-02-06T10:18:43.000000Z",
                                        "scheduled_at": "2025-02-06T10:18:43.000000Z",
                                        "sent_at": null,
                                        "delivered_at": null,
                                        "callback_url": "https://yoursite.com/your-callback-url",
                                        "status": "scheduled",
                                        "sender": "CALISERO",
                                        "shortened_urls": [
                                            {
                                                "id": "019adfbb-40a1-71ee-bcb5-8d551b8cfdae",
                                                "original_link": "https://www.google.com/search?q=calisero&rlz=1C5GCEM_enRO1174RO1174&oq=calisero&gs_lcrp=EgZjaHJvbWUqBggAEEUYOzIGCAAQRRg7MgYIARBFGDwyBggCEEUYPDIGCAMQRRg7MgcIBBAAGO8FMgoIBRAAGIAEGKIEMgoIBhAAGIAEGKIEMgcIBxAAGO8F0gEJMTcxNWowajE1qAIIsAIB&sourceid=chrome&ie=UTF-8",
                                                "shortened_link": "https://calisero.ro/s/ghJKPV",
                                                "click_count": 0,
                                                "last_click": null,
                                                "created_at": "2025-12-02T15:43:02.000000Z"
                                            },
                                            {
                                                "id": "019adfbb-40a4-70af-ba6c-55b7a07826e6",
                                                "original_link": "https://calisero.ro/stop/019999b5-5687-71cd-ae81-baf6eea9d86f/+40742***350?reason=Unsubscribe+from+SMS",
                                                "shortened_link": "https://calisero.ro/s/qpmHfD",
                                                "click_count": 0,
                                                "last_click": null,
                                                "created_at": "2025-12-02T15:43:02.000000Z"
                                            }
                                        ]
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/401Unauthorized"
                    },
                    "405": {
                        "$ref": "#/components/responses/405MethodNotAllowed"
                    },
                    "422": {
                        "$ref": "#/components/responses/422ValidationError"
                    },
                    "429": {
                        "description": "Too many requests, for one of two reasons. The account reached its daily sending limit: the body carries the code daily_limit_exceeded, X-Daily-Remaining is 0 and Retry-After counts the seconds until midnight, Romania time. Or the user exceeded the request rate limit of 240 requests a minute: the body is {\"message\": \"Too Many Attempts.\", \"trace_id\": \"…\"} without a code, X-RateLimit-Remaining is 0, and Retry-After and X-RateLimit-Reset say when to retry. Nothing is sent and nothing is billed.",
                        "headers": {
                            "Retry-After": {
                                "$ref": "#/components/headers/Retry-After"
                            },
                            "X-Daily-Limit": {
                                "$ref": "#/components/headers/X-Daily-Limit"
                            },
                            "X-Daily-Remaining": {
                                "$ref": "#/components/headers/X-Daily-Remaining-Exceeded"
                            },
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            },
                            "X-RateLimit-Reset": {
                                "$ref": "#/components/headers/X-RateLimit-Reset"
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/DailyLimitErrorResponse"
                                },
                                "example": {
                                    "message": "This account can send at most 1,000 messages a day. The limit resets at midnight, Romania time (2026-10-01T00:00:00+03:00). Contact us to raise it.",
                                    "code": "daily_limit_exceeded",
                                    "daily_limit": 1000,
                                    "daily_remaining": 0,
                                    "resets_at": "2026-10-01T00:00:00+03:00",
                                    "trace_id": "9b80eef1-49d4-4502-85a8-febb68cc11a7"
                                }
                            }
                        }
                    },
                    "500": {
                        "$ref": "#/components/responses/500InternalServerError"
                    }
                },
                "callbacks": {
                    "deliveryStatus": {
                        "{$request.body#/callback_url}": {
                            "post": {
                                "summary": "Delivery status webhook (Calisero -> Client)",
                                "operationId": "deliveryStatusWebhook",
                                "tags": [
                                    "Webhooks (Callbacks)"
                                ],
                                "description": "Calisero sends delivery status updates to the callback URL you provide when creating a message (`callback_url`). This callback documents the JSON payload you should expect to receive. Your endpoint must return any 2xx status code to acknowledge receipt. Only a failed connection or no answer within 2 seconds is retried, at most 5 attempts in total (after 1 s, 10 s, 1 min and 6 min); a non-2xx response is not retried.",
                                "requestBody": {
                                    "required": true,
                                    "content": {
                                        "application/json": {
                                            "schema": {
                                                "$ref": "#/components/schemas/DeliveryWebhookMessage"
                                            },
                                            "example": {
                                                "price": 0.0378,
                                                "sender": "CALISERO",
                                                "sentAt": "2025-09-19T12:01:15.000000Z",
                                                "status": "delivered",
                                                "messageId": "019961db-14a7-7348-963f-5a7a789a969f",
                                                "recipient": "+40742**350",
                                                "scheduleAt": "2025-09-19T12:02:51.000000Z",
                                                "deliveredAt": "2025-09-19T12:02:53.000000Z",
                                                "remainingBalance": 999.392,
                                                "dailyLimit": 1000,
                                                "dailyRemaining": 588,
                                                "sentToday": 412
                                            }
                                        }
                                    }
                                },
                                "responses": {
                                    "2XX": {
                                        "description": "Any 2xx status acknowledges the report. Answer within 2 seconds and do the work afterwards: a slower answer counts as a failure and the report is sent again."
                                    }
                                }
                            }
                        }
                    }
                }
            },
            "get": {
                "summary": "Retrieve a list of messages",
                "operationId": "listMessages",
                "tags": [
                    "Messages"
                ],
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "description": "Page number for pagination",
                        "schema": {
                            "type": "integer",
                            "default": 1,
                            "minimum": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "List of messages",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/PaginatedMessages"
                                },
                                "example": {
                                    "data": [
                                        {
                                            "id": "9d0e0bd3-c805-4dd0-bafb-07c5ded0a8e1",
                                            "recipient": "40752******",
                                            "body": "Mesaje de test anonimizat ***",
                                            "parts": 1,
                                            "created_at": "2024-09-20T12:48:55.000000Z",
                                            "scheduled_at": "2024-09-20T12:48:55.000000Z",
                                            "sent_at": "2024-09-20T12:49:07.000000Z",
                                            "delivered_at": null,
                                            "callback_url": "https://yoursite.com/your-callback-url",
                                            "status": "sent",
                                            "sender": "CALISERO",
                                            "shortened_urls": [
                                                {
                                                    "id": "019adfbb-40a1-71ee-bcb5-8d551b8cfdae",
                                                    "original_link": "https://www.google.com/search?q=calisero&rlz=1C5GCEM_enRO1174RO1174&oq=calisero&gs_lcrp=EgZjaHJvbWUqBggAEEUYOzIGCAAQRRg7MgYIARBFGDwyBggCEEUYPDIGCAMQRRg7MgcIBBAAGO8FMgoIBRAAGIAEGKIEMgoIBhAAGIAEGKIEMgcIBxAAGO8F0gEJMTcxNWowajE1qAIIsAIB&sourceid=chrome&ie=UTF-8",
                                                    "shortened_link": "https://calisero.ro/s/ghJKPV",
                                                    "click_count": 0,
                                                    "last_click": null,
                                                    "created_at": "2025-12-02T15:43:02.000000Z"
                                                }
                                            ]
                                        }
                                    ],
                                    "links": {
                                        "first": "https://rest.calisero.ro/api/v1/messages?page=1",
                                        "last": null,
                                        "prev": null,
                                        "next": "https://rest.calisero.ro/api/v1/messages?page=2"
                                    },
                                    "meta": {
                                        "current_page": 1,
                                        "from": 1,
                                        "path": "https://rest.calisero.ro/api/v1/messages",
                                        "per_page": 50,
                                        "to": 50
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/401Unauthorized"
                    },
                    "405": {
                        "$ref": "#/components/responses/405MethodNotAllowed"
                    },
                    "500": {
                        "$ref": "#/components/responses/500InternalServerError"
                    }
                }
            }
        },
        "/messages/{messageId}": {
            "get": {
                "summary": "Retrieve a single message",
                "operationId": "getMessage",
                "tags": [
                    "Messages"
                ],
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "messageId",
                        "in": "path",
                        "required": true,
                        "description": "The UUID of the message",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Message details",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/GetMessageResponse"
                                },
                                "example": {
                                    "data": {
                                        "id": "9d0e0bd3-c805-4dd0-bafb-07c5ded0a8e1",
                                        "recipient": "40752******",
                                        "body": "Mesaje de test anonimizat ***",
                                        "parts": 1,
                                        "created_at": "2024-09-20T12:48:55.000000Z",
                                        "scheduled_at": "2024-09-20T12:48:55.000000Z",
                                        "sent_at": "2024-09-20T12:49:07.000000Z",
                                        "delivered_at": null,
                                        "callback_url": "https://yoursite.com/your-callback-url",
                                        "status": "sent",
                                        "sender": "CALISERO",
                                        "shortened_urls": [
                                            {
                                                "id": "019adfbb-40a1-71ee-bcb5-8d551b8cfdae",
                                                "original_link": "https://www.google.com/search?q=calisero&rlz=1C5GCEM_enRO1174RO1174&oq=calisero&gs_lcrp=EgZjaHJvbWUqBggAEEUYOzIGCAAQRRg7MgYIARBFGDwyBggCEEUYPDIGCAMQRRg7MgcIBBAAGO8FMgoIBRAAGIAEGKIEMgoIBhAAGIAEGKIEMgcIBxAAGO8F0gEJMTcxNWowajE1qAIIsAIB&sourceid=chrome&ie=UTF-8",
                                                "shortened_link": "https://calisero.ro/s/ghJKPV",
                                                "click_count": 0,
                                                "last_click": null,
                                                "created_at": "2025-12-02T15:43:02.000000Z"
                                            }
                                        ]
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/401Unauthorized"
                    },
                    "404": {
                        "$ref": "#/components/responses/404NotFound"
                    },
                    "405": {
                        "$ref": "#/components/responses/405MethodNotAllowed"
                    },
                    "500": {
                        "$ref": "#/components/responses/500InternalServerError"
                    }
                }
            },
            "delete": {
                "summary": "Delete a message",
                "operationId": "deleteMessage",
                "tags": [
                    "Messages"
                ],
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "messageId",
                        "in": "path",
                        "required": true,
                        "description": "The UUID of the message",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Message deleted successfully",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {}
                                },
                                "example": {}
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/401Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/403ForbiddenDelete"
                    },
                    "404": {
                        "$ref": "#/components/responses/404NotFound"
                    },
                    "405": {
                        "$ref": "#/components/responses/405MethodNotAllowed"
                    },
                    "500": {
                        "$ref": "#/components/responses/500InternalServerError"
                    }
                }
            }
        },
        "/opt-outs": {
            "get": {
                "summary": "Retrieve a list of opt-outs",
                "operationId": "listOptOuts",
                "tags": [
                    "Opt-outs"
                ],
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "description": "Page number for pagination",
                        "schema": {
                            "type": "integer",
                            "default": 1,
                            "minimum": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "List of opt-outs",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/PaginatedOptOuts"
                                },
                                "example": {
                                    "data": [
                                        {
                                            "id": "9d0e0bd3-c805-4dd0-bafb-07c5ded0a8e1",
                                            "phone": "40752******",
                                            "reason": "User requested opt-out",
                                            "created_at": "2024-09-20T12:48:55.000000Z",
                                            "updated_at": "2024-09-20T12:48:55.000000Z"
                                        }
                                    ],
                                    "links": {
                                        "first": "https://rest.calisero.ro/api/v1/opt-outs?page=1",
                                        "last": null,
                                        "prev": null,
                                        "next": "https://rest.calisero.ro/api/v1/opt-outs?page=2"
                                    },
                                    "meta": {
                                        "current_page": 1,
                                        "from": 1,
                                        "path": "https://rest.calisero.ro/api/v1/opt-outs",
                                        "per_page": 50,
                                        "to": 50
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/401Unauthorized"
                    },
                    "405": {
                        "$ref": "#/components/responses/405MethodNotAllowed"
                    },
                    "500": {
                        "$ref": "#/components/responses/500InternalServerError"
                    }
                }
            },
            "post": {
                "summary": "Create a new opt-out",
                "operationId": "createOptOut",
                "tags": [
                    "Opt-outs"
                ],
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/CreateOptOutRequest"
                            },
                            "example": {
                                "phone": "40752******",
                                "reason": "User requested opt-out"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Opt-out created successfully",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/CreateOptOutResponse"
                                },
                                "example": {
                                    "data": {
                                        "id": "9d0e0bd3-c805-4dd0-bafb-07c5ded0a8e1",
                                        "phone": "40752******",
                                        "reason": "User requested opt-out",
                                        "created_at": "2024-09-20T12:48:55.000000Z",
                                        "updated_at": "2024-09-20T12:48:55.000000Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/401Unauthorized"
                    },
                    "405": {
                        "$ref": "#/components/responses/405MethodNotAllowed"
                    },
                    "422": {
                        "$ref": "#/components/responses/422ValidationError"
                    },
                    "500": {
                        "$ref": "#/components/responses/500InternalServerError"
                    }
                }
            }
        },
        "/opt-outs/{optOutId}": {
            "get": {
                "summary": "Retrieve a single opt-out",
                "operationId": "getOptOut",
                "tags": [
                    "Opt-outs"
                ],
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "optOutId",
                        "in": "path",
                        "required": true,
                        "description": "The UUID of the opt-out",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Opt-out details",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/GetOptOutResponse"
                                },
                                "example": {
                                    "data": {
                                        "id": "9d0e0bd3-c805-4dd0-bafb-07c5ded0a8e1",
                                        "phone": "40752******",
                                        "reason": "User requested opt-out",
                                        "created_at": "2024-09-20T12:48:55.000000Z",
                                        "updated_at": "2024-09-20T12:48:55.000000Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/401Unauthorized"
                    },
                    "404": {
                        "$ref": "#/components/responses/404NotFound"
                    },
                    "405": {
                        "$ref": "#/components/responses/405MethodNotAllowed"
                    },
                    "500": {
                        "$ref": "#/components/responses/500InternalServerError"
                    }
                }
            },
            "put": {
                "summary": "Update an opt-out",
                "operationId": "updateOptOut",
                "tags": [
                    "Opt-outs"
                ],
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "optOutId",
                        "in": "path",
                        "required": true,
                        "description": "The UUID of the opt-out",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/UpdateOptOutRequest"
                            },
                            "example": {
                                "phone": "40752******",
                                "reason": "Updated reason"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Opt-out updated successfully",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/GetOptOutResponse"
                                },
                                "example": {
                                    "data": {
                                        "id": "9d0e0bd3-c805-4dd0-bafb-07c5ded0a8e1",
                                        "phone": "40752******",
                                        "reason": "Customer asked to stop the reminders",
                                        "created_at": "2024-09-20T12:48:55.000000Z",
                                        "updated_at": "2024-10-02T08:15:31.000000Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/401Unauthorized"
                    },
                    "404": {
                        "$ref": "#/components/responses/404NotFound"
                    },
                    "405": {
                        "$ref": "#/components/responses/405MethodNotAllowed"
                    },
                    "422": {
                        "$ref": "#/components/responses/422ValidationError"
                    },
                    "500": {
                        "$ref": "#/components/responses/500InternalServerError"
                    }
                }
            },
            "delete": {
                "summary": "Delete an opt-out",
                "operationId": "deleteOptOut",
                "tags": [
                    "Opt-outs"
                ],
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "optOutId",
                        "in": "path",
                        "required": true,
                        "description": "The UUID of the opt-out",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Opt-out deleted successfully",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {}
                                },
                                "example": {}
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/401Unauthorized"
                    },
                    "404": {
                        "$ref": "#/components/responses/404NotFound"
                    },
                    "405": {
                        "$ref": "#/components/responses/405MethodNotAllowed"
                    },
                    "500": {
                        "$ref": "#/components/responses/500InternalServerError"
                    }
                }
            }
        },
        "/verifications": {
            "get": {
                "summary": "Retrieve a list of verifications",
                "operationId": "listVerifications",
                "tags": [
                    "Verifications (OTP & 2FA)"
                ],
                "security": [
                    { "BearerAuth": [] }
                ],
                "parameters": [
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "description": "Page number for pagination",
                        "schema": { "type": "integer", "default": 1, "minimum": 1 }
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "Filter by verification status",
                        "schema": { "type": "string", "enum": ["verified", "unverified"] }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "List of verifications",
                        "content": {
                            "application/json": {
                                "schema": { "$ref": "#/components/schemas/PaginatedVerifications" },
                                "example": {
                                    "data": [
                                        {
                                            "id": "019a62f1-66b7-7387-a64f-2742c12a2860",
                                            "phone": "+40742**350",
                                            "brand": "Calisero",
                                            "status": "verified",
                                            "template": null,
                                            "created_at": "2025-11-08T10:09:38.000000Z",
                                            "expires_at": "2025-11-08T10:12:38.000000Z",
                                            "verified_at": "2025-11-08T10:10:18.000000Z",
                                            "attempts": 1,
                                            "expired": false
                                        }
                                    ],
                                    "links": {
                                        "first": "https://rest.calisero.ro/api/v1/verifications?page=1",
                                        "last": null,
                                        "prev": null,
                                        "next": "https://rest.calisero.ro/api/v1/verifications?page=2"
                                    },
                                    "meta": {
                                        "current_page": 1,
                                        "from": 1,
                                        "path": "https://rest.calisero.ro/api/v1/verifications",
                                        "per_page": 50,
                                        "to": 50
                                    }
                                }
                            }
                        }
                    },
                    "401": { "$ref": "#/components/responses/401Unauthorized" },
                    "403": { "$ref": "#/components/responses/403Forbidden" },
                    "405": { "$ref": "#/components/responses/405MethodNotAllowed" },
                    "500": { "$ref": "#/components/responses/500InternalServerError" }
                }
            },
            "post": {
                "summary": "Create a new verification request",
                "operationId": "createVerification",
                "description": "Generates a code, sends it by SMS to `phone` and keeps it for `PUT /verifications/validate`.\n\n**Daily sending limit.** The code's SMS counts towards the account's daily limit like any message of `POST /messages` (a new account starts with 200 messages a day); the day ends at midnight, Romania time (Europe/Bucharest). While the account has a limit, the answer to a created verification carries `X-Daily-Limit` and `X-Daily-Remaining`. Once the limit is reached the answer is `429` with `\"code\": \"daily_limit_exceeded\"`, `Retry-After` and `X-Daily-Remaining: 0` until midnight, Romania time: no code is sent and nothing is billed. See [Daily sending limit](#daily-limit).\n\n**Request rate limit.** Separately, each API user may make 240 requests a minute; above the rate the answer is `429` with `{\"message\": \"Too Many Attempts.\", \"trace_id\": \"…\"}`, no `code`, plus `Retry-After` and `X-RateLimit-Reset`.",
                "tags": [
                    "Verifications (OTP & 2FA)"
                ],
                "security": [
                    { "BearerAuth": [] }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": { "$ref": "#/components/schemas/CreateVerificationRequest" },
                            "example": {
                                "phone": "+40742**350",
                                "brand": "Calisero"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Verification created successfully",
                        "headers": {
                            "X-Daily-Limit": { "$ref": "#/components/headers/X-Daily-Limit" },
                            "X-Daily-Remaining": { "$ref": "#/components/headers/X-Daily-Remaining" },
                            "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" },
                            "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" }
                        },
                        "content": {
                            "application/json": {
                                "schema": { "$ref": "#/components/schemas/CreateVerificationResponse" },
                                "example": {
                                    "data": {
                                        "id": "019a62f1-66b7-7387-a64f-2742c12a2860",
                                        "phone": "+40742**350",
                                        "brand": "Calisero",
                                        "status": "unverified",
                                        "template": null,
                                        "created_at": "2025-11-08T10:09:38.000000Z",
                                        "expires_at": "2025-11-08T10:12:38.000000Z",
                                        "verified_at": null,
                                        "attempts": 0,
                                        "expired": false
                                    }
                                }
                            }
                        }
                    },
                    "401": { "$ref": "#/components/responses/401Unauthorized" },
                    "403": { "$ref": "#/components/responses/403Forbidden" },
                    "405": { "$ref": "#/components/responses/405MethodNotAllowed" },
                    "422": { "$ref": "#/components/responses/422ValidationError" },
                    "429": {
                        "description": "Too many requests, for one of two reasons. The account reached its daily sending limit: the body carries the code daily_limit_exceeded, X-Daily-Remaining is 0 and Retry-After counts the seconds until midnight, Romania time. Or the user exceeded the request rate limit of 240 requests a minute: the body is {\"message\": \"Too Many Attempts.\", \"trace_id\": \"…\"} without a code, X-RateLimit-Remaining is 0, and Retry-After and X-RateLimit-Reset say when to retry. No code is sent and nothing is billed.",
                        "headers": {
                            "Retry-After": { "$ref": "#/components/headers/Retry-After" },
                            "X-Daily-Limit": { "$ref": "#/components/headers/X-Daily-Limit" },
                            "X-Daily-Remaining": { "$ref": "#/components/headers/X-Daily-Remaining-Exceeded" },
                            "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" },
                            "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" },
                            "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }
                        },
                        "content": {
                            "application/json": {
                                "schema": { "$ref": "#/components/schemas/DailyLimitErrorResponse" },
                                "example": {
                                    "message": "This account can send at most 1,000 messages a day. The limit resets at midnight, Romania time (2026-10-01T00:00:00+03:00). Contact us to raise it.",
                                    "code": "daily_limit_exceeded",
                                    "daily_limit": 1000,
                                    "daily_remaining": 0,
                                    "resets_at": "2026-10-01T00:00:00+03:00",
                                    "trace_id": "9b80eef1-49d4-4502-85a8-febb68cc11a7"
                                }
                            }
                        }
                    },
                    "500": { "$ref": "#/components/responses/500InternalServerError" }
                }
            }
        },
        "/verifications/{verificationId}": {
            "get": {
                "summary": "Retrieve a single verification",
                "operationId": "getVerification",
                "tags": [
                    "Verifications (OTP & 2FA)"
                ],
                "security": [
                    { "BearerAuth": [] }
                ],
                "parameters": [
                    {
                        "name": "verificationId",
                        "in": "path",
                        "required": true,
                        "description": "The UUID of the verification",
                        "schema": { "type": "string", "format": "uuid" }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Verification details",
                        "content": {
                            "application/json": {
                                "schema": { "$ref": "#/components/schemas/GetVerificationResponse" },
                                "example": {
                                    "data": {
                                        "id": "019a62f1-66b7-7387-a64f-2742c12a2860",
                                        "phone": "+40742**350",
                                        "brand": "Calisero",
                                        "status": "verified",
                                        "template": null,
                                        "created_at": "2025-11-08T10:09:38.000000Z",
                                        "expires_at": "2025-11-08T10:12:38.000000Z",
                                        "verified_at": "2025-11-08T10:10:18.000000Z",
                                        "attempts": 1,
                                        "expired": false
                                    }
                                }
                            }
                        }
                    },
                    "401": { "$ref": "#/components/responses/401Unauthorized" },
                    "403": { "$ref": "#/components/responses/403Forbidden" },
                    "404": { "$ref": "#/components/responses/404NotFound" },
                    "405": { "$ref": "#/components/responses/405MethodNotAllowed" },
                    "500": { "$ref": "#/components/responses/500InternalServerError" }
                }
            }
        },
        "/verifications/validate": {
            "put": {
                "summary": "Verify a code (OTP) for a phone number",
                "operationId": "validateVerificationPost",
                "tags": [
                    "Verifications (OTP & 2FA)"
                ],
                "security": [
                    { "BearerAuth": [] }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": { "$ref": "#/components/schemas/VerificationCheckRequest" },
                            "example": {
                                "phone": "+40742**350",
                                "code": "SBMH0f"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Phone number verified successfully (idempotent if already verified)",
                        "content": {
                            "application/json": {
                                "schema": { "$ref": "#/components/schemas/GetVerificationResponse" },
                                "example": {
                                    "data": {
                                        "id": "019a62f1-66b7-7387-a64f-2742c12a2860",
                                        "phone": "+40742**350",
                                        "brand": "Calisero",
                                        "status": "verified",
                                        "template": null,
                                        "created_at": "2025-11-08T10:09:38.000000Z",
                                        "expires_at": "2025-11-08T10:12:38.000000Z",
                                        "verified_at": "2025-11-08T10:10:18.000000Z",
                                        "attempts": 1,
                                        "expired": false
                                    }
                                }
                            }
                        }
                    },
                    "401": { "$ref": "#/components/responses/401Unauthorized" },
                    "403": { "$ref": "#/components/responses/403Forbidden" },
                    "404": { "$ref": "#/components/responses/404NotFound" },
                    "405": { "$ref": "#/components/responses/405MethodNotAllowed" },
                    "422": {
                        "description": "Validation errors (e.g., code incorrect, expired, attempts exceeded)",
                        "content": {
                            "application/json": {
                                "schema": { "$ref": "#/components/schemas/ValidationErrorResponse" },
                                "examples": {
                                    "code_incorrect": {
                                        "summary": "Incorrect code",
                                        "value": {
                                            "message": "The validation code is incorrect.",
                                            "errors": { "code": ["The validation code is incorrect."] }
                                        }
                                    },
                                    "code_expired": {
                                        "summary": "Expired code",
                                        "value": {
                                            "message": "The validation code has expired.",
                                            "errors": { "code": ["The validation code has expired."] }
                                        }
                                    },
                                    "attempts_exceeded": {
                                        "summary": "Max attempts exceeded",
                                        "value": {
                                            "message": "The maximum number of verification attempts has been exceeded.",
                                            "errors": { "code": ["The maximum number of verification attempts has been exceeded."] }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "500": { "$ref": "#/components/responses/500InternalServerError" }
                }
            }
        }
    },
    "components": {
        "securitySchemes": {
            "BearerAuth": {
                "type": "http",
                "scheme": "bearer",
                "bearerFormat": "JWT"
            }
        },
        "responses": {
            "401Unauthorized": {
                "description": "Unauthorized - Invalid or missing Bearer token",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/ErrorResponse"
                        },
                        "example": {
                            "message": "Unauthenticated."
                        }
                    }
                }
            },
            "403Forbidden": {
                "description": "Forbidden - Insufficient permissions",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/ErrorResponse"
                        },
                        "example": {
                            "message": "You don't have permission to access this resource."
                        }
                    }
                }
            },
            "403ForbiddenDelete": {
                "description": "Forbidden - Not authorized or resource not deletable",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/ErrorResponse"
                        },
                        "example": {
                            "message": "You are not authorized to delete this resource or the resource has been queued, sent or delivered"
                        }
                    }
                }
            },
            "404NotFound": {
                "description": "Resource not found",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/ErrorResponse"
                        },
                        "example": {
                            "message": "Resource not found!"
                        }
                    }
                }
            },
            "405MethodNotAllowed": {
                "description": "Method not allowed",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/ErrorResponse"
                        },
                        "example": {
                            "message": "This method is not supported for the requested route."
                        }
                    }
                }
            },
            "422ValidationError": {
                "description": "Validation error (e.g., missing required fields, duplicate SMS request detected)",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/ValidationErrorResponse"
                        },
                        "example": {
                            "message": "The recipient field is required.",
                            "errors": {
                                "recipient": [
                                    "The recipient field is required."
                                ]
                            }
                        }
                    }
                }
            },
            "500InternalServerError": {
                "description": "Internal server error",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/ErrorResponse"
                        },
                        "example": {
                            "message": "Internal server error!"
                        }
                    }
                }
            }
        },
        "headers": {
            "X-Daily-Limit": {
                "description": "The account's daily sending limit: how many messages it can send in a day, midnight to midnight, Romania time. Sent only while the account has a limit.",
                "schema": {
                    "type": "integer",
                    "example": 1000
                }
            },
            "X-Daily-Remaining": {
                "description": "How many messages the account can still send today, after this one. Sent only while the account has a limit.",
                "schema": {
                    "type": "integer",
                    "example": 873
                }
            },
            "X-Daily-Remaining-Exceeded": {
                "description": "0 when the daily sending limit refused the message; absent on a refusal of the request rate limit.",
                "schema": {
                    "type": "integer",
                    "example": 0
                }
            },
            "Retry-After": {
                "description": "Seconds to wait before sending again: until midnight, Romania time, for the daily sending limit; until the request rate limit frees up for that one.",
                "schema": {
                    "type": "integer",
                    "example": 21600
                }
            },
            "X-RateLimit-Limit": {
                "description": "The request rate limit: how many requests the API user may make a minute. Sent with every answer.",
                "schema": {
                    "type": "integer",
                    "example": 240
                }
            },
            "X-RateLimit-Remaining": {
                "description": "How many requests the API user may still make this minute. Sent with every answer; 0 on a refusal of the request rate limit.",
                "schema": {
                    "type": "integer",
                    "example": 239
                }
            },
            "X-RateLimit-Reset": {
                "description": "Only on a refusal of the request rate limit: when requests are accepted again, as a Unix timestamp.",
                "schema": {
                    "type": "integer",
                    "example": 1790000000
                }
            }
        },
        "schemas": {
            "CreateMessageRequest": {
                "type": "object",
                "properties": {
                    "recipient": {
                        "type": "string",
                        "description": "Recipient's phone number (in E.164 format)"
                    },
                    "body": {
                        "type": "string",
                        "description": "Text body of the message",
                        "maxLength": 1600
                    },
                    "visible_body": {
                        "type": "string",
                        "description": "Visible body for display purposes",
                        "maxLength": 1600,
                        "nullable": true
                    },
                    "validity": {
                        "type": "integer",
                        "description": "Message validity period in hours",
                        "minimum": 0,
                        "nullable": true
                    },
                    "schedule_at": {
                        "type": "string",
                        "format": "date-time",
                        "description": "Scheduled send time in 'YYYY-MM-DD HH:MM:SS' format",
                        "nullable": true
                    },
                    "callback_url": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true,
                        "description": "Optional callback URL to receive delivery reports. It must be an http or https address on the public Internet: private, loopback and link-local addresses are refused, and redirects are not followed."
                    },
                    "sender": {
                        "type": "string",
                        "description": "Custom sender ID. It must be a sender already approved for your account (Messages > Senders in the dashboard), written exactly as approved: the match is case-sensitive. A sender that is unknown, pending, rejected or not approved yet is refused with 422 (\"The sender is invalid or is not approved.\") and nothing is sent. Leave the field out, or send null, to use the default sender. CALISERO in the examples is a placeholder, not a sender you can use.",
                        "nullable": true
                    },
                    "shorten_urls": {
                        "type": "boolean",
                        "description": "If true, URLs inside the body are shortened and returned in the response",
                        "nullable": true
                    }
                },
                "required": [
                    "recipient",
                    "body"
                ]
            },
            "CreateOptOutRequest": {
                "type": "object",
                "properties": {
                    "phone": {
                        "type": "string",
                        "description": "Phone number to opt-out (in E.164 format)"
                    },
                    "reason": {
                        "type": "string",
                        "description": "Reason for opt-out",
                        "maxLength": 600,
                        "nullable": true
                    }
                },
                "required": [
                    "phone"
                ]
            },
            "UpdateOptOutRequest": {
                "type": "object",
                "properties": {
                    "phone": {
                        "type": "string",
                        "description": "Phone number to opt-out (in E.164 format)"
                    },
                    "reason": {
                        "type": "string",
                        "description": "Reason for opt-out",
                        "maxLength": 600,
                        "nullable": true
                    }
                },
                "required": [
                    "phone"
                ]
            },
            "Message": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "uuid"
                    },
                    "recipient": {
                        "type": "string"
                    },
                    "body": {
                        "type": "string"
                    },
                    "parts": {
                        "type": "integer",
                        "description": "Number of SMS parts"
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "scheduled_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "sent_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "delivered_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "callback_url": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true
                    },
                    "status": {
                        "type": "string",
                        "description": "Current status (e.g., scheduled, sent, failed)"
                    },
                    "sender": {
                        "type": "string",
                        "description": "Sender name or phone number",
                        "nullable": true
                    },
                    "shortened_urls": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/ShortenedLink"
                        },
                        "description": "List of shortened links generated from the message body"
                    }
                }
            },
            "ShortenedLink": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "uuid"
                    },
                    "original_link": {
                        "type": "string",
                        "format": "uri"
                    },
                    "shortened_link": {
                        "type": "string",
                        "format": "uri"
                    },
                    "click_count": {
                        "type": "integer",
                        "description": "Number of recorded clicks",
                        "minimum": 0
                    },
                    "last_click": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true,
                        "description": "Most recent click timestamp, null if never clicked"
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    }
                }
            },
            "OptOut": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "uuid"
                    },
                    "phone": {
                        "type": "string",
                        "description": "Phone number that opted out"
                    },
                    "reason": {
                        "type": "string",
                        "description": "Reason for opt-out",
                        "nullable": true
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "updated_at": {
                        "type": "string",
                        "format": "date-time"
                    }
                }
            },
            "Account": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "uuid"
                    },
                    "code": {
                        "type": "string",
                        "description": "Unique account code"
                    },
                    "name": {
                        "type": "string",
                        "description": "Account name"
                    },
                    "description": {
                        "type": "string",
                        "description": "Account description",
                        "nullable": true
                    },
                    "fiscal_code": {
                        "type": "string",
                        "description": "Fiscal registration code",
                        "nullable": true
                    },
                    "registry_number": {
                        "type": "string",
                        "description": "Company registry number",
                        "nullable": true
                    },
                    "iban": {
                        "type": "string",
                        "description": "International Bank Account Number",
                        "nullable": true
                    },
                    "city": {
                        "type": "string",
                        "description": "City"
                    },
                    "state": {
                        "type": "string",
                        "description": "State/Province"
                    },
                    "country": {
                        "type": "string",
                        "description": "Country code"
                    },
                    "address": {
                        "type": "string",
                        "description": "Street address"
                    },
                    "postal_code": {
                        "type": "integer",
                        "description": "Postal/ZIP code",
                        "nullable": true
                    },
                    "email": {
                        "type": "string",
                        "format": "email",
                        "description": "Contact email",
                        "nullable": true
                    },
                    "phone": {
                        "type": "string",
                        "description": "Contact phone number",
                        "nullable": true
                    },
                    "contact_person": {
                        "type": "string",
                        "description": "Contact person name",
                        "nullable": true
                    },
                    "credit": {
                        "type": "number",
                        "format": "float",
                        "description": "Account credit balance"
                    },
                    "status": {
                        "type": "string",
                        "description": "Account status"
                    },
                    "sandbox": {
                        "type": "boolean",
                        "description": "Whether this is a sandbox account"
                    },
                    "daily_limit": {
                        "type": "integer",
                        "description": "How many messages the account can send in a day, midnight to midnight, Romania time; null when no daily limit applies",
                        "nullable": true
                    },
                    "daily_remaining": {
                        "type": "integer",
                        "description": "How many messages the account can still send today, as the X-Daily-Remaining header says; null when no daily limit applies",
                        "nullable": true
                    },
                    "sent_today": {
                        "type": "integer",
                        "description": "The real messages the account created today, Romania time, OTP codes included and test messages left out, one per message whatever its parts"
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    }
                }
            },
            "CreateMessageResponse": {
                "type": "object",
                "properties": {
                    "data": {
                        "$ref": "#/components/schemas/Message"
                    }
                }
            },
            "GetMessageResponse": {
                "type": "object",
                "properties": {
                    "data": {
                        "$ref": "#/components/schemas/Message"
                    }
                }
            },
            "CreateOptOutResponse": {
                "type": "object",
                "properties": {
                    "data": {
                        "$ref": "#/components/schemas/OptOut"
                    }
                }
            },
            "GetOptOutResponse": {
                "type": "object",
                "properties": {
                    "data": {
                        "$ref": "#/components/schemas/OptOut"
                    }
                }
            },
            "GetAccountResponse": {
                "type": "object",
                "properties": {
                    "data": {
                        "$ref": "#/components/schemas/Account"
                    }
                }
            },
            "PaginatedMessages": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Message"
                        }
                    },
                    "links": {
                        "type": "object",
                        "properties": {
                            "first": {
                                "type": "string",
                                "format": "uri",
                                "nullable": true
                            },
                            "last": {
                                "type": "string",
                                "format": "uri",
                                "nullable": true
                            },
                            "prev": {
                                "type": "string",
                                "format": "uri",
                                "nullable": true
                            },
                            "next": {
                                "type": "string",
                                "format": "uri",
                                "nullable": true
                            }
                        }
                    },
                    "meta": {
                        "type": "object",
                        "properties": {
                            "current_page": {
                                "type": "integer"
                            },
                            "from": {
                                "type": "integer",
                                "nullable": true
                            },
                            "path": {
                                "type": "string"
                            },
                            "per_page": {
                                "type": "integer"
                            },
                            "to": {
                                "type": "integer",
                                "nullable": true
                            }
                        }
                    }
                }
            },
            "PaginatedOptOuts": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/OptOut"
                        }
                    },
                    "links": {
                        "type": "object",
                        "properties": {
                            "first": {
                                "type": "string",
                                "format": "uri",
                                "nullable": true
                            },
                            "last": {
                                "type": "string",
                                "format": "uri",
                                "nullable": true
                            },
                            "prev": {
                                "type": "string",
                                "format": "uri",
                                "nullable": true
                            },
                            "next": {
                                "type": "string",
                                "format": "uri",
                                "nullable": true
                            }
                        }
                    },
                    "meta": {
                        "type": "object",
                        "properties": {
                            "current_page": {
                                "type": "integer"
                            },
                            "from": {
                                "type": "integer",
                                "nullable": true
                            },
                            "path": {
                                "type": "string"
                            },
                            "per_page": {
                                "type": "integer"
                            },
                            "to": {
                                "type": "integer",
                                "nullable": true
                            }
                        }
                    }
                }
            },
            "ErrorResponse": {
                "type": "object",
                "properties": {
                    "message": {
                        "type": "string",
                        "description": "Error or status message"
                    },
                    "trace_id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "The request's trace id, the same as the X-Trace-Id header: quote it to support or follow it in the dashboard (Developers, Debug)",
                        "example": "9b80eef1-49d4-4502-85a8-febb68cc11a7"
                    }
                }
            },
            "DailyLimitErrorResponse": {
                "type": "object",
                "description": "A message refused because the account reached its daily sending limit. The request rate limit's 429 has no code: {\"message\": \"Too Many Attempts.\", \"trace_id\": \"…\"}.",
                "properties": {
                    "message": {
                        "type": "string",
                        "description": "What happened, when the limit resets and that it can be raised",
                        "example": "This account can send at most 1,000 messages a day. The limit resets at midnight, Romania time (2026-10-01T00:00:00+03:00). Contact us to raise it."
                    },
                    "code": {
                        "type": "string",
                        "description": "Always daily_limit_exceeded: tells this refusal from the request rate limit's",
                        "enum": [
                            "daily_limit_exceeded"
                        ]
                    },
                    "daily_limit": {
                        "type": "integer",
                        "description": "The account's daily limit, as in the X-Daily-Limit header",
                        "example": 1000
                    },
                    "daily_remaining": {
                        "type": "integer",
                        "description": "How many messages the account can still send today, as in the X-Daily-Remaining header: 0 once the limit is reached",
                        "example": 0
                    },
                    "resets_at": {
                        "type": "string",
                        "format": "date-time",
                        "description": "The next midnight, Romania time, when the account can send again",
                        "example": "2026-10-01T00:00:00+03:00"
                    },
                    "trace_id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "The request's trace id, the same as the X-Trace-Id header: quote it to support or follow it in the dashboard (Developers, Debug)",
                        "example": "9b80eef1-49d4-4502-85a8-febb68cc11a7"
                    }
                }
            },
            "ValidationErrorResponse": {
                "type": "object",
                "properties": {
                    "message": {
                        "type": "string",
                        "description": "Short description of the validation error"
                    },
                    "errors": {
                        "type": "object",
                        "description": "Detailed field validation errors",
                        "additionalProperties": {
                            "type": "array",
                            "items": {
                                "type": "string"
                            }
                        }
                    },
                    "trace_id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "The request's trace id, the same as the X-Trace-Id header: quote it to support or follow it in the dashboard (Developers, Debug)",
                        "example": "9b80eef1-49d4-4502-85a8-febb68cc11a7"
                    }
                }
            },
            "Verification": {
                "type": "object",
                "properties": {
                    "id": { "type": "string", "format": "uuid" },
                    "phone": { "type": "string", "description": "Phone number to verify (E.164 format)" },
                    "brand": { "type": "string", "nullable": true, "description": "Brand to be used in default message template if custom template not provided" },
                    "status": { "type": "string", "enum": ["verified", "unverified"], "description": "Verification status" },
                    "template": { "type": "string", "nullable": true, "description": "Custom SMS template containing {code}" },
                    "created_at": { "type": "string", "format": "date-time" },
                    "expires_at": { "type": "string", "format": "date-time" },
                    "verified_at": { "type": "string", "format": "date-time", "nullable": true },
                    "attempts": { "type": "integer", "minimum": 0 },
                    "expired": { "type": "boolean" }
                }
            },
            "CreateVerificationRequest": {
                "type": "object",
                "properties": {
                    "phone": { "type": "string", "description": "Phone number to verify (E.164 format)" },
                    "brand": { "type": "string", "nullable": true, "maxLength": 120, "description": "Brand used in default message when template is not provided. It may not contain links (web addresses, domains, emails or IP addresses)." },
                    "template": { "type": "string", "nullable": true, "maxLength": 600, "description": "Custom SMS template that MUST include {code}. It may not contain links (web addresses, domains, emails or IP addresses): the code is sent from a shared sender." },
                    "expires_in": { "type": "integer", "nullable": true, "minimum": 1, "maximum": 10, "description": "OTP validity in minutes (1-10). Default 5." }
                },
                "required": ["phone"]
            },
            "VerificationCheckRequest": {
                "type": "object",
                "properties": {
                    "phone": { "type": "string", "description": "Phone number to verify (E.164 format)" },
                    "code": { "type": "string", "minLength": 6, "maxLength": 6, "description": "6 character OTP code (case-insensitive)" }
                },
                "required": ["phone", "code"]
            },
            "CreateVerificationResponse": {
                "type": "object",
                "properties": {
                    "data": { "$ref": "#/components/schemas/Verification" }
                }
            },
            "GetVerificationResponse": {
                "type": "object",
                "properties": {
                    "data": { "$ref": "#/components/schemas/Verification" }
                }
            },
            "PaginatedVerifications": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "array",
                        "items": { "$ref": "#/components/schemas/Verification" }
                    },
                    "links": {
                        "type": "object",
                        "properties": {
                            "first": { "type": "string", "format": "uri", "nullable": true },
                            "last": { "type": "string", "format": "uri", "nullable": true },
                            "prev": { "type": "string", "format": "uri", "nullable": true },
                            "next": { "type": "string", "format": "uri", "nullable": true }
                        }
                    },
                    "meta": {
                        "type": "object",
                        "properties": {
                            "current_page": { "type": "integer" },
                            "from": { "type": "integer", "nullable": true },
                            "path": { "type": "string" },
                            "per_page": { "type": "integer" },
                            "to": { "type": "integer", "nullable": true }
                        }
                    }
                }
            },
            "DeliveryWebhookMessage": {
                "type": "object",
                "description": "Payload sent by Calisero to the provided callback URL when a message status changes.",
                "properties": {
                    "price": {"type": "number", "format": "float", "description": "Price charged for the message part(s)."},
                    "sender": {"type": "string", "description": "Sender ID or phone number."},
                    "status": {"type": "string", "enum": ["sent", "delivered", "undelivered"], "description": "Delivery status."},
                    "messageId": {"type": "string", "format": "uuid", "description": "Unique identifier of the message."},
                    "recipient": {"type": "string", "description": "Recipient MSISDN in E.164 format."},
                    "sentAt": {"type": "string", "format": "date-time", "nullable": true, "description": "Timestamp when the message was sent to the network (present for statuses sent or delivered)."},
                    "deliveredAt": {"type": "string", "format": "date-time", "nullable": true, "description": "Timestamp when the handset confirmed delivery (present only for delivered)."},
                    "scheduleAt": {"type": "string", "format": "date-time", "nullable": true, "description": "Original scheduled sending time if the message was scheduled."},
                    "remainingBalance": {"type": "number", "format": "float", "nullable": true, "description": "Remaining account balance after billing (if available)."},
                    "dailyLimit": {"type": "integer", "nullable": true, "description": "The account's daily sending limit when the callback was sent; null when no daily limit applies. The same as daily_limit in GET /accounts/{accountId}."},
                    "dailyRemaining": {"type": "integer", "nullable": true, "description": "How many messages the account could still send today when the callback was sent; null when no daily limit applies. The same as daily_remaining in GET /accounts/{accountId}."},
                    "sentToday": {"type": "integer", "description": "The real messages the account created today, Romania time, when the callback was sent: OTP codes included, test messages left out, one per message whatever its parts. The same as sent_today in GET /accounts/{accountId}."}
                },
                "required": ["price", "sender", "status", "messageId", "recipient"]
            }
        }
    }
}
