Skip to content
SMS (XML, legacy)

API reference

Send SMS (XML, legacy)

POST /api/v1/xml/bulk/sms is kept for older integrations. It takes form-encoded fields and answers in XML. New integrations should use the JSON endpoint.

Legacy endpoint

This endpoint exists for integrations built against the old gateway and is kept working as it is. It returns no message IDs and its request is not XML despite the name. New integrations should use Send SMS (JSON), which has the same sender, number and bundle rules and returns a message ID per recipient.

POST/api/v1/xml/bulk/sms

Legacy SMS endpoint: form-encoded request, XML response. Requires an API key (see Authentication).

Parameters

fromRequiredstring
A sender ID registered and active on your account for SMS.
Example: Unicom360
toRequiredstring
1 to 2,000 numbers separated by commas, each in international format.
Example: 260971234567,260961234567
messageRequiredstring
The text, 1 to 1,200 GSM 7-bit characters.
Example: Your verification code is 482193
sourceRequiredstring
A label for the sending system. Required on this endpoint (the validator insists on it), any non-empty value will do.
Example: legacy-crm
msg_refOptionalstring
Your own reference for this send, the same idea as user_reference_id on the JSON endpoint.
Example: order-10421
callback_urlOptionalstring
HTTPS URL that receives a POST with the delivery status of each message.
Example: https://example.com/webhooks/unicom360/sms

Example request

curl -X POST https://api.unicom360.com/api/v1/xml/bulk/sms \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Accept: application/xml" \
  --data-urlencode "from=Unicom360" \
  --data-urlencode "to=260971234567,260961234567" \
  --data-urlencode "message=Your verification code is 482193. It expires in 5 minutes." \
  --data-urlencode "source=legacy-crm"

Responses

200 accepted
<?xml version="1.0" encoding="UTF-8"?>
<error>
  <response status-code="0">
    <message>SUCCESS</message>
  </response>
</error>

Yes, the root element is <error> even on success; status-code 0 and SUCCESS mean the messages were accepted. No message IDs are returned on this endpoint.

200 refused
<?xml version="1.0" encoding="UTF-8"?>
<error>
  <response status-code="-6">
    <message>INSUFFICIENT_BUNDLE_LIMIT</message>
  </response>
</error>

status-code -6 with one of INVALID_SENDER_ID, INVALID_RECIPIENT_LIMIT, INSUFFICIENT_BUNDLE_LIMIT, DUPLICATE_MSG_REF or INVALID_REQUEST. A missing field gives the validator's text instead, for example Missing required keys: ["source"].

401 authentication error
{
  "message": "AUTHENTICATION_FAILED",
  "success": false,
  "api_reference": "1764184470578998353"
}

Authentication failures are JSON, even on this endpoint, because they are raised before the XML handler runs.

Notes

  • There is no XML request body parser. Send the fields as application/x-www-form-urlencoded (as in the samples), as JSON, or in the query string. An XML document in the body is ignored and the request fails with Missing required keys.
  • The response is text/xml. Send an Accept header that allows XML (application/xml, text/xml or */*); an Accept header limited to application/json gets 406 Not Acceptable.
  • Older integrations that send sender or senderid instead of from, and mobiles instead of to, still work: those names take precedence when both are present. from and to must still be present to pass validation.

Differences from the JSON endpoint

  • The request body is form-encoded, with recipients as one comma-separated to field. source is required here and optional on JSON.
  • Your own reference is msg_ref rather than user_reference_id. The same rule applies: a reference already used for the same recipient is refused.
  • Every outcome is HTTP 200 with an XML body: status-code 0 for success and -6 for any refusal, including a missing field. Only authentication failures (401, 429) and an Accept header that excludes XML (406) use the HTTP status.
  • No message IDs come back. If you give a callback_url, the delivery callbacks carry a message_id you have not seen before; match on mobile_number instead, or move to the JSON endpoint.
  • A single number that cannot be parsed does not fail the request; it is recorded as invalid and the rest are sent. The XML response does not say which.