Skip to content

מספרי שולח מאומתים

ה-source בשליחה — השם או המספר שההודעה נראית כאילו הגיעה ממנו — חייב להיות מאומת לפני שאפשר להשתמש בו. שתי הפעולות האלה שולחות מספרים לאימות ומציגות את אלה שאושרו.

http
POST https://my.textme.co.il/api

שליחה משולח לא מאומת נכשלת בסטטוס 515.

verify_phone שליחת מספרים לאימות

מתחילה אימות של מספר אחד או יותר. גם מספרים ניידים וגם קווים נייחים מתקבלים, וכל אחד מאומת בדרך שונה — ראו את ההערה על התשובה למטה.

פרמטרים

שםסוגתיאורחובה
verify_phoneobjectמכיל את כל האלמנטים האחרים.✔️
userobjectמכיל את אלמנט המשתמש.✔️
usernamestringשם המשתמש של החשבון שבו אתם מזוהים במערכת.✔️
phoneobjectמספר לשימוש כמספר שולח ל-SMS. חייב להיות מספר נייד או נייח חוקי. חזרתי.✔️

דוגמת בקשה

xml
<?xml version="1.0" encoding="UTF-8"?>
<verify_phone>
    <user>
        <username>Leeroy</username>
    </user>
    <phone>5xxxxxxxx</phone>
    <phone>3xxxxxxx</phone>
</verify_phone>
json
{
  "verify_phone": {
    "user": {
      "username": "Leeroy"
    },
    "phone": [
      "5xxxxxxxx",
      "3xxxxxxx"
    ]
  }
}
bash
curl --location 'https://my.textme.co.il/api' \
--header "Authorization: Bearer $TEXTME_API_TOKEN" \
--header 'Content-Type: application/json' \
--data '{
  "verify_phone": {
    "user": {
      "username": "Leeroy"
    },
    "phone": [
      "5xxxxxxxx",
      "3xxxxxxx"
    ]
  }
}'
js
// Node.js 18+ / דפדפנים — ללא תלויות
const response = await fetch('https://my.textme.co.il/api', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.TEXTME_API_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    verify_phone: {
      user: {
        username: 'Leeroy',
      },
      phone: [
        '5xxxxxxxx',
        '3xxxxxxx',
      ],
    },
  }),
})

const result = await response.json()

// גם שגיאה חוזרת כ-HTTP 200 — הסטטוס שבגוף התשובה הוא הקובע
if (Number(result.status) !== 0) {
  throw new Error(`TextMe ${result.status}: ${result.message}`)
}

console.log(result)
php
<?php
// composer require guzzlehttp/guzzle

