# SMS API > **Prefix:** `/api/v1/sms` > **Providers:** `kavenegar` (default) | `rangineh` > All send operations are dispatched **asynchronously** via Symfony Messenger → Redis queue. --- ## POST `/api/v1/sms/send` Send a direct SMS message (free text). **Permission:** `ROLE_ADMIN` ### Request Body (`application/json`) ```json { "mobile": "09123456789", "message": "سلام، پیام آزمایشی", "provider": "kavenegar" } ``` | Field | Type | Required | Description | |-------|------|----------|-------------| | `mobile` | string | ✅ | Recipient mobile (`09XXXXXXXXX`) | | `message` | string | ✅ | Message text | | `provider` | string | ❌ | `"kavenegar"` or `"rangineh"` (default from env) | ### Response `200` ```json { "success": true, "data": { "message": "پیامک با موفقیت ارسال شد" } } ``` ### Errors | Code | HTTP | Description | |------|------|-------------| | `ERR_AUTH_001` | 401 | Missing token | | `ERR_AUTH_006` | 403 | Not admin | | `ERR_VALIDATION_001` | 422 | Invalid mobile format | --- ## POST `/api/v1/sms/send-template` Send an SMS using an approved template. **Permission:** `ROLE_ADMIN` ### Request Body (`application/json`) ```json { "mobile": "09123456789", "template_uuid": "tmpl-uuid-...", "vars": { "name": "دکتر علی احمدی", "date": "۱۵ خرداد ۱۴۰۴" }, "provider": "kavenegar" } ``` | Field | Type | Required | Description | |-------|------|----------|-------------| | `mobile` | string | ✅ | Recipient mobile | | `template_uuid` | string (UUID) | ✅ | UUID of an approved template | | `vars` | object | ❌ | Key-value substitutions for template placeholders | | `provider` | string | ❌ | Override provider | ### Response `200` ```json { "success": true, "data": { "message": "پیامک با موفقیت ارسال شد" } } ``` ### Errors | Code | HTTP | Description | |------|------|-------------| | `ERR_AUTH_001` | 401 | Missing token | | `ERR_AUTH_006` | 403 | Not admin | | `ERR_NOT_FOUND_001` | 404 | Template not found | | `ERR_VALIDATION_001` | 422 | Template not approved | --- ## POST `/api/v1/sms/template` Create a new SMS template. **Permission:** `ROLE_ADMIN` ### Request Body (`application/json`) ```json { "name": "تأیید نوبت", "body": "دکتر گرامی ${name}، نوبت شما در تاریخ ${date} تأیید شد.", "variables": ["name", "date"] } ``` | Field | Type | Required | Description | |-------|------|----------|-------------| | `name` | string | ✅ | Template display name | | `body` | string | ✅ | Template text with `${variable}` placeholders | | `variables` | string[] | ❌ | List of expected variable names | ### Response `201` ```json { "success": true, "data": { "uuid": "tmpl-uuid-...", "name": "تأیید نوبت", "body": "دکتر گرامی ${name}...", "variables": ["name", "date"], "status": "draft", "created_at": 1717000000 } } ``` **Template Status Values:** | Value | Description | |-------|-------------| | `draft` | Created, not submitted | | `pending` | Submitted for review | | `approved` | Ready to use | | `rejected` | Rejected | ### Errors | Code | HTTP | Description | |------|------|-------------| | `ERR_AUTH_001` | 401 | Missing token | | `ERR_AUTH_006` | 403 | Not admin | | `ERR_VALIDATION_002` | 422 | Missing required field | --- ## GET `/api/v1/sms/template/{uuid}` Get template detail. **Permission:** `AUTH` ### Response `200` Template object. ### Errors | Code | HTTP | Description | |------|------|-------------| | `ERR_AUTH_001` | 401 | Missing token | | `ERR_NOT_FOUND_001` | 404 | Template not found | --- ## PATCH `/api/v1/sms/template/{uuid}` Update a template (only allowed in `draft` or `rejected` status). **Permission:** `ROLE_ADMIN` ### Request Body (`application/json`) ```json { "name": "تأیید نوبت - ویرایش", "body": "نوبت شما در ${date} تأیید شد.", "variables": ["date"] } ``` All fields optional. ### Response `200` Updated template object. ### Errors | Code | HTTP | Description | |------|------|-------------| | `ERR_AUTH_001` | 401 | Missing token | | `ERR_AUTH_006` | 403 | Not admin | | `ERR_NOT_FOUND_001` | 404 | Template not found | | `ERR_SMS_003` | 422 | Template already submitted/approved | --- ## POST `/api/v1/sms/template/{uuid}/submit` Submit template for admin review (moves status from `draft` to `pending`). **Permission:** `ROLE_ADMIN` ### Response `200` Updated template with `status: "pending"`. ### Errors | Code | HTTP | Description | |------|------|-------------| | `ERR_AUTH_001` | 401 | Missing token | | `ERR_AUTH_006` | 403 | Not admin | | `ERR_NOT_FOUND_001` | 404 | Template not found | | `ERR_SMS_003` | 422 | Already submitted | --- ## DELETE `/api/v1/sms/template/{uuid}` Delete a template. **Permission:** `ROLE_ADMIN` ### Response `200` ```json { "success": true, "data": { "message": "قالب پیامک حذف شد" } } ``` ### Errors | Code | HTTP | Description | |------|------|-------------| | `ERR_AUTH_001` | 401 | Missing token | | `ERR_AUTH_006` | 403 | Not admin | | `ERR_NOT_FOUND_001` | 404 | Template not found | --- ## GET `/api/v1/admin/sms/templates` List all templates (admin view with all statuses). **Permission:** `ROLE_ADMIN` ### Response `200` ```json { "success": true, "data": [ { "uuid": "...", "name": "تأیید نوبت", "status": "approved", "created_at": 1717000000 } ] } ``` --- ## POST `/api/v1/admin/sms/template/{uuid}/approve` Approve a pending template. **Permission:** `ROLE_ADMIN` ### Request Body (`application/json`) ```json { "note": "تأیید شد", "provider_code": "verify_appointment" } ``` | Field | Type | Required | Description | |-------|------|----------|-------------| | `note` | string | ❌ | Admin note | | `provider_code` | string | ❌ | Provider-side template code | ### Response `200` Updated template with `status: "approved"`. --- ## POST `/api/v1/admin/sms/template/{uuid}/reject` Reject a pending template. **Permission:** `ROLE_ADMIN` ### Request Body ```json { "note": "متن قالب نامناسب است" } ``` | Field | Type | Required | |-------|------|----------| | `note` | string | ✅ | ### Response `200` Updated template with `status: "rejected"`. ### Errors | Code | HTTP | Description | |------|------|-------------| | `ERR_VALIDATION_002` | 422 | Missing note |