You need a OneTouch account with an active plan and tokens. Create an API key in Dashboard → Developer API.
1. Quick start
Send this from your server:
curl -X POST https://neo1touch.com/api/v1/sms.php \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"to": "+2348031234567", "message": "Welcome to MyApp! Your code is 482913"}'
A successful reply:
{
"success": true,
"data": {
"message_id": "3017544054459094834646",
"status": "sent",
"recipients": 1,
"pages": 1,
"tokens_charged": 6,
"balance": 9814,
"sender": "MyBrand",
"reference": null
}
}
2. Authentication
Every request carries your API key in a header — either form works:
Authorization: Bearer ot_live_…
X-API-Key: ot_live_…
- Call the API from your server only. Never put the key in a mobile app, a website’s JavaScript or a public repository — anyone who finds it can send SMS with your tokens. The API refuses browser (CORS) requests for this reason.
- Keep the key in an environment variable or your server’s config file.
- Leaked or no longer needed? Revoke it in Developer API; it stops working at once.
3. Send SMS
JSON body:
| Field | Type | Required | Description |
|---|---|---|---|
to | string or array | Yes | One number, or up to 100. International format such as +2348031234567; Nigerian local numbers (08031234567) are accepted too. |
message | string | Yes | The SMS text, up to 6 SMS pages (see Pricing). |
reference | string | No | Your own id (up to 64 characters), echoed back and shown in your OneTouch log. |
SMS go out from your account’s approved Sender ID (request one in OneTouch → SMS Sender ID) through the DND route, so they also reach numbers on Do-Not-Disturb — right for sign-up and login codes.
4. Send email
curl -X POST https://neo1touch.com/api/v1/email.php \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"to": "ada@example.com", "subject": "Welcome to MyApp", "html": "<h1>Welcome, Ada!</h1><p>Your account is ready.</p>", "reply_to": "support@myapp.com"}'
| Field | Type | Required | Description |
|---|---|---|---|
to | string or array | Yes | One address, or up to 50. Each person gets their own email; they don’t see each other. |
subject | string | Yes | Up to 200 characters. |
html | string | One of html/text | The email as HTML (up to 300 KB). Scripts, forms and embedded frames are removed. Pictures must be online links (https://…). |
text | string | One of html/text | A plain-text version. Send both if you can; if you send only one, we make the other. |
from_name | string | No | The sender name people see. Defaults to the organisation name on the OneTouch account. |
reply_to | string | No | Where replies go, e.g. your support address. |
reference | string | No | Your own id (up to 64 characters), echoed back. |
A successful reply lists each recipient:
{
"success": true,
"data": {
"status": "sent",
"sent": 1,
"failed": 0,
"results": [ { "to": "ada@example.com", "status": "sent", "id": "4ef9a417-…" } ],
"tokens_charged": 1,
"balance": 9813,
"from": "MyApp",
"reference": null
}
}
With several recipients, status is "partial" when some failed; you’re charged only for the ones sent. Emails come from OneTouch’s sending address with your name as the sender. The API is for transactional email (codes, welcomes, receipts, alerts) — not newsletters or marketing lists; use OneTouch broadcasts for those, which handle unsubscribes.
5. Check your balance
{ "success": true, "data": { "balance": 9814, "tokens_per_sms_page": 6, "tokens_per_email": 1, "sender": "MyBrand", "plan_active": true } }
6. Errors
Errors use HTTP status codes and this shape: {"success": false, "error": {"code": "…", "message": "…"}}. Show your users your own message; log ours.
| HTTP | code | Meaning |
|---|---|---|
| 400 | invalid_body | The body isn’t JSON with to and message. |
| 401 | invalid_api_key | Missing, wrong or revoked key. |
| 402 | plan_required | The account has no active plan. |
| 402 | insufficient_tokens | Not enough tokens — top up in OneTouch. Nothing was sent. |
| 405 | method_not_allowed | Wrong HTTP method. |
| 422 | message_required, message_too_long, invalid_recipient, subject_required, content_required, content_too_large, invalid_html, invalid_reply_to | Fix the request; the message says what’s wrong. |
| 429 | rate_limited | Over 120 messages (SMS + email) a minute for this key. Wait and retry (see Retry-After). |
| 502 | send_failed | The SMS network or email service refused it (for SMS, often the Sender ID). Nothing was charged. |
| 500 | server_error | A problem on our side. Retry later. |
7. Pricing and limits
- Each SMS uses tokens from your OneTouch balance: the price per page (see
tokens_per_sms_page) × pages × recipients. You’re charged only when the SMS is accepted for delivery. - Each email costs
tokens_per_emailper recipient it was sent to. - One page = 160 characters (153 per page when split). A message with emoji or special characters (like ’ or “) is Unicode: 70 characters (67 per page when split).
- SMS: up to 100 recipients and 6 pages per request. Email: up to 50 recipients per request. 120 messages a minute per key in total.
8. Example: send a code when someone registers
Generate the code on your server, store it with an expiry, send it, then check what the user types.
<?php
// After saving the new user:
$code = random_int(100000, 999999);
// save $code (hashed) with an expiry of e.g. 10 minutes against the user …
$ch = curl_init('https://neo1touch.com/api/v1/sms.php');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('ONETOUCH_API_KEY'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode([
'to' => $user['phone'],
'message' => "Welcome to MyApp! Your verification code is $code. It expires in 10 minutes.",
'reference' => 'signup-' . $user['id'],
]),
]);
$res = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status !== 200 || empty($res['success'])) {
error_log('OneTouch SMS failed: ' . ($res['error']['message'] ?? "HTTP $status"));
// let the user ask for a new code
}
// Node 18+ (built-in fetch). After saving the new user:
const code = crypto.randomInt(100000, 1000000);
// save the code (hashed) with an expiry against the user …
const res = await fetch('https://neo1touch.com/api/v1/sms.php', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.ONETOUCH_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
to: user.phone,
message: `Welcome to MyApp! Your verification code is ${code}. It expires in 10 minutes.`,
reference: `signup-${user.id}`,
}),
});
const body = await res.json();
if (!res.ok || !body.success) {
console.error('OneTouch SMS failed:', body.error?.message ?? res.status);
}
# pip install requests. After saving the new user:
import os, secrets, requests
code = 100000 + secrets.randbelow(900000)
# save the code (hashed) with an expiry against the user …
r = requests.post(
"https://neo1touch.com/api/v1/sms.php",
headers={"Authorization": f"Bearer {os.environ['ONETOUCH_API_KEY']}"},
json={
"to": user.phone,
"message": f"Welcome to MyApp! Your verification code is {code}. It expires in 10 minutes.",
"reference": f"signup-{user.id}",
},
timeout=30,
)
body = r.json()
if r.status_code != 200 or not body.get("success"):
print("OneTouch SMS failed:", body.get("error", {}).get("message", r.status_code))
A welcome email is the same request to /email.php with to, subject and html instead of message.
9. Good practice
- Limit how often one phone number or IP can ask for a code (for example 3 an hour), so nobody can spend your tokens by abusing your sign-up form.
- Store codes hashed, expire them after a few minutes, and allow only a few wrong attempts.
- Don’t retry automatically on
402or422; on429,500or a timeout, retry once after a short wait. - Use a Sender ID your users recognise; until yours is approved, SMS come from the shared OneTouch name.
- Set
reply_toto an inbox you read, so replies to your emails reach you. - Watch usage and failures in Dashboard → Developer API.
Need help?
Email admin@httn.org with your account email and the reference or time of the message.