$client = new \GuzzleHttp\Client([
    'headers' => [
        'Authorization' => 'Bearer '.getenv('TEXTME_API_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

$response = $client->post('https://my.textme.co.il/api', [
    'json' => [
        'verify_phone' => [
            'user' => [
                'username' => 'Leeroy',
            ],
            'phone' => [
                '5xxxxxxxx',
                '3xxxxxxx',
            ],
        ],
    ],
]);

$result = json_decode($response->getBody()->getContents(), true);

// גם שגיאה חוזרת כ-HTTP 200 — הסטטוס שבגוף התשובה הוא הקובע
if ((int) $result['status'] !== 0) {
    throw new RuntimeException("TextMe {$result['status']}: {$result['message']}");
}

print_r($result);
php
<?php

use Illuminate\Support\Facades\Http;

$result = Http::withToken(config('services.textme.token'))
    ->acceptJson()
    ->post('https://my.textme.co.il/api', [
        'verify_phone' => [
            'user' => [
                'username' => 'Leeroy',
            ],
            'phone' => [
                '5xxxxxxxx',
                '3xxxxxxx',
            ],
        ],
    ])
    ->throw()
    ->json();

// גם שגיאה חוזרת כ-HTTP 200 — הסטטוס שבגוף התשובה הוא הקובע
throw_if((int) $result['status'] !== 0, RuntimeException::class,
    "TextMe {$result['status']}: {$result['message']}");

logger()->info('TextMe', $result);
python
# pip install httpx
import os

import httpx

response = httpx.post(
    "https://my.textme.co.il/api",
    headers={"Authorization": f"Bearer {os.environ['TEXTME_API_TOKEN']}"},
    json={
        "verify_phone": {
            "user": {
                "username": "Leeroy",
            },
            "phone": [
                "5xxxxxxxx",
                "3xxxxxxx",
            ],
        },
    },
)
response.raise_for_status()
result = response.json()

# גם שגיאה חוזרת כ-HTTP 200 — הסטטוס שבגוף התשובה הוא הקובע
if int(result["status"]) != 0:
    raise RuntimeError(f"TextMe {result['status']}: {result['message']}")

print(result)
go
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
	"os"
)

func main() {
	payload, _ := json.Marshal(map[string]any{
		"verify_phone": map[string]any{
			"user": map[string]any{
				"username": "Leeroy",
			},
			"phone": []any{
				"5xxxxxxxx",
				"3xxxxxxx",
			},
		},
	})

	req, _ := http.NewRequest("POST", "https://my.textme.co.il/api", bytes.NewReader(payload))
	req.Header.Set("Authorization", "Bearer "+os.Getenv("TEXTME_API_TOKEN"))
	req.Header.Set("Content-Type", "application/json")

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	var result struct {
		Status  json.Number `json:"status"`
		Message string      `json:"message"`
	}
	if err := json.NewDecoder(res.Body).Decode(&result); err != nil {
		panic(err)
	}

	// גם שגיאה חוזרת כ-HTTP 200 — הסטטוס שבגוף התשובה הוא הקובע
	if result.Status.String() != "0" {
		panic(fmt.Sprintf("TextMe %s: %s", result.Status, result.Message))
	}

	fmt.Println(result.Message)
}
java
// Java 17+ — java.net.http, ללא תלויות (פענוח עם Jackson/Gson)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class TextMeVerifyPhone {
    public static void main(String[] args) throws Exception {
        String body = """
            {
              "verify_phone": {
                "user": {
                  "username": "Leeroy"
                },
                "phone": [
                  "5xxxxxxxx",
                  "3xxxxxxx"
                ]
              }
            }
            """;

        HttpRequest request = HttpRequest.newBuilder(URI.create("https://my.textme.co.il/api"))
            .header("Authorization", "Bearer " + System.getenv("TEXTME_API_TOKEN"))
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(body))
            .build();

        HttpResponse<String> response = HttpClient.newHttpClient()
            .send(request, HttpResponse.BodyHandlers.ofString());

        // גם שגיאה חוזרת כ-HTTP 200 — הסטטוס שבגוף התשובה הוא הקובע
        System.out.println(response.body());
    }
}
csharp
// .NET 8+ — System.Net.Http
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;

var payload = """
    {
      "verify_phone": {
        "user": {
          "username": "Leeroy"
        },
        "phone": [
          "5xxxxxxxx",
          "3xxxxxxx"
        ]
      }
    }
    """;

using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
    "Bearer", Environment.GetEnvironmentVariable("TEXTME_API_TOKEN"));

var response = await http.PostAsync("https://my.textme.co.il/api",
    new StringContent(payload, Encoding.UTF8, "application/json"));

var result = JsonDocument.Parse(await response.Content.ReadAsStringAsync()).RootElement;
var status = result.GetProperty("status").ToString();

// גם שגיאה חוזרת כ-HTTP 200 — הסטטוס שבגוף התשובה הוא הקובע
if (status != "0")
{
    var message = result.GetProperty("message").ToString();
    throw new Exception($"TextMe {status}: {message}");
}

Console.WriteLine(result);
ruby
require "net/http"
require "json"

uri = URI("https://my.textme.co.il/api")

request = Net::HTTP::Post.new(uri)
request["Authorization"] = "Bearer #{ENV.fetch('TEXTME_API_TOKEN')}"
request["Content-Type"] = "application/json"
request.body = JSON.dump({
  "verify_phone" => {
    "user" => {
      "username" => "Leeroy",
    },
    "phone" => [
      "5xxxxxxxx",
      "3xxxxxxx",
    ],
  },
})

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(request)
end

result = JSON.parse(response.body)

# גם שגיאה חוזרת כ-HTTP 200 — הסטטוס שבגוף התשובה הוא הקובע
raise "TextMe #{result['status']}: #{result['message']}" unless result["status"].to_i.zero?

