openapi: 3.2.0 info: title: api.onesignal.com Notifications?c=sms API version: '11.6' servers: - url: https://api.onesignal.com security: - {} tags: - name: Notifications?c=sms paths: /notifications?c=sms: post: summary: SMS description: Send a message using the SMS channel. operationId: sms x-codeSamples: - lang: typescript label: Node.js SDK source: "import Onesignal from '@onesignal/node-onesignal';\nimport { randomUUID } from 'node:crypto';\n\nconst configuration = Onesignal.createConfiguration({\n restApiKey: 'YOUR_REST_API_KEY',\n});\nconst apiInstance = new Onesignal.DefaultApi(configuration);\n\nconst notification = new Onesignal.Notification();\nnotification.app_id = 'YOUR_APP_ID';\nnotification.contents = { en: 'Hello from OneSignal!' };\nnotification.sms_from = '+15551234567';\n// Target by External ID: alias keys must match the API (external_id, not externalId).\nnotification.include_aliases = { external_id: ['YOUR_USER_EXTERNAL_ID'] };\nnotification.target_channel = 'sms';\n// Idempotency key: a client-generated UUID that lets you safely retry on network failure.\n// If two requests arrive with the same key inside the 30-day window, only the first is sent\n// and the second returns the original response. `randomUUID` is imported from `node:crypto`\n// (available on Node 14.17+) — DO NOT reuse keys across logically distinct sends.\nnotification.idempotency_key = randomUUID();\n\ntry {\n const response = await apiInstance.createNotification(notification);\n if (!response.id) {\n console.warn(\"Notification was not sent:\", response.errors);\n } else if (response.errors) {\n console.log(\"Notification created:\", response.id, \"(partial failures:\", response.errors, \")\");\n } else {\n console.log(\"Notification created:\", response.id);\n }\n} catch (e) {\n if (e instanceof Onesignal.ApiException) {\n // `e.errorMessages` flattens any error-envelope shape to a `string[]`;\n // the raw parsed body remains on `e.body`.\n console.error(\"createNotification failed: HTTP \" + e.code, e.errorMessages);\n } else {\n throw e;\n }\n}" - lang: python label: Python SDK source: "import uuid\nimport onesignal\nfrom onesignal.api import default_api\nfrom onesignal.model.language_string_map import LanguageStringMap\nfrom onesignal.model.notification import Notification\n\n# See configuration.py for a list of all supported configuration parameters.\n# Some of the OneSignal endpoints require ORGANIZATION_API_KEY token for authorization, while others require REST_API_KEY.\n# We recommend adding both of them in the configuration page so that you will not need to figure it out yourself.\nconfiguration = onesignal.Configuration(\n rest_api_key = \"YOUR_REST_API_KEY\", # App REST API key required for most endpoints\n organization_api_key = \"YOUR_ORGANIZATION_API_KEY\" # Organization key is only required for creating new apps and other top-level endpoints\n)\n\n\nwith onesignal.ApiClient(configuration) as api_client:\n api_instance = default_api.DefaultApi(api_client)\n notification = Notification(\n app_id='YOUR_APP_ID',\n contents=LanguageStringMap(en='Hello from OneSignal!'),\n sms_from='+15551234567',\n include_aliases={'external_id': ['YOUR_USER_EXTERNAL_ID']},\n target_channel='sms',\n # Idempotency key: a client-generated UUID that lets you safely retry on network\n # failure. If two requests arrive with the same key inside the 30-day window, only\n # the first is sent and the second returns the original response. Use uuid.uuid4()\n # or a similar source of randomness — DO NOT reuse keys across logically distinct\n # sends.\n idempotency_key=str(uuid.uuid4()),\n )\n try:\n api_response = api_instance.create_notification(notification)\n # `api_response.id` discriminates the two HTTP 200 shapes. A falsy value means no\n # notification was created (e.g. all targets were unreachable / not subscribed).\n # `api_response.errors` is polymorphic: a `list[str]` in the no-subscribers case, or\n # a dict keyed by recipient-identifier type (`invalid_player_ids`,\n # `invalid_external_user_ids`, `invalid_aliases`, ...) when the notification WAS\n # created but some recipients were skipped. Access via `.get('errors')` rather than\n # attribute access — the legacy Python generator's `ModelNormal.__getattr__` raises\n # `ApiAttributeError` for optional fields that the server omitted, so plain\n # `api_response.errors` would crash on the pure-success path.\n response_id = api_response.get('id')\n response_errors = api_response.get('errors')\n if not response_id:\n print('Notification was not sent:', response_errors)\n elif response_errors:\n print('Notification created:', response_id, '(partial failures:', response_errors, ')')\n else:\n print('Notification created:', response_id)\n except onesignal.ApiException as e:\n print('Exception when calling DefaultApi->create_notification: %s\\n' % e)\n print('Status Code: %s' % e.status)\n # `e.error_messages` flattens any error-envelope shape to a list[str];\n # the raw body remains on `e.body`.\n print('Error Messages: %s' % e.error_messages)\n print('Response Body: %s' % e.body)" - lang: php label: PHP SDK source: "setRestApiKeyToken('YOUR_REST_API_KEY')\n ->setOrganizationApiKeyToken('YOUR_ORGANIZATION_API_KEY');\n\n\n\n$apiInstance = new onesignal\\client\\Api\\DefaultApi(\n new GuzzleHttp\\Client(),\n $config\n);\n\n$notification = new onesignal\\client\\Model\\Notification();\n$notification->setAppId('YOUR_APP_ID');\n$contents = new onesignal\\client\\Model\\LanguageStringMap();\n$contents->setEn('Hello from OneSignal!');\n$notification->setContents($contents);\n$notification->setSmsFrom('+15551234567');\n$notification->setIncludeAliases(['external_id' => ['YOUR_USER_EXTERNAL_ID']]);\n$notification->setTargetChannel('sms');\n// Idempotency key: a client-generated UUID that lets you safely retry on network failure.\n// If two requests arrive with the same key inside the 30-day window, only the first is sent\n// and the second returns the original response. Use a strong source of randomness — DO NOT\n// reuse keys across logically distinct sends. We use PHP 7+'s built-in random_bytes() here\n// so the snippet works against this SDK's declared composer.json deps (Guzzle + PSR-7) with\n// no extra install; projects that already pull in ramsey/uuid can swap in\n// `\\Ramsey\\Uuid\\Uuid::uuid4()->toString()` instead.\n$idempotencyKeyBytes = random_bytes(16);\n$idempotencyKeyBytes[6] = chr(ord($idempotencyKeyBytes[6]) & 0x0f | 0x40);\n$idempotencyKeyBytes[8] = chr(ord($idempotencyKeyBytes[8]) & 0x3f | 0x80);\n$idempotencyKey = vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($idempotencyKeyBytes), 4));\n$notification->setIdempotencyKey($idempotencyKey);\n\ntry {\n $result = $apiInstance->createNotification($notification);\n // `$result->getId()` discriminates the two HTTP 200 shapes. A falsy value (empty\n // string or null) means no notification was created (e.g. all targets were\n // unreachable / not subscribed). `$result->getErrors()` is polymorphic: a `string[]`\n // in the no-subscribers case, or an object keyed by recipient-identifier type\n // (`invalid_player_ids`, `invalid_external_user_ids`, `invalid_aliases`, ...) when\n // the notification WAS created but some recipients were skipped.\n if (!$result->getId()) {\n echo 'Notification was not sent: ', print_r($result->getErrors(), true), PHP_EOL;\n } elseif ($result->getErrors()) {\n echo 'Notification created: ', $result->getId(), ' (partial failures: ', print_r($result->getErrors(), true), ')', PHP_EOL;\n } else {\n echo 'Notification created: ', $result->getId(), PHP_EOL;\n }\n} catch (\\onesignal\\client\\ApiException $e) {\n echo 'Exception when calling DefaultApi->createNotification: ', $e->getMessage(), PHP_EOL;\n echo 'Status Code: ', $e->getCode(), PHP_EOL;\n echo 'Response Body: ', $e->getResponseBody(), PHP_EOL;\n} catch (\\Exception $e) {\n echo 'Exception when calling DefaultApi->createNotification: ', $e->getMessage(), PHP_EOL;\n}" - lang: go label: Go SDK source: "package main\n\nimport (\n \"context\"\n \"fmt\"\n \"os\"\n\n \"github.com/google/uuid\"\n \"github.com/OneSignal/onesignal-go-api/v5\"\n)\n\nfunc main() {\n configuration := onesignal.NewConfiguration()\n apiClient := onesignal.NewAPIClient(configuration)\n\n restAuth := context.WithValue(context.Background(), onesignal.RestApiKey, \"YOUR_REST_API_KEY\")\n\n notification := onesignal.NewNotification(\"YOUR_APP_ID\")\n contents := onesignal.NewLanguageStringMap()\n contents.SetEn(\"Hello from OneSignal!\")\n notification.SetContents(*contents)\n notification.SetSmsFrom(\"+15551234567\")\n notification.SetIncludeAliases(map[string][]string{\"external_id\": {\"YOUR_USER_EXTERNAL_ID\"}})\n notification.SetTargetChannel(\"sms\")\n // Idempotency key: a client-generated UUID that lets you safely retry on network failure.\n // If two requests arrive with the same key inside the 30-day window, only the first is\n // sent and the second returns the original response. The `github.com/google/uuid` module\n // is not a declared dep of this SDK; run `go get github.com/google/uuid` (or `go mod tidy`\n // after importing it) before building. DO NOT reuse keys across logically distinct sends.\n notification.SetIdempotencyKey(uuid.NewString())\n\n resp, r, err := apiClient.DefaultApi.CreateNotification(restAuth).Notification(*notification).Execute()\n if err != nil {\n fmt.Fprintf(os.Stderr, \"Error when calling `DefaultApi.CreateNotification``: %v\\n\", err)\n fmt.Fprintf(os.Stderr, \"Full HTTP response: %v\\n\", r)\n if apiErr, ok := err.(*onesignal.GenericOpenAPIError); ok {\n fmt.Fprintf(os.Stderr, \"Response Body: %s\\n\", apiErr.Body())\n }\n return\n }\n // `resp.GetId()` discriminates the two HTTP 200 shapes. An empty string means no\n // notification was created (e.g. all targets were unreachable / not subscribed).\n // `resp.GetErrors()` is `interface{}` because the field is polymorphic: a `[]string` in\n // the no-subscribers case, or a map keyed by recipient-identifier type\n // (`invalid_player_ids`, `invalid_external_user_ids`, `invalid_aliases`, ...) when\n // the notification WAS created but some recipients were skipped.\n if resp.GetId() == \"\" {\n fmt.Fprintf(os.Stderr, \"Notification was not sent: %v\\n\", resp.GetErrors())\n } else if errors := resp.GetErrors(); errors != nil {\n fmt.Fprintf(os.Stdout, \"Notification created: %s (partial failures: %v)\\n\", resp.GetId(), errors)\n } else {\n fmt.Fprintf(os.Stdout, \"Notification created: %s\\n\", resp.GetId())\n }\n}" - lang: ruby label: Ruby SDK source: "require 'onesignal'\n# setup authorization\nOneSignal.configure do |config|\n # Configure Bearer authorization: rest_api_key\n config.rest_api_key = 'YOUR_REST_API_KEY'\n\nend\n\napi_instance = OneSignal::DefaultApi.new\nrequire 'securerandom'\n\nnotification = OneSignal::Notification.new\nnotification.app_id = 'YOUR_APP_ID'\nnotification.contents = OneSignal::LanguageStringMap.new({ en: 'Hello from OneSignal!' })\nnotification.sms_from = '+15551234567'\nnotification.include_aliases = { 'external_id' => ['YOUR_USER_EXTERNAL_ID'] }\nnotification.target_channel = 'sms'\n# Idempotency key: a client-generated UUID that lets you safely retry on network failure.\n# If two requests arrive with the same key inside the 30-day window, only the first is sent\n# and the second returns the original response. Use SecureRandom.uuid — DO NOT reuse keys\n# across logically distinct sends.\nnotification.idempotency_key = SecureRandom.uuid\n\nbegin\n # Create notification\n result = api_instance.create_notification(notification)\n # `result.id` discriminates the two HTTP 200 shapes. An empty string means no\n # notification was created (e.g. all targets were unreachable / not subscribed).\n # `result.errors` is polymorphic: an `Array` in the no-subscribers case, or\n # a Hash keyed by recipient-identifier type (`invalid_player_ids`,\n # `invalid_external_user_ids`, `invalid_aliases`, ...) when the notification WAS\n # created but some recipients were skipped.\n if result.id.to_s.empty?\n puts \"Notification was not sent: #{result.errors}\"\n elsif result.errors\n puts \"Notification created: #{result.id} (partial failures: #{result.errors})\"\n else\n puts \"Notification created: #{result.id}\"\n end\nrescue OneSignal::ApiError => e\n puts \"Error when calling DefaultApi->create_notification: #{e}\"\n puts \"Status Code: #{e.code}\"\n # `e.error_messages` flattens any error-envelope shape to an Array;\n # the raw body remains on `e.response_body`.\n puts \"Error Messages: #{e.error_messages}\"\n puts \"Response Body: #{e.response_body}\"\nend" - lang: java label: Java SDK source: "// Import classes:\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.UUID;\n\nimport com.onesignal.client.ApiClient;\nimport com.onesignal.client.ApiException;\nimport com.onesignal.client.Configuration;\nimport com.onesignal.client.auth.*;\nimport com.onesignal.client.model.*;\nimport com.onesignal.client.api.DefaultApi;\n\npublic class Example {\n public static void main(String[] args) {\n ApiClient defaultClient = Configuration.getDefaultApiClient();\n defaultClient.setBasePath(\"https://api.onesignal.com\");\n\n HttpBearerAuth rest_api_key = (HttpBearerAuth) defaultClient.getAuthentication(\"rest_api_key\");\n rest_api_key.setBearerToken(\"YOUR_REST_API_KEY\");\n\n DefaultApi apiInstance = new DefaultApi(defaultClient);\n Notification notification = new Notification();\n notification.setAppId(\"YOUR_APP_ID\");\n LanguageStringMap contents = new LanguageStringMap();\n contents.setEn(\"Hello from OneSignal!\");\n notification.setContents(contents);\n notification.setSmsFrom(\"+15551234567\");\n Map> aliases = new HashMap<>();\n aliases.put(\"external_id\", Arrays.asList(\"YOUR_USER_EXTERNAL_ID\"));\n notification.setIncludeAliases(aliases);\n notification.setTargetChannel(Notification.TargetChannelEnum.SMS);\n // Idempotency key: a client-generated UUID that lets you safely retry on network failure.\n // If two requests arrive with the same key inside the 30-day window, only the first is\n // sent and the second returns the original response. Use UUID.randomUUID() — DO NOT\n // reuse keys across logically distinct sends.\n notification.setIdempotencyKey(UUID.randomUUID().toString());\n\n try {\n CreateNotificationSuccessResponse result = apiInstance.createNotification(notification);\n // `result.getId()` discriminates the two HTTP 200 shapes. An empty string means no\n // notification was created (e.g. all targets were unreachable / not subscribed).\n // `result.getErrors()` is polymorphic (declared as `Object`): a `List` in the\n // no-subscribers case, or a Map keyed by recipient-identifier type\n // (`invalid_player_ids`, `invalid_external_user_ids`, `invalid_aliases`, ...) when\n // the notification WAS created but some recipients were skipped.\n if (result.getId() == null || result.getId().isEmpty()) {\n System.out.println(\"Notification was not sent: \" + result.getErrors());\n } else if (result.getErrors() != null) {\n System.out.println(\"Notification created: \" + result.getId() + \" (partial failures: \" + result.getErrors() + \")\");\n } else {\n System.out.println(\"Notification created: \" + result.getId());\n }\n } catch (ApiException e) {\n System.err.println(\"Exception when calling DefaultApi#createNotification\");\n System.err.println(\"Status code: \" + e.getCode());\n System.err.println(\"Reason: \" + e.getResponseBody());\n System.err.println(\"Response headers: \" + e.getResponseHeaders());\n e.printStackTrace();\n }\n }\n}" - lang: csharp label: C# SDK source: "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing OneSignalApi.Api;\nusing OneSignalApi.Client;\nusing OneSignalApi.Model;\n\nnamespace Example\n{\n public class CreateNotificationExample\n {\n public static void Main()\n {\n Configuration config = new Configuration();\n config.BasePath = \"https://api.onesignal.com\";\n config.AccessToken = \"YOUR_REST_API_KEY\";\n\n var apiInstance = new DefaultApi(config);\n\n var notification = new Notification\n {\n AppId = \"YOUR_APP_ID\",\n Contents = new LanguageStringMap(en: \"Hello from OneSignal!\"),\n SmsFrom = \"+15551234567\",\n IncludeAliases = new Dictionary>\n {\n { \"external_id\", new List { \"YOUR_USER_EXTERNAL_ID\" } }\n },\n TargetChannel = Notification.TargetChannelEnum.Sms,\n // Idempotency key: a client-generated UUID that lets you safely retry on\n // network failure. If two requests arrive with the same key inside the\n // 30-day window, only the first is sent and the second returns the original\n // response. Use Guid.NewGuid() — DO NOT reuse keys across logically distinct\n // sends.\n IdempotencyKey = Guid.NewGuid().ToString()\n };\n\n try\n {\n CreateNotificationSuccessResponse result = apiInstance.CreateNotification(notification);\n // `result.Id` discriminates the two HTTP 200 shapes. An empty string means\n // no notification was created (e.g. all targets were unreachable / not\n // subscribed). `result.Errors` is polymorphic: a `List` in the\n // no-subscribers case, or an object keyed by recipient-identifier type\n // (`invalid_player_ids`, `invalid_external_user_ids`, `invalid_aliases`, ...)\n // when the notification WAS created but some recipients were skipped.\n if (string.IsNullOrEmpty(result.Id))\n {\n Debug.WriteLine(\"Notification was not sent: \" + result.Errors);\n }\n else if (result.Errors != null)\n {\n Debug.WriteLine(\"Notification created: \" + result.Id + \" (partial failures: \" + result.Errors + \")\");\n }\n else\n {\n Debug.WriteLine(\"Notification created: \" + result.Id);\n }\n }\n catch (ApiException e)\n {\n Debug.Print(\"Exception when calling DefaultApi.CreateNotification: \" + e.Message);\n Debug.Print(\"Status Code: \" + e.ErrorCode);\n Debug.Print(\"Response Body: \" + e.ErrorContent);\n Debug.Print(e.StackTrace);\n }\n }\n }\n}" - lang: rust label: Rust SDK source: "use onesignal_rust_api::apis::configuration::Configuration;\nuse onesignal_rust_api::apis::default_api;\nuse onesignal_rust_api::models::notification::TargetChannelType;\nuse onesignal_rust_api::models::{LanguageStringMap, Notification};\nuse uuid::Uuid;\n\n#[tokio::main]\nasync fn main() {\n let mut configuration = Configuration::new();\n configuration.rest_api_key_token = Some(\"YOUR_REST_API_KEY\".to_string());\n\n let mut notification = Notification::new(\"YOUR_APP_ID\".to_string());\n notification.contents = Some(Box::new(LanguageStringMap {\n en: Some(\"Hello from OneSignal!\".to_string()),\n ..Default::default()\n }));\n notification.sms_from = Some(\"+15551234567\".to_string());\n let mut aliases = std::collections::HashMap::new();\n aliases.insert(\n \"external_id\".to_string(),\n vec![\"YOUR_USER_EXTERNAL_ID\".to_string()],\n );\n notification.include_aliases = Some(aliases);\n notification.target_channel = Some(TargetChannelType::Sms);\n // Idempotency key: a client-generated UUID that lets you safely retry on network failure.\n // If two requests arrive with the same key inside the 30-day window, only the first is\n // sent and the second returns the original response. The `uuid` crate must be declared\n // in your own Cargo.toml (Cargo doesn't expose transitive crates by name to downstream\n // code) — add `uuid = { version = \"1\", features = [\"v4\"] }` to your `[dependencies]`.\n // DO NOT reuse keys across logically distinct sends.\n notification.idempotency_key = Some(Uuid::new_v4().to_string());\n\n match default_api::create_notification(&configuration, notification).await {\n Ok(resp) => {\n // `resp.id` discriminates the two HTTP 200 shapes. An empty string or `None`\n // means no notification was created (e.g. all targets were unreachable / not\n // subscribed). `resp.errors` is polymorphic (typed as `Option`):\n // a `Vec` in the no-subscribers case, or an object keyed by\n // recipient-identifier type (`invalid_player_ids`, `invalid_external_user_ids`,\n // `invalid_aliases`, ...) when the notification WAS created but some recipients\n // were skipped.\n match resp.id.as_deref() {\n Some(\"\") | None => eprintln!(\"Notification was not sent: {:?}\", resp.errors),\n Some(id) if resp.errors.is_some() => {\n println!(\"Notification created: {} (partial failures: {:?})\", id, resp.errors)\n }\n Some(id) => println!(\"Notification created: {}\", id),\n }\n }\n Err(onesignal_rust_api::apis::Error::ResponseError(content)) => {\n eprintln!(\"create_notification failed: HTTP {}\", content.status);\n eprintln!(\"Response Body: {}\", content.content);\n }\n Err(e) => eprintln!(\"create_notification failed: {:?}\", e),\n }\n}" parameters: - name: Authorization in: header description: Your App API key with prefix `Key `. See [Keys & IDs](/docs/en/keys-and-ids). required: true schema: type: string default: Key YOUR_APP_API_KEY requestBody: content: application/json: schema: type: object required: - app_id - contents - target_channel properties: app_id: type: string description: Your OneSignal App ID in UUID v4 format. See [Keys & IDs](/docs/en/keys-and-ids). default: YOUR_APP_ID contents: type: object description: 'The main message body with [language-specific values](/docs/en/multi-language-messaging#supported-languages). Too many characters may result in multiple messages and increased costs. See [SMS](/docs/sms-messaging). Required unless using `template_id`. Supports [Message Personalization](/docs/message-personalization). You can add trackable links to your SMS via the API by including liquid syntax in your message contents. For example: {{''your_url'' | track_link}} The liquid syntax block will be replaced with a trackable short link in the following format: 1sgnl.co/XXXX. Using trackable links allows you to see the click through rates of your SMS.' required: - en properties: en: type: string description: The required message language type. See [Supported Languages](/docs/en/multi-language-messaging#supported-languages). include_aliases: type: object description: Target up to 20,000 users by their `external_id`, `onesignal_id`, or your own custom alias. Use with `target_channel` to control the delivery channel. Not compatible with any other targeting parameters like `filters`, `include_subscription_ids`, `included_segments`, or `excluded_segments`. See [Sending messages with the OneSignal API](/reference/create-message#include-aliases). format: json properties: external_id: description: An array of external IDs which should be the same as the user ID in your app. This is the recommended method for targeting users. See [Users](/docs/users). type: array items: type: string target_channel: type: string description: The targeted delivery channel. Required when using `include_aliases` and `included_segments` for SMS/RCS. Accepts `push`, `email`, or `sms`. enum: - push - email - sms default: sms include_subscription_ids: type: array description: Target users' specific [subscriptions](/docs/subscriptions) by ID. Include up to 20,000 `subscription_id` per API call. Not compatible with any other targeting parameters like `filters`, `include_aliases`, `included_segments`, or `excluded_segments`. See [Sending messages with the OneSignal API](/reference/create-message). items: type: string include_phone_numbers: type: array description: Send SMS/MMS to specific users by their phone number in [E.164 format](/docs/sms-setup#what-is-e164-format). Can only be used when sending [SMS/MMS](/reference/sms). Include up to 20,000 phone numbers per API call. If the phone number does not exist within the OneSignal App, then a new SMS Subscription will be created. Not compatible with any other targeting parameters like `filters`, `include_aliases`, `included_segments`, or `excluded_segments`. See [Sending messages with the OneSignal API](/reference/create-message). items: type: string included_segments: type: array description: Target predefined [Segments](/docs/segmentation). Users that are in multiple segments will only be sent the message once. Can be combined with `excluded_segments`. Requires `target_channel` to be set to `'sms'` or `isSms=true` when sending SMS/RCS. Not compatible with any other targeting parameters like `filters`, `include_aliases`, or `include_subscription_ids`. See [Sending messages with the OneSignal API](/reference/create-message). items: type: string excluded_segments: type: array description: Exclude users in predefined [Segments](/docs/segmentation). Overrides membership in any segment specified in the `included_segments`. Not compatible with any other targeting parameters like `filters`, `include_aliases`, or `include_subscription_ids`. See [Sending messages with the OneSignal API](/reference/create-message). items: type: string filters: type: array description: Filters define the segment based on user properties like tags, activity, or location using flexible AND/OR logic. Limited to 200 total entries, including fields and `OR` operators. See [Sending messages with the OneSignal API](/reference/create-message#filters). items: oneOf: - title: Filter description: Required. The fitler object. required: - field - relation type: object properties: field: type: string description: The name of the filter to use. enum: - tag - last_session - first_session - session_count - session_time - language - app_version - location - country relation: type: string description: Used with most filters. See details on the specific filter. enum: - '=' - '!=' - '>' - < - exists - not_exists - in_array - not_in_array - time_elapsed_gt - time_elapsed_lt key: type: string description: Used with the `tag` filter. This is the tag `key`. value: type: string description: The value of the `field` or tag `key` in which you want to filter with. - title: Operator type: object properties: operator: type: string description: Chain filter conditions with implicit `AND` and `OR` logic. Never end your `filters` object with an `operator`. See [filters](/reference/create-message#filters) for more. enum: - AND - OR default: AND minItems: 1 maxItems: 200 sms_from: type: string description: The [Messaging Service ID](/docs/en/sms-setup#step-2-create-senders) or phone number used to send the SMS or MMS. Its recommended to use Messaging Service SIDs (e.g., `MGxxxxxxxxxxxxxxx`) but also accepts E.164 phone numbers (e.g., `+12065551234`). Defaults to the sender selected in [SMS Setup](/docs/en/sms-setup). If using [per-sender opt-out](/docs/en/sms-consent-keyword-management), you must use a Messaging Service ID. sms_media_urls: type: array description: URLs for the media files to be sent as MMS. Additional rates apply. `sms_from` must support sending MMS messages. See [SMS](/docs/sms-messaging). items: type: string name: type: string description: An internal name you set to help organize and track messages. Not shown to recipients. Maximum 128 characters. template_id: type: string description: The template ID in UUID v4 format set for the message if applicable. See [Templates](/docs/en/templates). custom_data: type: object description: 'Include user or context-specific data (e.g., cart items, OTPs, links) in a message. Use with `template_id`. See [Message Personalization](/docs/message-personalization). Max size: 2KB (Push/SMS), 10KB (Email).' send_after: type: string description: 'Schedule delivery for a future date/time (in UTC). The format must be valid per the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) standard and compatible with [`JavaScript’s Date() parser`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date#datestring). Example: `2025-09-24T14:00:00-07:00`' idempotency_key: type: string description: A unique identifier used to prevent duplicate messages from repeat API calls. See [Idempotent notification requests](/reference/idempotent-notification-requests). Any RFC 9562 UUID supported. Valid for 30 days. Previously called `external_id`. responses: '200': description: '200' content: application/json: schema: oneOf: - title: Message Sent type: object properties: id: type: string description: Notification ID in UUID v4 format. If `id` is an empty string, then the message was not sent. format: uuid external_id: type: - string - 'null' description: The `idempotency_key` parameter from the request, echoed back. Null when no idempotency_key was provided. Used to detect duplicate-send attempts — see [Idempotent message requests](/reference/idempotent-notification-requests). errors: type: object description: Per-channel listings of invalid identifiers in the request. Only emitted when at least one identifier in the request failed validation. Each listed key is optional; the keys present depend on the channel and request. properties: invalid_phone_numbers: type: array items: type: string description: The listed phone numbers used in the `include_phone_numbers` parameter that were unsubscribed from the message channel before the message was sent. invalid_aliases: type: object description: The alias label that was used in the `include_aliases` parameter. properties: external_id: type: array items: type: string description: The alias IDs associated with the unsubscribed Subscriptions. The Subscriptions associated with the listed aliases were unsubscribed before the message was sent. In this example, `user_id_1` has two unsubscribed Subscriptions while `user_id_2` has one unsubscribed Subscription. example: '["user_id_1", "user_id_1", "user_id_2"]' onesignal_id: type: array items: type: string description: The OneSignal ID associated with the unsubscribed Subscription. The Subscriptions associated with the listed OneSignal IDs were unsubscribed before the message was sent. In this example, the user with OneSignal ID `1589641e-bed1-4325-bce4-d2234e578884` has three unsubscribed Subscriptions. example: '["1589641e-bed1-4325-bce4-d2234e578884", "1589641e-bed1-4325-bce4-d2234e578884", "1589641e-bed1-4325-bce4-d2234e578884"]' invalid_player_ids: type: array items: type: string description: The Subscription ID exists in the OneSignal app but is unsubscribed from the message channel. If the Subscription ID did not exist, it will not be reported. warnings: oneOf: - type: object description: Object form. properties: invalid_external_user_ids: type: string description: external_ids whose subscriptions are unsubscribed. additionalProperties: true - type: array items: type: string description: Array form. Contains non-fatal warning messages. description: Non-fatal warnings emitted alongside a successful send. description: Notification was accepted and dispatched to one or more subscribers. `errors` (when present) reports per-channel invalid identifiers; `warnings` (when present) reports non-fatal issues such as unsubscribed external IDs. `external_id` echoes the request's `idempotency_key` (or null when not provided). required: - id - title: Message Not Sent type: object properties: id: type: string description: If the message `id` is an empty string, then no message was sent. The request appears to be formatted correctly, but there are issues with the aliases, segments, or filters targeted. example: '' enum: - '' errors: type: array items: type: string description: Reasons the message was not dispatched. The most common value is `"All included players are not subscribed"`, which means every subscription matched by the segments/aliases/filters was unsubscribed before send time. Per-channel sentinels (e.g., invalid identifiers) may also appear. example: - All included players are not subscribed warnings: oneOf: - type: object description: Object form. properties: invalid_external_user_ids: type: string description: external_ids whose subscriptions are unsubscribed. additionalProperties: true - type: array items: type: string description: Array form. Contains non-fatal warning messages. description: Non-fatal warnings emitted alongside a successful send. description: Validation passed but the targeting matched zero subscribers (and the notification is not lightspeed-eligible). HTTP status is 200 even though no message was dispatched. `id` is always the empty string in this branch — use it as the discriminator from the Message Sent variant. required: - id - errors description: 'Two variants are possible with HTTP 200, distinguished by the `id` field: a UUID indicates the message was accepted and dispatched (Message Sent); an empty string indicates the request was valid but no subscribers matched (Message Not Sent). Inspect `errors` when `id` is empty.' headers: Idempotent-Replayed: description: Present and set to `true` when this response is a replay of a previous successful request that used the same `idempotency_key`. Absent on fresh executions. Use this to distinguish "new send" from "deduplicated retry" without inspecting the body. schema: type: boolean enum: - true '400': description: '400' content: application/json: schema: type: object properties: errors: type: array description: The reason for the bad request. items: properties: Message Notifications must have English language content: type: string description: Make sure the request or template has English language ('en')content. This is required but can be any language desired. 'Incorrect subscription_id format in include_subscription_ids (not a valid UUID):': type: string description: The provided `subscription_id` is not a valid UUID. ? Platforms You may only send to one delivery channel at a time. Make sure you are only including one of push platforms, Email, or SMS. : type: string description: You are attempting to send a message to a Subscription for a different channel. Make sure you are only targeting one channel at a time. '403': description: Forbidden. The Authorization key cannot send SMS for this app, or the request targets a feature the app's plan does not enable. content: application/json: schema: $ref: '#/components/schemas/BasicErrorResponse' example: errors: - This API is not available for applications on your plan. '429': description: Rate limit exceeded. Wait the number of seconds in the `Retry-After` header before retrying. headers: Retry-After: description: Number of seconds to wait before retrying the request. Always emitted on 429 responses. schema: type: integer minimum: 0 content: application/json: schema: $ref: '#/components/schemas/BasicErrorResponse' example: errors: - API rate limit exceeded '503': description: Service temporarily unavailable. Retry after a short backoff. The body may be empty or non-JSON in some failure modes. headers: Retry-After: description: Number of seconds to wait before retrying. Optional — may be absent when the response is generated upstream. schema: type: integer minimum: 0 content: application/json: schema: $ref: '#/components/schemas/BasicErrorResponse' example: errors: - Service temporarily unavailable deprecated: false tags: - Notifications?c=sms components: schemas: BasicErrorResponse: type: object properties: errors: type: array items: type: string description: One or more human-readable error messages. success: type: boolean description: Present (and `false`) on some endpoints (notifications, templates, segments). Not emitted by every endpoint. reference: type: array items: type: string description: Documentation URL fragments related to the error. Only emitted by the API-key auth error helpers.