curl --request POST \
--url https://public-api.etoro.com/api/v1/users/phone/verifications \
--header 'Content-Type: application/json' \
--header 'X-Request-ID: <x-request-id>' \
--header 'x-api-key: <api-key>' \
--header 'x-user-key: <api-key>' \
--data '
{
"phoneCountryCode": "+1",
"phoneNumber": "5551234567",
"verificationType": "sms"
}
'import requests
url = "https://public-api.etoro.com/api/v1/users/phone/verifications"
payload = {
"phoneCountryCode": "+1",
"phoneNumber": "5551234567",
"verificationType": "sms"
}
headers = {
"X-Request-ID": "<x-request-id>",
"x-api-key": "<api-key>",
"x-user-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Request-ID': '<x-request-id>',
'x-api-key': '<api-key>',
'x-user-key': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({phoneCountryCode: '+1', phoneNumber: '5551234567', verificationType: 'sms'})
};
fetch('https://public-api.etoro.com/api/v1/users/phone/verifications', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://public-api.etoro.com/api/v1/users/phone/verifications",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'phoneCountryCode' => '+1',
'phoneNumber' => '5551234567',
'verificationType' => 'sms'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Request-ID: <x-request-id>",
"x-api-key: <api-key>",
"x-user-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://public-api.etoro.com/api/v1/users/phone/verifications"
payload := strings.NewReader("{\n \"phoneCountryCode\": \"+1\",\n \"phoneNumber\": \"5551234567\",\n \"verificationType\": \"sms\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Request-ID", "<x-request-id>")
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("x-user-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://public-api.etoro.com/api/v1/users/phone/verifications")
.header("X-Request-ID", "<x-request-id>")
.header("x-api-key", "<api-key>")
.header("x-user-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"phoneCountryCode\": \"+1\",\n \"phoneNumber\": \"5551234567\",\n \"verificationType\": \"sms\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://public-api.etoro.com/api/v1/users/phone/verifications")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Request-ID"] = '<x-request-id>'
request["x-api-key"] = '<api-key>'
request["x-user-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"phoneCountryCode\": \"+1\",\n \"phoneNumber\": \"5551234567\",\n \"verificationType\": \"sms\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"referenceId": "ref_abc123xyz",
"expiresAt": "2026-05-03T12:15:00Z"
}
}{
"success": false,
"error": {
"code": "InvalidPhoneCountryCode",
"message": "PhoneCountryCode must be a valid E.164 country code prefix.",
"details": "<string>",
"field": "<string>",
"value": "<unknown>"
}
}{
"success": false,
"error": {
"code": "InvalidPhoneCountryCode",
"message": "PhoneCountryCode must be a valid E.164 country code prefix.",
"details": "<string>",
"field": "<string>",
"value": "<unknown>"
}
}{
"success": false,
"error": {
"code": "InvalidPhoneCountryCode",
"message": "PhoneCountryCode must be a valid E.164 country code prefix.",
"details": "<string>",
"field": "<string>",
"value": "<unknown>"
}
}{
"success": false,
"error": {
"code": "InvalidPhoneCountryCode",
"message": "PhoneCountryCode must be a valid E.164 country code prefix.",
"details": "<string>",
"field": "<string>",
"value": "<unknown>"
}
}{
"success": false,
"error": {
"code": "InvalidPhoneCountryCode",
"message": "PhoneCountryCode must be a valid E.164 country code prefix.",
"details": "<string>",
"field": "<string>",
"value": "<unknown>"
}
}Initiate phone verification
Rate limit: 60 requests per 60 seconds. This is a shared quota — the same budget is consumed by a group of related endpoints, so calling any of them reduces what is left for the others (you cannot call each at the full rate independently). Endpoints sharing this quota:
POST /api/v1/users/phone/verifications/confirmationsPOST /api/v1/users/phone/verifications/direct-confirmations
Sends a verification code to the specified phone number. Returns a referenceId to use when verifying the code.
SECURITY: This endpoint can ONLY be used to set a phone number for users who do not yet have a verified phone number. Changing an existing verified phone number is NOT permitted through this endpoint.
To change an existing phone number, users must contact Customer Support.
curl --request POST \
--url https://public-api.etoro.com/api/v1/users/phone/verifications \
--header 'Content-Type: application/json' \
--header 'X-Request-ID: <x-request-id>' \
--header 'x-api-key: <api-key>' \
--header 'x-user-key: <api-key>' \
--data '
{
"phoneCountryCode": "+1",
"phoneNumber": "5551234567",
"verificationType": "sms"
}
'import requests
url = "https://public-api.etoro.com/api/v1/users/phone/verifications"
payload = {
"phoneCountryCode": "+1",
"phoneNumber": "5551234567",
"verificationType": "sms"
}
headers = {
"X-Request-ID": "<x-request-id>",
"x-api-key": "<api-key>",
"x-user-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Request-ID': '<x-request-id>',
'x-api-key': '<api-key>',
'x-user-key': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({phoneCountryCode: '+1', phoneNumber: '5551234567', verificationType: 'sms'})
};
fetch('https://public-api.etoro.com/api/v1/users/phone/verifications', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://public-api.etoro.com/api/v1/users/phone/verifications",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'phoneCountryCode' => '+1',
'phoneNumber' => '5551234567',
'verificationType' => 'sms'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Request-ID: <x-request-id>",
"x-api-key: <api-key>",
"x-user-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://public-api.etoro.com/api/v1/users/phone/verifications"
payload := strings.NewReader("{\n \"phoneCountryCode\": \"+1\",\n \"phoneNumber\": \"5551234567\",\n \"verificationType\": \"sms\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Request-ID", "<x-request-id>")
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("x-user-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://public-api.etoro.com/api/v1/users/phone/verifications")
.header("X-Request-ID", "<x-request-id>")
.header("x-api-key", "<api-key>")
.header("x-user-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"phoneCountryCode\": \"+1\",\n \"phoneNumber\": \"5551234567\",\n \"verificationType\": \"sms\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://public-api.etoro.com/api/v1/users/phone/verifications")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Request-ID"] = '<x-request-id>'
request["x-api-key"] = '<api-key>'
request["x-user-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"phoneCountryCode\": \"+1\",\n \"phoneNumber\": \"5551234567\",\n \"verificationType\": \"sms\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"referenceId": "ref_abc123xyz",
"expiresAt": "2026-05-03T12:15:00Z"
}
}{
"success": false,
"error": {
"code": "InvalidPhoneCountryCode",
"message": "PhoneCountryCode must be a valid E.164 country code prefix.",
"details": "<string>",
"field": "<string>",
"value": "<unknown>"
}
}{
"success": false,
"error": {
"code": "InvalidPhoneCountryCode",
"message": "PhoneCountryCode must be a valid E.164 country code prefix.",
"details": "<string>",
"field": "<string>",
"value": "<unknown>"
}
}{
"success": false,
"error": {
"code": "InvalidPhoneCountryCode",
"message": "PhoneCountryCode must be a valid E.164 country code prefix.",
"details": "<string>",
"field": "<string>",
"value": "<unknown>"
}
}{
"success": false,
"error": {
"code": "InvalidPhoneCountryCode",
"message": "PhoneCountryCode must be a valid E.164 country code prefix.",
"details": "<string>",
"field": "<string>",
"value": "<unknown>"
}
}{
"success": false,
"error": {
"code": "InvalidPhoneCountryCode",
"message": "PhoneCountryCode must be a valid E.164 country code prefix.",
"details": "<string>",
"field": "<string>",
"value": "<unknown>"
}
}Authorizations
API key of the application. Only valid together with the x-user-key header — the pair is an alternative to OAuth bearer authentication, never sent alongside it. The pair is granted the same permissions the operation's OAuth scopes describe.
Demo credential for trying the API from these docs: lhgfaslk21490FAScVPkdsb53F9dNkfHG4faZSG5vfjndfcfgdssdgsdHF4663
User-specific authentication key. Only valid together with the x-api-key header — the pair is an alternative to OAuth bearer authentication, never sent alongside it.
Demo credential for trying the API from these docs: eyJlYW4iOiJVbnJlZ2lzdGVyZWRBcHBsaWNhdGlvbiIsImVrIjoiOE5sZ2cwcW5EUVdROUFNWGpXT2lmOWktZnpidG5KcUlqWGJ3WHJZZkpZcldrbG90ZEhvLVBjSWhQaU8xU1ZtMW84aU1WZGZqN2xWNzFjLXFxLmcybXE1dnh4Q1hUT25xaWRUaTFlcEhmVk1fIn0_
Headers
Body
Country dial code in E.164 prefix format (e.g., "+1", "+44").
^\+[1-9][0-9]{0,3}$"+1"
Phone number digits without country code.
^[0-9]{6,15}$"5551234567"
Method of verification. Defaults to sms if not specified.
sms, voiceCall "sms"