pp result
rust
// [dependencies]
// reqwest = { version = "0.12", features = ["json"] }
// tokio = { version = "1", features = ["full"] }
// serde_json = "1"
use serde_json::{json, Value};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let result: Value = reqwest::Client::new()
        .post("https://my.textme.co.il/api")
        .bearer_auth(std::env::var("TEXTME_API_TOKEN")?)
        .json(&json!({
          "verify_phone": {
            "user": {
              "username": "Leeroy"
            },
            "phone": [
              "5xxxxxxxx",
              "3xxxxxxx"
            ]
          }
        }))
        .send()
        .await?
        .json()
        .await?;

    // גם שגיאה חוזרת כ-HTTP 200 — הסטטוס שבגוף התשובה הוא הקובע
    if result["status"] != 0 {
        return Err(format!("TextMe {}: {}", result["status"], result["message"]).into());
    }

    println!("{result}");
    Ok(())
}

תשובה

xml
<?xml version="1.0" encoding="utf-8"?>
<verify_phone>
    <status>0</status>
    <verify_message>verification link will be send to 5******** in order to complete the verification of 3******* call to 0552458888</verify_message>
</verify_phone>
json
{
  "status": 0,
  "verify_message": "verification link will be send to 5******** in order to complete the verification of 3******* call to 0552458888"
}
שדהסוגתיאור
statusint0 — המספרים נתקבלו לאימות.
verify_messagestringמה קורה עכשיו, לכל מספר. שימו לב לשם השדה: verify_message, לא message.

"נתקבל" אינו "מאומת"

status: 0 אומר שהאימות התחיל. ה-verify_message מסביר מה כל מספר עוד צריך:

  • מספרים ניידים מקבלים קישור אימות ב-SMS, שמישהו צריך ללחוץ עליו.
  • קווים נייחים אינם יכולים לקבל SMS, ולכן האימות מושלם בשיחה למספר שמופיע בהודעה.

עד להשלמת השלב הזה לא ניתן לשלוח מהמספר. ודאו עם getVerifiedPhones במקום להניח.

שגיאות

Statusמתי
510invalid verify_phone request: no phones to verify — לא נשלח אף אלמנט phone.
9מספר קצר או ארוך מדי.
511החשבון אינו רשאי לבצע את הפעולה.

getVerifiedPhones רשימת המספרים המאומתים

מחזירה את המספרים שאושרו כשולחים, עם מועד השיוך ומועד העדכון האחרון.

פרמטרים

שםסוגתיאורחובה
getVerifiedPhonesobjectמכיל את כל האלמנטים האחרים.✔️
userobjectמכיל את אלמנט המשתמש.✔️
usernamestringשם המשתמש של החשבון שבו אתם מזוהים במערכת.✔️
is_subsintערך 1 כדי לכלול את המספרים המאומתים של חשבונות המשנה שלכם. השמיטו את השדה כליל כדי לא לכלול אותם.

דוגמת בקשה

xml
<?xml version="1.0" encoding="UTF-8"?>
<getVerifiedPhones>
    <user>
        <username>username</username>
    </user>
    <is_subs>1</is_subs>
</getVerifiedPhones>
json
{
  "getVerifiedPhones": {
    "user": {
      "username": "username"
    },
    "is_subs": "1"
  }
}
bash
curl --location 'https://my.textme.co.il/api' \
--header "Authorization: Bearer $TEXTME_API_TOKEN" \
--header 'Content-Type: application/json' \
--data '{
  "getVerifiedPhones": {
    "user": {
      "username": "username"
    },
    "is_subs": "1"
  }
}'
js
// Node.js 18+ / דפדפנים — ללא תלויות
const response = await fetch('https://my.textme.co.il/api', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.TEXTME_API_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    getVerifiedPhones: {
      user: {
        username: 'username',
      },
      is_subs: '1',
    },
  }),
})

const result = await response.json()

// גם שגיאה חוזרת כ-HTTP 200 — הסטטוס שבגוף התשובה הוא הקובע
if (Number(result.status) !== 0) {
  throw new Error(`TextMe ${result.status}: ${result.message}`)
}

console.log(result)
php
<?php
// composer require guzzlehttp/guzzle

$client = new \GuzzleHttp\Client([
    'headers' => [
        'Authorization' => 'Bearer '.getenv('TEXTME_API_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

$response = $client->post('https://my.textme.co.il/api', [
    'json' => [
        'getVerifiedPhones' => [
            'user' => [
                'username' => 'username',
            ],
            'is_subs' => '1',
        ],
    ],
]);

$result = json_decode($response->getBody()->getContents(), true);

// גם שגיאה חוזרת כ-HTTP 200 — הסטטוס שבגוף התשובה הוא הקובע
if ((int) $result['status'] !== 0) {
    throw new RuntimeException("TextMe {$result['status']}: {$result['message']}");
}

print_r($result);
php
<?php

use Illuminate\Support\Facades\Http;

$result = Http::withToken(config('services.textme.token'))
    ->acceptJson()
    ->post('https://my.textme.co.il/api', [
        'getVerifiedPhones' => [
            'user' => [
                'username' => 'username',
            ],
            'is_subs' => '1',
        ],
    ])
    ->throw()
    ->json();

// גם שגיאה חוזרת כ-HTTP 200 — הסטטוס שבגוף התשובה הוא הקובע
throw_if((int) $result['status'] !== 0, RuntimeException::class,
    "TextMe {$result['status']}: {$result['message']}");

logger()->info('TextMe', $result);
python
# pip install httpx
import os

import httpx

response = httpx.post(
    "https://my.textme.co.il/api",
    headers={"Authorization": f"Bearer {os.environ['TEXTME_API_TOKEN']}"},
    json={
        "getVerifiedPhones": {
            "user": {
                "username": "username",
            },
            "is_subs": "1",
        },
    },
)
response.raise_for_status()
result = response.json()

# גם שגיאה חוזרת כ-HTTP 200 — הסטטוס שבגוף התשובה הוא הקובע
if int(result["status"]) != 0:
    raise RuntimeError(f"TextMe {result['status']}: {result['message']}")

print(result)
go
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
	"os"
)

func main() {
	payload, _ := json.Marshal(map[string]any{
		"getVerifiedPhones": map[string]any{
			"user": map[string]any{
				"username": "username",
			},
			"is_subs": "1",
		},
	})

	req, _ := http.NewRequest("POST", "https://my.textme.co.il/api", bytes.NewReader(payload))
	req.Header.Set("Authorization", "Bearer "+os.Getenv("TEXTME_API_TOKEN"))
	req.Header.Set("Content-Type", "application/json")

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	var result struct {
		Status  json.Number `json:"status"`
		Message string      `json:"message"`
	}
	if err := json.NewDecoder(res.Body).Decode(&result); err != nil {
		panic(err)
	}

	// גם שגיאה חוזרת כ-HTTP 200 — הסטטוס שבגוף התשובה הוא הקובע
	if result.Status.String() != "0" {
		panic(fmt.Sprintf("TextMe %s: %s", result.Status, result.Message))
	}

	fmt.Println(result.Message)
}
java
// Java 17+ — java.net.http, ללא תלויות (פענוח עם Jackson/Gson)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class TextMeVerifiedPhones {
    public static void main(String[] args) throws Exception {
        String body = """
            {
              "getVerifiedPhones": {
                "user": {
                  "username": "username"
                },
                "is_subs": "1"
              }
            }
            """;

        HttpRequest request = HttpRequest.newBuilder(URI.create("https://my.textme.co.il/api"))
            .header("Authorization", "Bearer " + System.getenv("TEXTME_API_TOKEN"))
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(body))
            .build();

        HttpResponse<String> response = HttpClient.newHttpClient()
            .send(request, HttpResponse.BodyHandlers.ofString());

        // גם שגיאה חוזרת כ-HTTP 200 — הסטטוס שבגוף התשובה הוא הקובע
        System.out.println(response.body());
    }
}
csharp
// .NET 8+ — System.Net.Http
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;

var payload = """
    {
      "getVerifiedPhones": {
        "user": {
          "username": "username"
        },
        "is_subs": "1"
      }
    }
    """;

using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
    "Bearer", Environment.GetEnvironmentVariable("TEXTME_API_TOKEN"));

var response = await http.PostAsync("https://my.textme.co.il/api",
    new StringContent(payload, Encoding.UTF8, "application/json"));

var result = JsonDocument.Parse(await response.Content.ReadAsStringAsync()).RootElement;
var status = result.GetProperty("status").ToString();

// גם שגיאה חוזרת כ-HTTP 200 — הסטטוס שבגוף התשובה הוא הקובע
if (status != "0")
{
    var message = result.GetProperty("message").ToString();
    throw new Exception($"TextMe {status}: {message}");
}

Console.WriteLine(result);
ruby
require "net/http"
require "json"

uri = URI("https://my.textme.co.il/api")

request = Net::HTTP::Post.new(uri)
request["Authorization"] = "Bearer #{ENV.fetch('TEXTME_API_TOKEN')}"
request["Content-Type"] = "application/json"
request.body = JSON.dump({
  "getVerifiedPhones" => {
    "user" => {
      "username" => "username",
    },
    "is_subs" => "1",
  },
})

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(request)
end

result = JSON.parse(response.body)

# גם שגיאה חוזרת כ-HTTP 200 — הסטטוס שבגוף התשובה הוא הקובע
raise "TextMe #{result['status']}: #{result['message']}" unless result["status"].to_i.zero?

pp result
rust
// [dependencies]
// reqwest = { version = "0.12", features = ["json"] }
// tokio = { version = "1", features = ["full"] }
// serde_json = "1"
use serde_json::{json, Value};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let result: Value = reqwest::Client::new()
        .post("https://my.textme.co.il/api")
        .bearer_auth(std::env::var("TEXTME_API_TOKEN")?)
        .json(&json!({
          "getVerifiedPhones": {
            "user": {
              "username": "username"
            },
            "is_subs": "1"
          }
        }))
        .send()
        .await?
        .json()
        .await?;

    // גם שגיאה חוזרת כ-HTTP 200 — הסטטוס שבגוף התשובה הוא הקובע
    if result["status"] != 0 {
        return Err(format!("TextMe {}: {}", result["status"], result["message"]).into());
    }

    println!("{result}");
    Ok(())
}

תשובה

xml
<?xml version="1.0" encoding="UTF-8"?>
<getVerifiedPhones>
    <status>0</status>
    <message></message>
    <verified_phones>
        <verified_phone>
            <PHONE>xxxxxxxxxx</PHONE>
            <USER_ID>xxx</USER_ID>
            <ASSIGNMENT_DATE>03/12/14 12:33</ASSIGNMENT_DATE>
            <LAST_UPDATE>03/12/14 12:33</LAST_UPDATE>
        </verified_phone>
    </verified_phones>
</getVerifiedPhones>
json
{
  "status": 0,
  "message": "",
  "verified_phones": [
    {
      "PHONE": "xxxxxxxxxx",
      "USER_ID": "XXXX",
      "ASSIGNMENT_DATE": "03/12/14 12:33",
      "LAST_UPDATE": "03/12/14 12:33"
    }
  ]
}
שדהסוגתיאור
verified_phonesarrayרשומה אחת לכל מספר מאומת.
PHONEstringהמספר המאומת.
USER_IDstringהחשבון שאליו הוא שייך — שימושי כש-is_subs בערך 1.
ASSIGNMENT_DATEstringמועד האימות, dd/mm/yy hh:mm.
LAST_UPDATEstringמועד השינוי האחרון ברשומה.

שמות השדות כאן באותיות גדולות

כמו בקמפייני יום הולדת, התשובה הזו משתמשת ב-PHONE, USER_ID, ASSIGNMENT_DATE ו-LAST_UPDATE ולא בסגנון האותיות הקטנות שנהוג בשאר ה-API.

שגיאות

Statusמתי
3, 10, 11טוקן לא תקף, פג תוקף, או שייך ל-username אחר.
511החשבון אינו רשאי לבצע את הפעולה.

הערות על השדות

מספרים ושמות שולח באנגלית

source יכול להיות מספר (0551234567) או שם קצר באנגלית (DemoAPI) — עד 11 תווים, אותיות וספרות בלבד, בלי +.

verify_phone מכסה את המקרה המספרי: היא מוכיחה שהקו בשליטתכם. שמות שולח באנגלית מוסדרים ישירות עם TextMe ולא דרך הפעולה הזו, כי אין קו שאפשר לשלוח אליו קישור אימות.

לאמת לפני שצריך

באימות מעורב אדם — לחיצה על קישור, או ביצוע שיחה — ולכן זה לא משהו לגלות בזמן פריסה. קראו ל-getVerifiedPhones כבדיקת עלייה והיכשלו בקול רם אם השולח שההגדרות מצפות לו חסר. כך רצף של כשלי 515 בשקט הופך לשגיאה אחת ברורה עוד לפני שתעבורה זזה.

חשבונות משנה

חשבונות המשנה של משווק מאמתים את השולחים שלהם. is_subs: 1 נותן להורה מבט אחד על כולם, כאשר USER_ID מזהה את הבעלים של כל רשומה. ניהול חשבונות משנה מכוסה במנויים.

שיחות קוליות לא משתמשות בזה

שיחת TTS יוצאת תמיד ממספר מערכת של TextMe, מה ש-source לא יגיד. האימות חל על חלק ה-SMS של השליחה בלבד.